Compare commits

...
Author SHA1 Message Date
Stefan Eilers 5c69589355 Merge remote-tracking branch 'Slevenbits/master' into slevenbits-master 2013-01-02 14:45:22 +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
Stefan Eilers c7e0341c2c Merge remote-tracking branch 'Slevenbits/master' into slevenbits-master 2012-12-26 21:33:40 +01: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
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
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
Stefan Eilers a61db69dea Merge branch 'master' of git://github.com/slevenbits/cappuccino into slevenbits-master 2012-12-14 16:33:55 +01: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
Stefan Eilers f974955d4b Fix "jake release" 2012-12-13 17:06:15 +01: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
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
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
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
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
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
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
Alexander Ljungberg 7de4fe7afa Fixed: automatic table view sort descriptors didn't work for deeper bindings.
If a table view column showed for example `arrangedObjects.user.name`, it would try to sort arranged objects by `name` instead of `user.name`.
2012-10-23 15:24:10 +01:00
Alexander Ljungberg fb155dec58 Allow non-string tooltips.
Technically the tooltip should be a `CPString` but if a date or a number is passed this will now work without a crash.
2012-10-23 11:44:21 +01:00
Alexander Ljungberg 90d27133b0 Fixed: relative URLs were deemed to fail the SOP test by web views. 2012-10-23 11:22:24 +01:00
Alexander Ljungberg 0f5d459ed8 Fixed: collection view crash on unepexted drag events. 2012-10-23 11:21:42 +01:00
Alexander Ljungberg f4dc08f1f8 Merge branch 'master' of github.com:cappuccino/cappuccino 2012-10-22 23:14:08 +01:00
Alexander Ljungberg 4bedd52e16 CPGraphicsContext saveGraphicsState and restoreGraphicsState. 2012-10-22 15:03:32 +01:00
Alexander Ljungberg 391701fdc7 - CPBezierPath addClip and setClip.
This enables e.g. a `CPGradient` to be drawn clipped by an arbitrary bezier path.
2012-10-22 15:02:28 +01:00
Antoine Mercadal a973be2566 fix bad import 2012-10-18 15:26:15 -07:00
Antoine Mercadal 298fd49c55 Merge branch 'master' of https://github.com/cappuccino/cappuccino 2012-10-18 14:23:22 -07:00
Antoine Mercadal 23adbd4407 Improve tooltips API and avoid some sticky tooltips 2012-10-18 14:22:47 -07:00
Alexander Ljungberg eba3e95b81 CPBezierPath controlPointBounds and CGPathGetBoundingBox. 2012-10-15 11:10:23 +01:00
Alexander Ljungberg 8819fd5fd7 Improve nib2cib support for NSMatrix based radio groups.
Without this fix, a matrix with a target-action pair would crash when the cib was loaded due to the matrix having been replaced with a `CPView` (which cannot take a target-action pair).

Now if the matrix is for radio buttons, the action connection for the matrix is made to the `CPRadioGroup` instead and works as expected when radio selections are made.
2012-10-15 02:55:04 +01:00
Alexander Ljungberg 9c2cb393c2 CGContextIsPathEmpty for non-canvas based platforms.
Unfortunately there doesn't seem to be a way to get the current path from a canvas context so this function only works in VML mode for now.
2012-10-15 02:49:11 +01:00
Alexander Ljungberg ca4e034a3b CPBezierPath appendBezierPathWithArcFromPoint:toPoint:radius: and CGPathAddArcToPoint. 2012-10-15 02:47:37 +01:00
Alexander Ljungberg fd138cfae7 - CPBox setTitleFont support. 2012-10-15 01:10:08 +01:00
Alexander Ljungberg e530831b81 + CPFont systemFontSizeForControlSize:. 2012-10-15 01:09:21 +01:00
Alexander Ljungberg 7c56ea47dd Skeleton CPColor colorUsingColorSpaceName:.
The method does nothing but is provided for API compatibility with `NSColor`.
2012-10-15 01:00:29 +01:00
Alexander Ljungberg adb6404a0f Support Cib/Interface Builder window positioning masks.
Without this feature windows could easily end up being placed outside of the screen/browser when loaded in Cappuccino due to e.g. the window position being 100 px from the bottom of a 1418 px tall screen but the browser only being 800 px.

This commit adds support for all "initial position" window masks in Interface Builder except "centre". Position can be specified in current screen space coordinates and then adjusted proportionally to the browser size, or adjusted while preserving a left or right margin and a top or bottom margin.
2012-10-15 00:20:22 +01:00
Alexander Ljungberg 084e0a315f Clean up.
Put `_CPCibWindowTemplate` coding support in its own category to match most Cappuccino classes.
2012-10-14 20:18:48 +01:00
Alexander Ljungberg c2f9b91fe2 Implicit sort descriptor binding support.
Sort descriptor bindings are now automatically established when a table view has a column value binding (normally to an array controller).
2012-10-14 19:39:39 +01:00
Alexander Ljungberg b629b882b4 Clean up and fix ArrayController1 test.
Use `CPValueBinding` instead of `@"value"` in case someone reads this as an example.
2012-10-14 19:32:47 +01:00
Alexander Ljungberg da91ab9879 Fixed: implicitly set selectionIndexes.
`CPTableView`'s `selectionIndexes` binding shouldn't be set automatically unless the content binding was also set automatically (through a table column binding).

Assume that manual content binding implies a desire to manually bind selection indexes (and sort descriptors) as well.
2012-10-14 19:31:53 +01:00
Alexander Ljungberg a70bc7d953 "Creates Sort Descriptors" CPTableColumn value binding option.
With this option an array controller driven table view can be sorted by clicking the table column headers without manually setting up sort descriptor prototypes.

If `CPCreatesSortDescriptorBindingOption` is enabled on a table column value binding, sort descriptors will be created automatically. The default value for this option is YES.
2012-10-14 18:27:25 +01:00
Aparajita Fishman 7614c18fea Merge branch 'master' of github.com:cappuccino/cappuccino 2012-10-11 12:35:01 -04:00
Aparajita Fishman c37783c895 Fixed table column header styling
- Attributes set in IB are now obeyed.
- Added accessor methods to programmatically style _CPTableColumnHeaderView.

Since we don't have an NSCell and _CPImageAndTextView is supposed to be private, it's better to have the styling methods in _CPTableColumnHeaderView.
2012-10-11 12:34:55 -04:00
Antoine Mercadal 905d23d159 small graphical fix in CPPredicateEditor 2012-10-10 15:33:53 -07:00
Antoine Mercadal 7bf46cb40b Add support for disabling sudo action
you can set CAPP_NOSUDO=1 in your environment to disable any sudo action.
This means that if a command failed as current user, jake
will not try to run it with sudo,and will simply return the error code
2012-10-10 12:24:36 -07:00
Aparajita Fishman 385de88e2f Merge branch 'master' of github.com:cappuccino/cappuccino 2012-10-08 17:30:40 -04:00
Aparajita Fishman c2da96e311 CPWebView should be converted to WebView* in the shadow header 2012-10-08 17:30:28 -04:00
Saikat Chakrabarti e46cd1478b Fix syntax of validateVisibleItems 2012-10-07 14:45:23 -04:00
Antoine Mercadal 8bbb3d30b2 Merge branch 'master' of https://github.com/cappuccino/cappuccino 2012-10-05 17:59:57 -07:00
Antoine Mercadal 1edcc511d6 Allow custom action for search button
If there is no menu, and search button has a target/action, then
send the action.
2012-10-05 17:58:54 -07:00
aparajita 9b22b33616 Merge pull request #1682 from slevenbits/clickedColumn
Implemented CPTableView -clickedColumn
2012-10-02 14:21:51 -07:00
Aparajita Fishman 3992ca71c6 Merge branch 'clickedColumn' 2012-10-02 17:20:53 -04:00
Aparajita Fishman 3fd8d3e5be Implemented CPTableView -clickedColumn 2012-10-02 17:20:39 -04:00
Aparajita Fishman ce167cf92d Removed unused variable 2012-10-02 08:41:57 -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 3ccaa4de50 Button types can be set in IB, no need for code 2012-09-28 18:04:31 -04:00
aparajita 5cd137b745 Merge pull request #1680 from slevenbits/tag-fix
Fix tag reading from IB
2012-09-28 14:46:35 -07:00
Aparajita Fishman 95246d73c1 Fixed xib to work correctly with smaller screens 2012-09-28 17:44:56 -04:00
Aparajita Fishman 1c3300b066 Merge branch 'tag-fix' 2012-09-28 16:21:27 -04:00
Aparajita Fishman 8ff2a32b47 Fix tag reading from IB
Both controls and cells can have tags in IB, but Cappuccino has no cells. If the control has a tag, that takes precedence. Tag reading was moved to NSControl from NSView, since NSView does not have a tag in Cocoa.
2012-09-28 16:20:55 -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
Aparajita Fishman 90d52a8bb4 Don't show environment vars when building 2012-09-28 14:55:33 -04:00
Alexander Ljungberg a337bc28f9 Reduce number of divs used by typical apps.
Without this optimisation nil or 0x0 sized image slices in three part and nine part images result in useless empty divs.

Eliminating these divs should improve performance and reduce memory usage.

Although exact memory usage is hard to measure, in a large app the number of divs on screen went from 1012 to 984, a reduction of about 2.7%.
2012-09-26 12:32:09 +01:00
Alexander Ljungberg 8a5923527f Mention our trailing whitespace policy. 2012-09-24 17:14:37 +01:00
Alexander Ljungberg 59ad8499df Refs #1676. Whitespace. 2012-09-24 17:05:35 +01:00
Alexander Ljungberg 566cd6c6e8 Merge pull request #1676 from deltaprojects/master
CPNumberFormatterPercentStyle and CPTableView hidden column bug fix
2012-09-24 16:56:18 +01:00
Johan Stille 02a885eb09 Added test for initially hidden table column fix. 2012-09-24 14:22:39 +02:00
Johan Stille 632fba9dd5 Null check when laying out columns in CPTableView. 2012-09-24 13:17:24 +02:00
Johan Stille eb2bb24c19 Added support for CPNumberFormatterPercentStyle in CPNumberFormatter. 2012-09-24 12:08:31 +02:00
Alexander Ljungberg c8a37b4f99 Improve readability. 2012-09-17 19:46:36 +01:00
Alexander Ljungberg 117d946ed3 Contributing guidelines.
These will be shown in GitHub: https://github.com/blog/1184-contributing-guidelines.
2012-09-17 18:54:25 +01:00
Antoine Mercadal d4b0e2a124 fix some paths using non unicode chars causing xcc_general_include.h import problems 2012-09-15 12:17:43 -07:00
Antoine Mercadal 4acda0c447 fix and update css for documentation when using doxygen 1.8 2012-09-14 14:33:13 -07:00
Antoine Mercadal a7b40a5cdd XcodeCapp now uses both .m and .h shadow files in addition of the general include .h. Seems to fix most of the problems + refactoring 2012-09-13 19:07:46 -07:00
Antoine Mercadal ad5b9b658e take care of the .h and .m 2012-09-13 19:06:34 -07:00
Antoine Mercadal df28a4696e parser.j now generate both header and implementation files 2012-09-13 19:06:00 -07:00
Antoine Mercadal c30a6fb843 import the general include file to allow XCode to understand custom class inheritance 2012-09-13 14:09:30 -07:00
Antoine Mercadal 2e7afc3ca1 when managin the project, create a file containing includes of all projects files 2012-09-13 14:09:02 -07:00
Antoine Mercadal 2f428fa389 test item visibility when expanding/collapsing items 2012-09-10 15:19:32 -07:00
Antoine Mercadal 0a189906cd notify delegate that item did collapse after reloading them 2012-09-10 15:17:45 -07:00
Antoine Mercadal e4a6d8520c CPOutlineView notify for items expanded after having reloaded them 2012-09-10 13:49:40 -07:00
Alexander Ljungberg adbc420e0f Merge branch 'master' into slevenbits 2012-09-04 16:39:20 +01:00
Alexander Ljungberg fe138be7ae Merge pull request #1668 from BlairDuncan/SelectionCompatibility
Windows selection compatibility. Fix for issue 1390
2012-09-04 13:45:31 +01:00
Alexander Ljungberg ff51263671 Merge pull request #1669 from slevenbits/cpscrollview-frame
Fix frame of CPScrollView is calculated incorrectly.
2012-09-04 13:34:08 +01:00
Blair Duncan 04f650dde7 Windows selection compatibility. Fix for issue 1390 2012-09-03 23:47:11 -04:00
Alexander Ljungberg e95648ca16 Merge branch 'master' into slevenbits 2012-09-03 20:20:52 +01:00
Alexander Ljungberg 48e797a80d Minor hit test optimisation. 2012-09-03 20:20:23 +01:00
Alexander Ljungberg bf3a152946 Whitespace. 2012-09-03 20:20:05 +01:00
Alexander Ljungberg d0d66227cb Merge branch 'master' into slevenbits 2012-09-03 11:36:33 +01:00
Alexander Ljungberg 7264692a0a Optimise CPSegmentedButton setEnabled:forSegment:.
Don't relayout the segmented button if the enabled state of a segment is not changed.
2012-09-02 23:33:56 +01:00
Alexander Ljungberg 9d57d02eb5 Merge branch 'master' into slevenbits 2012-09-02 23:12:16 +01:00
Alexander Ljungberg b5776445ec Significantly optimise CPToolbar validation.
Avoid sending notifications about toolbar items' enabled state needlessly.

Tiling is expensive, but even if the toolbar item ignores redundant `setEnabled:` calls, the cost of notifications alone can really add up when there are many toolbar items.
2012-09-02 23:08:14 +01:00
Ilya Kulakov ee1c5478b1 Fix frame of CPScrollView is calculated incorrectly. 2012-09-03 03:41:14 +07:00
Alexander Ljungberg 63bad1dae0 Setting _data just once is enough. 2012-09-02 17:28:34 +01:00
Alexander Ljungberg d0fa16b96b Fix NSPopUpButton in previous commit. 2012-08-31 23:19:24 +01:00
Alexander Ljungberg bc93b3f6c7 Merge branch 'master' into slevenbits 2012-08-31 22:31:58 +01:00
Alexander Ljungberg 3dacb4a5ef Fix nib2cib alignment ofCPColorWell, CPComboBox, CPPopUpButton and CPSegmentedControl. 2012-08-31 22:31:40 +01:00
Alexander Ljungberg 63b57b886e Merge branch 'master' into slevenbits 2012-08-31 22:12:16 +01:00
Alexander Ljungberg ce80ee1739 Merge pull request #1667 from slevenbits/stepper-visuals
Visual `CPStepper` fixes.
2012-08-31 22:11:19 +01:00
Alexander Ljungberg 4e6b9978ce Adjust size in NSStepper to CPStepper. 2012-08-31 22:09:11 +01:00
Alexander Ljungberg 31d5ddb20a Improve CPStepper graphics.
* Disabled `CPStepper` looked larger than the regular stepper due to the outline becoming white.
* Wrong pixels at bottom corners.
2012-08-31 22:08:25 +01:00
Alexander Ljungberg 2355b7a38b Fixes #1666: since 5763ebd extremely slow double clicks would be accepted.
`CPEvent timestamp` is now in seconds so the double click delay has to be adjusted. Also slightly increased double click interval to account for lower precision.
2012-08-31 13:56:14 +01:00
Alexander Ljungberg 0e68729d7f Fixed: dragged table view columns ignored custom column header views. 2012-08-29 16:41:43 +01:00
Alexander Ljungberg b33763caeb Fixed: popovers could only properly open relative to views in the main window.
This would make the popover open with the wrong coordinates if the positioning view was in a window different than the main window, such as a utility window which can't become the main window.
2012-08-28 16:25:41 +01:00
Alexander Ljungberg 5b19c967f4 Merge branch 'master' of github.com:cappuccino/cappuccino 2012-08-28 14:33:45 +01:00
Alexander Ljungberg acd98b5c88 Clarify CPTabView code. 2012-08-28 14:32:04 +01:00
Alexander Ljungberg ff93262873 Work around rendering bugs in WebKit when moving canvas backed views.
This bug would cause errors such as the subviews of a CPBox not drawing properly as the box moved (e.g. due to animation).
2012-08-28 14:31:35 +01:00
Alexander Ljungberg f535a6a242 Minor CPTabView optimisation. 2012-08-28 11:42:38 +01:00
Antoine Mercadal d1c978669b run ImageOptim on all images. Saved around 30% of original size 2012-08-24 11:48:55 -07:00
Alexander Ljungberg b28673d23d Eliminate some debug output from jake test runs. 2012-08-24 17:26:27 +01:00
Alexander Ljungberg 46848562d0 Improve describe format of CPDictionary and CPArray to be more like literals.
E.g. a dictionary is expressed as @{key1: value1}, an array like @[value2, value2], a string like @"<value>".

Also don't put all child objects into quotation marks - that makes them all look like strings.
2012-08-24 17:25:37 +01:00
Alexander Ljungberg 9cbc52e858 Cappuccino v0.9.6 RC2. 2012-08-22 22:35:53 +01:00
Alexander Ljungberg 3cdf4fbc88 RC2 bootstrap. 2012-08-21 23:18:24 +01:00
Alexander Ljungberg b032c9e455 Fixed: objcc --includeTypeSignatures typo. 2012-08-21 22:37:08 +01:00
Alexander Ljungberg 6d4ce10150 Formatting. 2012-08-21 01:24:36 +01:00
Alexander Ljungberg 8b227798e1 Merge branch 'master' of github.com:cappuccino/cappuccino 2012-08-19 17:32:09 +01:00
Alexander Ljungberg 1514e8e981 Fixed: don't crash in unit tests if using Rhino.
Apparently Rhino doesn't have `<input element>.setAttribute` and an error would be thrown in `CPCompatibility.j`: `Cannot find function setAttribute in object [object Object].`
2012-08-19 17:16:09 +01:00
Alexander Ljungberg 4fbd0fdc42 Unit test KVCArray setArray: behaviour. 2012-08-19 16:50:09 +01:00
Antoine Mercadal fea31d54f8 Update comments to remove references to .xCodeSupport 2012-08-17 20:14:26 -07:00
Alexander Ljungberg 10f6c8e8f6 Merge branch 'master' into slevenbits 2012-08-16 19:14:36 +01:00
Alexander Ljungberg 3dffbd6071 Refs #1001. Make it easy to test text field cut/paste behaviour. 2012-08-16 19:13:59 +01:00
Alexander Ljungberg 876757e748 Refs #1001. Don't use old cut/paste workaround if oninput fix is available. 2012-08-16 19:13:30 +01:00
Alexander Ljungberg 7abaa30526 Refs #1001. Fixed: text field cut/paste by context menu would not trigger a change notification.
Also just regular copy and paste could fail to trigger notifications.
2012-08-16 19:03:18 +01:00
Alexander Ljungberg 7b3136dae3 Merge branch 'master' into slevenbits 2012-08-15 18:32:36 +01:00
Alexander Ljungberg 1a467f9208 Test text fields with various sizes. 2012-08-15 18:31:39 +01:00
Alexander Ljungberg 54d5f4b0a4 Fixed: horizontal text jump when editing text fields in some browsers.
We were compensating for a bug in Safari, older versions of Chrome and Firefox in our input placement. But new Chrome and neither IE 8 nor IE 9 needed it which resulted in the text being off in those browsers.
2012-08-15 18:31:20 +01:00
Alexander Ljungberg ca3a4f9b9c Fixed: text field font size while editing was wrong in Internet Explorer.
Tested in Internet Explorer 8 and 9.
2012-08-15 18:12:53 +01:00
Alexander Ljungberg d53b8c5b1f Fixed: in Firefox the text of edited text fields would "jump" down 1 px.
Locking down the line height and vertical alignment explicitly seems to work in Safari 6, Chrome 21, Firefox 14 and IE 8 (although Chrome and IE exhibit some unrelated horizontal jumping.)
2012-08-15 17:13:34 +01:00
Alexander Ljungberg 1e49704062 Fixed: the size with string fix broke metricsOfFont:. 2012-08-15 15:36:15 +01:00
Alexander Ljungberg b7ee0fe44d Merge branch 'master' into slevenbits 2012-08-15 13:39:09 +01:00
Alexander Ljungberg d95268b548 Refs #1654. Fix up missing bits. 2012-08-15 13:38:49 +01:00
Alexander Ljungberg 0150271e67 Merge branch 'master' into slevenbits 2012-08-15 02:09:40 +01:00
Alexander Ljungberg e9bafa8f13 Merge pull request #1654 from slevenbits/key-window-style
Inactive (non-key) window titles. Layout tweaks.
2012-08-15 02:07:11 +01:00
Alexander Ljungberg ef66334292 Inactive HUD window title.
Also fix close and title positioning.
2012-08-15 02:03:48 +01:00
Alexander Ljungberg aa17d8c700 Pull up window title code to a superclass for reuse. 2012-08-15 01:38:25 +01:00
Alexander Ljungberg 9f59ac96dd Inactive window title, start on window theming support.
Now the key window can be recognised by the window title.
2012-08-15 01:03:08 +01:00
Alexander Ljungberg 425888ee1f Fixed: in recent revisions vertical text centring was off by 1 upwards, including window titles.
This was caused by making text display generally 1 px taller to allow for fractional pixels at the bottom to show. This should however not be allowed to affect positioning (even if there is a fractional pixel below vertically centred text the text should not move up 0.5 px.)
2012-08-15 00:52:45 +01:00
Alexander Ljungberg f72615dcbe Fixed: non-key window text fields tried to receive input, looked active.
Only the first responder of the key window should receive text input. This is important in multi-window apps or windows with sheets.

In the multi window case it should be possible to switch between two windows with first responder text fields and keep right on typing. First responder status should not be lost, but new typing should always go into the first responder text field of the key window.

For sheets, a text field which was active when the sheet opened should not receive input nor look active while the sheet is open.
2012-08-14 23:41:09 +01:00
Alexander Ljungberg e3d0d69918 Refs #1364. Avoid repeated makeFirstResponder: calls within sheet parent.
If a window contained a text field which was the initial first responder, and the window was displaying a sheet, clicking on the window would cause the text field to alternate between being the first responder and not.

This was caused by the window `orderFront:` setting its first responder to the initial responder if there wasn't any responder yet. This would cause the text field to focus, even that the window wasn't the key window, and then on the next click the text field would blur which would make the text field automatically resign its first responder status.

The solution is to leave the first responder status alone if a window which isn't the key window is `orderFront:`ed. This appears to be more sensible UX in general. You don't expect the first responder of non-key windows to change when you click it's background.
2012-08-14 22:43:01 +01:00
Alexander Ljungberg 77266e0b3c Refs #1364. Don't orderFront: sheet parent view twice.
The sheet's orderFront: already calls the parent window's orderFront:, no need to call it by hand.
2012-08-14 03:10:08 +01:00
Alexander Ljungberg 64bbe0c641 Refs #1364. Fixed: incorrect key window change when displaying a sheet.
When the key window changes the previous window's resignKeyWindow must be called.
2012-08-14 02:39:18 +01:00
Alexander Ljungberg 120cea8734 Refs #1364. Fix CPTextField test to work with new sheet changes. 2012-08-14 00:15:03 +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
Alexander Ljungberg 5a8c94183a Refs #1364. Formatting, don't shadow window global. 2012-08-11 19:35:05 +01:00
Alexander Ljungberg de8e08f4f4 Refs #1364. Add an index-debug.html to test app. 2012-08-11 16:11:04 +01:00
Alexander Ljungberg 1e55b79b49 Merge pull request #1364 from walisser/master
Doc-modal/window-modal sheets and other sheet issues [+1]
2012-08-11 15:59:52 +01:00
aparajita dcdc7cef65 Merge pull request #1652 from slevenbits/stringValue-fix
stringValue fix
2012-08-09 20:33:31 -07:00
Aparajita Fishman 9e1d09909e Merge branch 'stringValue-fix' 2012-08-09 20:31:37 -07:00
Aparajita Fishman 6e40020906 Allow nil value in presence of formatter, the formatter may want to format that 2012-08-09 20:31:26 -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
Alexander Ljungberg c4c7da3967 Merge pull request #1651 from slevenbits/stringsize-fix
Fixed: wrong text sizing across the board for custom fonts.
2012-08-10 03:47:36 +01:00
Alexander Ljungberg 580da9caef Fixed: wrong text sizing across the board for custom fonts.
If a custom font was used with the CSS @font-face syntax, Cappuccino would calculate the wrong sizes for strings throughout. This could result in e.g. cut off sizeToFit labels.

The sizing tests were being performed inside of an iframe and that iframe would not have the same CSS @font-face declarations. For maximum fidelity all string size tests are now performed in the main document, just off screen.
2012-08-10 03:46:09 +01:00
Antoine Mercadal 657baf9135 Merge branch 'master' of https://github.com/cappuccino/cappuccino 2012-08-09 12:52:11 -07:00
Antoine Mercadal 15c75f05e5 Update some labels 2012-08-09 12:51:43 -07:00
aparajita a8553c7c10 Merge pull request #1648 from slevenbits/fix-xcc-warnings
Fix compiler warnings
2012-08-09 12:19:16 -07:00
Aparajita Fishman 79cd71d2ab Merge branch 'fix-xcc-warnings' 2012-08-09 12:17:52 -07:00
Aparajita Fishman 2b6d8697d5 Fix compiler warnings 2012-08-09 12:17:31 -07:00
Antoine Mercadal dcd3995230 remove old pbxproj sample 2012-08-09 11:42:05 -07:00
Aparajita Fishman 081cf61e68 Merge branch 'refs/heads/upstream' 2012-08-09 11:27:32 -07:00
Antoine Mercadal ad88dabfd1 Update NativeHost.xcodeproj to build on new Xcode 2012-08-09 10:04:08 -07:00
Antoine Mercadal 4e13f3f2fd Add reference to .j too in a group called Sources 2012-08-08 22:35:35 -07:00
Antoine Mercadal 6a2d7bd2df Remove useless product group 2012-08-08 22:34:58 -07:00
Antoine Mercadal 81c1f0c7c9 don't be stupid 2012-08-08 22:34:40 -07:00
Antoine Mercadal cfd6928baa make XcodeSupport hidden 2012-08-08 21:56:33 -07:00
Antoine Mercadal 7b9582181c By default ignore *.xcodeproj and DS_Store 2012-08-08 21:53:25 -07:00
Antoine Mercadal 455ec8e3ae Simplify the FSEvent callback.
Events are not so reliable, there are many flaws and special cases (like trashing a folder etc)
In order to simplify the process is the following

- We receive an event
- We tidy up the shadow files
- We check if the given path exists
- If it's a folder, we continue
- If it's a file and it exists : we run handleFileModification
- If it's a file and it doesn't exist: we run handleFileRemoval
2012-08-08 21:51:38 -07:00
Antoine Mercadal ea31bd2be2 make XcodeCapp compatible with Xcode 4.4 2012-08-08 19:08:16 -07:00
Antoine Mercadal bf6c0c95eb Update Xcode project 2012-08-08 19:05:07 -07:00
Antoine Mercadal bb20a8f4ff pbxprojModifier.py now uses the mod_pbxproj 2012-08-08 19:04:52 -07:00
Antoine Mercadal cc18a5d3e2 Update default PBXProj 2012-08-08 19:04:30 -07:00
Antoine Mercadal 88287c6c2d add attribute to hold the pbxmodifier script 2012-08-08 19:04:04 -07:00
Antoine Mercadal 0fd0a05cd1 basic support for removing a reference of a file 2012-08-08 19:03:44 -07:00
Antoine Mercadal b0b084dbe8 add necessary imports 2012-08-08 16:02:00 -07:00
Antoine Mercadal 41a6621ac2 Make XCC generating .m files with @property for outlets
This is step 1 to have XCC working with Xcode 4.4.
2012-08-08 14:59:29 -07:00
Alexander Ljungberg ed0fd87646 Merge branch 'master' into slevenbits 2012-08-07 12:32:47 +01:00
Alexander Ljungberg 9fb73e26dc Merge pull request #1645 from slevenbits/isViewLoaded
Added CPViewController -isViewLoaded, fixed CPWindowController -setViewController to use that
2012-08-07 12:29:59 +01:00
Aparajita Fishman 59e8160f18 Added CPViewController -isViewLoaded, fixed CPWindowController -setViewController to use that
Before this fix, CPWindowController -setViewController was unconditionally loading the view, which should not happen.
2012-08-06 17:33:58 -07:00
Alexander Ljungberg 4136953752 Merge branch 'refs/heads/master' into slevenbits 2012-08-06 14:03:37 +01:00
Alexander Ljungberg fdf3e499be Merge pull request #1644 from slevenbits/CPArrayController-preserveSelectionFix
Fix wrong indexes are selected when removing arranged objects.
2012-08-06 13:53:31 +01:00
Ilya Kulakov c1ace9a7c3 Fix wrong indexes are selected when removing arranged objects. 2012-08-06 19:19:13 +07: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
Alexander Ljungberg f9a1d7240e Merge pull request #1643 from slevenbits/cpdecimalnumber-fix
fix CPDecimalMakeString to support '.003' and '-.003' style numbers
2012-08-05 12:34:40 +01:00
Eric Wong 7ad24efe4f Merge branch 'cpdecimalnumber-fix' 2012-08-05 10:10:40 +08:00
Eric Wong def8016f44 code style change 2012-08-05 09:35:44 +08:00
Eric Wong 175c70d99e fix a new bug in CPDecimalMakeWithString and remove some test cases 2012-08-05 08:37:44 +08:00
Darrell Walisser 872d65b824 -fix docs for new delegate methods 2012-08-04 14:06:11 -04:00
Darrell Walisser 339937a316 -support for tags on NSCell, useful for radio groups 2012-08-04 13:58:31 -04:00
Darrell Walisser eed93dc30d -capp_lint 2012-08-04 13:57:56 -04:00
Darrell Walisser bff22779ae -capp_lint 2012-08-04 13:53:05 -04:00
Darrell Walisser 24ef4d41d2 -capp_lint
-enable close buttons based on context
-remove stuff that doesn't work
2012-08-04 13:20:35 -04:00
Eric Wong 9f1a8fa7a2 enable '.003' or '-.003' style number in CPDecimalMakeWithString function and add new test cases 2012-08-04 23:04:40 +08:00
Alexander Ljungberg a055d6d97e Merge branch 'refs/heads/master' into slevenbits 2012-08-04 14:11:25 +01:00
Alexander Ljungberg 729d2493cd Merge pull request #1642 from slevenbits/currency-formatter
`CPNumberFormatter` improvements.
2012-08-04 14:10:39 +01:00
Alexander Ljungberg 4d8758f755 Fix CPTextFieldTest. 2012-08-04 13:58:29 +01:00
Alexander Ljungberg 31ea0da526 CPNumberFormatter generatesDecimalNumbers support, enabled by default. 2012-08-04 13:45:45 +01:00
Alexander Ljungberg 3a2bf36359 Very basic CPNumberFormattercurrency style. 2012-08-04 13:37:42 +01:00
Alexander Ljungberg dc0c63ccc3 Extend CPNumberFormatter CPCoding support and fix rounding default. 2012-08-04 02:31:43 +01:00
Alexander Ljungberg 534635cbc2 Fix CPNumberFormatter maximum/minimum fraction digits property name. 2012-08-04 01:21:42 +01:00
Alexander Ljungberg a7f22a0c5a Correct CPNumberFormatter maximumFractionalDigits default. 2012-08-04 01:09:51 +01:00
Alexander Ljungberg b279a92e4c CPNumberFormatter setMinimumFractionDigits: support. 2012-08-04 00:55:41 +01:00
Alexander Ljungberg 055dd7229e Properly allow CPNumberFormatter to operate on most CPNumber types.
This only worked by accident before.
2012-08-04 00:48:45 +01:00
Antoine Mercadal 0922f3dab7 Merge pull request #1573 from mrcarlberg/binding_support_popup_button
Added key value binding support for CPPopupButton
2012-08-02 15:58:15 -07:00
Alexander Ljungberg 23ed09a84e Merge branch 'refs/heads/master' into slevenbits 2012-08-02 15:54:36 +01:00
Alexander Ljungberg b4cfa8cefb CPEvent description. 2012-08-02 15:53:27 +01:00
Alexander Ljungberg 6b660a0c76 Fixed: CPEvent data1 and data2 weren't stored right.
They were stored in globals instead of ivars, allowing only one data1 or data2 in the whole app.
2012-08-02 15:53:04 +01:00
Alexander Ljungberg 1ccd89ddd8 Refs #1640. Unit test. 2012-08-02 15:44:19 +01:00
Alexander Ljungberg cbb710cde7 Merge pull request #1640 from slevenbits/CPEvent-modifierFlags
Add +[CPEvent modifierFlags]
2012-08-02 14:36:17 +01:00
Ilya Kulakov d3b38ac5e8 Add +[CPEvent modifierFlags]. 2012-08-02 17:37:40 +07:00
Alexander Ljungberg 1fb09dcfae Fix typo. 2012-08-02 00:53:30 +01:00
Alexander Ljungberg f06be56fa3 Fixed: accidental global. 2012-08-02 00:45:33 +01:00
Alexander Ljungberg 9768ea4af9 Fixed: multiple rows of tokens in token fields wouldn't scroll right.
In recent versions, moving the cursor to a new row of tokens would place the scroll point somewhere halfway between the two rows of tokens.
2012-08-02 00:44:58 +01:00
Alexander Ljungberg 26c26914da Fixed: token field scrolling away from selected token.
Sometimes clicking a token would cause the token field to scroll to some other spot. This appears to have been caused by the inactive input element gaining focus.

We no longer need the input element for keyboard navigation so we can hide it entirely when it's not used to input a new token. Also, avoid focusing the input element needlessly.
2012-08-02 00:38:21 +01:00
Alexander Ljungberg 41783e87a3 Fixed: in recent builds token field text didn't align.
Text inside of tokens appeared 1 px higher than text typed in the text field area.
2012-08-01 21:12:53 +01:00
Alexander Ljungberg 299998b247 Merge pull request #1639 from slevenbits/tokenfield-fix
Fixed: token fields would sometimes unexpectedly steal first responder status.
2012-08-01 21:02:44 +01:00
Alexander Ljungberg 90ae5766e6 Fixed: token fields would sometimes unexpectedly steal first responder status.
If an autocomplete choice was made followed by immediately focusing on another control, the token field would reclaim first responder status a moment later.
2012-08-01 19:18:40 +01:00
Alexander Ljungberg 31ab70d6fc Refs #1530. Fixed: table views could not be interacted with if they couldn't become the first responder. 2012-08-01 18:59:54 +01:00
Alexander Ljungberg 7537f4d032 Eliminate some duplicate methods. 2012-08-01 16:35:34 +01:00
Darrell Walisser 32c5c82cb9 -removed unused import 2012-07-29 14:04:06 -04:00
Darrell Walisser 1c18862e0f -added manual test 2012-07-29 12:54:34 -04:00
Darrell Walisser 97b3679101 Merge remote-tracking branch 'upstream/master'
Conflicts:
	AppKit/CPApplication.j
	AppKit/CPWindow/_CPDocModalWindowView.j
2012-07-29 12:31:47 -04:00
Alexander Ljungberg 22b882648b Formatting. 2012-07-28 02:06:05 +01:00
Alexander Ljungberg a8150a84be Merge branch 'master' of github.com:cappuccino/cappuccino 2012-07-28 01:59:06 +01:00
Alexander Ljungberg df5a7104b1 Fixes #1638. The case of the incomplete optimisation. 2012-07-28 01:58:41 +01:00
aparajita 2400b6aeab Merge pull request #1637 from cacaodev/CPCib-initWithCibNamed
CPCib -initWithContentsOfURL: return nil if the requested data is nil.
2012-07-27 14:51:22 -07:00
cacaodev f42b241469 CPCib -initWithContentsOfURL: return nil if the requested data is nil 2012-07-27 20:19:20 +02:00
aparajita 4c86c75b5f Merge pull request #1635 from wmeddie/patch-1
Removed tailing comma from CPColorWithImages call.
2012-07-27 10:18:56 -07:00
Eduardo Gonzalez 9d2bdea8d9 Removed tailing comma from CPColorWithImages call.
The extra comma causes IE to think it was passed an array with 4
values and causes CPColorWithImages to return a NinePartImage even
though it only has three parts.
2012-07-27 20:51:29 +09: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 bd0114aa06 Refs #1632. Remove debug logging. 2012-07-26 13:42:01 +01:00
Alexander Ljungberg 1db154ac5b Merge branch 'refs/heads/master' into slevenbits 2012-07-26 13:34:45 +01:00
Alexander Ljungberg 43506e708d Merge branch 'master' of github.com:cappuccino/cappuccino 2012-07-26 13:32:20 +01:00
Alexander Ljungberg 3e218d6aec Refs #1632. Unit test for CPUndoManagerDidCloseUndoGroupNotification. 2012-07-26 13:32:01 +01:00
Alexander Ljungberg bf3c22f42c Merge pull request #1632 from slevenbits/cpundomanager-notification
Starting from 10.7 NSUndoManager posts NSUndoManagerDidCloseUndoGroupNotification
2012-07-26 13:05:40 +01:00
Antoine Mercadal dcee0e5057 Revert "small fix in theme to avoid 1px offset when editing a CPTextField"
This reverts commit fa1441cf71.
2012-07-25 18:19:15 -07:00
Antoine Mercadal 673c3c19f0 Merge branch 'master' of https://github.com/cappuccino/cappuccino 2012-07-25 12:00:36 -07:00
Antoine Mercadal fa1441cf71 small fix in theme to avoid 1px offset when editing a CPTextField 2012-07-25 12:00:09 -07:00
Ilya Kulakov c57ef67784 Starting from 10.7 NSUndoManager posts NSUndoManagerDidCloseUndoGroupNotification. 2012-07-25 17:02:06 +07:00
Alexander Ljungberg b1e519fd62 Merge branch 'master' of github.com:cappuccino/cappuccino 2012-07-24 20:09:58 +02:00
Alexander Ljungberg b51a2e25c2 Refs #1631. Unit test last index of index set with a single index. 2012-07-24 20:09:18 +02:00
aparajita 7b2835028a Merge pull request #1628 from cacaodev/CPCib-instantiateCibWithOwner_topLevelObjects_
CPCib -instantiateCibWithOwner:topLevelObjects:
2012-07-23 14:02:09 -07:00
Alexander Ljungberg 7ab833495f Merge branch 'refs/heads/master' into slevenbits 2012-07-23 15:39:03 +02:00
Alexander Ljungberg 9eee7a214e Refs #1630. Add test. 2012-07-23 15:35:52 +02:00
Alexander Ljungberg d0b152c638 Merge pull request #1630 from slevenbits/cparray-fix
Fix CPArray should throw an exception when observer is added/removed.
2012-07-23 15:34:38 +02:00
Alexander Ljungberg 6d08f0d60b Formatting. 2012-07-23 15:26:03 +02:00
Alexander Ljungberg aab8ade15b Refs #1629. Fixed: aSet removeObject: for an object not a member is not an error. 2012-07-23 15:25:52 +02:00
cacaodev 5456bad23d Remove unwanted import in AppController test app 2012-07-23 14:59:48 +02:00
Alexander Ljungberg 8e6634168a Merge pull request #1629 from slevenbits/cpset-fix
Fix CPSet's member never checks equality of objects at Objj level.
2012-07-23 14:56:29 +02:00
Ilya Kulakov a3179080d3 Fix CPArray should throw an exception when observer is added/removed. 2012-07-23 19:48:05 +07:00
Ilya Kulakov 985759ce91 Fix CPSet's member never checks equality of objects at Objj level. 2012-07-23 19:34:40 +07:00
Martin Carlberg a688a3de79 Added test case for selectedIndex binding with CPInsertsNullPlaceholderBindingOption 2012-07-23 12:14:53 +02:00
Martin Carlberg 2184c7ca4d Fixed code format issues 2012-07-23 12:12:55 +02:00
Martin Carlberg f6b378513d Merge branch 'master' of https://github.com/cappuccino/cappuccino into binding_support_popup_button
Conflicts:
	AppKit/CPKeyValueBinding.j
	AppKit/CPPopUpButton.j
	Tests/AppKit/CPPopUpButtonTest.j
2012-07-23 11:19:21 +02:00
cacaodev 02a89e2343 CPCib -instantiateCibWithOwner:(id)anOwner topLevelObjects:(CPArray)topLevelObjects : allow anOwner to be nil 2012-07-22 22:08:31 +02:00
Alexander Ljungberg 8d1a5ac6b9 Format code. 2012-07-21 13:24:13 +01:00
Alexander Ljungberg 030bd9388b Merge branch 'master' of github.com:cappuccino/cappuccino 2012-07-21 13:13:28 +01:00
Alexander Ljungberg a78c1bf03a Refs #1624. Fix grouping separator support.
`perMillSymbol` was incorrectly used as the grouping separator.
2012-07-21 13:13:14 +01:00
Alexander Ljungberg 7e562fa3aa Fixes #1624. Fix grouping for CPNumberFormatter. 2012-07-21 13:08:54 +01:00
aparajita 5caf76fb3a Merge pull request #1536 from mrcarlberg/main_bundle_path_commonjs
Fixed mainBundle having no '/' at the end when running in CommonJS. This would make relative paths fail.
2012-07-20 17:18:16 -07:00
aparajita 30509823bb Merge pull request #1620 from ggsato/removingFirstObjectImprovement
fixed a bug that removeObject shows empty selection if an object at index 0 was removed
2012-07-20 16:24:15 -07:00
Alexander Ljungberg 835bd59330 Fixed: popovers in modal windows couldn't be interacted with.
This prevented e.g. date picker popovers in sheet dialogs.
2012-07-19 16:34:15 +01: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
Alexander Ljungberg e73cb7d363 Merge branch 'master' of github.com:cappuccino/cappuccino 2012-07-19 01:05:48 +01:00
Alexander Ljungberg 8aee458022 nib2cib support for button and radio button tags. 2012-07-19 01:05:09 +01:00
Aparajita Fishman fe04cfbe1f Merge branch 'refs/heads/upstream' 2012-07-18 14:48:56 -07:00
Aparajita Fishman 20eb62b3d2 Use the proper modern DOCTYPE 2012-07-18 14:48:23 -07:00
Alexander Ljungberg d57f5427fb Merge branch 'master' into slevenbits 2012-07-18 19:23:05 +01:00
Alexander Ljungberg f4f9e8880c Merge branch 'master' of github.com:cappuccino/cappuccino 2012-07-18 19:21:43 +01:00
Alexander Ljungberg b0a56f1690 Fixed: removing selected CPPopUpButton item.
When the selected item of a `CPPopUpButton` is removed the first item should become selected. This matches Cocoa's behaviour.
2012-07-18 19:21:20 +01:00
Aparajita Fishman 6537a44c02 Merge branch 'refs/heads/upstream' 2012-07-18 09:53:32 -07:00
Aparajita Fishman 8444f808f6 By default controls will track the system font size
Use current system font size elsewhere
2012-07-18 09:53:09 -07:00
Aparajita Fishman f8cc2eb670 Merge branch 'refs/heads/upstream' 2012-07-17 15:12:50 -07:00
Aparajita Fishman b959f13a0c Merge branch 'master' of github.com:cappuccino/cappuccino into upstream 2012-07-17 15:11:13 -07:00
Aparajita Fishman f0163e13c9 Added CGInsetMakeInvertedCopy 2012-07-17 15:10:58 -07:00
Alexander Ljungberg c83b4bf3af Merge branch 'master' into slevenbits 2012-07-17 23:02:17 +01:00
Alexander Ljungberg a89ca14abe Merge pull request #1622 from slevenbits/tableview-column-move-notify
Notify when a `CPTableView` column moves.
2012-07-17 22:59:53 +01:00
Alexander Ljungberg 9b77f1b7ac Notify when a CPTableView column moves.
Both through `CPNotificationCenter` and to the delegate.
2012-07-17 22:57:36 +01:00
Alexander Ljungberg 5c5d2e47a9 Merge branch 'master' into slevenbits 2012-07-17 21:11:45 +01:00
Alexander Ljungberg e68077d159 Merge pull request #1621 from slevenbits/cpdictionary-enumerate
`CPDictionary enumerateKeysAndObjectsUsingBlock:`.
2012-07-17 20:51:22 +01:00
Alexander Ljungberg 5724dfe21d CPDictionary enumerateKeysAndObjectsUsingBlock:. 2012-07-17 20:48:52 +01:00
ggsato 364208e029 fixed a bug that removeObject shows empty selection if an object at index 0 was removed 2012-07-17 15:36:18 +09: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
Alexander Ljungberg fea0299033 Merge branch 'master' of github.com:cappuccino/cappuccino 2012-07-16 03:16:31 +01:00
Alexander Ljungberg c1dd821c6e Merge pull request #1618 from slevenbits/fontmanager
New `CPFontManager` methods.
2012-07-16 03:16:21 +01:00
Alexander Ljungberg 6a67243460 CPFontManager convertFont:toFace:. 2012-07-16 03:11:21 +01:00
Alexander Ljungberg 7f1b396ce8 CPFontManager weightOfFont: and traitsOfFont:. 2012-07-15 23:39:29 +01:00
Alexander Ljungberg 1e5bccd48e CPFontManager convertFont:, convertFont:toHaveTrait: and addFontTrait:. 2012-07-15 23:38:32 +01:00
Alexander Ljungberg d016e8a5e8 CPFontManager setSelectedFont:isMultiple: and other basic properties. 2012-07-15 21:45:50 +01:00
Alexander Ljungberg fc49574947 Test CPFontManager. 2012-07-15 21:01:29 +01:00
aparajita 2c0cf72a60 Merge pull request #1617 from slevenbits/dictionary-key-methods
CPDictionary key methods


keysOfEntriesPassingTest:
keysOfEntriesWithOptions:passingTest:
keysSortedByValueUsingComparator:
2012-07-15 09:30:31 -07:00
Aparajita Fishman c166a20b89 Merge branch 'dictionary-key-methods' 2012-07-15 09:28:15 -07:00
Aparajita Fishman c4dc9c8bdb CPDictionary key methods
keysOfEntriesPassingTest:
keysOfEntriesWithOptions:passingTest:
keysSortedByValueUsingComparator:
2012-07-15 09:27:04 -07:00
Aparajita Fishman dec7ca1e19 Make NSClipView obey the Draw Background checkbox in IB 2012-07-14 10:32:21 -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
Alexander Ljungberg ccb6b3b4a2 Code formatting. 2012-07-14 14:11:38 +01:00
Alexander Ljungberg 5658ea2c1e Merge pull request #1616 from slevenbits/kvo-willchange-fix-2
Fix crash if an observer is set between willChange…/didChange…
2012-07-14 13:58:18 +01:00
Ilya Kulakov 3886f27acd Fix crash if an observer is set between willChange…/didChange…
When you add an observer to an object first time, its class is
implicitly changed to a KVO_originalClassName (subclass of original
class). This subclass adds willChange…/didChange… methods for
observable properties.
If you send willChange… before you add an observer, it does nothing.
But if you send didChange… just after, the app will crash, because
new KVO_originalClassName nerver receives willChange…

The idea is to maintain counter of all received willChange… messages
(per key) and decrease it in didChange…
When KVO_originalClassName is created and didChange… is received
(without opening willChange… to new class), exception is not thrown
immediately, but the counter is checked first.
If it's greater than 0, then didChange… just closes
an unboserved willChange… Otherwise exception is thrown, as expected.
2012-07-14 19:32:25 +07:00
Aparajita Fishman 4958b4c47b Merge branch 'master' of github.com:slevenbits/cappuccino 2012-07-13 21:05:36 -07:00
aparajita 76738a0208 Merge pull request #1615 from slevenbits/text-size-theming
Text size and theming enhancements

- _CPImageAndTextView adds extra pixels to allow for fractional pixels in -sizeToFit.

- NSButton now allows buttons that are not fixed height, if the theme allows it.

- Documented the mapping between bezel style constants and their IB style names.
2012-07-13 21:04:41 -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
Aparajita Fishman 32dc0826cb Text size and theming enhancements
- _CPImageAndTextView adds extra pixels to allow for fractional pixels in -sizeToFit.

- NSButton now allows buttons that are not fixed height, if the theme allows it.

- Documented the mapping between bezel style constants and their IB style names.
2012-07-13 21:00:02 -07:00
Aparajita Fishman 590b7ec704 format strings was not set in the xib 2012-07-13 20:26:57 -07:00
Aparajita Fishman 98b735b185 Install imagesize binary in both debug/release so that it works when install-debug-symlinks is used 2012-07-13 20:07:25 -07:00
Aparajita Fishman dd686a0fca Fixed spelling error in test app 2012-07-13 18:23:08 -07:00
aparajita 3fe2e4487e Merge pull request #1571 from tancred/xcodecapp_fix_wrong_format_specifier
Corrected the format specifier for a logging statement in XcodeCapp.
2012-07-13 07:51:07 -07:00
cacaodevandAparajita Fishman 2cf9fdf0d0 Check for sendsActionOnEndEditing 2012-07-13 07:45:08 -07:00
cacaodevandAparajita Fishman 7c01f14bfe Fix for #1593 2012-07-13 07:44:48 -07:00
Alexander Ljungberg 0e87659093 Merge branch 'refs/heads/master' into slevenbits 2012-07-13 15:35:29 +01:00
Alexander Ljungberg 716c340825 Merge branch 'master' of github.com:cappuccino/cappuccino 2012-07-13 15:11:46 +01:00
aparajita 625e47a725 Merge pull request #1591 from claimable/master
Fix for CPPredicateEditor Action Bug

Make sure the predicate value editor sends its action when resigning, so the predicate is updated.
2012-07-13 07:07:25 -07:00
Alexander Ljungberg 2ca3f657f9 Refs #1530. Fix CPTableViewTest to work regardless of #1530 decision. 2012-07-13 13:24:43 +01:00
Alexander Ljungberg b038b6baf6 Fixed: browser propagation control when not in browser.
This would lead to a `[CPPlatformWindow _willPropagateCurrentDOMEvent] unrecognized selector sent to instance` error if an event was sent in a non DOM environment.
2012-07-13 12:41:26 +01:00
Alexander Ljungberg eb990b6d4f Merge branch 'refs/heads/master' into slevenbits 2012-07-13 11:38:49 +01:00
Alexander Ljungberg 9abb79d191 Merge pull request #1612 from slevenbits/cpgeometry-improvements
Cpgeometry improvements
2012-07-13 11:37:02 +01:00
Malte Tancred c3740c548d Corrected the corrected format specifier for the flags variable. 2012-07-13 08:11:24 +02:00
aparajita 629f12a851 Merge pull request #1543 from cacaodev/CPTableView-content-binding
Added support for using bindings with CPTableView content (as opposed to CPTableColumn value bindings)
2012-07-12 19:58:12 -07:00
aparajita e4de525a09 Merge pull request #1552 from mrcarlberg/outlineview_disclosure_width
Width of disclosure button determined by current disclosure control
2012-07-12 19:38:52 -07:00
aparajita 1a4e5a345d Merge pull request #1576 from ggsato/fixForOpeningExistingDocument
fixed needsUntitled evaluation

An untitled window will only open if ALL documents fail to load.
2012-07-12 19:29:07 -07:00
Alexander Ljungberg a4ae36929b Fix CPGeometry.j import.
CPGeometry.j is now in Foundation.
2012-07-13 01:29:01 +01:00
Alexander Ljungberg b9b98a39bb Avoid Foundation depending on AppKit.
CPGeometry.j and CGGeometry.j now share their implementation in two private API classes in the lower layer Foundation.
2012-07-13 01:28:38 +01:00
Alexander Ljungberg ae4b7cb58e Sort imports. 2012-07-13 01:26:14 +01:00
Aparajita Fishman 12ea224f21 Merge branch 'master' of github.com:cappuccino/cappuccino 2012-07-12 17:21:40 -07:00
Aparajita Fishman f7d67e4b87 Cleanup, documented hacks 2012-07-12 17:20:30 -07:00
Antoine Mercadal 20c7ed0034 fix CPTextField baseline alignement 2012-07-12 15:23:17 -07:00
Aparajita Fishman 98260630ac Merge branch 'master' of github.com:cappuccino/cappuccino 2012-07-12 15:17:06 -07:00
Antoine Mercadal 5c00ea627e Add manual test case for label baseline alignment 2012-07-12 15:10:04 -07:00
Vladimir Shevchenko ff074294ee mistakes corrected 2012-07-13 03:47:34 +07:00
Vladimir Shevchenko 028965e708 mistakes corrected 2012-07-13 03:43:12 +07:00
Vladimir Shevchenko 28b48edf02 Completed aliases and tests 2012-07-13 01:52:06 +07:00
Aparajita Fishman 86b83338c0 CPRuleEditor fixes
- Fixed case where no format strings are specified in xib (which ends up being an empty string).

- Fixed case where malformed strings file would not match regex.

- General cleanup.
2012-07-12 10:16:49 -07:00
aparajita 25f51eb5cd Merge pull request #1602 from mrcarlberg/sort_using_descriptors_with_key_path
Fixed sortUsingDescriptors: so it can handle sort descriptors with a key path
2012-07-12 08:19:46 -07:00
Aparajita Fishman ba7fa38924 Merge branch 'master' of github.com:cappuccino/cappuccino 2012-07-12 07:15:19 -07:00
aparajita 7586af8f91 Merge pull request #1606 from slevenbits/system-font
Overhaul of system font handling

- System fonts now track the currently configured system font at runtime.
- You can specify CPFontCurrentSystemSize as a system font size to track the currently configured system font size at runtime.
- Theme fonts and nib2cib now determine face and size at runtime, there is no need to recompile if the system font is changed in Info.plist.
- All hard-coded references to 12.0 as a system font size have been replaced by the current system font size.
- Documented the font substitution algorithm and how to use custom fonts in the CPFont class docs.
- See Tests/Manual/FontEnhancementTest for a demo.
2012-07-12 07:01:30 -07:00
Vladimir Shevchenko d6b9daf7ca Fixed documentation & spaces 2012-07-12 02:47:12 +07:00
Vladimir Shevchenko 2905cd1586 Linked methods from CPGeometry to CGGeometry + added unit tests 2012-07-12 00:19:10 +07:00
Aparajita Fishman 744bbd15d7 Merge branch 'master' of github.com:cappuccino/cappuccino 2012-07-11 09:24:35 -07:00
aparajita 7a6009f2e3 Merge pull request #1610 from slevenbits/text-clip-fix
Text clip fix


Currently when controls and text fields size to fit text, they use a to determine the correct height/width. Some browsers do not account for fractional pixels that arise from antialiasing. Cappuccino views must clip their contents, so the fractional pixels get clipped, and depending on the font this can be quite noticeable.

This patch adds 1 pixel when necessary to ensure no clipping occurs.
2012-07-11 09:19:46 -07:00
Aparajita Fishman 61f683b2e3 Merge branch 'text-clip-fix' 2012-07-11 09:11:04 -07:00
Vladimir Shevchenko a6d6fb1a1e CPGeometry moved to Foundation 2012-07-11 16:29:30 +07:00
Aparajita Fishman 4af061516c CPTableColumn -setHidden documentation was backwards. 2012-07-10 21:53:51 -07:00
Aparajita Fishman 49521b44fb Merge branch 'system-font' 2012-07-10 18:54:42 -07:00
Aparajita Fishman df9611cc2c Cleanup 2012-07-10 18:53:41 -07:00
Aparajita Fishman 99cd246ed8 Fix clipping of text due to fractional pixels 2012-07-10 18:08:33 -07:00
Aparajita Fishman 872df9fe39 Fixed window positioning 2012-07-10 17:35:42 -07:00
Aparajita Fishman f76404ef5e Merge branch 'refs/heads/system-font' 2012-07-10 16:41:06 -07:00
Aparajita Fishman ec4bfa00ee Per Cocoa, 0 size means create a static font in the current system font size. Added tests. 2012-07-10 16:40:44 -07:00
Aparajita Fishman 68c001e0c0 Don't attempt show CPScrollView, CPScroller or tooltips in the showcase, it doesn't work 2012-07-10 15:36:33 -07:00
Aparajita Fishman 5e40d6702e jake clobber should only clobber the theme, not Cappuccino 2012-07-10 12:47:55 -07:00
Aparajita Fishman a3d4dc2f9a Wrap _DOMElement access in #if PLATFORM(DOM), cleanup 2012-07-09 22:19:26 -07:00
aparajita a8d1224097 Merge pull request #1607 from slevenbits/archive-formatter
CPControl archives/unarchives its formatter

This allows you to use a formatter with a table column's data view.
2012-07-09 21:32:24 -07:00
Aparajita Fishman 4df0b7c940 Merge branch 'archive-formatter' 2012-07-09 21:31:09 -07:00
Aparajita Fishman 73fea44aa2 CPControl now archives/unarchives its formatter
This allows you to use a formatter with a table column's data view.
2012-07-09 21:30:09 -07:00
Aparajita Fishman 6cd2c96152 Merge branch 'system-font' 2012-07-09 16:50:55 -07:00
Aparajita Fishman 309463f15d Fixed parameter name 2012-07-09 16:50:31 -07:00
Aparajita Fishman 37a89a7b0a Cleanup 2012-07-09 15:47:26 -07:00
Aparajita Fishman 106e21b79c Merge branch 'system-font' 2012-07-09 15:33:34 -07:00
Aparajita Fishman 6b6f5d98e4 Overhaul of system font handling
- System fonts now track the currently configured system font at runtime.
- You can specify CPFontCurrentSystemSize as a system font size to track the currently configured system font size at runtime.
- Theme fonts and nib2cib now determine face and size at runtime, there is no need to recompile if the system font is changed in Info.plist.
- All hard-coded references to 12.0 as a system font size have been replaced by the current system font size.
2012-07-09 15:29:56 -07:00
Antoine Mercadal 2712a4d45c removed debug console.log 2012-07-09 15:05:03 -07:00
Antoine Mercadal d93fa98d1e Merge branch 'master' of https://github.com/cappuccino/cappuccino 2012-07-09 15:04:17 -07:00
Antoine Mercadal 63616cc50a fix enter key not working to select items in CPComboBox. With the help of @aparajita 2012-07-09 15:03:59 -07:00
Alexander Ljungberg 970dc912cb Merge branch 'master' into slevenbits 2012-07-09 20:32:07 +01:00
Alexander Ljungberg eb643a2df8 Simplify code. 2012-07-09 20:31:29 +01:00
Alexander Ljungberg 81f958eee1 Merge pull request #1605 from slevenbits/colorwell-styling
`CPColorWell` and `CPColorPanel` updates.
2012-07-09 20:17:49 +01:00
Alexander Ljungberg 613f61a898 Unit test CPColorWell archiving. 2012-07-09 20:03:19 +01:00
Alexander Ljungberg 77a009c9a6 Highlighted and disabled looks for bordered CPColorWell. 2012-07-09 19:53:57 +01:00
Alexander Ljungberg 2d8a849d12 nib2cib size fix for bordered CPColorWell. 2012-07-09 19:19:38 +01:00
Alexander Ljungberg b09908e6af Themable CPColorWell with Aristo look when bordered. 2012-07-09 19:18:46 +01:00
Antoine Mercadal ad74e93ea2 use CPPopUpMenuWindowLevel for _CPPopUpList's window level 2012-07-09 10:20:18 -07:00
Alexander Ljungberg 754311d2e2 More colour panel clean up. 2012-07-09 16:06:09 +01:00
Alexander Ljungberg f6514f3c64 Fix CPColorPanel errors and code style. 2012-07-09 15:57:24 +01:00
Alexander Ljungberg f398185aad CGRectInsetByInset geometry function.
This operation appears again and again in Cappuccino.
2012-07-09 15:44:13 +01:00
Alexander Ljungberg 4390bea31f Simplify CPColorWell drawing and mouse handling.
Use standard CPControl mouse handling and highlighting.

Switch to setNeedsLayout based drawing and hook up first themed property.
2012-07-09 13:01:44 +01:00
Alexander Ljungberg 660c98d6e5 Use theme system for CPColorWell bordered state.
This is more consistent with the rest of Cappuccino and prepares for theming support.
2012-07-09 12:20:47 +01:00
Alexander Ljungberg 1154a629a7 Code formatting. 2012-07-09 11:11:37 +01:00
Alexander Ljungberg 6f84440bcd Merge branch 'master' into slevenbits 2012-07-08 21:29:08 +01:00
Alexander Ljungberg 09e235eb60 Refs #1603. Optimise slightly. 2012-07-08 21:26:47 +01:00
Alexander Ljungberg 9dab0f083d Merge pull request #1603 from slevenbits/indexset-passingtest
Add *passingTest methods to CPIndexSet
2012-07-08 21:26:05 +01:00
Ilya Kulakov 6dd44687c5 Implement *passingTest methods of CPIndexSet. 2012-07-09 02:40:47 +07:00
Alexander Ljungberg 4f69d82a4e Merge branch 'master' into slevenbits 2012-07-08 14:13:37 +01:00
Alexander Ljungberg 1a639afd99 Typos. 2012-07-08 14:13:21 +01:00
Antoine Mercadal 72cc494df4 fix bug showing the CPComboBox's list under popover 2012-07-06 16:02:40 -07:00
cacaodev f516078510 PR #1573
Support value transformers for CPContent and CPContentValues bindings.
Made _CPPopUpContentValuesBinder a subclass of CPPopUpContentBinder and reuse setContent:.
Fixed a bug in selectedIndex binding set and reverse set when insertsNull options is on.
_CPPopUPSelectionBinder : simplified the code for getting the unique selection binder in use.
ojunit and manual tests for contentvalues + value transformer.
2012-07-06 22:35:37 +02:00
cacaodev 6a1e5840b5 Merge remote-tracking branch 'mrcarlberg/binding_support_popup_button' into binding_support_popup_button
Conflicts:
	AppKit/CPPopUpButton.j
2012-07-06 22:30:12 +02:00
aparajita 98fbf3abc1 Merge pull request #1601 from slevenbits/CPComboBox
CPComboBox and CPTextField enhancements

- Full Cocoa-compliant implementation of CPComboBox and CPComboBoxDelegate.

- Better focus ring for CPTextField and all subclasses.

- CPTextField and its subclasses draw disabled contents differently, per Cocoa.
2012-07-06 13:24:01 -07:00
Martin Carlberg e265d09034 Fixed sortUsingDescriptors: so it can handle sort descriptors
with a key path instead of just a key.
Also added a test case for this.
2012-07-06 20:52:33 +02:00
Martin Carlberg dbb88b8a17 Included content and contentValue bindings improvments from cacaodev
Fixed a small typo error
2012-07-06 20:06:19 +02:00
Aparajita Fishman b85e44098b Merge branch 'CPComboBox' 2012-07-06 08:51:19 -07:00
Alexander Ljungberg 34e7d4abe5 Merge pull request #1600 from slevenbits/window-controller-container-view
Window controller container view
2012-07-06 16:36:26 +01:00
Ilya KulakovandAlexander Ljungberg f434717372 Fix style. 2012-07-06 16:03:29 +01:00
Ilya KulakovandAlexander Ljungberg 88f8581dcc Implement -[CPWindowController setViewControllerContainerView:], fix -[CPWindowController setViewControllerView:]
Container view is responsible for laying out its views.
Container view is a content view of the window.
If there is no container view, view controller's view is a content view of the window.
2012-07-06 16:03:29 +01:00
Alexander Ljungberg 552ba68187 Refs #1599. Fix teacher.car.year unit test message. 2012-07-06 15:53:19 +01:00
Alexander Ljungberg cff29904d7 Refs #1599. Format code. 2012-07-06 15:53:03 +01:00
Alexander Ljungberg b1774cdccf Merge pull request #1599 from slevenbits/kvo-fix
Wrong key path and change send to the observer
2012-07-06 15:38:50 +01:00
Aparajita Fishman 32737e0b72 CPComboBox and CPTextField enhancements
- Full Cocoa-compliant implementation of CPComboBox and CPComboBoxDelegate.

- Better focus ring for CPTextField and all subclasses.

- CPTextField and its subclasses draw disabled contents differently, per Cocoa.
2012-07-06 00:15:23 -07:00
aparajita b54ce4d782 Merge pull request #1597 from slevenbits/cptableview-grid
Make the default grid color in IB show correctly in CPTableView.

- Changed the default grid color from #dce0e2 to #ccc.
- Fixed NSColor to recognize the named color "gridColor" and set it to #ccc.
- NSTableView always saves the grid color from IB.
2012-07-05 16:16:30 -07:00
Aparajita Fishman b6adf26549 Make Alexander happy. ;-) 2012-07-05 12:26:55 -07:00
Aparajita Fishman d0bfde1887 Annotate indexOfObject methods, use "index" instead of "idx" 2012-07-05 11:34:01 -07:00
Ilya Kulakov 4094a1f826 Fix wrong change is sent to observer when top level object is changed.
When you change the top level object, observer MUST receive value
for the key path of the previous top level object as old and
value for the key path of the new top level object as new.
2012-07-05 17:59:29 +07:00
Alexander Ljungberg 8afb67521d Annotate indexesOfObjectsPassingTest: function signature. 2012-07-04 23:26:07 +01:00
Alexander Ljungberg 34be9cea3a Refs #1559. Fix split view autosave test. 2012-07-04 23:17:38 +01:00
Aparajita Fishman 618194996a Fixed CPString -hasSuffix docs 2012-07-04 17:29:28 -04:00
cacaodev 42f49795af Ignore Value Transformers, no error and log an info message. 2012-07-04 23:18:47 +02:00
aparajita e444a5d60a Merge pull request #1598 from slevenbits/array-filters-fix
Fixed the method names committed in 0f5a6b4e5e
2012-07-04 14:16:14 -07:00
Aparajita Fishman 593f3c2109 Fixed the method names 2012-07-04 17:03:53 -04:00
Aparajita Fishman e9fb821721 Make the default grid color in IB show correctly in CPTableView
Currently #888888 is being used as the default, mainly because NSColor.j doesn't recognize the "gridColor" named color, and the cached color in the .xib is #888888 for some reason. Actually the default grid color is #CCCCCC.
2012-07-04 16:39:47 -04:00
aparajita a4afe1bde9 Merge pull request #1596 from slevenbits/cptableview-typos
Added missing @
2012-07-04 13:29:45 -07:00
Aparajita Fishman 1d29fda5fd Added missing @ 2012-07-04 16:25:59 -04:00
aparajita 16b7093e19 Merge pull request #1595 from slevenbits/array-filters
Added CPArray -indexesOfObjectPassingTest methods
2012-07-04 12:46:51 -07:00
Aparajita Fishman 0f5a6b4e5e Added CPArray -indexesOfObjectPassingTest methods 2012-07-04 15:41:45 -04:00
cacaodev c7a8124be8 CPPopUpButtonTest test CPContentValuesBinding with value transformer. Currently failing. 2012-07-04 17:55:39 +02:00
Alexander Ljungberg c3c74a13c0 Merge pull request #1592 from slevenbits/splitview-autosave-improvement
Improve split view autosave.
2012-07-03 23:58:08 +01:00
Alexander Ljungberg cde50cc8b4 Refs #1558. Better ivar name and type. 2012-07-03 13:57:11 +01:00
Alexander Ljungberg fcc11b8969 Fixes #1559. Nested split view autosave and better override support.
Nested split views now correctly restore their divider positions by restoring "top down". E.g. a nesting split view is restored before the nested split view so that the nested split view has the correct frame size for the position it is restoring.

This commit also makes it easier to override autosave restores in a subclass or a controller's `viewDidLoad`. Now if `setPosition:ofDividerAtIndex:` is called after the split view's `initWithCoder:` has finished, but before the final autosave restore has occurred, the autosave restore is cancelled. This preserves whatever the modification the programmer intended to make instead of overwriting it with the autosaved position.

This commit also fixes a bug where an autosaved position would not be restored, or would be restored at an unexpected time, if `setFrameSize:` was not sent to the split view shortly after its `initWithCoder:`. (Such a `setFrameSize:` message is often sent due to a window `setFullPlatformWindow:` call in `AppController.j`'s `awakeFromCib`, but it's not necessarily sent.)
2012-07-03 13:53:52 +01:00
Alexander Ljungberg c9b7d1e842 Refs #1559. Autosave split view positions for frame size changes.
This covers the case where the whole split view is resized and the divider moves as a consequence. For example if the split view was made much smaller the fixed position of the divider previously autosaved might not even be inside of the split view frame anymore, and on restore from autosave that side of the split view might unexpectedly become collapsed.

The new behaviour also more closely matches Cocoa's, although there is still a slight difference in implementation.
2012-07-03 13:44:59 +01:00
Martin Carlberg e5f4a7c39a Added support for CPNullPlaceholderBindingOption and made some clean up of code 2012-07-03 12:36:19 +02:00
Alexander Ljungberg 814e72879e Manual test for split view autosave. 2012-07-03 11:09:39 +01:00
Alexander Ljungberg 5f9463a030 Refs #1558. Test all split view divider types. 2012-07-03 10:54:27 +01:00
Alexander Ljungberg 37d4a06aa4 Fixes #1558. Support "thick divider" split view style in nib2cib.
The thick divider style is converted to the pane splitter style in nib2cib since we only use two styles in Cappuccino.
2012-07-03 10:44:07 +01:00
aparajita fb590550cd Merge pull request #1589 from slevenbits/nib2cib-fixes
nib2cib fixes
2012-07-02 06:57:09 -07:00
Aparajita Fishman 2f27291c53 Tweaked debug output of custom image resources in nib2cib 2012-07-02 09:55:52 -04:00
Aparajita Fishman fc23863d85 Added support for alternate button title in nib2cib 2012-07-02 09:55:52 -04:00
aparajita 8651a59f43 Merge pull request #1587 from slevenbits/non-bordered-buttons
Non-bordered buttons should retain their size, not shrink to fit
2012-07-02 06:41:49 -07:00
Aparajita Fishman 2f1e9d76ec Non-bordered buttons should retain their size, not shrink to fit. 2012-07-02 09:40:00 -04:00
Mike Holman 2e1a72030e Fix CPPredicateEditor CPTextField action bug. 2012-07-02 16:17:35 +08:00
aparajita c9f32ac77b Merge pull request #1584 from slevenbits/splitview-autosave
CPSplitView autosave optimization
2012-06-30 13:34:50 -07:00
Aparajita Fishman 6efa30c52a autosave of position should not happen until divider tracking is completely done.
Also renamed a local variable that looked like an ivar.
2012-06-30 16:19:06 -04:00
Martin Carlberg ef30e21506 Missed to remove some line in manual merge 2012-06-30 09:20:50 +02:00
Martin Carlberg 70b5f9ee98 Merge branch 'popup_button_binder_subclass' of https://github.com/cacaodev/cappuccino into binding_support_popup_button
Conflicts:
	AppKit/CPPopUpButton.j
2012-06-30 08:41:14 +02:00
aparajita 3137839322 Merge pull request #1583 from slevenbits/splitview-userinfo
Splitview userinfo
2012-06-29 13:11:23 -07:00
Aparajita Fishman 345a865cc8 Post OS X 10.5, Cocoa adds a userInfo with the divider index when the user drags the divider 2012-06-29 13:09:47 -07:00
aparajita 2a4ef4394c Merge pull request #1582 from slevenbits/nib2cib-images
nib2cib image fixes
2012-06-29 11:33:13 -07:00
Aparajita Fishman 3ba5be1ec6 nib2cib image fixes
- nib2cib will now log the path and size of custom image resources in super verbose mode.

- Alternate images for buttons were not being set by nib2cib, that has been fixed.

- Fixed the name of the imagesize binary in the Xcode project.
2012-06-29 11:29:53 -07:00
Aparajita Fishman 606f3dfe6b Replaced Java-based image utility with Cocoa command line app, cleaned up some fontinfo stuff 2012-06-29 11:29:46 -07:00
cacaodev c865644e6c Test for CPPopUpButton bindings. 2012-06-29 19:42:20 +02:00
Martin Carlbergandcacaodev fec1586380 CPPopUpButton bindings support (set for all and reverse for selection related bindings) using a CPBinder subclass instead of dedicated selectors. 2012-06-29 19:40:23 +02:00
cacaodev 8e2afde3e4 CPKeyValueBinding -reverseSetValueFor: -> extract a method for getting the source value for a given binding. the goal is to facilitate subclassing. 2012-06-29 19:37:35 +02:00
Aparajita Fishman 5410884e03 Fixed the documentation for CPArray -indexOfObject methods 2012-06-29 09:02:35 -07:00
Aparajita Fishman e9ceb1d0c6 Documentation tweak 2012-06-28 15:25:39 -07:00
Alexander Ljungberg 8d14bdd819 CPToolbar autovalidate. 2012-06-28 22:41:41 +01:00
Alexander Ljungberg 23f3a01e3c Merge pull request #1579 from slevenbits/cptoolbar-delegate
CPToolbar delegate fix
2012-06-28 20:27:23 +01:00
aparajita 3540dd1c26 Merge pull request #1578 from slevenbits/initialize-fix
Implement missing +initialize checks and regularize checks
2012-06-28 12:09:42 -07:00
Aparajita Fishman cae5486ec6 Added missing class checks in +initialize, regularized checking code 2012-06-28 12:05:18 -07:00
Alexander Ljungberg a769618e3e Don't copy an array we'll copy again 2 lines later.
If the delegate returns nil we're just copying nil, and if it does return an array we only use it for a single read-only `arrayByAddingObjectsFromArray:`.
2012-06-28 19:15:20 +01:00
Alexander Ljungberg 80d537958e Fixed: CPToolbar delegate toolbarDefaultItemIdentifiers: is optional.
This fix makes it possible for a toolbar defined in a cib to have a delegate set without defining `toolbarDefaultItemIdentifiers:` like in Cocoa. You might be implementing other delegate methods.
2012-06-28 19:12:05 +01:00
aparajita d923fb56e2 Merge pull request #1577 from slevenbits/key-loop-fix
Key loop fix
2012-06-28 10:06:30 -07:00
Aparajita Fishman 7747bbffcf Fixed key loop calculation, might as well use _initialFirstResponder instance variable instead of accessor 2012-06-28 10:01:07 -07:00
ggsato db47d8fb85 fixed needsUntitled evaluation 2012-06-28 12:01:37 +09:00
Alexander Ljungberg c52315cd8d Refs #1572. Merge extra commit re highlights. 2012-06-25 21:58:02 +01:00
Alexander Ljungberg a2787f8783 Formatting. 2012-06-25 21:57:28 +01:00
Ilya Kulakov 913308d886 Refs #1572. Fix highlighted status is not preserved.
When higlightsBy == CPNoCellMask and showsStateBy == CPChangeBackgroundCellMask
higlighted status must be preserved when a user switch state from Off to On.
2012-06-26 03:54:59 +07:00
Alexander Ljungberg 21bb383193 Refs #1527. Fix button performClick: highlight.
Critically this is what enables button highlighting on key equivalents.
2012-06-25 18:13:16 +01:00
Alexander Ljungberg bd83885eca Refs #1527. Backwards compatibility.
If no highlight or state masks were encoded (button was encoded prior to them being added), make sure to let the default settings stand.
2012-06-25 17:42:31 +01:00
Alexander Ljungberg d34d139658 Refs #1572. Default CPButton type.
If a button is created in code it should act like a regular momentary push in button by default.
2012-06-25 17:21:56 +01:00
Alexander Ljungberg f5c201c0be Refs #1572. Fixed: CPPushInCellMask in showsStateBy.
Code didn't match comment.
2012-06-25 17:18:07 +01:00
Alexander Ljungberg 10fcc0c452 Refs #1572. Minor fixes. 2012-06-25 16:26:44 +01:00
Alexander Ljungberg 378822b777 Merge pull request #1572 from slevenbits/cpbutton-masks
CPButton and subclasses respect highlightsBy and showsStateBy masks now.

Conflicts:
	AppKit/CPButton.j
	Tests/Manual/CPButtonTest/AppController.j
	Tests/Manual/CPButtonTest/Info.plist
	Tests/Manual/CPButtonTest/Resources/MainMenu.cib
	Tests/Manual/CPButtonTest/Resources/MainMenu.xib
2012-06-25 16:05:03 +01:00
Alexander Ljungberg edebb81ed4 Merge pull request #1570 from aradabaugh/cpbutton-types
Enable additional button types for CPButton
2012-06-25 15:40:23 +01:00
Ilya Kulakov 7cf3ac3b40 CPButton and subclasses respect highlightsBy and showsStateBy now. 2012-06-25 18:57:10 +07:00
Ilya Kulakov c46c365823 Extenend CPButtonTest to test highlightsBy and showsStateBy. 2012-06-25 18:57:06 +07:00
Ilya Kulakov 66f5e1fb64 Take into account highlightsBy and showsStateBy when decoding cib.
nib2cib was modified to take into account these variables
during conversion nib->cib.
2012-06-25 18:57:01 +07:00
Ilya Kulakov c80417c433 Add highlightsBy method that returns current higlightsBy mask. 2012-06-25 18:56:56 +07:00
Martin Carlberg 32e3df1e80 Added key value binding support for CPPopupButton 2012-06-25 08:23:14 +02:00
Malte Tancred 3f65153d4f Corrected the format specifier for the flags variable. 2012-06-23 22:46:25 +02:00
Adam Radabaugh 5fbf0f83cb Make the check for CPOnOffButton tracking correctly use the highlights mask. 2012-06-23 14:26:46 -06:00
Adam Radabaugh 84c8427bb4 Merge branch master 2012-06-23 14:21:45 -06:00
cacaodev 539a8f0ca9 An OJTest for the table view's content binding 2012-06-22 21:59:41 +02:00
Alexander Ljungberg d39849b297 Improve token field keyboard navigation when tokens are selected.
If one or more token is selected and the left arrow key is pressed, collapse the selection to the left of the first selected token.

Similarly, on right arrow key collapse to the right of the last token.

Note that shift-left and shift-right have no effect if the first or last token respectively in the field are already selected.
2012-06-21 19:24:22 +01:00
Alexander Ljungberg 7764921c21 Select all support for CPTokenField.
Cmd-A (Mac) or Ctrl-A (other) finishes any ongoing editing and selects all tokens in a token field.

This commit also adds support for the `selectText:` and `selectAll:` methods.
2012-06-21 19:17:34 +01:00
Alexander Ljungberg 26ceb25e7b Merge pull request #1569 from slevenbits/rwelephant-token-field
Token field improved autocomplete, key bindings support, clean up
2012-06-21 10:32:33 -07:00
Aparajita Fishman 13423e43d5 Removed stray console.log 2012-06-20 11:05:22 -07:00
Aparajita Fishman 45da163230 text tweak 2012-06-18 09:31:34 -07:00
aparajita 281e3c925c Merge pull request #1566 from slevenbits/CPArrayController-tweaks
CPArrayController tweaks
2012-06-18 09:03:22 -07:00
Aparajita Fishman 6f50900b1b Added missing removeObjectAtArrangedObjectIndex, added missing return 2012-06-18 09:00:59 -07:00
Alexander Ljungberg 2200e40001 Fixed: browser shortcuts wouldn't work when a token field was active.
We now leave the default propagation policy of Cappuccino in place, which normally is NO for regular characters but YES for things which could be shortcuts.
2012-06-16 12:31:50 +01:00
Alexander Ljungberg 44b609f604 Don't make space for editing in token field if tokens are selected.
If the editor is placed while there is a token selection it can cause the token view to become scrollable to a white area at the bottom even that there is no editing cursor. And even if the editor is not at the bottom, the empty space made for the editor makes no sense when no editing cursor is visible.
2012-06-16 12:31:50 +01:00
Alexander Ljungberg d5918157ff Overwrite selected tokens by typing support.
If tokens are selected in `CPTokenField` and new text is entered, the selected tokens are overwritten by the newly entered text.
2012-06-16 12:31:50 +01:00
Alexander Ljungberg 19b53746cf Fix nil representedObjectForEditingString: response handling.
If `tokenField: representedObjectForEditingString:` returns nil, act the same as if the delegate method didn't exist. This matches Cocoa.
2012-06-16 12:31:50 +01:00
Alexander Ljungberg d0769ec360 Oops. Fix object value fix. 2012-06-16 12:31:49 +01:00
Alexander Ljungberg 3c20bf8ad6 Allow token field insertText: to be somewhat overridden.
If `insertText:` is overridden to do nothing, nothing in inserted.
2012-06-16 12:31:49 +01:00
Alexander Ljungberg 3eab2a528f Make token field object value more like Cocoa.
If a half typed token is in the field, Cocoa tries to convert it to a representedObject before responding to objectValue. Now CPTokenField does the same.
2012-06-16 12:31:49 +01:00
Alexander Ljungberg fb404a0671 Hide private token field API. Fix return type. 2012-06-16 12:31:49 +01:00
Alexander Ljungberg 6d6cf52180 Minor token field optimisation. 2012-06-16 12:31:49 +01:00
Alexander Ljungberg e9ba326610 Inlineable range functions. 2012-06-16 12:31:49 +01:00
Alexander Ljungberg 55ca956f50 Remove nonstandard CPCopyRange. 2012-06-16 12:31:49 +01:00
Alexander Ljungberg f43c643d5a Allow token field subclasses to override defaultCompletionDelay.
Also fixed incorrect return type.
2012-06-16 12:31:49 +01:00
Alexander Ljungberg 69f5fc536c Key bindings support for token field.
Also improve compatibility with `CPTextField` superclass and subclassing support by properly using `interpretKeyEvents:` like `CPTextField`.
2012-06-16 12:31:49 +01:00
Alexander Ljungberg 132ac7c03f Token field 'keyUp:' support. 2012-06-16 12:31:49 +01:00
Alexander Ljungberg 5683af9bc8 Improve token field subclassing support.
Token field now triggers autocompletion from textDidChange: which better meets the expectations of Cappuccino programmers, and is closer to how Cocoa does it.

Eliminated custom non-Cappuccino key press handler.
2012-06-16 12:31:48 +01:00
Alexander Ljungberg 429933f601 Fix token field keyDown: handling.
`CPTokenField` had custom key down handling making it function poorly with Cappuccino's event handling and subclasses.
2012-06-16 12:31:48 +01:00
Alexander Ljungberg 317364681a Fixed: make sure autocomplete menu fits within browser. 2012-06-16 12:31:48 +01:00
Alexander Ljungberg 9575fd7771 Autosize token field autocomplete menu.
The new menu is much more efficient for the user:

* Less tall items makes it much easier to select among many completions.
* Exactly wide enough for widest item.
* Tall enough to show all items (instead of just 3 as before).
* Uses a maximum width and height defined by the screen edges and some Cocoa-like constants.
2012-06-16 12:31:48 +01:00
Alexander Ljungberg 85cfb18906 Place token autocomplete underneath what's being completed.
This matches Cocoa.
2012-06-16 12:31:48 +01:00
Alexander Ljungberg 33fe1573ad Ensure autocomplete menu is on top.
The menu should appear above other normal windows and controls like a regular CPMenu. To do this, put the pop up in its own window with the `CPPopUpMenuWindowLevel` window level.
2012-06-16 12:31:48 +01:00
Alexander Ljungberg 2574fac44a Remove token field reference. 2012-06-16 12:31:48 +01:00
Alexander Ljungberg b166995327 Move autocomplete into reusable class. 2012-06-16 12:31:48 +01:00
Alexander Ljungberg feaf9c6f20 Improve CPTokenField autocomplete scrolling. 2012-06-16 12:31:48 +01:00
Alexander Ljungberg 0ef03d31b8 Refactor CPTokenField autocomplete.
The new code is simpler (single responsibility principle) and makes it easier to improve on autocomplete.
2012-06-16 12:31:48 +01:00
Alexander Ljungberg 80ee88d3a7 Hide another non-public API in CPTokenField. 2012-06-16 12:31:48 +01:00
Alexander Ljungberg bbc45dd947 Support tokenField:representedObjectForEditingString: delegate method.
This improves support for represented objects and is used both when an autocompletion suggestion is used or when the name of a token is typed in by hand.

The behaviour of taking an array of strings from `completionsForSubstring` and then asking for a represented object once a choice has been accepted matches the behaviour of Cocoa.
2012-06-16 12:31:47 +01:00
Alexander Ljungberg d07ee3ea23 Hide non-public API in CPTokenField.
Also improve documentation.
2012-06-16 12:31:47 +01:00
Alexander Ljungberg 7ffd65476b Fixed: token field auto completions.
Auto completions are strings, not represented objects. Revert "Fix CPTokenField autocompletion to deal with represented objects"

This reverts commit 8b9a0edeba.
2012-06-16 12:31:47 +01:00
Alexander Ljungberg ca0a07cab8 Formatting. 2012-06-16 12:31:47 +01:00
Antoine Mercadal 0d29f15b70 Merge pull request #1513 from BlairDuncan/MenuTimestampFix
Fix for menu selection that was broken with the change to CPEvent timestamp
2012-06-14 17:02:06 -07:00
Antoine Mercadal 714d36d8c8 Merge branch 'CPImageView-bindings' of https://github.com/cacaodev/cappuccino into pull1534 2012-06-14 13:05:04 -07:00
Antoine Mercadal cd94819099 Merge branch 'issue1435' of https://github.com/stewa/cappuccino into issue1435 2012-06-14 11:58:49 -07:00
Antoine Mercadal 52199776d5 Merge pull request #1537 from mrcarlberg/cptableview_selection_radius
Added a themed attribute for round rect selection of rows. [+1]
2012-06-14 10:29:58 -07:00
Antoine Mercadal f8df87edcf Merge pull request #1561 from tancred/xcodeapp_always_creates_support_sources
Create support sources folder if necessary.

Reviewed.
2012-06-14 10:27:43 -07:00
Antoine Mercadal dc68daa859 Merge pull request #1564 from tancred/xcodecapp_sync_last_event_id_more_frequently
Make XcodeCapp synchronize file system event status more frequently.

Reviewed.
2012-06-14 10:24:40 -07:00
Malte Tancred 1fd021770e Split -synchronizeLastEventId in two methods.
The first method (updateUserDefaultsWithLastEventId) just
sets the default while the other (synchronizeUserDefaultsWithDisk)
forces a synchronization with the disk.
2012-06-14 11:43:52 +02:00
Antoine Mercadal 6f32e598e9 Add manual tests for disabled button with image 2012-06-13 15:22:53 -07:00
Antoine Mercadal 19794b06ab nib2cib sets _imageDimsWhenDisabled to YES for buttons 2012-06-13 15:22:26 -07:00
Antoine Mercadal ecdb064a5b Makes CPButton to dim image when disabled by default 2012-06-13 15:21:45 -07:00
Antoine Mercadal d67a03bfb4 make disabled buttonbar buttons more visible 2012-06-13 14:30:26 -07:00
Antoine Mercadal c361d7a52a Merge branch 'new-cpbuttonbar-artwork' 2012-06-13 10:12:05 -07:00
Malte Tancred 0018be6fd8 Make XcodeCapp synchronize file system event status more frequently.
This is a small fix that makes XcodeCapp update the latestEventId value
in the defaults database at the end of each FSEvents callback.

Prior to this fix, the synchronization was performed only when the user
actively decided to stop listening to a project.
2012-06-13 10:37:08 +02:00
Antoine Mercadal 4a4aa5fc10 update artwork for CPButtonBar 2012-06-12 19:03:32 -07:00
Alexander Ljungberg 8791195673 Merge branch 'master' of github.com:cappuccino/cappuccino 2012-06-13 02:21:07 +01:00
Alexander Ljungberg 72374257ef Minor optimisation and clean up. 2012-06-13 02:20:58 +01:00
Alexander Ljungberg 1b9def2101 Allow asymmetric toolbar margins. Foundation for theming.
Toolbars cannot be themed yet but when theming becomes possible this code should adapt readily.
2012-06-13 02:17:13 +01:00
Alexander Ljungberg 7a467e249e Manual test for toolbars. 2012-06-13 01:40:59 +01:00
Alexander Ljungberg a66942b1b1 Fix and tweak toolbar margins. 2012-06-13 01:40:20 +01:00
Alexander Ljungberg acd3425c43 Dynamic CPToolbar height,
* Support for tall custom widgets. You can now finally have that CPTableView you always wanted in your toolbar.
* "Labels only" mode now makes sense, resulting in a narrow text only toolbar instead of a very tall toolbar with centred labels.
* Use any size toolbar icons such as 48x48 and the toolbar adapts automatically (unlike Cocoa).
2012-06-13 01:26:33 +01:00
Alexander Ljungberg 70bc45ba12 Toolbar CPToolbarDisplayModeIconOnly support. 2012-06-12 23:26:43 +01:00
Alexander Ljungberg 026c210e64 Toolbar CPToolbarDisplayModeIconOnly support. 2012-06-12 23:05:16 +01:00
Alexander Ljungberg 3bc1849041 Improve toolbar item layout.
The height of all items is determined by the tallest item, like in Cocoa. But unlike Cocoa our toolbar is presently fixed height so in order to make this look well for small or large items, the whole row of items is now vertically centred, making the allocation of margin above and below automatic.

Furthermore if a toolbar item has a small view or a small icon, it is now centred within the available space above the label. For example, for a tiny icon in one item next to a normal size icon the tiny icon would be centre aligned with the larger icon.
2012-06-12 23:04:33 +01:00
Antoine Mercadal 17668aca17 Merge remote-tracking branch 'upstream/master' 2012-06-12 11:59:26 -07:00
Antoine Mercadal 2a48b0ca54 make actualResizeEvent a private method 2012-06-12 11:57:19 -07:00
Antoine Mercadal 5acc15ea9e Merge https://github.com/jivadevoe/cappuccino into pr-1545 2012-06-12 11:45:34 -07:00
Malte Tancred 52fff2056b Fixed code standard issues. 2012-06-12 17:44:17 +02:00
Alexander Ljungberg 2a955884b8 Fix header. 2012-06-11 13:14:00 +01:00
Alexander Ljungberg ad5403b538 Setting the shadow style just once will do. 2012-06-11 13:13:36 +01:00
Alexander Ljungberg f538cbc51d Re #1560. Remove obsolete function. 2012-06-10 01:18:56 +01:00
Alexander Ljungberg e232b18b94 Merge pull request #1560 from mrcarlberg/cappuccino
---

I needed to sort a lot of objects and was not impressed by the speed.
Sharing my improvements...
2012-06-10 01:00:40 +01:00
Alexander Ljungberg fcf62080d6 Re #1562. Make native comparison more realistic.
This might have a small speed implication.
2012-06-10 00:59:08 +01:00
Alexander Ljungberg 58103ce0f3 Re #1562. Also performance test selector sort.
It looks like issue #1560 will cause a different sorting function to be used for selectors vs descriptors so performance of both should be monitored for regressions.
2012-06-10 00:58:27 +01:00
Alexander Ljungberg 0827f584be Re #1562. Simplify. 2012-06-10 00:39:37 +01:00
Alexander Ljungberg f042996e7f Re #1562. Only load sort text for tests which use it. 2012-06-09 23:16:52 +01:00
Alexander Ljungberg 7b307a6fb4 Re #1562. Format code. 2012-06-09 23:08:27 +01:00
Alexander Ljungberg bb8a7bacdc Merge pull request #1562 from cacaodev/cappuccino
---

for random numeric array and text array.
2012-06-09 16:49:23 +01:00
Martin Carlberg 0696b22971 Fixed formatting 2012-06-08 20:18:22 +02:00
Martin Carlberg d7ff93f7f2 SortUsingDescriptors: Using the selector in the descriptor instead of always using compare: 2012-06-08 19:48:39 +02:00
cacaodev 0483f9d714 CPArrayPerformanceTest: fixed native sort testing, added tests for random numeric array and text array 2012-06-08 18:19:37 +02:00
Malte Tancred 56c0f7f6f1 Create support sources folder if necessary.
Make sure the the xCodeSupport/Sources folder is always
present. The objj tool will fail if it's missing.

The Sources folder could be missing if it's not checked
into a repos for example.
2012-06-08 13:21:47 +02:00
Martin Carlberg dc30092b60 A very fast sortUsingDescriptors:
I needed to sort a lot of objects and was not impressed by the speed.
Sharing my improvements...
2012-06-07 23:25:58 +02:00
aparajita 7ccd6f842b Merge pull request #1557 from cacaodev/CPTableView-selectedColumn-typo
CPTableView -selectedColumn : missing return statement
2012-06-06 08:08:23 -07:00
cacaodev 299a664b9c CPTableView -selectedColumn : missing return statement 2012-06-06 14:24:28 +02:00
Alexander Ljungberg 0ed398310f Merge branch 'master' of github.com:cappuccino/cappuccino 2012-06-02 13:19:13 -07:00
Alexander Ljungberg 55709cb83a Test CPDate testInitWithString with a date prior to 1970.
This verifies that there are no problems with negative time intervals.
2012-06-02 13:18:58 -07:00
Alexander Ljungberg d0c7796e7c Match CPDate distantPast and distantFuture with Cocoa. 2012-06-02 13:17:34 -07:00
aparajita 544dff205d Merge pull request #1556 from cacaodev/CPDate-referenceDate
CPDateReferenceDate should be 'Jan 1 2001' instead of 'Feb 1 2001'
2012-06-02 12:41:46 -07:00
Alexander Ljungberg 25763962b2 Code formatting. 2012-06-02 11:53:04 -07:00
Alexander Ljungberg fc858933be Re #1556. Make CPDate testSince1970 agree with new reference date. 2012-06-02 11:32:19 -07:00
Alexander Ljungberg 6877aaaf61 Re #1556. Unit test CPDate dateWithTimeIntervalSinceReferenceDate:. 2012-06-02 11:27:19 -07:00
Alexander Ljungberg e4ab1256da Merge pull request #1556 from cacaodev/cappuccino
---

See <https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSDate_Class/Reference/Reference.html#//apple_ref/occ/clm/NSDate/dateWithTimeIntervalSinceReferenceDate:>
2012-06-02 11:23:22 -07:00
cacaodev f2dd6b5dce CPDateReferenceDate should be 'Jan 1 2001' instead of 'Feb 1 2001' 2012-06-02 19:38:34 +02:00
Blair Duncan eeceaa0c9b unlite if mouse is moved off and cursor up hilites last item if none 2012-06-01 20:17:09 -04:00
Alexander Ljungberg bc79d57712 Clean up. 2012-05-27 22:21:11 +01:00
aparajita 954ec26e80 Merge pull request #1551 from ggsato/subclassingDocController
fixed shared CPDocumentController instantiation and added its test
2012-05-26 12:44:18 -07:00
cacaodev 086c0e6ef0 Merge remote-tracking branch 'upstream/master' into CPTableView-content-binding 2012-05-26 08:03:56 +02:00
ggsato fabe1d8991 formatting and now subclassing is tested by Open a document 2012-05-26 11:08:57 +09:00
Antoine Mercadal 02b65e6dfb Fix a bug in Nib2Cib.j when configInfo is null 2012-05-25 18:06:05 -07:00
Alexander Ljungberg aa546374f3 Fixed: typo in aa4eff9. 2012-05-26 00:22:23 +01:00
Alexander Ljungberg 288ec78c3e Fixed: split view autosave.
The fix to prevent incorrect autosaving prevented correct autosaving as well.
2012-05-26 00:04:12 +01:00
Martin Carlberg 2f875615a2 Removed hardcoded width in disclosure button 2012-05-25 11:14:43 +02:00
Martin Carlberg 49adcd85fc Removed useless space after capp_lint warning 2012-05-25 10:54:10 +02:00
Martin Carlberg 8e785c2210 Removed set and get methods and blank line before if added. 2012-05-25 10:47:07 +02:00
ggsato 310422adb1 Added another way to subclass CPDocumentController 2012-05-25 17:09:31 +09:00
ggsato 0dbebf2f04 Added another way to subclass CPDocumentController 2012-05-25 16:54:10 +09:00
Alexander Ljungberg 46aabf0ea2 Code formatting. 2012-05-25 01:12:57 +01:00
Alexander Ljungberg 1a14ef2418 Fixed: capp_lint handling of string literals with escapes.
This could cause capp_lint to warn about what it perceived as code inside of string literals if the string literal ended with an escaped backslash.
2012-05-25 01:07:35 +01:00
Alexander Ljungberg aa4eff9f8d Format code, fix accidental global. 2012-05-25 00:04:46 +01:00
Alexander Ljungberg 9ffaf538e2 Remove unary + warning from capp_lint.
A statement like `x = +y;` actually does have an effect in JavaScript.
2012-05-24 23:58:01 +01:00
Alexander Ljungberg 2a21ce4a0c Support function argument types in capp_lint.
Syntax such as function(/*CPString*/anArgument) {} should not generate a warning, and in general inline /**/ comments should be ignored for linting purposes.
2012-05-24 23:52:30 +01:00
Alexander Ljungberg 09d5957c82 Code formatting. 2012-05-24 23:40:15 +01:00
Alexander Ljungberg 2b8b570dd4 Fixed: capp_lint exponential warnings.
capp_lint issued warnings over numerical literals like 2.1e+6 even that they were correctly formatted.
2012-05-24 23:22:24 +01:00
Alexander Ljungberg a7bee74fb0 Report the original line contents in capp_lint.
capp_lint does some preprocessing of lines to simplify the lint tests, but the user will expect the regular, non processed lines in the output.
2012-05-24 22:34:50 +01:00
Alexander Ljungberg 1f803f52d1 Add some illustrative capp_lint doctests. 2012-05-24 19:37:30 +01:00
Alexander Ljungberg 0d5b4d4958 Fixed: if linted text didn't end with a newline the last character would be ignored. 2012-05-24 19:26:05 +01:00
Alexander Ljungberg 24cce3ca8a Make LintChecker().lint_text('<code>') possible.
Made LintChecker()'s "view" and lint_text's "filename" arguments optional. Filename will default to <stdin> like Python does when you pipe to it. Also return found errors from lint_text as a convenience.
2012-05-24 19:24:50 +01:00
ggsato 2a0ee14130 wrapped window.status clear statement 2012-05-25 01:52:09 +09:00
Alexander Ljungberg e25394a322 Code formatting. 2012-05-24 17:10:46 +01:00
ggsato ab1dc15393 moved types declaration 2012-05-24 23:58:59 +09:00
ggsato 3a750591bb moved types declaration 2012-05-24 23:55:04 +09:00
ggsato 7da9877c5f fixed shared CPDocumentController instantiation and added its test 2012-05-24 23:12:07 +09:00
Alexander Ljungberg 66ff5dcb86 Merge pull request #1550 from ggsato/cappuccino
---

This is a tiny little minor fix of MainMenu.xib template. 

Before

https://www.dropbox.com/s/cqq8zhy8o2yof51/NibTemplate_Before.png

After

https://www.dropbox.com/s/78j95f1gl596vro/NibTemplate_After.png
2012-05-24 13:54:57 +01:00
ggsato f50a6ea7a3 fixed menu labels by removing numbers at Identity Label 2012-05-24 18:09:17 +09:00
Adam Radabaugh 253d7497ef Merge branch 'master' of git://github.com/cappuccino/cappuccino 2012-05-23 00:15:22 -06:00
Aparajita Fishman 1efc2e3c15 Fixed parsing in CGSizeFromString and CGPointFromString 2012-05-22 12:52:54 -07:00
Adam Radabaugh 909c6ed171 Fix style issue in CPControl 2012-05-19 16:56:57 -06:00
Aparajita Fishman b4f916351e Added capp_lint check for space inside parens and dependent statement on same line, cleaned up CPString.j 2012-05-19 14:20:07 -07:00
Adam Radabaugh a47a5b76eb Fix style issue in CPButton.j 2012-05-18 23:15:26 -06:00
Adam Radabaugh 919bfb7960 Fix style issue in CPControl 2012-05-18 17:11:04 -06:00
Antoine Mercadal bc09c99952 Merge branch 'master' of https://github.com/cappuccino/cappuccino 2012-05-18 12:51:34 -07:00
Antoine Mercadal 28ccb27d4f Merge branch 'cpstring_append_path_component_cocoa_way' of https://github.com/mrcarlberg/cappuccino into PR_mrcarlberg_cpstring_append_path_component_cocoa_way 2012-05-18 12:47:41 -07:00
Jiva DeVoe d205c4eac7 updating to remove a comment and to fix a formatting issue 2012-05-18 10:25:06 -07:00
Jiva DeVoe 18662deec6 removed the if statement before the invalidate 2012-05-17 23:52:41 -07:00
Jiva DeVoe d955eceafa fixed an errant semicolon 2012-05-17 23:34:26 -07:00
Jiva DeVoe 995d529fb7 Added a very hacky workaround for the jittery resize bug in webkit. Ref: https://github.com/cappuccino/cappuccino/issues/1325 2012-05-17 23:10:04 -07:00
Aparajita Fishman d4e460dac5 When popover closes implicitly, popoverShouldClose delegate method should be called.
Added extra button popover to test -close method, which does not consult popoverShouldClose.
2012-05-17 17:02:45 -07:00
cacaodev 0314005e0e Added CPImage -data. If needed, generates data for canvas compatible browsers. Added a test in CPImageViewTest where an image is created from the data of another image 2012-05-17 23:02:49 +02:00
cacaodev 7831085a97 Merge remote-tracking branch 'upstream/master' into CPImageView-bindings
Conflicts:
	Tests/Manual/CPImageViewbindingsTest/Resources/MainMenu.cib
2012-05-17 14:01:20 +02:00
cacaodev db8f2fdf75 Added support for CPTableView content binding, generally used with view-based tables.
Grouped the 3 ways to set objectValue on a dataview (content binding, column value binding or regular delegate method) under one main method: _setObjectValueFortableColumn:row:ForView:
    Also fixed a bug where the dragging rows didn't have their bindings applied. Columns and row dragging are now using the previous method for setting data view objectValue.

    Updated TableBindings example: table with content binding vs. columns with value binding.
2012-05-16 15:57:26 +02:00
aparajita d18e77329f Merge pull request #1542 from BlairDuncan/controlDidFailToFormatStringFix
controlDidFailToFormatString should send a string not an HTML element
2012-05-15 21:39:14 -07:00
Blair Duncan 8f4acc98d4 controlDidFailToFormatString should send a string not an HTML element 2012-05-16 00:03:00 -04:00
Adam Radabaugh 95f7ba29cc Update latest nib2cib with demo of button types 2012-05-15 14:38:54 -06:00
Adam Radabaugh 7ab20145d1 Merge branch 'master' of git://github.com/cappuccino/cappuccino
Conflicts:
	Tests/Manual/CPButtonTest/Resources/MainMenu.cib
2012-05-15 14:15:03 -06:00
Blair Duncan 5f7d1e8dc3 controlDidFailToFormatString should send a string not an HTML element 2012-05-15 16:07:56 -04:00
Antoine Mercadal 6010288124 Merge pull request #1541 from cacaodev/CPPopover-setBehavior
CPPopover typo: setBehaviour: -> setBehavior:

Reviewed.
2012-05-15 12:49:59 -07:00
cacaodev 8a10105f48 CPPopover typo: setBehaviour: -> setBehavior: 2012-05-15 21:42:14 +02:00
Antoine Mercadal 478fb43d2a Fix all Manual tests showing empty UI. (re-run nib2cib on all of them) 2012-05-15 12:08:19 -07:00
Alexander Ljungberg 4b7cef637b Refs #1538. Reapply formatting. 2012-05-14 21:21:45 +01:00
Alexander Ljungberg 69c72d366e (Fix commit attribution) Merge pull request #1538 from mrcarlberg/cappuccino
---

Dont you hate when your logs of arrays and dictionaries display [Object object] when you have JavaScript objects in them. Now with this patch all JavaScript objects will be display with all attributes in a nice good looking way. Log CGRect, CGPoint and other JavaScript objects withour any hassle anymore. For example: console.log([myRect]);

Conflicts:
	Foundation/CPObject.j
	Tests/Foundation/CPMutableArrayTest.j
2012-05-14 21:20:41 +01:00
Alexander Ljungberg 5e7125e310 Refs #1538. Clean up, accidental global. 2012-05-14 21:12:31 +01:00
Alexander Ljungberg bc370a2a5a Merge pull request #1538 from mrcarlberg/cappuccino
---

Dont you hate when your logs of arrays and dictionaries display [Object object] when you have JavaScript objects in them. Now with this patch all JavaScript objects will be display with all attributes in a nice good looking way. Log CGRect, CGPoint and other JavaScript objects withour any hassle anymore. For example: console.log([myRect]);
2012-05-14 21:12:17 +01:00
Martin Carlberg 0abd9855c2 Moved new description functionallity from CFDictionary to CPDictionary.
Added testcase for both CPDictionary and CPArray. Fixed failing testcase.
Checked all new code with capp_lint for correct formatting.
2012-05-14 10:14:05 +02:00
Alexander Ljungberg 3525bd0183 Code formatting. 2012-05-13 14:26:19 +01:00
Darrell Walisser 098f72651c -correct documentation 2012-05-12 15:05:48 -04:00
Darrell Walisser 8c1d147319 -remove next sheet context hack
-order of notifications/didEndSelect are correct now
2012-05-12 14:22:54 -04:00
Martin Carlberg 327debe3a8 Some more clean-up 2012-05-11 23:39:41 +02:00
Martin Carlberg 4af27541d0 Clean-up 2012-05-11 23:33:37 +02:00
Martin Carlberg 70182a0ea2 Description methods in CPArray and CPDictionary will display JavaScript object attributes instead of displaying [Object object]
Don't you hate when your logs of arrays and dictionaries display [Object object] when you have JavaScript objects in them.
Now with this patch all JavaScript objects will be display with all attributes in a nice good looking way. Log CGRect, CGPoint
and other JavaScript objects withour any hassle anymore. For example: console.log([myRect]);
2012-05-11 17:40:11 +02:00
Martin Carlberg 183260d9e3 Added a themed attribute for round rect selection of rows.
Selections in the tableview can now have round corners. The default is a regular
rect, but if the selecction radius is changed. Nice good looking round rect
selections will appear.
2012-05-11 16:14:14 +02:00
Martin Carlberg df2cf923e1 MainBundle path has no '/' at the end when running in CommonJS.
This will make relative paths fail. For example if OBJJ_INCLUDE_PATHS has the path "../../MyLibrary".
MyLibrary will not be found when the path is joined with mainBundlePath without an ending '/'.
This is working when running in Browser.
2012-05-11 15:52:44 +02:00
Martin Carlberg c35ccde682 Added stringByAppendingPathComponent: and stringByAppendingPathExtension: to CPString. Also, changed CPString path behaviour to correspond to Cocoa behaviour. 2012-05-11 15:32:18 +02:00
Alexander Ljungberg afbfde0909 Code formatting. 2012-05-10 16:01:22 +01:00
Alexander Ljungberg e72093c91e Merge pull request #1531 from BlairDuncan/cappuccino
---
2012-05-10 15:50:10 +01:00
Blair Duncan 1ffdaf0f8b typo, LOG should be log 2012-05-10 09:01:03 -04:00
Blair Duncan 74431972d8 added missing LOG math global and replaced any math. with correspoinding global 2012-05-10 08:55:19 -04:00
Stefan Wallström 19804720af CPTableView: Don't update selection etc unless becoming first responder succeeds.
Fix for issue #1435
2012-05-10 13:42:37 +02:00
Alexander Ljungberg 1f8555ffd2 Merge branch 'master' of github.com:cappuccino/cappuccino 2012-05-10 00:19:49 +01:00
Alexander Ljungberg 4218c49a7e Refs #1529. Verify that the actual issue error is gone. 2012-05-10 00:17:25 +01:00
Alexander Ljungberg 8aaf298466 Fixes #1529. Fixed: Incorrect CPDecimalNumber result for 220000/220.
And in general divisions where the quotient had fewer digits than the dividend when disregarding exponent would fail.

We want to stop dividing when we've gone over all the digits in the dividend and the remainder is 0.
2012-05-10 00:16:56 +01:00
Alexander Ljungberg 82e2c7a0e8 Refs #1529. Simpler test: 11/11. 2012-05-10 00:02:44 +01:00
Alexander Ljungberg 27fa01648f Code formatting, delete stray */. 2012-05-10 00:01:03 +01:00
Alexander Ljungberg ab25408429 Refs #1529. Unit test exposing division error. 2012-05-09 23:39:11 +01:00
Alexander Ljungberg d896baf38b Code formatting. 2012-05-09 19:09:35 +01:00
Darrell Walisser 53798c1545 -allow any window to become a sheet 2012-05-06 12:07:02 -04:00
Darrell Walisser 1e6f0090da -allow any window to become a sheet 2012-05-06 12:06:23 -04:00
aparajita 0dcca6d388 Merge pull request #1527 from BlairDuncan/reNib2cibTestFiles
ran nib2cib on all of current test files xib's
2012-05-04 18:04:55 -07:00
Blair Duncan 934691fffb nib2cib all of current test files xib's 2012-05-04 20:10:55 -04:00
Alexander Ljungberg 6bc26eb0cc Test app to verify CPProgressIndicator rendering, nib2cib and coding. 2012-05-03 20:42:41 +01:00
Alexander Ljungberg bdcc1539ac Use an ephemeral subview for the bar of a progress indicator.
This is clearer code and avoids encoding the 'pill view' automatically.
2012-05-03 20:40:50 +01:00
Alexander Ljungberg 6715fbbce2 nib2cib support for CPProgressIndicator size. Fixed: a regular size spinner in IB became twice as large in Cappuccino. 2012-05-03 20:27:05 +01:00
Alexander Ljungberg da055f83b3 Fixed: CPProgressIndicator encoder wasted space and caused errors.
The errors would cause exceptions such as "Not allowed to load local resource: file:///<some local path from the machine that ran nib2cib>" when loading cib driven app through a web server.
2012-05-03 19:45:12 +01:00
Alexander Ljungberg 1476efce90 Minor formatting. 2012-05-03 01:36:17 +01:00
Adam Radabaugh 2078d0e23b Restore copywrite info in headers. 2012-05-01 15:16:44 -06:00
Adam Radabaugh ea0107f67f Enable additional button types in CPButton with manual test. 2012-05-01 15:11:34 -06:00
Darrell Walisser c71f5baef2 -implement orderOut: to control sheet dismissal
-lots of comments and a few debug prints
2012-04-28 20:36:10 -04:00
Darrell Walisser 66f55df44a -use _endSheet to end sheets
-do not call orderFront: if the sheet is already visible
2012-04-28 20:32:13 -04:00
Darrell Walisser 8fd5f30b87 -call orderOut: to dismiss the alert sheet 2012-04-28 20:28:09 -04:00
Darrell Walisser 8bc4a287a6 -update docs for sheet notifications 2012-04-28 11:31:01 -04:00
cacaodev d1dd177bfd CPImageView: support for CPDataBinding. Test. 2012-04-28 17:12:22 +02:00
cacaodev 80b6788638 CPImage -initWithData: 2012-04-28 17:11:37 +02:00
Darrell Walisser ce6444c30e -implement CPWindow sheet notifications on delegate
-raise error when window already has a sheet, or attaching sheet to a sheet
2012-04-28 10:13:02 -04:00
Alexander Ljungberg c437537749 Merge branch 'master' of github.com:cappuccino/cappuccino 2012-04-27 01:19:56 +01:00
Alexander Ljungberg c16c0309c8 Fixed: CPOutlineView setMenu: was not effective.
A CPOutlineView without a delegate `outlineView:menuForTableColumn:item` method, would not display its context menu as specified by `setMenu:` or in IB.
2012-04-27 01:19:47 +01:00
aparajita 1dcd380bb2 Merge pull request #1283 from cacaodev/CPRulePredicateEditor
CPRuleEditor & CPPredicateEditor fixes and enhancements
2012-04-26 12:02:07 -07:00
cacaodev 6fe3d53a13 Merge remote-tracking branch 'upstream/master' into CPRulePredicateEditor 2012-04-26 20:34:18 +02:00
cacaodev 92cdda1d22 capplinted CPRuleEditor/*.j 2012-04-26 20:34:09 +02:00
Aparajita Fishman 3eb4155489 Switched to /usr/bin/env bash for better cross-platform compatibility 2012-04-26 19:11:05 +02:00
Aparajita Fishman e657e7a684 Make capp_lint use a single code base for command line and SublimeLinter 2012-04-26 18:14:06 +02:00
Alexander Ljungberg 5446bedfcc Fixes #1519. Fixed: capp_lint __init__ takes at least 2 arguments error.
Some SublimeLinter specific bits appear to have made it into the standalone capp_lint.
2012-04-26 16:02:41 +01:00
Alexander Ljungberg be36803570 Fixed: CPPredicateEditor "Display value must be…" exception in recent revisions. 2012-04-26 15:35:55 +01:00
Alexander Ljungberg 998bdb550b Merge branch 'master' of github.com:cappuccino/cappuccino 2012-04-26 15:25:59 +01:00
Alexander Ljungberg a0c7305334 Fixed: collection views cleared their selection whenever the content was changed.
This was unlike Cocoa and prevented CPArrayController's selectsInsertedObjects from working.
2012-04-26 15:19:18 +01:00
cacaodev edb86ebeeb CPPredicateEditorValueBinder cleaning, conforms to recent CPBinder updates 2012-04-26 16:09:32 +02:00
cacaodev bfe53a1d54 Merge branch 'CPPredicateEditorRowNode-formatting' into CPRulePredicateEditor 2012-04-26 15:39:16 +02:00
cacaodev 3ab2ebf71f Merge remote-tracking branch 'upstream/master' into CPRulePredicateEditor
Conflicts:
	AppKit/CPRuleEditor/CPRuleEditor.j
2012-04-26 15:38:30 +02:00
Darrell Walisser 0f43cdee00 -sheet attached to modal window runs in modal context
-events in modal run loop get passed to sheet's parent window, so it can move and resize
2012-04-25 21:04:38 -04:00
Antoine Mercadal b04dbb647b Typo in method name + make some methods private 2012-04-25 12:41:22 -07:00
aparajita 72092732f3 Merge pull request #1516 from zittix/Xcodecapp_mising_help_fix
Add missing help file in XcodeCapp to avoid startup crash
2012-04-25 08:10:26 -07:00
zittix 7f0ff5fd0a Add missing help file in XcodeCapp 2012-04-25 16:25:58 +02:00
Antoine Mercadal 0318d23ab6 Fix stupid error in tooltips management when initializing from a coder 2012-04-24 18:10:33 -07:00
Antoine Mercadal 8fdf78cf67 Move the tooltip code into the CPView code (remove category). Fix problem with tooltips not working when using deploy 2012-04-24 17:57:05 -07:00
Darrell Walisser 06348bbe0b -keep parent window behind sheet when orderFront: on sheet or left mouse down on parent window 2012-04-24 20:54:09 -04:00
Antoine Mercadal 3ec4d3e374 Encode/Decode tooltip in CPView 2012-04-24 16:27:36 -07:00
Antoine Mercadal 9866bf19a4 Support for setting ToolTips right from IB 2012-04-24 16:13:37 -07:00
Aparajita Fishman 1e3c668c9b Added instructions for using pre-commit hook 2012-04-24 10:37:40 +02:00
Aparajita Fishman 36bfc7c675 Fixed decode methods to return the correct defaults, removed unnecessary containsValueForKey and || with defaults 2012-04-24 10:15:19 +02:00
Blair Duncan d6429e532b typo fix 2012-04-24 00:02:12 -04:00
Blair Duncan 864db16e33 Fix for issue 1491, don't scroll if active menu container is menubar 2012-04-23 23:54:13 -04:00
Blair Duncan 02ebb6e4f7 highlite menu item only if the active item was found 2012-04-23 23:06:31 -04:00
Alexander Ljungberg 44521a3c22 Merge branch 'master' of github.com:cappuccino/cappuccino 2012-04-23 23:56:59 +01:00
Alexander Ljungberg c5afd3d39f Fixes #1512. Patch to improve rhino-narwhal platform support.
This rhino-narwhal patch can be applied to add JAVA_OPTS support when running Cappuccino utilities through rhino. This generally improves configurability for special cases, and specifically enables a work around for the "failed to map segment from shared object" error on some platforms.
2012-04-23 23:45:29 +01:00
Blair Duncan 5b5034da63 CPEvent - send a valid timestamp for periodic events 2012-04-23 18:19:37 -04:00
Aparajita Fishman 2fd67f6ba8 Merge branch 'master' of github.com:cappuccino/cappuccino 2012-04-23 23:24:27 +02:00
Blair Duncan 5b6779a3a9 Fix for menu selection that was broken with the change to CPEvent timestamp 2012-04-23 16:51:10 -04:00
Alexander Ljungberg 74820a5040 Merge branch 'master' of github.com:cappuccino/cappuccino 2012-04-23 19:16:05 +01:00
Alexander Ljungberg be76424513 Fixes #1460. Add an xcode-select warning to bootstrap.sh. 2012-04-23 19:15:37 +01:00
Alexander Ljungberg 2d4e544931 Don't mention a website which no longer exists. 2012-04-23 18:48:21 +01:00
Aparajita Fishman 1077294e9a Added missing -adjustSubviews method, code cleanup. 2012-04-23 12:08:12 +02:00
Aparajita Fishman bd691d5307 Hopefully finally fixed the problem with CPScrollView/CPScroller initialization. Fixes #1485. 2012-04-23 01:12:24 +02:00
Aparajita Fishman 48ef639408 Merge branch 'master' of github.com:cappuccino/cappuccino 2012-04-22 23:14:18 +02:00
Aparajita Fishman 9830b2b115 Subviews may not be accessed during initWithCoder. Fixes #1485. 2012-04-22 23:13:58 +02:00
Alexander Ljungberg 40e07bbb45 Missing semicolons. 2012-04-22 15:22:00 +01:00
Alexander Ljungberg 7efc8230a2 Fixed: a collection view wouldn't become the first responder when its items were clicked. 2012-04-20 17:30:17 +01:00
Alexander Ljungberg 38dd03652a Merge branch 'master' of github.com:cappuccino/cappuccino 2012-04-20 15:14:37 +01:00
Alexander Ljungberg 21a34f88b2 Fixed: don't crash when removing objects from an array controller which has its arrangedObjects.@count observed. 2012-04-20 15:12:59 +01:00
Aparajita Fishman 092cb01bb3 Added capp_lint to Tools 2012-04-20 11:57:18 +02:00
Alexander Ljungberg d9640aa205 Merge branch 'master' of github.com:cappuccino/cappuccino 2012-04-19 22:44:06 +01:00
Alexander Ljungberg 469414cb35 Fixed: a CPURLRequest created without using the designated initialiser wouldn't work.
Now `init` calls the designated initialiser like in Cocoa.
2012-04-19 22:43:45 +01:00
aparajita f96c113065 Merge pull request #1509 from cacaodev/CPData-bytes-base64
CFData: completed bytes(), base64() and adds CPData +dataWithBytes and +dataWithBase64:
2012-04-17 10:44:53 -07:00
cacaodev 7fe576163d CFData: Adds lazy getters bytes(), base64().
CPData: Adds +dataWithBytes and +dataWithBase64:
Tests.
2012-04-17 19:08:29 +02:00
Alexander Ljungberg 314be1ec11 Merge branch 'master' of github.com:cappuccino/cappuccino 2012-04-17 15:28:11 +01:00
Alexander Ljungberg 0d810e64b7 Stub out CPDateFormatter and nib2cib support. 2012-04-17 15:27:47 +01:00
Aparajita Fishman 5763ebdf2b Fixed CPEvent -timestamp to return seconds since startup, as documented in Cocoa.
Miscellaneous cleanup of timestamp usage as well.
2012-04-15 11:30:27 -04:00
aparajita 3f58c4ea6f Merge pull request #1494 from cacaodev/CPImageView-bindings
CPImageView: support CPValueURLBinding and CPValuePathBinding.
2012-04-15 05:52:22 -07:00
cacaodev 22f75fa9cd Very minor UI changes 2012-04-15 09:52:57 +02:00
Randall Luecke 340b86e97f CPAlert shouldn't use 'alert' as a variable name 2012-04-13 10:59:30 -04:00
Aparajita Fishman 4fff92f3ee Ignore NS_*.j userland NS classes in XcodeCapp 2012-04-13 08:25:19 -04:00
cacaodev 0c8715dd8d Merge remote-tracking branch 'upstream/master' into CPImageView-bindings 2012-04-12 23:26:11 +02:00
cacaodev 487d38fd21 Merge remote-tracking branch 'upstream/master' into CPImageView-bindings 2012-04-12 23:12:09 +02:00
Aparajita Fishman c028c0ad26 Fixed infinite loop when finished editing a tableview cell. 2012-04-12 17:09:20 -04:00
cacaodev 925a922d90 Remove first row in the plist 2012-04-12 21:41:26 +02:00
Aparajita Fishman aeb2671fc0 CPImageView enhancements
- Changed from deprecated image scaling constants to new ones.
- Added support for CPImageScaleProportionallyUpOrDown (thanks BlairDuncan).
- Cleaned up image layout code.
2012-04-12 14:55:46 -04:00
Aparajita Fishman 502edbd152 nib2cib enhancements
- Added support for User Defined Runtime Attributes in IB.
- Added support for userland NS classes in IB.
- Added support for file-based nib2cib configuration.
- Converted nib2cib to Objective-J from straight Javascript.
- Updated man page for new features.
- Test app.
2012-04-12 12:09:24 -04:00
Aparajita Fishman 5fed81e1dc CFURL/CPURL fixes/enhancements
- Fixed bizarre bug where local variable path was being set as attribute of object in CPURL -pathComponents.
- Added CPURL -URLByDeletingLastPathComponent.
- Linted CFURL.js.
- CFURL constructor should copy when passed a CFURL.
- Added CFURL.createCopyDeletingLastPathComponent.
- Added test for URLByDeletingLastPathComponent.
2012-04-12 10:45:01 -04:00
Aparajita Fishman 6293380406 Let jake proceed if a man page cannot be copied 2012-04-10 22:42:46 -04:00
Antoine Mercadal 73641cb726 Merge remote-tracking branch 'upstream/master' 2012-04-10 16:10:14 -07:00
Antoine Mercadal 71cfeae5f1 fix typo preventing the highlighting color to be draw. 2012-04-10 16:08:17 -07:00
Aparajita Fishman c40aaa04f6 Merge branch 'master' of github.com:cappuccino/cappuccino into cappuccino 2012-04-10 18:42:43 -04:00
Aparajita Fishman f4f4554cde Fixed test of result of sudo() 2012-04-10 18:42:26 -04:00
aparajita 1b0fa21f28 Merge pull request #1498 from BlairDuncan/unnecessaryGlobals
Unnecessary globals
2012-04-10 14:57:40 -07:00
Aparajita Fishman 5c0e079873 CPBinder: In reverseSetValueFor:, suspend observation to avoid unwanted setValueFor:
isssue #1463
Manual test and ojtest.
2012-04-10 17:28:20 -04:00
Blair Duncan 6ede1ccb04 Unnecessary globals 2012-04-10 17:25:46 -04:00
aparajita 7173d3c866 Merge pull request #1496 from BlairDuncan/testBranch
Fix for issue 1425 CPOutlineView expand all items
2012-04-10 14:15:10 -07:00
cacaodev c989c30e00 Use new CPBinder methods from #1495 2012-04-10 22:57:20 +02:00
cacaodev d649fc2413 Merge remote-tracking branch 'upstream/master' into CPImageView-bindings 2012-04-10 22:26:23 +02:00
aparajita 8015106976 Merge pull request #1495 from cacaodev/CPBinder
CPBinder: consolidate setValueFor: with placeholders management
2012-04-10 13:22:23 -07:00
Blair Duncan 6b6c44c4d5 Fix for issue 1425 CPOutlineView expand all items when option key is pressed while clicking the disclosure triangle 2012-04-10 16:11:31 -04:00
cacaodev 742bfcb0e7 Fix non-applicable syntax 2012-04-10 22:06:50 +02:00
cacaodev f222d7bfe7 CPBinder: move placeholder handling to superclass, add 2 subclassable methods for appying the regular value or a placeholder value.
Update binder subclasses for CPTextField, CPCheckBox, CPColorWeel.
2012-04-10 21:48:09 +02:00
Aparajita Fishman f6bdf06e45 Fix _CPFormatLogMessage to do something intelligent if aLevel and/or aTitle is empty or not passed 2012-04-10 15:07:39 -04:00
Aparajita Fishman c04f188adc Fix for dump_theme failing without admin rights, common.jake linting 2012-04-10 14:26:00 -04:00
Antoine Mercadal 1e2964ad8f Fix a crash do to calling non-existing selector
That said, the popover is not moving correctly with the
attached view as it did. Patch in a following commit
2012-04-09 19:20:47 -07:00
Aparajita Fishman dd63174493 Merge branch 'master' of github.com:cappuccino/cappuccino into cappuccino 2012-04-09 15:53:53 -04:00
Aparajita Fishman 91642080d6 Eliminate flashing of insertion point when becoming first responder due to double setTimeout 2012-04-09 15:53:31 -04:00
cacaodev ccf18bb9cb CPPredicateEditorRowNode formatting 2012-04-09 19:54:00 +02:00
Antoine Mercadal 64a74d9ac6 Merge branch 'master' of https://github.com/cappuccino/cappuccino 2012-04-09 10:28:02 -07:00
Aparajita Fishman bc8dc10ac3 Fix for #1433 2012-04-09 13:25:38 -04:00
Antoine Mercadal 324e75650d code style cleaning 2012-04-09 10:24:39 -07:00
Antoine Mercadal 8c205faf2d Merge https://github.com/rvanzon/cappuccino into rvanzon-xcc 2012-04-09 10:23:59 -07:00
Richard van Zon d56a15db83 Using fm instance and ignore errors 2012-04-09 08:06:53 +02:00
Aparajita Fishman 342bde7767 Started linting CPRuleEditor classes 2012-04-09 01:56:59 -04:00
Aparajita Fishman ec80a4c9e6 Add some missing imports 2012-04-09 00:59:57 -04:00
aparajita 2a1af53d79 Merge pull request #1456 from cacaodev/CPTabView
CPTabView: Do not track the segment when the delegate disallows item selection
2012-04-08 21:38:53 -07:00
Alexander Ljungberg c528563421 Merge branch 'master' of github.com:cappuccino/cappuccino 2012-04-08 18:51:15 +02:00
Alexander Ljungberg a3a01c2419 Missing semicolons, whitespace. 2012-04-08 18:50:54 +02:00
Alexander Ljungberg 40d30459b8 Missing semicolons. 2012-04-08 18:10:54 +02:00
Alexander Ljungberg b746824933 Formatting. 2012-04-08 18:10:41 +02:00
cacaodev 1e9958c4c7 Handle CPValueBinding in the custom binder. Added a CPImageView with CPValueBinding to the test app.
Removed setBackgroundColor:gray for placeholders because it's a bad idea (non cocoa and need to restore bg when the value != placeholder).
2012-04-08 10:01:04 +02:00
aparajita 3230ea2519 Merge pull request #1492 from daboe01/master
fix for issue 1451
2012-04-07 13:25:39 -07:00
aparajita 22fc8337a3 Merge pull request #1257 from aparajita/_CPImageAndTextView-API
Add textFrame method to locate the text within the view
2012-04-07 10:51:10 -07:00
Aparajita Fishman 86d5818c0f Revert "Use /var/tmp, in Lion /tmp is not world writable"
This reverts commit e9d076adcd.
2012-04-07 10:42:27 -07:00
cacaodev b6a173cc0c CPImageView: support CPValueURLBinding and CPValuePathBinding. Readonly. With test. 2012-04-07 13:16:16 +02:00
daboe01 ec9c682052 Small progress indicator images fixed (http://www.preloaders.net/en/terms_of_use) 2012-04-06 13:56:06 +02:00
Aparajita Fishman e9d076adcd Use /var/tmp, in Lion /tmp is not world writable 2012-04-05 20:28:14 -07:00
Aparajita Fishman d59bc012b6 Added dump_theme tool 2012-04-05 20:25:14 -07:00
Aparajita Fishman eb292e6d87 Factored image creation code so -description can be added 2012-04-05 19:57:30 -07:00
Aparajita Fishman 129a8cb411 Added ability to specify bundle, which makes this usable with non-main bundle images. 2012-04-05 19:42:23 -07:00
Aparajita Fishman d76706b865 Cocoa always sends NSControlTextDidEndEditingNotification and the action when resigning, whether or not editing had begun. 2012-04-05 18:04:10 -07:00
aparajita 159c5c7342 Merge pull request #1253 from aparajita/better-theme-template
Improvements to the ThemeDescriptor capp template
2012-04-05 17:07:40 -07:00
Aparajita Fishman 4d50eea29b capp templates
- Small comment tweaks
2012-04-05 17:06:15 -07:00
daboe01 0ec10515cd Small progress indicator images 2012-04-05 20:45:19 +02:00
Aparajita Fishman c2f20c21e6 Added CGInsetUnion and CGInsetDifference 2012-04-04 23:17:24 -07:00
Aparajita Fishman e2ead56256 Collection KVC fixes, nextObject correctness
- Moved common CPArray/CPSet collection KVC operators to _CPCollectionKVCOperators.
- Implemented KVC operator dispatch using Objective-J.
- Fixed infinite loop with empty  collection in @min, @max and @sum operators.
- Correctly return valueForUndefinedKey when necessary.
- valueForUndefinedKey reason uses raw description for consistency, class' overridden description may not helpful at all.
- Don't create a forwarder for @ operators with property paths.
- Fixed CPSet -valueForKeyPath to correctly deal with nil/undefined/empty values.
- Added tests for collection  KVC operators.
- enumerator -nextObject should always compare against nil for clarity, correctness, and consistency.
2012-04-03 22:16:55 -07:00
Aparajita Fishman 029e45d027 Use === when possible, made it clearer where the ternary operator ends 2012-04-03 17:17:26 -07:00
Aparajita Fishman 93cc97002a Cocoa conformance and bug fixes
- showRelativeToRect:ofView:preferredEdge: must take provide a view, and if the rect is empty it defaults to the view's bounds.
- If If showRelativeToRect is called while a popover is closing, it is ignored.
- If showRelativeToRect is called when the popover is already open, it should just reposition the existing popover.
- close should NOT consult the delegate's popoverShouldClose. Only performClose should do that.
- If a window is closed, all of its popovers immediately order out.
- Updated demo app to cover more cases.
- Note that child popovers are currently not supported, as this requires support for child windows in CPWindow.
2012-03-31 18:40:47 -07:00
Aparajita Fishman 8fed89164f Add the appkit_tag_dom_elements flag to the NibApplication index-debug.html template 2012-03-30 11:19:40 -07:00
Aparajita Fishman 48b9f3198f Methods that return CGPoint should always copy! 2012-03-30 10:53:00 -07:00
Aparajita Fishman 5893b33962 Merge branch 'master' of github.com:cappuccino/cappuccino into cappuccino 2012-03-27 16:29:51 -07:00
Alexander Ljungberg d2f3ceaf67 Documentation. 2012-03-27 23:45:18 +01:00
Alexander Ljungberg 271b935ba2 + (BOOL)automaticallyNotifiesObserversOf<Key> support. 2012-03-27 23:42:17 +01:00
Aparajita Fishman 3ddab9e26a Added configurable list of source directories for framework Jakefile 2012-03-27 11:20:31 -07:00
Aparajita Fishman d68278e41f Use isMenuBar instead of testing class 2012-03-27 11:19:41 -07:00
Alexander Ljungberg 25676b4460 Fixed: reverse value transformations were not applied for table view bindings. 2012-03-27 13:56:25 +01:00
Alexander Ljungberg 56c7e1991e Fixed: check box binding value transformers were ignored. 2012-03-27 13:53:32 +01:00
Alexander Ljungberg ff68ccdeab Fix CPPopUpButtonTest. 2012-03-27 13:51:52 +01:00
Alexander Ljungberg 4acbfd5587 Formatters are a part of Foundation. 2012-03-27 10:37:15 +01:00
Alexander Ljungberg 8df2e608ab Merge branch 'master' of github.com:cappuccino/cappuccino 2012-03-27 10:02:52 +01:00
Alexander Ljungberg 38f8b1a931 Raise an exception if a view is added to itself as a subview.
This is better than a DOM node exception.
2012-03-27 10:02:27 +01:00
Aparajita Fishman 9e8f659faf Stop generating useless XML from doxygen. 2012-03-26 12:47:05 -07:00
Aparajita Fishman cd148c36c9 Menu tracking fixes:
- Finally fixed #1457.
- Fixed case where mouse is dragged and then released over a submenu, which should release the menu.
- Fixed case where clicking without dragging, then clicking again on a menu title would not close the menu.
2012-03-26 12:38:50 -07:00
Richard van Zon ee190d07c5 Added support for directory symbolic links 2012-02-29 13:13:31 +01:00
cacaodev d581dec6cf CPTabView: Do not track the segment when the delegate disallows item selection. 2012-02-13 00:32:22 +01:00
cacaodev 0908139218 Merge branch 'master' of git://github.com/cappuccino/cappuccino into CPRulePredicateEditor 2012-01-07 09:39:34 +01:00
cacaodev 926bcfb514 CPRuleEditor : Moved _CPRuleEditor*Button customization from class to controller and added initWithCoder methods. 2012-01-06 22:49:42 +01:00
cacaodev 8d59fc1334 CPPredicateEditor tests: updated xib to Xcode 4.2 and nib2cibed.
SmartFoldersDemo: disable the size-to-fit like feature in the controller because 1/ CPPredicateEditor should have its own sizeToFit and 2/ It was shadowing other resizing bugs.
2011-12-31 17:19:14 +01:00
cacaodev 0aae4f2627 Merge branch 'master' of git://github.com/cappuccino/cappuccino into CPRulePredicateEditor 2011-12-31 15:37:59 +01:00
cacaodev fe1bd1a978 Cleanup: removed log statements, some comments, css transition hack for fading the drop line separator. 2011-12-29 18:44:06 +01:00
cacaodev 7a8173bf6f CPRuleEditor : Fixes a bug where a rule editor embedded in a scroll view was not updating its frameSize when rows where added/removed.
Reported here: https://groups.google.com/d/msg/objectivej/G2MFGGSHaOY/ojcQaoNSpcAJ
I also adjusted the plus button right padding to give enough space for the scroller.
Edited CPRuleEditorCibTest xib to unhide the vertical scroller.
2011-12-25 22:16:01 +01:00
cacaodev edf07a8fbc CPRuleEditor: In -initWithFrame: the _CPRuleEditorLocalizer was not initialized by default. 2011-12-17 15:28:41 +01:00
cacaodev fab7d41446 CPRuleEditor: renamed private class RowObject -> _CPRuleEditorRowObject 2011-12-13 10:32:34 +01:00
cacaodev f33a55f1d0 CPPredicateEditor: bindings compatibility. Send control action only after a UI interaction to prevent sending unwanted notifications to the binder.
Send action through the responder chain even if target or action is nil. CPControl relies on this to send updates to the binder.
2011-12-13 10:32:34 +01:00
cacaodev 96a3eef4e1 CPRuleEditor IE7/8/9 compatibility, closes #1279 2011-12-13 10:32:22 +01:00
cacaodev 93dc4d1bc9 CPRuleEditor: -bind:toObject:withKeyPath:options: removed a useless check that was causing an exception when keyPath was a compound key path.
CPPredicateEditor test app: bind textfield and editor to a CPObjectController.
2011-12-13 09:54:24 +01:00
cacaodev d973670026 CPPredicateEditor: - Templates merging. Means that from the same left item you can have different views on the right:
* date is (today, yesterday)
                      * date is less than [text field]

                    - CPPredicateEditorCibTest example: templates merging in the 'mixed' criterion.
                    - ojtest AppKit/CPPredicateEditorTest testing the merging feature.

                    - Cleaned and rearranged code related to the right control action method.
                    - re-enable tooltips.
2011-12-13 09:50:26 +01:00
cacaodev c327956537 CPRuleEditor: Since commit 2b52f7d, CPRuleEditor's delegate method -ruleEditor:displayValueForCriterion:inRow: is more restricive: you must return the same view object for a specific criterion in a given row.
In CPRuleEditorCibTest, the delegate has been updated to follow this rule, it also fixes a bug where the predicate was not correctly handling custom control values.
2011-12-13 09:49:35 +01:00
Darrell Walisser a2eb9e728c Various fixes for sheet bugs
-handle attempt to close sheet while it is animating in
-fixes Safari 5.1 animate out bug by using a timer to
initiate the in/out process
-allow window shadow to become 0 width/height for smoother animation
2011-11-24 19:28:04 -05:00
dwalisser 604a49634d Merge remote-tracking branch 'upstream/master' 2011-11-24 09:43:10 -05:00
Darrell Walisser 3c7783f97c Revert "-fix uninitialized _selectedRange member when loading from cib",
putting in another branch

This reverts commit 2a82703e46.
2011-11-15 10:31:44 -05:00
Darrell Walisser 2a82703e46 -fix uninitialized _selectedRange member when loading from cib 2011-11-15 10:14:07 -05:00
Darrell Walisser 6eace4258f -initial stab at doc-modal sheets 2011-09-18 16:08:10 -04:00
Aparajita Fishman 329baa1719 Added license to header, SYS var 2011-05-11 11:39:18 -04:00
Aparajita Fishman 85080f5c58 Made colorPrint function local 2011-05-11 09:02:05 -04:00
Aparajita Fishman 910f02ea50 Removed duplicate productName 2011-05-10 12:20:26 -04:00
Aparajita Fishman bfd8eefa0e Added textFrame method to locate the text within the view 2011-05-09 21:15:12 -04:00
Aparajita Fishman 2d96fcf87f Improvements to the ThemeDescriptor capp template:
- New/improved jake tasks: debug, release, all, clean, clobber, test, test-release, help.
- help task shows comprehensive, formatted documentation for the available tasks.
- BlendKit is automatically symlinked into the Frameworks directory if necessary as part of the build process, so that the showcase will always work.
- User can easily change the build directory by changing one line.
- Fixed incorrect placeholders in main.j.
2011-05-07 13:12:12 -04:00
1272 changed files with 63741 additions and 21369 deletions
+8
View File
@@ -0,0 +1,8 @@
language: node_js
node_js:
- 0.8
before_install:
- jdk_switcher use openjdk6
install: ./bootstrap.sh --quiet --noprompt --directory ./narwhal
script: jake test
env: PATH=/home/travis/builds/cappuccino/cappuccino/narwhal/bin:$PATH CAPP_BUILD=/home/travis/builds/cappuccino/cappuccino/Build NARWHAL_ENGINE=rhino
+8 -3
View File
@@ -20,7 +20,10 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "_CPToolTip.j"
@import "CALayer.j"
@import "CGGeometry.j"
@import "CPAccordionView.j"
@import "CPAlert.j"
@import "CPAnimation.j"
@import "CPApplication.j"
@@ -35,8 +38,10 @@
@import "CPCibBindingConnector.j"
@import "CPCibConnector.j"
@import "CPCibControlConnector.j"
@import "CPCibHelpConnector.j"
@import "CPCibLoading.j"
@import "CPCibOutletConnector.j"
@import "CPCibRuntimeAttributesConnector.j"
@import "CPClipView.j"
@import "CPCollectionView.j"
@import "CPCollectionViewItem.j"
@@ -44,8 +49,10 @@
@import "CPColorPanel.j"
@import "CPColorSpace.j"
@import "CPColorWell.j"
@import "CPComboBox.j"
@import "CPCompatibility.j"
@import "CPControl.j"
@import "CPController.j"
@import "CPCookie.j"
@import "CPCursor.j"
@import "CPDocument.j"
@@ -55,7 +62,6 @@
@import "CPFlashView.j"
@import "CPFont.j"
@import "CPFontManager.j"
@import "CPGeometry.j"
@import "CPGradient.j"
@import "CPGraphics.j"
@import "CPImage.j"
@@ -94,13 +100,12 @@
@import "CPTokenField.j"
@import "CPToolbar.j"
@import "CPToolbarItem.j"
@import "_CPToolTip.j"
@import "CPTreeNode.j"
@import "CPUserDefaultsController.j"
@import "CPView.j"
@import "CPViewAnimation.j"
@import "CPViewController.j"
@import "CPWebView.j"
@import "CPWorkspace.j"
@import "CPWindow.j"
@import "CPWindowController.j"
@import "CPWorkspace.j"
+94 -70
View File
@@ -75,32 +75,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
@@ -117,21 +118,21 @@ CPCriticalAlertStyle = 2;
*/
+ (CPAlert)alertWithMessageText:(CPString)aMessage defaultButton:(CPString)defaultButtonTitle alternateButton:(CPString)alternateButtonTitle otherButton:(CPString)otherButtonTitle informativeTextWithFormat:(CPString)informativeText
{
var alert = [[self alloc] init];
var newAlert = [[self alloc] init];
[alert setMessageText:aMessage];
[alert addButtonWithTitle:defaultButtonTitle];
[newAlert setMessageText:aMessage];
[newAlert addButtonWithTitle:defaultButtonTitle];
if (alternateButtonTitle)
[alert addButtonWithTitle:alternateButtonTitle];
[newAlert addButtonWithTitle:alternateButtonTitle];
if (otherButtonTitle)
[alert addButtonWithTitle:otherButtonTitle];
[newAlert addButtonWithTitle:otherButtonTitle];
if (informativeText)
[alert setInformativeText:informativeText];
[newAlert setInformativeText:informativeText];
return alert;
return newAlert;
}
/*!
@@ -142,12 +143,12 @@ CPCriticalAlertStyle = 2;
*/
+ (CPAlert)alertWithError:(CPString)anErrorMessage
{
var alert = [[self alloc] init];
var newAlert = [[self alloc] init];
[alert setMessageText:anErrorMessage];
[alert setAlertStyle:CPCriticalAlertStyle];
[newAlert setMessageText:anErrorMessage];
[newAlert setAlertStyle:CPCriticalAlertStyle];
return alert;
return newAlert;
}
/*!
@@ -164,6 +165,7 @@ CPCriticalAlertStyle = 2;
_showHelp = NO;
_needsLayout = YES;
_defaultWindowStyle = CPTitledWindowMask;
_themeView = [_CPAlertThemeView new];
_messageLabel = [CPTextField labelWithTitle:@"Alert"];
_alertImageView = [[CPImageView alloc] init];
@@ -180,6 +182,11 @@ CPCriticalAlertStyle = 2;
#pragma mark Accessors
- (CPTheme)theme
{
return [_themeView theme];
}
/*!
set the theme to use
@@ -197,9 +204,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 +352,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 +375,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 +404,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 +421,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,12 +442,12 @@ 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,
offsetX;
@@ -461,8 +479,8 @@ CPCriticalAlertStyle = 2;
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 +505,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 +513,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;
}
@@ -592,9 +610,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 setLevel:CPStatusWindowLevel];
if (_title)
[_window setTitle:_title];
@@ -631,7 +650,10 @@ CPCriticalAlertStyle = 2;
- (@action)_takeReturnCodeFrom:(id)aSender
{
if ([_window isSheet])
{
[_window orderOut:nil];
[CPApp endSheet:_window returnCode:[aSender tag]];
}
else
{
[CPApp abortModal];
@@ -646,17 +668,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
{
+2 -1
View File
@@ -122,6 +122,7 @@ ACTUAL_FRAME_RATE = 0;
*/
- (void)setAnimationCurve:(CPAnimationCurve)anAnimationCurve
{
var timingFunctionName;
switch (anAnimationCurve)
{
case CPAnimationEaseInOut: timingFunctionName = kCAMediaTimingFunctionEaseInEaseOut;
@@ -306,7 +307,7 @@ ACTUAL_FRAME_RATE = 0;
if ([_delegate respondsToSelector:@selector(animation:valueForProgress:)])
return [_delegate animation:self valueForProgress:t];
if (_animationCurve == CPAnimationLinear)
return t;
+100 -37
View File
@@ -20,6 +20,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#import "../Foundation/CPRange.h"
@import <Foundation/CPBundle.j>
@import "CPCompatibility.j"
@@ -33,7 +35,8 @@
var CPMainCibFile = @"CPMainCibFile",
CPMainCibFileHumanFriendly = @"Main cib file base name";
CPMainCibFileHumanFriendly = @"Main cib file base name",
CPEventModifierFlags = 0;
CPApp = nil;
@@ -138,9 +141,7 @@ CPRunContinuesResponse = -1002;
{
_eventListeners = [];
_windows = [];
[_windows addObject:nil];
_windows = [[CPNull null]];
}
return self;
@@ -219,28 +220,22 @@ CPRunContinuesResponse = -1002;
// At this point we clear the window.status to eliminate Safari's "Cancelled" error message
// The message shouldn't be displayed, because only an XHR is cancelled, but it is a usability issue.
// We do it here so that applications can change it in willFinish or didFinishLaunching
#if PLATFORM(DOM)
window.status = " ";
#endif
// We also want to set the default cursor on the body, so that buttons and things don't have an iBeam
[[CPCursor arrowCursor] set];
var bundle = [CPBundle mainBundle],
types = [bundle objectForInfoDictionaryKey:@"CPBundleDocumentTypes"];
if ([types count] > 0)
_documentController = [CPDocumentController sharedDocumentController];
var delegateClassName = [bundle objectForInfoDictionaryKey:@"CPApplicationDelegateClass"];
delegateClassName = [bundle objectForInfoDictionaryKey:@"CPApplicationDelegateClass"];
if (delegateClassName)
{
var delegateClass = objj_getClass(delegateClassName);
if (delegateClass)
if ([_documentController class] == delegateClass)
[self setDelegate:_documentController];
else
[self setDelegate:[[delegateClass alloc] init]];
[self setDelegate:[[delegateClass alloc] init]];
}
var defaultCenter = [CPNotificationCenter defaultCenter];
@@ -249,13 +244,23 @@ CPRunContinuesResponse = -1002;
postNotificationName:CPApplicationWillFinishLaunchingNotification
object:self];
var types = [bundle objectForInfoDictionaryKey:@"CPBundleDocumentTypes"];
if ([types count] > 0)
_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)
needsUntitled = ![self _openURL:[CPURL URLWithString:URLStrings[index]]] || needsUntitled;
needsUntitled = ![self _openURL:[CPURL URLWithString:URLStrings[index]]] && needsUntitled;
if (needsUntitled && [_delegate respondsToSelector:@selector(applicationShouldOpenUntitledFile:)])
needsUntitled = [_delegate applicationShouldOpenUntitledFile:self];
@@ -374,7 +379,7 @@ CPRunContinuesResponse = -1002;
standardPath = [[CPBundle bundleForClass:[self class]] pathForResource:@"standardApplicationIcon.png"];
// FIXME move this into the CIB eventually
[applicationLabel setFont:[CPFont boldSystemFontOfSize:14.0]];
[applicationLabel setFont:[CPFont boldSystemFontOfSize:[CPFont systemFontSize] + 2]];
[applicationLabel setAlignment:CPCenterTextAlignment];
[versionLabel setAlignment:CPCenterTextAlignment];
[copyrightLabel setAlignment:CPCenterTextAlignment];
@@ -576,28 +581,37 @@ CPRunContinuesResponse = -1002;
- (void)sendEvent:(CPEvent)anEvent
{
_currentEvent = anEvent;
CPEventModifierFlags = [anEvent modifierFlags];
var willPropagate = [[[anEvent window] platformWindow] _willPropagateCurrentDOMEvent];
var theWindow = [anEvent window];
#if PLATFORM(DOM)
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...
if ([anEvent _couldBeKeyEquivalent] && [self _handleKeyEquivalent:anEvent])
{
#if PLATFORM(DOM)
var characters = [anEvent characters],
modifierFlags = [anEvent modifierFlags];
// Unconditionally propagate on these keys to solve browser copy paste bugs
if ((characters == "c" || characters == "x" || characters == "v") && (modifierFlags & CPPlatformActionKeyMask))
[[[anEvent window] platformWindow] _propagateCurrentDOMEvent:YES];
[[theWindow platformWindow] _propagateCurrentDOMEvent:YES];
#endif
return;
}
#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)
{
@@ -607,7 +621,10 @@ CPRunContinuesResponse = -1002;
return;
}
[[anEvent window] sendEvent:anEvent];
if (theWindow)
[theWindow sendEvent:anEvent];
else if ([anEvent type] == CPMouseMoved)
[[CPCursor arrowCursor] set];
}
/*!
@@ -643,6 +660,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];
}
@@ -651,7 +672,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)];
}
/*!
@@ -926,15 +948,21 @@ CPRunContinuesResponse = -1002;
*/
- (void)beginSheet:(CPWindow)aSheet modalForWindow:(CPWindow)aWindow modalDelegate:(id)aModalDelegate didEndSelector:(SEL)aDidEndSelector contextInfo:(id)aContextInfo
{
var styleMask = [aSheet styleMask];
if (!(styleMask & CPDocModalWindowMask))
if ([aWindow isSheet])
{
[CPException raise:CPInternalInconsistencyException reason:@"Currently only CPDocModalWindowMask style mask is supported for attached sheets"];
[CPException raise:CPInternalInconsistencyException reason:@"The target window of beginSheet: cannot be a sheet"];
return;
}
[aWindow orderFront:self];
[aSheet setPlatformWindow:[aWindow platformWindow]];
[aSheet._windowView _enableSheet:YES];
// -dw- if a sheet is already visible, we skip this since it serves no purpose and causes
// orderOut: to be called on the sheet, which is not what we want.
if (![aWindow isVisible])
{
[aWindow orderFront:self];
[aSheet setPlatformWindow:[aWindow platformWindow]];
}
[aWindow _attachSheet:aSheet modalDelegate:aModalDelegate didEndSelector:aDidEndSelector contextInfo:aContextInfo];
}
@@ -963,7 +991,7 @@ CPRunContinuesResponse = -1002;
if (context != nil && context["sheet"] === sheet)
{
context["returnCode"] = returnCode;
[aWindow _detachSheetWindow];
[aWindow _endSheet];
return;
}
}
@@ -996,7 +1024,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;
@@ -1023,8 +1052,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;
}
@@ -1039,12 +1069,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)
{
@@ -1181,7 +1214,14 @@ _CPRunModalLoop = function(anEvent)
var theWindow = [anEvent window],
modalSession = CPApp._currentSession;
if (theWindow == modalSession._window || [theWindow worksWhenModal])
// 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 sendEvent:anEvent];
};
@@ -1198,7 +1238,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],
@@ -1370,3 +1420,16 @@ var _CPAppBootstrapperActions = nil;
}
@end
@implementation CPEvent (CPApplicationModifierFlags)
/*!
Returns the currently pressed modifier flags.
*/
+ (unsigned)modifierFlags
{
return CPEventModifierFlags;
}
@end
+39 -25
View File
@@ -584,7 +584,7 @@
*/
- (BOOL)__setSelectionIndexes:(CPIndexSet)indexes
{
[self __setSelectionIndexes:indexes avoidEmpty:_avoidsEmptySelection];
return [self __setSelectionIndexes:indexes avoidEmpty:_avoidsEmptySelection];
}
- (BOOL)__setSelectionIndexes:(CPIndexSet)indexes avoidEmpty:(BOOL)avoidEmpty
@@ -879,6 +879,9 @@
[_arrangedObjects removeObjectAtIndex:pos];
[_selectionIndexes shiftIndexesStartingAtIndex:pos by:-1];
// This will automatically handle the avoidsEmptySelection case.
[self __setSelectionIndexes:_selectionIndexes];
}
[self didChangeValueForKey:@"content"];
@@ -920,6 +923,15 @@
[self removeObjectsAtArrangedObjectIndexes:_selectionIndexes];
}
/*!
Removes the object at the specified index in the controller's arranged objects from the content array.
@param int index - index of the object to remove.
*/
- (void)removeObjectAtArrangedObjectIndex:(int)index
{
[self removeObjectsAtArrangedObjectIndexes:[CPIndexSet indexSetWithIndex:index]];
}
/*!
Removes the objects at the specified indexes in the controller's arranged objects from the content array.
@param CPIndexSet indexes - indexes of the objects to remove.
@@ -934,36 +946,38 @@
_disableSetContent = YES;
var arrangedObjects = [self arrangedObjects],
index = [anIndexSet lastIndex],
position = CPNotFound,
newSelectionIndexes = [_selectionIndexes copy];
while (index !== CPNotFound)
{
var object = [arrangedObjects objectAtIndex:index];
// First try the simple case which should work if there are no sort descriptors.
if ([_contentObject objectAtIndex:index] === object)
[_contentObject removeObjectAtIndex:index];
else
[anIndexSet enumerateIndexesWithOptions:CPEnumerationReverse
usingBlock:function(anIndex)
{
// Since we don't have a reverse mapping between the sorted order and the
// unsorted one, we'll just simply have to remove an arbitrary pointer. It might
// 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];
[_contentObject removeObjectAtIndex:contentIndex];
}
[arrangedObjects removeObjectAtIndex:index];
var object = [arrangedObjects objectAtIndex:anIndex];
// Deselect this row if it was selected, and either way shift all selection indexes
// following it up by 1.
[newSelectionIndexes removeIndex:index];
[newSelectionIndexes shiftIndexesStartingAtIndex:index by:-1];
// First try the simple case which should work if there are no sort descriptors.
if ([_contentObject objectAtIndex:anIndex] === object)
[_contentObject removeObjectAtIndex:anIndex];
else
{
// Since we don't have a reverse mapping between the sorted order and the
// unsorted one, we'll just simply have to remove an arbitrary pointer. It might
// 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];
[_contentObject removeObjectAtIndex:contentIndex];
}
[arrangedObjects removeObjectAtIndex:anIndex];
if (!_avoidsEmptySelection || [newSelectionIndexes count] > 1)
{
[newSelectionIndexes removeIndex:anIndex];
[newSelectionIndexes shiftIndexesStartingAtIndex:anIndex by:-1];
}
else if ([newSelectionIndexes lastIndex] !== anIndex)
[newSelectionIndexes shiftIndexesStartingAtIndex:anIndex by:-1];
}];
index = [anIndexSet indexLessThanIndex:index];
}
// Allow handlesContentAsCompoundValue reverse sets to trigger.
[[CPBinder getBinding:@"contentArray" forObject:self] _contentArrayDidChange];
_disableSetContent = NO;
+35
View File
@@ -165,6 +165,19 @@ var DefaultLineWidth = 1.0;
CGPathAddCurveToPoint(_path, nil, controlPoint1.x, controlPoint1.y, controlPoint2.x, controlPoint2.y, endPoint.x, endPoint.y);
}
- (CGRect)bounds
{
// TODO: this should return this. The controlPointBounds is not a tight fit.
// return CGPathGetPathBoundingBox(_path);
return [self controlPointBounds];
}
- (CGRect)controlPointBounds
{
return CGPathGetBoundingBox(_path);
}
/*!
Create a line segment between the first and last points in the subpath, closing it.
*/
@@ -272,6 +285,11 @@ var DefaultLineWidth = 1.0;
CGPathAddPath(_path, nil, CGPathWithRoundedRectangleInRect(rect, xRadius, yRadius, YES, YES, YES, YES));
}
- (void)appendBezierPathWithArcFromPoint:(CGPoint)fromPoint toPoint:(CGPoint)toPoint radius:(float)radius
{
CGPathAddArcToPoint(_path, null, fromPoint.x, fromPoint.y, toPoint.x, toPoint.y, radius);
}
/*!
Append the contents of a CPBezierPath object.
*/
@@ -288,4 +306,21 @@ var DefaultLineWidth = 1.0;
_path = CGPathCreateMutable();
}
- (void)addClip
{
var ctx = [[CPGraphicsContext currentContext] graphicsPort];
CGContextAddPath(ctx, _path);
CGContextClip(ctx);
}
- (void)setClip
{
var ctx = [[CPGraphicsContext currentContext] graphicsPort];
CGContextBeginPath(ctx);
CGContextAddPath(ctx, _path);
CGContextClip(ctx);
}
@end
+20
View File
@@ -322,6 +322,26 @@ CPBelowBottom = 6;
[self _manageTitlePositioning];
}
- (CPFont)titleFont
{
return [_titleView font];
}
- (void)setTitleFont:(CPFont)aFont
{
[_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)
+2 -2
View File
@@ -258,7 +258,7 @@
var column = [[CPTableColumn alloc] initWithIdentifier:@"Image"],
view = [[CPImageView alloc] initWithFrame:CGRectMakeZero()];
[view setImageScaling:CPScaleProportionally];
[view setImageScaling:CPImageScaleProportionallyDown];
[column setDataView:view];
[column setResizingMask:CPTableColumnNoResizing];
@@ -988,7 +988,7 @@ var _CPBrowserResizeControlBackgroundImage = nil;
isHighlighted = [self themeState] & CPThemeStateSelectedDataView;
[imageView setImage: _isLeaf ? (isHighlighted ? _highlightedBranchImage : _branchImage) : nil];
[imageView setImageScaling:CPScaleNone];
[imageView setImageScaling:CPImageScaleNone];
}
- (void)encodeWithCoder:(CPCoder)aCoder
+211 -79
View File
@@ -29,20 +29,21 @@
/* @group CPBezelStyle */
CPRoundedBezelStyle = 1;
CPRegularSquareBezelStyle = 2;
// IB style
CPRoundedBezelStyle = 1; // Push
CPRegularSquareBezelStyle = 2; // Bevel
CPThickSquareBezelStyle = 3;
CPThickerSquareBezelStyle = 4;
CPDisclosureBezelStyle = 5;
CPShadowlessSquareBezelStyle = 6;
CPCircularBezelStyle = 7;
CPTexturedSquareBezelStyle = 8;
CPHelpButtonBezelStyle = 9;
CPSmallSquareBezelStyle = 10;
CPTexturedRoundedBezelStyle = 11;
CPRoundRectBezelStyle = 12;
CPRecessedBezelStyle = 13;
CPRoundedDisclosureBezelStyle = 14;
CPDisclosureBezelStyle = 5; // Disclosure triangle
CPShadowlessSquareBezelStyle = 6; // Square
CPCircularBezelStyle = 7; // Round
CPTexturedSquareBezelStyle = 8; // Textured
CPHelpButtonBezelStyle = 9; // Help
CPSmallSquareBezelStyle = 10; // Gradient
CPTexturedRoundedBezelStyle = 11; // Round Textured
CPRoundRectBezelStyle = 12; // Round Rect
CPRecessedBezelStyle = 13; // Recessed
CPRoundedDisclosureBezelStyle = 14; // Disclosure
CPHUDBezelStyle = -1;
@@ -111,6 +112,8 @@ CPButtonImageOffset = 3.0;
CPTimer _continuousTimer;
float _periodicDelay;
float _periodicInterval;
BOOL _isTracking;
}
+ (id)buttonWithTitle:(CPString)aTitle
@@ -141,9 +144,9 @@ CPButtonImageOffset = 3.0;
}
/*!
Initializes and returns a newly allocated CPButton object with a specified frame rectangle.
@param aFrame The frame rectangle for the created button object.
@return An initialized CPView object or nil if the object couldn't be created.
Initializes and returns a newly allocated CPButton object with a specified frame rectangle.
@param aFrame The frame rectangle for the created button object.
@return An initialized CPView object or nil if the object couldn't be created.
*/
- (id)initWithFrame:(CGRect)aFrame
{
@@ -155,7 +158,7 @@ CPButtonImageOffset = 3.0;
[self setValue:CPCenterTextAlignment forThemeAttribute:@"alignment"];
[self setValue:CPCenterVerticalTextAlignment forThemeAttribute:@"vertical-alignment"];
[self setValue:CPImageLeft forThemeAttribute:@"image-position"];
[self setValue:CPScaleNone forThemeAttribute:@"image-scaling"];
[self setValue:CPImageScaleNone forThemeAttribute:@"image-scaling"];
[self setBezelStyle:CPRoundRectBezelStyle];
[self setBordered:YES];
@@ -176,11 +179,13 @@ CPButtonImageOffset = 3.0;
// Continuous button defaults.
_periodicInterval = 0.05;
_periodicDelay = 0.5;
[self setButtonType:CPMomentaryPushInButton];
}
// Setting the state
/*!
Returns a Boolean value indicating whether the button allows a mixed state.
Returns a Boolean value indicating whether the button allows a mixed state.
@return \c YES if the button has a 'mixed' state in addition to on and off.
*/
- (BOOL)allowsMixedState
@@ -206,24 +211,20 @@ CPButtonImageOffset = 3.0;
}
/*!
Sets the value of the button using an Objective-J object.
@param anObjectValue The value of the button interpreted as an Objective-J object.
Sets the value of the button using an Objective-J object.
@param anObjectValue The value of the button interpreted as an Objective-J object.
*/
- (void)setObjectValue:(id)anObjectValue
{
if (!anObjectValue || anObjectValue === @"" || ([anObjectValue intValue] === 0))
anObjectValue = CPOffState;
else if (![anObjectValue isKindOfClass:[CPNumber class]])
anObjectValue = CPOnState;
else if (anObjectValue >= CPOnState)
anObjectValue = CPOnState
else if (anObjectValue < CPOffState)
if ([self allowsMixedState])
anObjectValue = CPMixedState;
else
anObjectValue = CPOnState;
@@ -231,24 +232,35 @@ CPButtonImageOffset = 3.0;
switch ([self objectValue])
{
case CPMixedState: [self unsetThemeState:CPThemeStateSelected];
[self setThemeState:CPButtonStateMixed];
break;
case CPMixedState:
[self unsetThemeState:CPThemeStateSelected];
[self setThemeState:CPButtonStateMixed];
if (_showsStateBy & (CPChangeGrayCellMask | CPChangeBackgroundCellMask))
[self setThemeState:CPThemeStateHighlighted];
else
[self unsetThemeState:CPThemeStateHighlighted];
break;
case CPOnState: [self unsetThemeState:CPButtonStateMixed];
[self setThemeState:CPThemeStateSelected];
break;
case CPOnState:
[self unsetThemeState:CPButtonStateMixed];
[self setThemeState:CPThemeStateSelected];
if (_showsStateBy & (CPChangeGrayCellMask | CPChangeBackgroundCellMask))
[self setThemeState:CPThemeStateHighlighted];
else
[self unsetThemeState:CPThemeStateHighlighted];
break;
case CPOffState: [self unsetThemeState:CPThemeStateSelected | CPButtonStateMixed];
case CPOffState:
[self unsetThemeState:CPThemeStateSelected | CPButtonStateMixed | CPThemeStateHighlighted];
}
}
/*!
Returns the button's next state.
@return The button's state. A button can have two or three states.
If it has two, this value is either \c CPOffState (the normal or unpressed state)
or \c CPOnState (the alternate or pressed state).
If it has three, this value can be \c CPOnState (the feature is in effect everywhere), \c CPOffState (the feature is in effect nowhere), or \c CPMixedState (the feature is in effect somewhere).
Returns the button's next state.
@return The button's state. A button can have two or three states.
If it has two, this value is either \c CPOffState (the normal or unpressed state)
or \c CPOnState (the alternate or pressed state).
If it has three, this value can be \c CPOnState (the feature is in effect everywhere), \c CPOffState (the feature is in effect nowhere), or \c CPMixedState (the feature is in effect somewhere).
*/
- (CPInteger)nextState
{
@@ -294,9 +306,9 @@ CPButtonImageOffset = 3.0;
}
/*!
Sets the title displayed by the button when in its normal state.
@param aTitle The string to set as the button's title. This title is always shown on buttons
that dont use their alternate contents when highlighting or displaying their alternate state.
Sets the title displayed by the button when in its normal state.
@param aTitle The string to set as the button's title. This title is always shown on buttons
that dont use their alternate contents when highlighting or displaying their alternate state.
*/
- (void)setTitle:(CPString)aTitle
{
@@ -310,9 +322,9 @@ CPButtonImageOffset = 3.0;
}
/*!
Returns the title displayed on the button when its in its normal state.
@return The title displayed on the receiver when its in its normal state
or the empty string if the button doesnt display a title.
Returns the title displayed on the button when its in its normal state.
@return The title displayed on the receiver when its in its normal state
or the empty string if the button doesnt display a title.
*/
- (CPString)title
{
@@ -374,11 +386,19 @@ CPButtonImageOffset = 3.0;
- (void)setShowsStateBy:(CPInteger)aMask
{
// CPPushInCellMask cannot be set for showsStateBy.
aMask &= ~CPPushInCellMask;
if (_showsStateBy === aMask)
return;
_showsStateBy = aMask;
if (_showsStateBy & (CPChangeGrayCellMask | CPChangeBackgroundCellMask) && [self state] != CPOffState)
[self setThemeState:CPThemeStateHighlighted];
else
[self unsetThemeState:CPThemeStateHighlighted];
[self setNeedsDisplay:YES];
[self setNeedsLayout];
}
@@ -402,15 +422,20 @@ CPButtonImageOffset = 3.0;
}
}
- (CPInteger)highlightsBy
{
return _highlightsBy;
}
- (void)setButtonType:(CPButtonType)aButtonType
{
switch (aButtonType)
{
case CPMomentaryLightButton: [self setHighlightsBy:CPChangeBackgroundCellMask];
case CPMomentaryLightButton: [self setHighlightsBy:CPChangeGrayCellMask | CPChangeBackgroundCellMask];
[self setShowsStateBy:CPNoCellMask];
break;
case CPMomentaryPushInButton: [self setHighlightsBy:CPPushInCellMask | CPChangeGrayCellMask];
case CPMomentaryPushInButton: [self setHighlightsBy:CPPushInCellMask | CPChangeGrayCellMask | CPChangeBackgroundCellMask];
[self setShowsStateBy:CPNoCellMask];
break;
@@ -418,12 +443,12 @@ CPButtonImageOffset = 3.0;
[self setShowsStateBy:CPNoCellMask];
break;
case CPPushOnPushOffButton: [self setHighlightsBy:CPPushInCellMask | CPChangeGrayCellMask];
[self setShowsStateBy:CPChangeBackgroundCellMask];
case CPPushOnPushOffButton: [self setHighlightsBy:CPPushInCellMask | CPChangeGrayCellMask | CPChangeBackgroundCellMask];
[self setShowsStateBy:CPChangeBackgroundCellMask | CPChangeGrayCellMask];
break;
case CPOnOffButton: [self setHighlightsBy:CPChangeBackgroundCellMask];
[self setShowsStateBy:CPChangeBackgroundCellMask];
case CPOnOffButton: [self setHighlightsBy:CPChangeGrayCellMask | CPChangeBackgroundCellMask];
[self setShowsStateBy:CPChangeGrayCellMask | CPChangeBackgroundCellMask];
break;
case CPToggleButton: [self setHighlightsBy:CPPushInCellMask | CPContentsCellMask];
@@ -494,20 +519,43 @@ CPButtonImageOffset = 3.0;
- (BOOL)startTrackingAt:(CGPoint)aPoint
{
[self highlight:YES];
_isTracking = YES;
return [super startTrackingAt:aPoint];
var startedTracking = [super startTrackingAt:aPoint];
if (_highlightsBy & (CPPushInCellMask | CPChangeGrayCellMask))
{
if (_showsStateBy & (CPChangeGrayCellMask | CPChangeBackgroundCellMask))
[self highlight:[self state] == CPOffState];
else
[self highlight:YES];
}
else
{
if (_showsStateBy & (CPChangeGrayCellMask | CPChangeBackgroundCellMask))
[self highlight:[self state] != CPOffState];
else
[self highlight:NO];
}
return startedTracking;
}
- (void)stopTracking:(CGPoint)lastPoint at:(CGPoint)aPoint mouseIsUp:(BOOL)mouseIsUp
{
[self highlight:NO];
[self invalidateTimers];
[super stopTracking:lastPoint at:aPoint mouseIsUp:mouseIsUp];
_isTracking = NO;
if (mouseIsUp && CGRectContainsPoint([self bounds], aPoint))
[self setNextState];
else
{
if (_showsStateBy & (CPChangeGrayCellMask | CPChangeBackgroundCellMask))
[self highlight:[self state] != CPOffState];
else
[self highlight:NO];
}
[self setNeedsLayout];
[self setNeedsDisplay:YES];
[self invalidateTimers];
}
- (void)invalidateTimers
@@ -529,35 +577,18 @@ CPButtonImageOffset = 3.0;
{
var contentInset = [self currentValueForThemeAttribute:@"content-inset"];
if (_CGInsetIsEmpty(contentInset))
return bounds;
bounds = _CGRectMakeCopy(bounds);
bounds.origin.x += contentInset.left;
bounds.origin.y += contentInset.top;
bounds.size.width -= contentInset.left + contentInset.right;
bounds.size.height -= contentInset.top + contentInset.bottom;
return bounds;
return _CGRectInsetByInset(bounds, contentInset);
}
- (CGRect)bezelRectForBounds:(CGRect)bounds
{
// Is this necessary? The theme itself can just change its inset to a zero inset when !CPThemeStateBordered.
if (![self isBordered])
return _CGRectMakeZero();
return bounds;
var bezelInset = [self currentValueForThemeAttribute:@"bezel-inset"];
if (_CGInsetIsEmpty(bezelInset))
return bounds;
bounds = _CGRectMakeCopy(bounds);
bounds.origin.x += bezelInset.left;
bounds.origin.y += bezelInset.top;
bounds.size.width -= bezelInset.left + bezelInset.right;
bounds.size.height -= bezelInset.top + bezelInset.bottom;
return bounds;
return _CGRectInsetByInset(bounds, bezelInset);
}
- (CGSize)_minimumFrameSize
@@ -641,8 +672,51 @@ CPButtonImageOffset = 3.0;
if (contentView)
{
[contentView setText:([self hasThemeState:CPThemeStateHighlighted] && _alternateTitle) ? _alternateTitle : _title];
[contentView setImage:[self currentValueForThemeAttribute:@"image"]];
var title = nil,
image = nil;
if (_isTracking)
{
if (_highlightsBy & CPContentsCellMask)
{
if (_showsStateBy & CPContentsCellMask)
{
title = ([self state] == CPOffState && _alternateTitle) ? _alternateTitle : _title;
image = ([self state] == CPOffState && [self alternateImage]) ? [self alternateImage] : [self image];
}
else
{
title = [self alternateTitle];
image = [self alternateImage];
}
}
else if (_showsStateBy & CPContentsCellMask)
{
title = ([self state] != CPOffState && _alternateTitle) ? _alternateTitle : _title;
image = ([self state] != CPOffState && [self alternateImage]) ? [self alternateImage] : [self image];
}
else
{
title = _title;
image = [self image];
}
}
else
{
if (_showsStateBy & CPContentsCellMask)
{
title = ([self state] != CPOffState && _alternateTitle) ? _alternateTitle : _title;
image = ([self state] != CPOffState && [self alternateImage]) ? [self alternateImage] : [self image];
}
else
{
title = _title;
image = [self image];
}
}
[contentView setText:title];
[contentView setImage:image];
[contentView setImageOffset:[self currentValueForThemeAttribute:@"image-offset"]];
[contentView setFont:[self currentValueForThemeAttribute:@"font"]];
@@ -741,9 +815,51 @@ CPButtonImageOffset = 3.0;
return NO;
[self performClick:nil];
return YES;
}
/*!
Perform a click on the receiver.
@param sender - The sender object
*/
- (void)performClick:(id)sender
{
// This is slightly different from [super performClick:] in that the highlight behaviour is dependent on
// highlightsBy and showsStateBy.
if (![self isEnabled])
return;
[self setState:[self nextState]];
var shouldHighlight = NO;
if (_highlightsBy & (CPPushInCellMask | CPChangeGrayCellMask))
{
if (_showsStateBy & (CPChangeGrayCellMask | CPChangeBackgroundCellMask))
shouldHighlight = [self state] == CPOffState;
else
shouldHighlight = YES;
}
[self highlight:shouldHighlight];
try
{
[self sendAction:[self action] to:[self target]];
}
catch (e)
{
throw e;
}
finally
{
if (shouldHighlight)
[CPTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(unhighlightButtonTimerDidFinish:) userInfo:nil repeats:NO];
}
}
@end
@implementation CPButton (NS)
@@ -784,7 +900,9 @@ var CPButtonImageKey = @"CPButtonImageKey",
CPButtonKeyEquivalentKey = @"CPButtonKeyEquivalentKey",
CPButtonKeyEquivalentMaskKey = @"CPButtonKeyEquivalentMaskKey",
CPButtonPeriodicDelayKey = @"CPButtonPeriodicDelayKey",
CPButtonPeriodicIntervalKey = @"CPButtonPeriodicIntervalKey";
CPButtonPeriodicIntervalKey = @"CPButtonPeriodicIntervalKey",
CPButtonHighlightsByKey = @"CPButtonHighlightsByKey",
CPButtonShowsStateByKey = @"CPButtonShowsStateByKey";
@implementation CPButton (CPCoding)
@@ -802,9 +920,20 @@ var CPButtonImageKey = @"CPButtonImageKey",
_title = [aCoder decodeObjectForKey:CPButtonTitleKey];
_alternateTitle = [aCoder decodeObjectForKey:CPButtonAlternateTitleKey];
_allowsMixedState = [aCoder decodeBoolForKey:CPButtonAllowsMixedStateKey];
if ([aCoder containsValueForKey:CPButtonAllowsMixedStateKey])
_allowsMixedState = [aCoder decodeBoolForKey:CPButtonAllowsMixedStateKey];
if ([aCoder containsValueForKey:CPButtonHighlightsByKey])
{
// If one exists, assume both do.
_highlightsBy = [aCoder decodeIntForKey:CPButtonHighlightsByKey];
_showsStateBy = [aCoder decodeIntForKey:CPButtonShowsStateByKey];
}
else
{
// Backwards compatibility: if this CPButton was encoded before coding of
// highlightsBy and showsStateBy were added, we should just use the
// default values from _init rather than overwriting with 0, 0.
}
[self setImageDimsWhenDisabled:[aCoder decodeObjectForKey:CPButtonImageDimsWhenDisabledKey]];
@@ -843,6 +972,9 @@ var CPButtonImageKey = @"CPButtonImageKey",
[aCoder encodeBool:_allowsMixedState forKey:CPButtonAllowsMixedStateKey];
[aCoder encodeInt:_highlightsBy forKey:CPButtonHighlightsByKey];
[aCoder encodeInt:_showsStateBy forKey:CPButtonShowsStateByKey];
[aCoder encodeBool:[self imageDimsWhenDisabled] forKey:CPButtonImageDimsWhenDisabledKey];
[aCoder encodeInt:[self imagePosition] forKey:CPButtonImagePositionKey];
+24 -30
View File
@@ -94,6 +94,23 @@ CPCheckBoxImageOffset = 4.0;
[self takeStateFromKeyPath:aKeyPath ofObjects:objects];
}
- (CPImage)image
{
return [self currentValueForThemeAttribute:@"image"];
}
- (CPImage)alternateImage
{
return [self currentValueForThemeAttribute:@"image"];
}
- (BOOL)startTrackingAt:(CGPoint)aPoint
{
var startedTracking = [super startTrackingAt:aPoint];
[self highlight:YES];
return startedTracking;
}
@end
@implementation _CPCheckBoxValueBinder : CPBinder
@@ -110,38 +127,15 @@ CPCheckBoxImageOffset = 4.0;
[self _setPlaceholder:CPOffState forMarker:CPNullMarker isDefault:YES];
}
- (void)setValueFor:(CPString)theBinding
- (void)setPlaceholderValue:(id)aValue withMarker:(CPString)aMarker forBinding:(CPString)aBinding
{
var destination = [_info objectForKey:CPObservedObjectKey],
keyPath = [_info objectForKey:CPObservedKeyPathKey],
options = [_info objectForKey:CPOptionsKey],
newValue = [destination valueForKeyPath:keyPath],
isPlaceholder = CPIsControllerMarker(newValue);
[_source setAllowsMixedState:(aValue === CPMixedState)];
[_source setState:aValue];
}
if (isPlaceholder)
{
if (newValue === CPNotApplicableMarker && [options objectForKey:CPRaisesForNotApplicableKeysBindingOption])
{
[CPException raise:CPGenericException
reason:@"can't transform non applicable key on: " + _source + " value: " + newValue];
}
newValue = [self _placeholderForMarker:newValue];
if (newValue === CPMixedState)
{
[_source setAllowsMixedState:YES];
}
else
{
// Cocoa will always set allowsMixedState to NO
// This behavior will be fine for Cappuccino as well if we (like Cocoa)
// default the CPConditionallySetsEnabledBindingOption to YES
[_source setAllowsMixedState:NO];
}
}
[_source setState:newValue];
- (void)setValue:(id)aValue forBinding:(CPString)aBinding
{
[_source setState:aValue];
}
@end
+34 -16
View File
@@ -28,7 +28,7 @@
@import "CPView.j"
@import "CPCollectionViewItem.j"
@import "CPCompatibility.j"
/*!
@ingroup appkit
@@ -242,13 +242,15 @@
Sets the content of the collection view to the content in \c anArray.
This array can be of any type, and each element will be passed to the \c -setRepresentedObject: method.
It's the responsibility of your custom collection view item to interpret the object.
@param anArray the content array
If the new content array is smaller than the previous one, note that [receiver selectionIndexes] may
refer to out of range indices. \c selectionIndexes is not changed as a result of calling the
\c setContent: method.
@param anArray a content array
*/
- (void)setContent:(CPArray)anArray
{
// reset the _selectionIndexes
[self setSelectionIndexes:[CPIndexSet indexSet]];
_content = anArray;
[self reloadContent];
@@ -284,9 +286,11 @@
if (!_isSelectable)
{
var index = CPNotFound;
var index = CPNotFound,
itemCount = [_items count];
while ((index = [_selectionIndexes indexGreaterThanIndex:index]) != CPNotFound)
// Be wary of invalid selection ranges since setContent: does not clear selection indexes.
while ((index = [_selectionIndexes indexGreaterThanIndex:index]) != CPNotFound && index < itemCount)
[_items[index] setSelected:NO];
}
}
@@ -345,9 +349,11 @@
if (!_isSelectable || [_selectionIndexes isEqual:anIndexSet])
return;
var index = CPNotFound;
var index = CPNotFound,
itemCount = [_items count];
while ((index = [_selectionIndexes indexGreaterThanIndex:index]) !== CPNotFound)
// Be wary of invalid selection ranges since setContent: does not clear selection indexes.
while ((index = [_selectionIndexes indexGreaterThanIndex:index]) !== CPNotFound && index < itemCount)
[_items[index] setSelected:NO];
_selectionIndexes = anIndexSet;
@@ -403,7 +409,8 @@
}
index = CPNotFound;
while ((index = [_selectionIndexes indexGreaterThanIndex:index]) != CPNotFound)
// Be wary of invalid selection ranges since setContent: does not clear selection indexes.
while ((index = [_selectionIndexes indexGreaterThanIndex:index]) != CPNotFound && index < count)
[_items[index] setSelected:YES];
[self tile];
@@ -640,9 +647,9 @@
if (index >= 0 && index < _items.length)
{
if (_allowsMultipleSelection && ([anEvent modifierFlags] & CPCommandKeyMask || [anEvent modifierFlags] & CPShiftKeyMask))
if (_allowsMultipleSelection && ([anEvent modifierFlags] & CPPlatformActionKeyMask || [anEvent modifierFlags] & CPShiftKeyMask))
{
if ([anEvent modifierFlags] & CPCommandKeyMask)
if ([anEvent modifierFlags] & CPPlatformActionKeyMask)
{
var indexes = [_selectionIndexes copy];
@@ -669,6 +676,13 @@
indexes = [CPIndexSet indexSetWithIndex:index];
[self setSelectionIndexes:indexes];
// TODO Is it allowable for collection view items to become the first responder? In that case they
// may have become that at this point by virtue of CPWindow's sendEvent: mouse down handling, and
// the following line will rudely snatch it away from them. For most cases though, clicking on an
// item should naturally make the collection view the first responder so that keyboard navigation
// is enabled.
[[self window] makeFirstResponder:self];
}
else if (_allowsEmptySelection)
[self setSelectionIndexes:[CPIndexSet indexSet]];
@@ -676,6 +690,10 @@
- (void)mouseDragged:(CPEvent)anEvent
{
// Don't crash if we never registered the intial click.
if (!_mouseDownEvent)
return;
var locationInWindow = [anEvent locationInWindow],
mouseDownLocationInWindow = [_mouseDownEvent locationInWindow];
@@ -994,11 +1012,11 @@ var CPCollectionViewMinItemSizeKey = @"CPCollectionViewMinItemSizeK
_itemSize = CGSizeMakeZero();
_minItemSize = [aCoder decodeSizeForKey:CPCollectionViewMinItemSizeKey] || CGSizeMakeZero();
_maxItemSize = [aCoder decodeSizeForKey:CPCollectionViewMaxItemSizeKey] || CGSizeMakeZero();
_minItemSize = [aCoder decodeSizeForKey:CPCollectionViewMinItemSizeKey];
_maxItemSize = [aCoder decodeSizeForKey:CPCollectionViewMaxItemSizeKey];
_maxNumberOfRows = [aCoder decodeIntForKey:CPCollectionViewMaxNumberOfRowsKey] || 0;
_maxNumberOfColumns = [aCoder decodeIntForKey:CPCollectionViewMaxNumberOfColumnsKey] || 0;
_maxNumberOfRows = [aCoder decodeIntForKey:CPCollectionViewMaxNumberOfRowsKey];
_maxNumberOfColumns = [aCoder decodeIntForKey:CPCollectionViewMaxNumberOfColumnsKey];
_verticalMargin = [aCoder decodeFloatForKey:CPCollectionViewVerticalMarginKey];
+8
View File
@@ -611,6 +611,14 @@ function CPColorWithImages()
return [[[self class] alloc] _initWithRGBA:components];
}
/*!
Returns the receiver. This method is a placeholder that does nothing but may be implemented in the future.
*/
- (CPColor)colorUsingColorSpaceName:(id)aColorSpaceName
{
return self;
}
/*!
Returns an array with the HSB values for this color.
The index values are ordered as:
+37 -36
View File
@@ -144,7 +144,7 @@ CPColorPickerViewHeight = 370;
- (void)setColor:(CPColor)aColor
{
_color = aColor;
[_previewView setBackgroundColor: _color];
[_previewView setBackgroundColor:_color];
[CPApp sendAction:@selector(changeColor:) to:nil from:self];
@@ -299,7 +299,7 @@ CPColorPickerViewHeight = 370;
bounds = [contentView bounds];
_toolbar = [[CPView alloc] initWithFrame:CGRectMake(0, 6, CGRectGetWidth(bounds), TOOLBAR_HEIGHT)];
[_toolbar setAutoresizingMask: CPViewWidthSizable];
[_toolbar setAutoresizingMask:CPViewWidthSizable];
var totalToolbarWidth = count * ICON_WIDTH + (count - 1) * ICON_PADDING,
leftOffset = (CGRectGetWidth(bounds) - totalToolbarWidth) / 2.0,
@@ -339,7 +339,7 @@ CPColorPickerViewHeight = 370;
[previewBox addSubview:_previewView];
var _previewLabel = [[CPTextField alloc] initWithFrame: CPRectMake(10, TOOLBAR_HEIGHT + 10, 60, 15)];
var _previewLabel = [[CPTextField alloc] initWithFrame:CGRectMake(10, TOOLBAR_HEIGHT + 10, 60, 15)];
[_previewLabel setStringValue:"Preview:"];
[_previewLabel setTextColor:[CPColor blackColor]];
[_previewLabel setAlignment:CPRightTextAlignment];
@@ -357,14 +357,14 @@ CPColorPickerViewHeight = 370;
[swatchBox addSubview:_swatchView];
var _swatchLabel = [[CPTextField alloc] initWithFrame: CPRectMake(10, TOOLBAR_HEIGHT + 8 + PREVIEW_HEIGHT + 6, 60, 15)];
[_swatchLabel setStringValue: "Swatches:"];
var _swatchLabel = [[CPTextField alloc] initWithFrame:CGRectMake(10, TOOLBAR_HEIGHT + 8 + PREVIEW_HEIGHT + 6, 60, 15)];
[_swatchLabel setStringValue:"Swatches:"];
[_swatchLabel setTextColor:[CPColor blackColor]];
[_swatchLabel setAlignment:CPRightTextAlignment];
var opacityLabel = [[CPTextField alloc] initWithFrame: CPRectMake(10, TOOLBAR_HEIGHT + PREVIEW_HEIGHT + 35, 60, 20)];
[opacityLabel setStringValue: "Opacity:"];
var opacityLabel = [[CPTextField alloc] initWithFrame:CGRectMake(10, TOOLBAR_HEIGHT + PREVIEW_HEIGHT + 35, 60, 20)];
[opacityLabel setStringValue:"Opacity:"];
[opacityLabel setTextColor:[CPColor blackColor]];
[opacityLabel setAlignment:CPRightTextAlignment];
@@ -389,7 +389,7 @@ CPColorPickerViewHeight = 370;
_action = nil;
_activePicker = nil;
[_previewView setBackgroundColor: _color];
[_previewView setBackgroundColor:_color];
if (buttonForLater)
[self _setPicker:buttonForLater];
@@ -407,12 +407,13 @@ CPColorPickerViewHeight = 370;
CPColorDragType = "CPColorDragType";
var CPColorPanelSwatchesCookie = "CPColorPanelSwatchesCookie";
/* @ignore */
@implementation _CPColorPanelSwatches : CPView
{
CPView[] _swatches;
CPArray _swatches;
CPColor _dragColor;
CPColorPanel _colorPanel;
CPCookie _swatchCookie;
@@ -422,13 +423,13 @@ var CPColorPanelSwatchesCookie = "CPColorPanelSwatchesCookie";
{
self = [super initWithFrame:aFrame];
[self setBackgroundColor: [CPColor grayColor]];
[self setBackgroundColor:[CPColor grayColor]];
[self registerForDraggedTypes:[CPArray arrayWithObjects:CPColorDragType]];
var whiteColor = [CPColor whiteColor];
_swatchCookie = [[CPCookie alloc] initWithName: CPColorPanelSwatchesCookie];
_swatchCookie = [[CPCookie alloc] initWithName:CPColorPanelSwatchesCookie];
var colorList = [self startingColorList];
_swatches = [];
@@ -436,15 +437,15 @@ 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:CPRectMake(13 * i + 1, 1, 12, 12)],
fillView = [[CPView alloc] initWithFrame:CGRectInset([view bounds], 1.0, 1.0)];
[view setBackgroundColor:whiteColor];
[fillView setBackgroundColor: (i < colorList.length) ? colorList[i] : whiteColor];
[fillView setBackgroundColor:(i < colorList.length) ? colorList[i] : whiteColor];
[view addSubview:fillView];
[self addSubview: view];
[self addSubview:view];
_swatches.push(view);
}
@@ -461,7 +462,7 @@ var CPColorPanelSwatchesCookie = "CPColorPanelSwatchesCookie";
{
var cookieValue = [_swatchCookie value];
if (cookieValue == "")
if (!cookieValue)
{
return [
[CPColor blackColor],
@@ -480,7 +481,7 @@ var CPColorPanelSwatchesCookie = "CPColorPanelSwatchesCookie";
result = [];
for (var i = 0; i < cookieValue.length; i++)
result.push([CPColor colorWithHexString: cookieValue[i]]);
result.push([CPColor colorWithHexString:cookieValue[i]]);
return result;
}
@@ -495,7 +496,7 @@ var CPColorPanelSwatchesCookie = "CPColorPanelSwatchesCookie";
var future = new Date();
future.setYear(2019);
[_swatchCookie setValue: JSON.stringify(result) expires:future domain: nil];
[_swatchCookie setValue:JSON.stringify(result) expires:future domain:nil];
}
- (void)setColorPanel:(CPColorPanel)panel
@@ -528,7 +529,7 @@ var CPColorPanelSwatchesCookie = "CPColorPanelSwatchesCookie";
if (!CGRectContainsPoint(bounds, point) || point.x > [self bounds].size.width - 1 || point.x < 1)
return NO;
[_colorPanel setColor: [self colorAtIndex:FLOOR(point.x / 13)] updatePicker: YES];
[_colorPanel setColor:[self colorAtIndex:FLOOR(point.x / 13)] updatePicker:YES];
}
- (void)mouseDragged:(CPEvent)anEvent
@@ -545,10 +546,10 @@ var CPColorPanelSwatchesCookie = "CPColorPanelSwatchesCookie";
// FIXME: http://280north.lighthouseapp.com/projects/13294-cappuccino/tickets/25-implement-cpbox
_dragColor = [[swatch subviews][0] backgroundColor];
var bounds = CPRectCreateCopy([swatch bounds]);
var bounds = CGRectMakeCopy([swatch bounds]);
// FIXME: http://280north.lighthouseapp.com/projects/13294-cappuccino/tickets/25-implement-cpbox
var dragView = [[CPView alloc] initWithFrame: bounds],
var dragView = [[CPView alloc] initWithFrame:bounds],
dragFillView = [[CPView alloc] initWithFrame:CGRectInset(bounds, 1.0, 1.0)];
[dragView setBackgroundColor:[CPColor blackColor]];
@@ -556,13 +557,13 @@ 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)
event: anEvent
pasteboard: nil
source: self
slideBack: YES];
[self dragView:dragView
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
slideBack:YES];
}
- (void)pasteboard:(CPPasteboard)aPasteboard provideDataForType:(CPString)aType
@@ -580,7 +581,7 @@ var CPColorPanelSwatchesCookie = "CPColorPanelSwatchesCookie";
if (![pasteboard availableTypeFromArray:[CPColorDragType]] || location.x > [self bounds].size.width - 1 || location.x < 1)
return NO;
[self setColor:[CPKeyedUnarchiver unarchiveObjectWithData:[pasteboard dataForType:CPColorDragType]] atIndex: FLOOR(location.x / 13)];
[self setColor:[CPKeyedUnarchiver unarchiveObjectWithData:[pasteboard dataForType:CPColorDragType]] atIndex:FLOOR(location.x / 13)];
}
@end
@@ -635,7 +636,7 @@ var CPColorPanelSwatchesCookie = "CPColorPanelSwatchesCookie";
var bounds = CPRectMake(0, 0, 15, 15);
// FIXME: http://280north.lighthouseapp.com/projects/13294-cappuccino/tickets/25-implement-cpbox
var dragView = [[CPView alloc] initWithFrame: bounds],
var dragView = [[CPView alloc] initWithFrame:bounds],
dragFillView = [[CPView alloc] initWithFrame:CGRectInset(bounds, 1.0, 1.0)];
[dragView setBackgroundColor:[CPColor blackColor]];
@@ -643,13 +644,13 @@ 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)
event: anEvent
pasteboard: nil
source: self
slideBack: YES];
[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)
event:anEvent
pasteboard:nil
source:self
slideBack:YES];
}
- (void)pasteboard:(CPPasteboard)aPasteboard provideDataForType:(CPString)aType
+40 -36
View File
@@ -44,10 +44,11 @@
*/
- (id)initWithPickerMask:(int)aMask colorPanel:(CPColorPanel)aPanel
{
self = [super init];
_panel = aPanel;
_mask = aMask;
if (self = [super init])
{
_panel = aPanel;
_mask = aMask;
}
return self;
}
@@ -76,7 +77,6 @@
*/
- (void)setMode:(CPColorPanelMode)mode
{
return;
}
/*!
@@ -85,7 +85,6 @@
*/
- (void)setColor:(CPColor)aColor
{
return;
}
@end
@@ -110,12 +109,12 @@
- (id)initView
{
aFrame = CPRectMake(0, 0, CPColorPickerViewWidth, CPColorPickerViewHeight);
var aFrame = _CGRectMake(0, 0, CPColorPickerViewWidth, CPColorPickerViewHeight);
_pickerView = [[CPView alloc] initWithFrame:aFrame];
[_pickerView setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
_brightnessSlider = [[CPSlider alloc] initWithFrame:CGRectMake(0, (aFrame.size.height - 34), aFrame.size.width, 15)];
_brightnessSlider = [[CPSlider alloc] initWithFrame:_CGRectMake(0, (aFrame.size.height - 34), aFrame.size.width, 15)];
[_brightnessSlider setValue:15.0 forThemeAttribute:@"track-width"];
[_brightnessSlider setValue:[CPColor colorWithPatternImage:[[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:[CPColorPicker class]] pathForResource:@"brightness_bar.png"]]] forThemeAttribute:@"track-color"];
@@ -128,9 +127,9 @@
[_brightnessSlider setAction:@selector(brightnessSliderDidChange:)];
[_brightnessSlider setAutoresizingMask:CPViewWidthSizable | CPViewMinYMargin];
_hueSaturationView = [[__CPColorWheel alloc] initWithFrame: CPRectMake(0, 0, aFrame.size.width, aFrame.size.height - 38)];
[_hueSaturationView setDelegate: self];
[_hueSaturationView setAutoresizingMask: (CPViewWidthSizable | CPViewHeightSizable)];
_hueSaturationView = [[__CPColorWheel alloc] initWithFrame:_CGRectMake(0, 0, aFrame.size.width, aFrame.size.height - 38)];
[_hueSaturationView setDelegate:self];
[_hueSaturationView setAutoresizingMask:(CPViewWidthSizable | CPViewHeightSizable)];
[_pickerView addSubview:_hueSaturationView];
[_pickerView addSubview:_brightnessSlider];
@@ -225,46 +224,49 @@
- (id)initWithFrame:(CPRect)aFrame
{
self = [super initWithFrame:aFrame];
var path = [[CPBundle bundleForClass:CPColorPicker] pathForResource:@"wheel.png"];
_wheelImage = new Image();
_wheelImage.src = path;
_wheelImage.style.position = "absolute";
path = [[CPBundle bundleForClass:CPColorPicker] pathForResource:@"wheel_black.png"];
_blackWheelImage = new Image();
_blackWheelImage.src = path;
_blackWheelImage.style.opacity = "0";
_blackWheelImage.style.filter = "alpha(opacity=0)"
_blackWheelImage.style.position = "absolute";
if (self = [super initWithFrame:aFrame])
{
#if PLATFORM(DOM)
_DOMElement.appendChild(_wheelImage);
_DOMElement.appendChild(_blackWheelImage);
var path = [[CPBundle bundleForClass:CPColorPicker] pathForResource:@"wheel.png"];
_wheelImage = new Image();
_wheelImage.src = path;
_wheelImage.style.position = "absolute";
path = [[CPBundle bundleForClass:CPColorPicker] pathForResource:@"wheel_black.png"];
_blackWheelImage = new Image();
_blackWheelImage.src = path;
_blackWheelImage.style.opacity = "0";
_blackWheelImage.style.filter = "alpha(opacity=0)"
_blackWheelImage.style.position = "absolute";
_DOMElement.appendChild(_wheelImage);
_DOMElement.appendChild(_blackWheelImage);
#endif
[self setWheelSize:aFrame.size];
[self setWheelSize:aFrame.size];
_crosshair = [[CPView alloc] initWithFrame:CPRectMake(_radius - 2, _radius - 2, 4, 4)];
[_crosshair setBackgroundColor:[CPColor blackColor]];
_crosshair = [[CPView alloc] initWithFrame:CGRectMake(_radius - 2, _radius - 2, 4, 4)];
[_crosshair setBackgroundColor:[CPColor blackColor]];
var view = [[CPView alloc] initWithFrame:CGRectInset([_crosshair bounds], 1.0, 1.0)];
[view setBackgroundColor:[CPColor whiteColor]];
var view = [[CPView alloc] initWithFrame:CGRectInset([_crosshair bounds], 1.0, 1.0)];
[view setBackgroundColor:[CPColor whiteColor]];
[_crosshair addSubview:view];
[_crosshair addSubview:view];
[self addSubview:_crosshair];
[self addSubview:_crosshair];
}
return self;
}
- (void)setWheelBrightness:(float)brightness
{
#if PLATFORM(DOM)
_blackWheelImage.style.opacity = 1.0 - brightness;
_blackWheelImage.style.filter = "alpha(opacity=" + (1.0 - brightness) * 100 + ")"
#endif
}
- (void)setFrameSize:(CPSize)aSize
@@ -277,6 +279,7 @@
{
var min = MIN(aSize.width, aSize.height);
#if PLATFORM(DOM)
_blackWheelImage.style.width = min;
_blackWheelImage.style.height = min;
_blackWheelImage.width = min;
@@ -290,6 +293,7 @@
_wheelImage.height = min;
_wheelImage.style.top = (aSize.height - min) / 2.0 + "px";
_wheelImage.style.left = (aSize.width - min) / 2.0 + "px";
#endif
_radius = min / 2.0;
+97 -78
View File
@@ -43,7 +43,6 @@ var _CPColorWellDidBecomeExclusiveNotification = @"_CPColorWellDidBecomeExclusiv
BOOL _bordered;
CPColor _color;
CPView _wellView;
}
+ (Class)_binderClassForBinding:(CPString)theBinding
@@ -54,6 +53,17 @@ var _CPColorWellDidBecomeExclusiveNotification = @"_CPColorWellDidBecomeExclusiv
return [super _binderClassForBinding:theBinding];
}
+ (CPString)defaultThemeClass
{
return @"colorwell";
}
+ (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"]];
}
- (void)_reverseSetBinding
{
var binderClass = [[self class] _binderClassForBinding:CPValueBinding],
@@ -69,11 +79,8 @@ var _CPColorWellDidBecomeExclusiveNotification = @"_CPColorWellDidBecomeExclusiv
if (self)
{
_active = NO;
_bordered = YES;
_color = [CPColor whiteColor];
[self drawBezelWithHighlight:NO];
[self drawWellInside:CGRectInset([self bounds], 3.0, 3.0)];
[self setBordered:YES];
[self _registerForNotifications];
}
@@ -98,25 +105,23 @@ var _CPColorWellDidBecomeExclusiveNotification = @"_CPColorWellDidBecomeExclusiv
object:[CPColorPanel sharedColorPanel]];
}
/*!
Sets whether the color well is bordered.
*/
- (void)setBordered:(BOOL)shouldBeBordered
{
if (shouldBeBordered)
[self setThemeState:CPThemeStateBordered];
else
[self unsetThemeState:CPThemeStateBordered];
}
/*!
Returns whether the color well is bordered
*/
- (BOOL)isBordered
{
return _bordered;
}
/*!
Sets the color well's current color.
*/
- (void)setBordered:(BOOL)bordered
{
if (_bordered == bordered)
return;
_bordered = bordered;
[self drawWellInside:CGRectInset([self bounds], 3.0, 3.0)];
return [self hasThemeState:CPThemeStateBordered];
}
// Managing Color From Color Wells
@@ -139,7 +144,7 @@ var _CPColorWellDidBecomeExclusiveNotification = @"_CPColorWellDidBecomeExclusiv
_color = aColor;
[self drawWellInside:CGRectInset([self bounds], 3.0, 3.0)];
[self setNeedsLayout];
}
/*!
@@ -202,31 +207,6 @@ var _CPColorWellDidBecomeExclusiveNotification = @"_CPColorWellDidBecomeExclusiv
return _active;
}
// Drawing a Color Well
- (void)drawBezelWithHighlight:(BOOL)shouldHighlight
{
}
/*!
Draws the colored area inside the color well without borders.
@param aRect the location at which to draw
*/
- (void)drawWellInside:(CGRect)aRect
{
if (!_wellView)
{
_wellView = [[CPView alloc] initWithFrame:aRect];
[_wellView setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
[self addSubview:_wellView];
}
else
[_wellView setFrame:aRect];
[_wellView setBackgroundColor:_color];
}
- (void)colorPanelDidChangeColor:(CPNotification)aNotification
{
[self takeColorFrom:[aNotification object]];
@@ -245,27 +225,11 @@ var _CPColorWellDidBecomeExclusiveNotification = @"_CPColorWellDidBecomeExclusiv
[self deactivate];
}
- (void)mouseDown:(CPEvent)anEvent
- (void)stopTracking:(CGPoint)lastPoint at:(CGPoint)aPoint mouseIsUp:(BOOL)mouseIsUp
{
if (![self isEnabled])
return;
[self highlight:NO];
[self drawBezelWithHighlight:YES];
}
- (void)mouseDragged:(CPEvent)anEvent
{
if (![self isEnabled])
return;
[self drawBezelWithHighlight:CGRectContainsPoint([self bounds], [self convertPoint:[anEvent locationInWindow] fromView:nil])];
}
- (void)mouseUp:(CPEvent)anEvent
{
[self drawBezelWithHighlight:NO];
if (!CGRectContainsPoint([self bounds], [self convertPoint:[anEvent locationInWindow] fromView:nil]) || ![self isEnabled])
if (!mouseIsUp || !CGRectContainsPoint([self bounds], aPoint) || ![self isEnabled])
return;
[self activate:YES];
@@ -276,6 +240,73 @@ var _CPColorWellDidBecomeExclusiveNotification = @"_CPColorWellDidBecomeExclusiv
[colorPanel orderFront:self];
}
- (CGRect)contentRectForBounds:(CGRect)bounds
{
var contentInset = [self currentValueForThemeAttribute:@"content-inset"];
return _CGRectInsetByInset(bounds, contentInset);
}
- (CGRect)bezelRectForBounds:(CGRect)bounds
{
var bezelInset = [self currentValueForThemeAttribute:@"bezel-inset"];
return _CGRectInsetByInset(bounds, bezelInset);
}
- (CGRect)contentBorderRectForBounds:(CGRect)bounds
{
var contentBorderInset = [self currentValueForThemeAttribute:@"content-border-inset"];
return _CGRectInsetByInset(bounds, contentBorderInset);
}
- (CGRect)rectForEphemeralSubviewNamed:(CPString)aName
{
switch (aName)
{
case "bezel-view":
return [self bezelRectForBounds:[self bounds]];
case "content-view":
return [self contentRectForBounds:[self bounds]];
case "content-border-view":
return [self contentBorderRectForBounds:[self bounds]];
}
return [super rectForEphemeralSubviewNamed:aName];
}
- (CPView)createEphemeralSubviewNamed:(CPString)aName
{
var view = [[CPView alloc] initWithFrame:_CGRectMakeZero()];
[view setHitTests:NO];
return view;
}
- (void)layoutSubviews
{
var bezelView = [self layoutEphemeralSubviewNamed:@"bezel-view"
positioned:CPWindowBelow
relativeToEphemeralSubviewNamed:@"content-view"];
[bezelView setBackgroundColor:[self currentValueForThemeAttribute:@"bezel-color"]];
var contentView = [self layoutEphemeralSubviewNamed:@"content-view"
positioned:CPWindowAbove
relativeToEphemeralSubviewNamed:@"bezel-view"];
[contentView setBackgroundColor:_color];
var contentBorderView = [self layoutEphemeralSubviewNamed:@"content-border-view"
positioned:CPWindowAbove
relativeToEphemeralSubviewNamed:@"content-view"];
[contentBorderView setBackgroundColor:[self currentValueForThemeAttribute:@"content-border-color"]];
}
@end
@implementation CPColorWellValueBinder : CPBinder
@@ -336,11 +367,8 @@ var CPColorWellColorKey = "CPColorWellColorKey",
if (self)
{
_active = NO;
_bordered = [aCoder decodeBoolForKey:CPColorWellBorderedKey];
_color = [aCoder decodeObjectForKey:CPColorWellColorKey];
[self drawBezelWithHighlight:NO];
[self drawWellInside:CGRectInset([self bounds], 3.0, 3.0)];
[self setBordered:[aCoder decodeBoolForKey:CPColorWellBorderedKey]];
[self _registerForNotifications];
}
@@ -354,19 +382,10 @@ var CPColorWellColorKey = "CPColorWellColorKey",
*/
- (void)encodeWithCoder:(CPCoder)aCoder
{
// We do this in order to avoid encoding the _wellView, which
// should just automatically be created programmatically as needed.
var actualSubviews = _subviews;
_subviews = [_subviews copy];
[_subviews removeObjectIdenticalTo:_wellView];
[super encodeWithCoder:aCoder];
_subviews = actualSubviews;
[aCoder encodeObject:_color forKey:CPColorWellColorKey];
[aCoder encodeObject:_bordered forKey:CPColorWellBorderedKey];
[aCoder encodeObject:[self isBordered] forKey:CPColorWellBorderedKey];
}
@end
+1192
View File
File diff suppressed because it is too large Load Diff
+130 -1
View File
@@ -67,13 +67,29 @@ CPHTML5DragAndDropSourceYOffBy1 = 1 << 26;
CPSOPDisabledFromFileURLs = 1 << 27;
// element.style.font can be set for an element not in the DOM.
CPInputSetFontOutsideOfDOM = 1 << 28;
// Input elements have 1 px of extra padding on the left regardless of padding setting.
CPInput1PxLeftPadding = 1 << 29;
CPInputOnInputEventFeature = 1 << 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
CPCanvasParentDrawErrorsOnMovementBug = 1 << 0;
var USER_AGENT = "",
PLATFORM_ENGINE = CPUnknownBrowserEngine,
PLATFORM_FEATURES = 0;
PLATFORM_FEATURES = 0,
PLATFORM_BUGS = 0,
PLATFORM_STYLE_JS_PROPERTIES = {};
// default these features to true
PLATFORM_FEATURES |= CPInputTypeCanBeChangedFeature;
PLATFORM_FEATURES |= CPInputSetFontOutsideOfDOM;
if (typeof window !== "undefined" && typeof window.navigator !== "undefined")
USER_AGENT = window.navigator.userAgent;
@@ -99,6 +115,9 @@ else if (typeof window !== "undefined" && window.attachEvent) // Must follow Ope
PLATFORM_FEATURES |= CPOpacityRequiresFilterFeature;
PLATFORM_FEATURES &= ~CPInputTypeCanBeChangedFeature;
// Tested in Internet Explore 8 and 9.
PLATFORM_FEATURES &= ~CPInputSetFontOutsideOfDOM;
}
// WebKit
@@ -135,8 +154,16 @@ else if (USER_AGENT.indexOf("AppleWebKit/") != -1)
if (majorVersion < 532 || (majorVersion === 532 && minorVersion < 6))
PLATFORM_FEATURES |= CPHTML5DragAndDropSourceYOffBy1;
// This is supposedly fixed in webkit r123603. Seems to work in Chrome 21 but not Safari 6.0.
if (majorVersion < 537)
PLATFORM_FEATURES |= CPInput1PxLeftPadding;
if (USER_AGENT.indexOf("Chrome") === CPNotFound)
PLATFORM_FEATURES |= CPSOPDisabledFromFileURLs;
// Assume this bug was introduced around Safari 5.1/Chrome 16. This could probably be tighter.
if (majorVersion > 533)
PLATFORM_BUGS |= CPCanvasParentDrawErrorsOnMovementBug;
}
// KHTML
@@ -160,6 +187,9 @@ else if (USER_AGENT.indexOf("Gecko") !== -1) // Must follow KHTML check.
if (version < 3.0)
PLATFORM_FEATURES |= CPJavaScriptMouseWheelValues_8_15;
// Some day this might be fixed and should be version prefixed. No known fixed version yet.
PLATFORM_FEATURES |= CPInput1PxLeftPadding;
}
// Feature Specific Checks
@@ -185,6 +215,16 @@ if (typeof document != "undefined")
PLATFORM_FEATURES |= CPJavaScriptInnerTextFeature;
else if (DOMElement.textContent != undefined)
PLATFORM_FEATURES |= CPJavaScriptTextContentFeature;
var DOMInputElement = document.createElement("input");
if ("oninput" in DOMInputElement)
PLATFORM_FEATURES |= CPInputOnInputEventFeature;
else if (typeof DOMInputElement.setAttribute === "function")
{
DOMInputElement.setAttribute("oninput", "return;");
if (typeof DOMInputElement.oninput === "function")
PLATFORM_FEATURES |= CPInputOnInputEventFeature;
}
}
function CPFeatureIsCompatible(aFeature)
@@ -192,6 +232,11 @@ function CPFeatureIsCompatible(aFeature)
return PLATFORM_FEATURES & aFeature;
}
function CPPlatformHasBug(aBug)
{
return PLATFORM_BUGS & aBug;
}
function CPBrowserIsEngine(anEngine)
{
return PLATFORM_ENGINE === anEngine;
@@ -229,3 +274,87 @@ 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"],
capProperty = [aProperty capitalizedString];
for (var i = 0; i < prefixes.length; i++)
{
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)
{
return prefixes[prefix] + browserProperty.substring(prefix.length).toLowerCase();
}
}
return browserProperty.toLowerCase();
}
+72 -58
View File
@@ -28,42 +28,48 @@
@import "CPView.j"
@import "CPKeyValueBinding.j"
CPLeftTextAlignment = 0;
CPRightTextAlignment = 1;
CPCenterTextAlignment = 2;
CPJustifiedTextAlignment = 3;
CPNaturalTextAlignment = 4;
CPLeftTextAlignment = 0;
CPRightTextAlignment = 1;
CPCenterTextAlignment = 2;
CPJustifiedTextAlignment = 3;
CPNaturalTextAlignment = 4;
CPRegularControlSize = 0;
CPSmallControlSize = 1;
CPMiniControlSize = 2;
CPRegularControlSize = 0;
CPSmallControlSize = 1;
CPMiniControlSize = 2;
CPLineBreakByWordWrapping = 0;
CPLineBreakByCharWrapping = 1;
CPLineBreakByClipping = 2;
CPLineBreakByTruncatingHead = 3;
CPLineBreakByTruncatingTail = 4;
CPLineBreakByTruncatingMiddle = 5;
CPLineBreakByWordWrapping = 0;
CPLineBreakByCharWrapping = 1;
CPLineBreakByClipping = 2;
CPLineBreakByTruncatingHead = 3;
CPLineBreakByTruncatingTail = 4;
CPLineBreakByTruncatingMiddle = 5;
CPTopVerticalTextAlignment = 1;
CPCenterVerticalTextAlignment = 2;
CPBottomVerticalTextAlignment = 3;
CPTopVerticalTextAlignment = 1;
CPCenterVerticalTextAlignment = 2;
CPBottomVerticalTextAlignment = 3;
CPScaleProportionally = 0;
CPScaleToFit = 1;
CPScaleNone = 2;
// Deprecated for use with images, use the CPImageScale constants
CPScaleProportionally = 0;
CPScaleToFit = 1;
CPScaleNone = 2;
CPNoImage = 0;
CPImageOnly = 1;
CPImageLeft = 2;
CPImageRight = 3;
CPImageBelow = 4;
CPImageAbove = 5;
CPImageOverlaps = 6;
CPImageScaleProportionallyDown = 0;
CPImageScaleAxesIndependently = 1;
CPImageScaleNone = 2;
CPImageScaleProportionallyUpOrDown = 3;
CPOnState = 1;
CPOffState = 0;
CPMixedState = -1;
CPNoImage = 0;
CPImageOnly = 1;
CPImageLeft = 2;
CPImageRight = 3;
CPImageBelow = 4;
CPImageAbove = 5;
CPImageOverlaps = 6;
CPOnState = 1;
CPOffState = 0;
CPMixedState = -1;
CPControlNormalBackgroundColor = "CPControlNormalBackgroundColor";
CPControlSelectedBackgroundColor = "CPControlSelectedBackgroundColor";
@@ -106,7 +112,7 @@ var CPControlBlackColor = [CPColor blackColor];
CPTopVerticalTextAlignment,
CPLineBreakByClipping,
[CPColor blackColor],
[CPFont systemFontOfSize:12.0],
[CPFont systemFontOfSize:CPFontCurrentSystemSize],
[CPNull null],
_CGSizeMakeZero(),
CPImageLeft,
@@ -128,18 +134,18 @@ var CPControlBlackColor = [CPColor blackColor];
+ (void)initialize
{
if (self === [CPControl class])
{
[self exposeBinding:@"value"];
[self exposeBinding:@"objectValue"];
[self exposeBinding:@"stringValue"];
[self exposeBinding:@"integerValue"];
[self exposeBinding:@"intValue"];
[self exposeBinding:@"doubleValue"];
[self exposeBinding:@"floatValue"];
if (self !== [CPControl class])
return;
[self exposeBinding:@"enabled"];
}
[self exposeBinding:@"value"];
[self exposeBinding:@"objectValue"];
[self exposeBinding:@"stringValue"];
[self exposeBinding:@"integerValue"];
[self exposeBinding:@"intValue"];
[self exposeBinding:@"doubleValue"];
[self exposeBinding:@"floatValue"];
[self exposeBinding:@"enabled"];
}
+ (Class)_binderClassForBinding:(CPString)theBinding
@@ -385,7 +391,10 @@ var CPControlBlackColor = [CPColor blackColor];
- (void)stopTracking:(CGPoint)lastPoint at:(CGPoint)aPoint mouseIsUp:(BOOL)mouseIsUp
{
[self highlight:NO];
if (mouseIsUp)
[self highlight:NO];
else
[self highlight:YES];
}
- (void)mouseDown:(CPEvent)anEvent
@@ -507,7 +516,7 @@ var CPControlBlackColor = [CPColor blackColor];
*/
- (CPString)stringValue
{
if (_formatter && _value !== undefined && _value !== nil)
if (_formatter && _value !== undefined)
{
var formattedValue = [self hasThemeState:CPThemeStateEditing] ? [_formatter editingStringForObjectValue:_value] : [_formatter stringForObjectValue:_value];
@@ -526,7 +535,7 @@ var CPControlBlackColor = [CPColor blackColor];
// Cocoa raises an invalid parameter assertion and returns if you pass nil.
if (aString === nil || aString === undefined)
{
CPLog.warn("nil sent to CPControl -setStringValue");
CPLog.warn("nil or undefined sent to CPControl -setStringValue");
return;
}
@@ -784,9 +793,10 @@ var CPControlBlackColor = [CPColor blackColor];
Sets the image scaling of the control.
<pre>
CPScaleProportionally
CPScaleToFit
CPScaleNone
CPImageScaleProportionallyDown
CPImageScaleAxesIndependently
CPImageScaleNone
CPImageScaleProportionallyUpOrDown
</pre>
*/
- (void)setImageScaling:(CPImageScaling)scaling
@@ -857,17 +867,16 @@ var CPControlBlackColor = [CPColor blackColor];
@end
var CPControlValueKey = "CPControlValueKey",
CPControlControlStateKey = @"CPControlControlStateKey",
CPControlIsEnabledKey = "CPControlIsEnabledKey",
var CPControlValueKey = @"CPControlValueKey",
CPControlControlStateKey = @"CPControlControlStateKey",
CPControlIsEnabledKey = @"CPControlIsEnabledKey",
CPControlTargetKey = @"CPControlTargetKey",
CPControlActionKey = @"CPControlActionKey",
CPControlSendActionOnKey = @"CPControlSendActionOnKey",
CPControlFormatterKey = @"CPControlFormatterKey",
CPControlSendsActionOnEndEditingKey = @"CPControlSendsActionOnEndEditingKey",
CPControlTargetKey = "CPControlTargetKey",
CPControlActionKey = "CPControlActionKey",
CPControlSendActionOnKey = "CPControlSendActionOnKey",
CPControlSendsActionOnEndEditingKey = "CPControlSendsActionOnEndEditingKey";
var __Deprecated__CPImageViewImageKey = @"CPImageViewImageKey";
__Deprecated__CPImageViewImageKey = @"CPImageViewImageKey";
@implementation CPControl (CPCoding)
@@ -890,6 +899,8 @@ var __Deprecated__CPImageViewImageKey = @"CPImageViewImageKey";
[self sendActionOn:[aCoder decodeIntForKey:CPControlSendActionOnKey]];
[self setSendsActionOnEndEditing:[aCoder decodeBoolForKey:CPControlSendsActionOnEndEditingKey]];
[self setFormatter:[aCoder decodeObjectForKey:CPControlFormatterKey]];
}
return self;
@@ -919,6 +930,9 @@ var __Deprecated__CPImageViewImageKey = @"CPImageViewImageKey";
[aCoder encodeObject:_action forKey:CPControlActionKey];
[aCoder encodeInt:_sendActionOn forKey:CPControlSendActionOnKey];
if (_formatter !== nil)
[aCoder encodeObject:_formatter forKey:CPControlFormatterKey];
}
@end
+6 -2
View File
@@ -111,8 +111,12 @@
for (var i = 0; i < ca.length; i++)
{
var c = ca[i];
while (c.charAt(0) == ' ') c = c.substring(1, c.length);
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
while (c.charAt(0) == ' ')
c = c.substring(1, c.length);
if (c.indexOf(nameEQ) == 0)
return c.substring(nameEQ.length, c.length);
}
#endif
return "";
+85 -10
View File
@@ -25,7 +25,8 @@ Cursor support by browser:
var currentCursor = nil,
cursorStack = [],
cursors = {};
cursors = {},
ieCursorMap = {};
@implementation CPCursor : CPObject
{
@@ -36,6 +37,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 +59,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];
}
+ (void)hide
{
[self _setCursorCSS:"none"]; // Not supported in IE
[self _setCursorCSS:@"none"]; // Not supported in IE < 9
}
+ (void)unhide
@@ -121,6 +143,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 +153,34 @@ 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;
cssString = [CPString stringWithFormat:@"url(%@/CPCursor/%@.cur), %@", [[CPBundle bundleForClass:self] resourcePath], cursorName, 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 +198,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 +253,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];
+47 -3
View File
@@ -179,7 +179,8 @@ CPDOMEventTouchCancel = "touchcancel";
var _CPEventPeriodicEventPeriod = 0,
_CPEventPeriodicEventTimer = nil,
_CPEventUpperCaseRegex = new RegExp("[A-Z]");
_CPEventUpperCaseRegex = new RegExp("[A-Z]"),
_CPEventStartupMilliseconds = new Date().getTime();
/*!
@ingroup appkit
@@ -203,12 +204,22 @@ var _CPEventPeriodicEventPeriod = 0,
BOOL _isARepeat;
unsigned _keyCode;
DOMEvent _DOMEvent;
int _data1;
int _data2;
float _deltaX;
float _deltaY;
float _deltaZ;
}
/*!
Returns the current time in fractional seconds since startup.
*/
+ (CPTimeInterval)currentTimestamp
{
return (new Date().getTime() - _CPEventStartupMilliseconds) / 1000;
}
/*!
Creates a new keyboard event.
@@ -389,7 +400,7 @@ var _CPEventPeriodicEventPeriod = 0,
}
/*!
Returns the time the event occurred.
Returns the time the event occurred in seconds since startup.
*/
- (CPTimeInterval)timestamp
{
@@ -508,6 +519,16 @@ var _CPEventPeriodicEventPeriod = 0,
return _DOMEvent;
}
- (int)data1
{
return _data1;
}
- (int)data2
{
return _data2;
}
// Getting Scroll Wheel Event Information
/*!
Returns the change in the x-axis for a mouse event.
@@ -621,11 +642,34 @@ var _CPEventPeriodicEventPeriod = 0,
_CPEventPeriodicEventTimer = nil;
}
- (CPString)description
{
switch (_type)
{
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];
case CPLeftMouseDown:
case CPLeftMouseUp:
case CPRightMouseDown:
case CPRightMouseUp:
case CPMouseMoved:
case CPLeftMouseDragged:
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];
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];
}
}
@end
function _CPEventFirePeriodEvent()
{
[CPApp sendEvent:[CPEvent otherEventWithType:CPPeriodic location:_CGPointMakeZero() modifierFlags:0 timestamp:0 windowNumber:0 context:nil subtype:0 data1:0 data2:0]];
[CPApp sendEvent:[CPEvent otherEventWithType:CPPeriodic location:_CGPointMakeZero() modifierFlags:0 timestamp:[CPEvent currentTimestamp] windowNumber:0 context:nil subtype:0 data1:0 data2:0]];
}
var CPEventClass = [CPEvent class];
+5 -5
View File
@@ -104,10 +104,10 @@ var IEFlashCLSID = "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000";
- (void)setFlashVars:(CPDictionary)aDictionary
{
var varString = @"",
enumerator = [aDictionary keyEnumerator];
enumerator = [aDictionary keyEnumerator],
key;
var key;
while (key = [enumerator nextObject])
while ((key = [enumerator nextObject]) !== nil)
varString = [varString stringByAppendingFormat:@"&%@=%@", key, [aDictionary objectForKey:key]];
if (!_params)
@@ -146,7 +146,7 @@ var IEFlashCLSID = "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000";
var enumerator = [_params keyEnumerator],
key;
while (_DOMObjectElement && (key = [enumerator nextObject]))
while (_DOMObjectElement && (key = [enumerator nextObject]) !== nil)
{
var param = document.createElement(@"param");
param.name = key;
@@ -178,7 +178,7 @@ var IEFlashCLSID = "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000";
paramEnumerator = [_params keyEnumerator],
key;
while (key = [paramEnumerator nextObject])
while ((key = [paramEnumerator nextObject]) !== nil)
paramString = [paramString stringByAppendingFormat:@"<param name='%@' value='%@' />", key, [_params objectForKey:key]];
_DOMObjectElement = document.createElement(@"object");
+190 -72
View File
@@ -28,46 +28,85 @@
CPFontDefaultSystemFontFace = @"Arial, sans-serif";
CPFontDefaultSystemFontSize = 12;
var _CPFonts = {},
_CPFontSystemFontFace = CPFontDefaultSystemFontFace,
_CPFontSystemFontSize = 12,
_CPFontFallbackFaces = CPFontDefaultSystemFontFace.split(", "),
_CPFontStripRegExp = new RegExp("(^\\s*[\"']?|[\"']?\\s*$)", "g");
/*!
To create a font of a size that will dynamically reflect the current
system font size, use this for the size argument.
*/
CPFontCurrentSystemSize = -1;
// For internal use only by this class and subclasses
_CPFontSystemFacePlaceholder = "_CPFontSystemFacePlaceholder";
var _CPFontCache = {},
_CPSystemFontCache = {},
_CPFontSystemFontFace = CPFontDefaultSystemFontFace,
_CPFontSystemFontSize = 12,
_CPFontFallbackFaces = CPFontDefaultSystemFontFace.split(", "),
_CPFontStripRegExp = new RegExp("(^\\s*[\"']?|[\"']?\\s*$)", "g");
#define _CPRealFontSize(aSize) (aSize <= 0 ? _CPFontSystemFontSize : aSize)
#define _CPFontNormalizedNames(aName) _CPFontNormalizedNameArray(aName).join(", ")
#define _CPCachedFont(aName, aSize, isBold, isItalic) _CPFonts[_CPFontCreateCSSString(_CPFontNormalizedNames(aName), aSize, isBold, isItalic)]
#define _CPCachedFont(aName, aSize, isBold, isItalic) _CPFontCache[_CPFontCreateCSSString(_CPFontNormalizedNames(aName), aSize, isBold, isItalic)]
#define _CPUserFont(aName, aSize, isBold, isItalic) _CPCachedFont(aName, aSize, isBold, isItalic) || [[CPFont alloc] _initWithName:aName size:aSize bold:isBold italic:isItalic system:NO]
#define _CPSystemFontCacheKey(aSize, isBold) (String(aSize) + (isBold ? "b" : ""))
#define _CPCachedSystemFont(aSize, isBold) _CPSystemFontCache[_CPSystemFontCacheKey(aSize, isBold)]
#define _CPSystemFont(aSize, isBold) (_CPCachedSystemFont(aSize, isBold) || [[CPFont alloc] _initWithName:_CPFontSystemFacePlaceholder size:aSize bold:isBold italic:NO system:YES])
/*!
@ingroup appkit
@class CPFont
@ingroup appkit
@class CPFont
The CPFont class allows control of the fonts used for displaying text anywhere on the screen.
The primary method for getting a particular font is through one of the class methods that take
a name and/or size as arguments, and return the appropriate CPFont.
The CPFont class allows control of the fonts used for displaying text anywhere on the screen.
The primary method for getting a particular font is through one of the class methods that take
a name and/or size as arguments, and return the appropriate CPFont.
By default the system font face/size is Arial 12px, with a fallback to sans-serif. You may
configure this at runtime in two ways:
### System fonts
When you create a font using \c -systemFontOfSize: or \c -boldSystemFontOfSize:, a proxy font is
created that always refers to the current system font face and size. By default the system
font face/size is Arial 12px, with a fallback to sans-serif 12px. You may configure this at
runtime in two ways:
- By sending [CPFont @link CPFont::setSystemFontFace: setSystemFontFace:@endlink] and/or [CPFont @link CPFont::setSystemFontSize: setSystemFontSize:@endlink].
- By configuring Info.plist for your application or for AppKit. You can set the font face
by adding a CPSystemFontFace string item to the Info.plist, and you can set the font size
by adding a CPSystemFontSize integer item to the Info.plist.
- By sending [CPFont setSystemFontFace:<face>] and/or [CPFont setSystemFontSize:<size>].
Note that if you change the system font face or size during runtime, the next time
any view using a system font is redrawn, it will show the new font.
- By configuring Info.plist for your application or for AppKit. You can set the font face
by adding a CPSystemFontFace string item to the Info.plist, and you can set the font size
by adding a CPSystemFontSize integer item to the Info.plist.
Note that in either case, you can specify a comma-delimited list of fonts as the font face.
The browser will use the first available font in the list. CPFont always ensures that Arial
and sans-serif are in the generated CSS string, so there is no need to add them to the end
of your font list.
Note that in either case, you can specify a comma-delimited list of fonts as the font face.
Do not quote enclose font faces that contain spaces, that is done automatically when a CSS
representation of a font is requested.
If you are using nib2cib, you should use the second method (using Info.plist),
and be sure to run nib2cib again any time you modify the CPSystemFontFace or CPSystemFontSize items.
For example, you might add this to your application's Info.plist to set the system font to Lucida Grande,
with an automatic fallback to Arial or sans-serif:
The browser will use the first available font in the list you supply. CPFont always ensures
that Arial and sans-serif are in the CSS representation of a font as a fallback, so there is
no need to add them to the end of your font list.
@code
### nib2cib conversion
Fonts are converted by nib2cib according to the following algorithm:
- If the font family is Lucida Grande, then a system font will be created.
- If the font is Lucida Grande 13 (plain), the "default" font will be used at runtime.
The default font is taken from the "font" theme attribute if one exists,
otherwise from the current system font face and size.
- Lucida Grande of any size other than 13 will retain its size.
- Fonts using any family other than Lucida Grande will be used as is, including the size.
### Using custom web fonts
The configurability of CPFont makes it easy to use a custom web font as the system font.
For example, if you want to use the google font Asap as the system font, you would do the
following:
- Add a <link> to the <head> of index-debug.html and index.html:
@code
<link href='http://fonts.googleapis.com/css?family=Asap:400,700' rel='stylesheet' type='text/css'>
@endcode
- Specify Asap as the system font in Info.plist by adding the following item:
@code
<key>CPSystemFontFace</key>
<string>Lucida Grande</string>
@endcode
<string>Asap</string>
@endcode
*/
@implementation CPFont : CPObject
{
@@ -78,19 +117,23 @@ var _CPFonts = {},
float _lineHeight;
BOOL _isBold @accessors(readonly, getter=isBold);
BOOL _isItalic @accessors(readonly, getter=isItalic);
BOOL _isSystem @accessors(readonly, getter=isSystem);
CPString _cssString;
}
+ (void)initialize
{
if (self !== [CPFont class])
return;
var systemFontFace = [[CPBundle mainBundle] objectForInfoDictionaryKey:@"CPSystemFontFace"];
if (!systemFontFace)
systemFontFace = [[CPBundle bundleForClass:[CPView class]] objectForInfoDictionaryKey:@"CPSystemFontFace"];
if (systemFontFace)
[self setSystemFontFace:systemFontFace];
_CPFontSystemFontFace = _CPFontNormalizedNames(systemFontFace);
var systemFontSize = [[CPBundle mainBundle] objectForInfoDictionaryKey:@"CPSystemFontSize"];
@@ -114,7 +157,13 @@ var _CPFonts = {},
*/
+ (CPString)setSystemFontFace:(CPString)aFace
{
_CPFontSystemFontFace = _CPFontNormalizedNames(aFace);
var normalizedFaces = _CPFontNormalizedNames(aFace);
if (normalizedFaces === _CPFontSystemFontFace)
return;
[self _invalidateSystemFontCache]
_CPFontSystemFontFace = aFace;
}
/*!
@@ -125,106 +174,156 @@ var _CPFonts = {},
return _CPFontSystemFontSize;
}
+ (float)systemFontSizeForControlSize:(CPControlSize)aSize
{
// TODO These sizes should be themable or made less arbitrary in some other way.
switch (aSize)
{
case CPSmallControlSize:
return _CPFontSystemFontSize - 1;
case CPMiniControlSize:
return _CPFontSystemFontSize - 2;
case CPRegularControlSize:
default:
return _CPFontSystemFontSize;
}
}
/*!
Sets the default system font size.
*/
+ (float)setSystemFontSize:(float)size
{
if (size > 0)
if (size > 0 && size !== _CPFontSystemFontSize)
{
[self _invalidateSystemFontCache];
_CPFontSystemFontSize = size;
}
}
+ (void)_invalidateSystemFontCache
{
var systemSize = String(_CPFontSystemFontSize),
currentSize = String(CPFontCurrentSystemSize);
for (key in _CPSystemFontCache)
{
if (_CPSystemFontCache.hasOwnProperty(key) &&
(key.indexOf(systemSize) === 0 || key.indexOf(currentSize) === 0))
{
delete _CPSystemFontCache[key];
}
}
}
/*!
Returns a font with the specified name and size.
@param aName the name of the font
@param aSize the size of the font (in px)
@param aSize the size of the font (in px). 0 or negative will create a font
in the current system font size.
@return the requested font
*/
+ (CPFont)fontWithName:(CPString)aName size:(float)aSize
{
return [CPFont fontWithName:aName size:aSize bold:NO italic:NO];
return _CPUserFont(aName, aSize <= 0 ? _CPFontSystemFontSize : aSize, NO, NO);
}
/*!
Returns a font with the specified name, size and style.
@param aName the name of the font
@param aSize the size of the font (in px)
@param aSize the size of the font (in px). 0 or negative will create a font
in the current system font size.
@param italic whether the font should be italicized
@return the requested font
*/
+ (CPFont)fontWithName:(CPString)aName size:(float)aSize italic:(BOOL)italic
{
return [CPFont fontWithName:aName size:aSize bold:NO italic:italic];
return _CPUserFont(aName, aSize <= 0 ? _CPFontSystemFontSize : aSize, NO, italic);
}
/*!
Returns a bold font with the specified name and size.
@param aName the name of the font
@param aSize the size of the font (in px)
@param aSize the size of the font (in px). 0 or negative will create a font
in the current system font size.
@return the requested bold font
*/
+ (CPFont)boldFontWithName:(CPString)aName size:(float)aSize
{
return [CPFont fontWithName:aName size:aSize bold:YES italic:NO];
return _CPUserFont(aName, aSize <= 0 ? _CPFontSystemFontSize : aSize, YES, NO);
}
/*!
Returns a bold font with the specified name, size and style.
@param aName the name of the font
@param aSize the size of the font (in px)
@param aSize the size of the font (in px). 0 or negative will create a font
in the current system font size.
@param italic whether the font should be italicized
@return the requested font
*/
+ (CPFont)boldFontWithName:(CPString)aName size:(float)aSize italic:(BOOL)italic
{
return [CPFont fontWithName:aName size:aSize bold:YES italic:italic];
return _CPUserFont(aName, aSize <= 0 ? _CPFontSystemFontSize : aSize, YES, italic);
}
/*!
Internal font getter like fontWithName:size:italic: with a bold selector.
*/
+ (CPFont)_fontWithName:(CPString)aName size:(float)aSize bold:(BOOL)bold italic:(BOOL)italic
{
return _CPUserFont(aName, aSize <= 0 ? _CPFontSystemFontSize : aSize, bold, italic);
}
/*!
Returns the system font scaled to the specified size
@param aSize the size of the font (in px)
@param aSize the size of the font (in px). 0 creates a static font
in the current system font size. Negative creates a font
that dynamically tracks the current system font size.
@return the requested system font
*/
+ (CPFont)systemFontOfSize:(CPSize)aSize
{
return [CPFont fontWithName:_CPFontSystemFontFace size:aSize bold:NO italic:NO];
return _CPSystemFont(aSize === 0 ? _CPFontSystemFontSize : aSize, NO);
}
/*!
Returns the bold system font scaled to the specified size
@param aSize the size of the font (in px)
@param aSize the size of the font (in px). 0 creates a static font
in the current system font size. Negative creates a font
that dynamically tracks the current system font size.
@return the requested bold system font
*/
+ (CPFont)boldSystemFontOfSize:(CPSize)aSize
{
return [CPFont fontWithName:_CPFontSystemFontFace size:aSize bold:YES italic:NO];
return _CPSystemFont(aSize === 0 ? _CPFontSystemFontSize : aSize, YES);
}
/* FIXME Font Descriptor
@ignore
*/
+ (CPFont)fontWithName:(CPString)aName size:(float)aSize bold:(BOOL)bold italic:(BOOL)italic
{
return _CPCachedFont(aName, aSize, bold, italic) || [[CPFont alloc] _initWithName:aName size:aSize bold:bold italic:italic];
}
- (id)_initWithName:(CPString)aName size:(float)aSize bold:(BOOL)isBold italic:(BOOL)isItalic
- (id)_initWithName:(CPString)aName size:(float)aSize bold:(BOOL)isBold italic:(BOOL)isItalic system:(BOOL)isSystem
{
self = [super init];
if (self)
{
_name = _CPFontNormalizedNames(aName);
_size = aSize;
_ascender = 0;
_descender = 0;
_lineHeight = 0;
_isBold = isBold;
_isItalic = isItalic;
_isSystem = isSystem;
_cssString = _CPFontCreateCSSString(_name, _size, _isBold, _isItalic);
_CPFonts[_cssString] = self;
if (isSystem)
{
_name = aName;
_cssString = _CPFontCreateCSSString(_CPFontSystemFontFace, _size, _isBold, _isItalic);
_CPSystemFontCache[_CPSystemFontCacheKey(_size, _isBold)] = self;
}
else
{
_name = _CPFontNormalizedNames(aName);
_cssString = _CPFontCreateCSSString(_name, _size, _isBold, _isItalic);
_CPFontCache[_cssString] = self;
}
}
return self;
@@ -235,10 +334,12 @@ var _CPFonts = {},
*/
- (float)ascender
{
if (!_ascender)
[self _getMetrics];
var font = _isSystem ? _CPSystemFont(_size, _isBold) : self;
return _ascender;
if (!font._ascender)
[font _getMetrics];
return font._ascender;
}
/*!
@@ -247,10 +348,12 @@ var _CPFonts = {},
*/
- (float)descender
{
if (!_descender)
[self _getMetrics];
var font = _isSystem ? _CPSystemFont(_size, _isBold) : self;
return _descender;
if (!font._descender)
[font _getMetrics];
return font._descender;
}
/*!
@@ -260,10 +363,12 @@ var _CPFonts = {},
*/
- (float)defaultLineHeightForFont
{
if (!_lineHeight)
[self _getMetrics];
var font = _isSystem ? _CPSystemFont(_size, _isBold) : self;
return _lineHeight;
if (!font._lineHeight)
[font _getMetrics];
return font._lineHeight;
}
/*!
@@ -271,7 +376,7 @@ var _CPFonts = {},
*/
- (float)size
{
return _size;
return _CPRealFontSize(_size);
}
/*!
@@ -279,7 +384,9 @@ var _CPFonts = {},
*/
- (CPString)cssString
{
return _cssString;
var font = _isSystem ? _CPSystemFont(_size, _isBold) : self;
return font._cssString;
}
/*!
@@ -287,9 +394,17 @@ var _CPFonts = {},
*/
- (CPString)familyName
{
if (_isSystem)
return _CPFontSystemFontFace;
return _name;
}
- (BOOL)isSystemSize
{
return _size <= 0;
}
- (BOOL)isEqual:(id)anObject
{
return [anObject isKindOfClass:[CPFont class]] && [anObject cssString] === _cssString;
@@ -302,7 +417,7 @@ var _CPFonts = {},
- (id)copy
{
return [[CPFont alloc] _initWithName:_name size:_size bold:_isBold italic:_isItalic];
return [[CPFont alloc] _initWithName:_name size:_size bold:_isBold italic:_isItalic system:_isSystem];
}
- (void)_getMetrics
@@ -319,7 +434,8 @@ var _CPFonts = {},
var CPFontNameKey = @"CPFontNameKey",
CPFontSizeKey = @"CPFontSizeKey",
CPFontIsBoldKey = @"CPFontIsBoldKey",
CPFontIsItalicKey = @"CPFontIsItalicKey";
CPFontIsItalicKey = @"CPFontIsItalicKey",
CPFontIsSystemKey = @"CPFontIsSystemKey";
@implementation CPFont (CPCoding)
@@ -333,9 +449,10 @@ var CPFontNameKey = @"CPFontNameKey",
var fontName = [aCoder decodeObjectForKey:CPFontNameKey],
size = [aCoder decodeFloatForKey:CPFontSizeKey],
isBold = [aCoder decodeBoolForKey:CPFontIsBoldKey],
isItalic = [aCoder decodeBoolForKey:CPFontIsItalicKey];
isItalic = [aCoder decodeBoolForKey:CPFontIsItalicKey],
isSystem = [aCoder decodeBoolForKey:CPFontIsSystemKey];
return [self _initWithName:fontName size:size bold:isBold italic:isItalic];
return [self _initWithName:fontName size:size bold:isBold italic:isItalic system:isSystem];
}
/*!
@@ -348,6 +465,7 @@ var CPFontNameKey = @"CPFontNameKey",
[aCoder encodeFloat:_size forKey:CPFontSizeKey];
[aCoder encodeBool:_isBold forKey:CPFontIsBoldKey];
[aCoder encodeBool:_isItalic forKey:CPFontIsItalicKey];
[aCoder encodeBool:_isSystem forKey:CPFontIsSystemKey];
}
@end
@@ -356,7 +474,7 @@ var CPFontNameKey = @"CPFontNameKey",
// aName must be normalized
var _CPFontCreateCSSString = function(aName, aSize, isBold, isItalic)
{
var properties = (isItalic ? "italic " : "") + (isBold ? "bold " : "") + aSize + "px ";
var properties = (isItalic ? "italic " : "") + (isBold ? "bold " : "") + _CPRealFontSize(aSize) + "px ";
return properties + _CPFontConcatNameWithFallback(aName);
};
+152 -28
View File
@@ -24,6 +24,19 @@
@import "CPFont.j"
CPItalicFontMask = 1 << 0;
CPBoldFontMask = 1 << 1;
CPUnboldFontMask = 1 << 2;
CPNonStandardCharacterSetFontMask = 1 << 3;
CPNarrowFontMask = 1 << 4;
CPExpandedFontMask = 1 << 5;
CPCondensedFontMask = 1 << 6;
CPSmallCapsFontMask = 1 << 7;
CPPosterFontMask = 1 << 8;
CPCompressedFontMask = 1 << 9;
CPFixedPitchFontMask = 1 << 10;
CPUnitalicFontMask = 1 << 24;
var CPSharedFontManager = nil,
CPFontManagerFactory = Nil;
@@ -33,7 +46,17 @@ var CPSharedFontManager = nil,
*/
@implementation CPFontManager : CPObject
{
CPArray _availableFonts;
CPArray _availableFonts;
id _target @accessors(property=target);
SEL _action @accessors(property=action);
id _delegate @accessors(property=delegate);
CPFont _selectedFont;
BOOL _multiple @accessors;
CPDictionary _activeChange;
}
// Getting the Shared Font Manager
@@ -59,6 +82,16 @@ var CPSharedFontManager = nil,
CPFontManagerFactory = aClass;
}
- (id)init
{
if (self = [super init])
{
_action = @selector(changeFont:);
}
return self;
}
/*!
Returns an array of the available fonts
*/
@@ -66,6 +99,9 @@ var CPSharedFontManager = nil,
{
if (!_availableFonts)
{
_availableFonts = [];
#if PLATFORM(DOM)
_CPFontDetectSpan = document.createElement("span");
_CPFontDetectSpan.fontSize = "24px";
_CPFontDetectSpan.appendChild(document.createTextNode("mmmmmmmmmml"));
@@ -77,13 +113,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;
}
@@ -97,43 +136,128 @@ var CPSharedFontManager = nil,
return _CPFontDetectFontAvailable(aFontName);
}
- (void)setSelectedFont:(CPFont)aFont isMultiple:(BOOL)aFlag
{
_selectedFont = aFont;
_isMultiple = aFlag;
// TODO Notify CPFontPanel when it exists.
}
- (CPFont)selectedFont
{
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
// precise than that.
return [aFont isBold] ? 9 : 5;
}
- (CPFontTraitMask)traitsOfFont:(CPFont)aFont
{
return ([aFont isBold] ? CPBoldFontMask : 0) | ([aFont isItalic] ? CPItalicFontMask : 0);
}
- (CPFont)convertFont:(CPFont)aFont
{
if (!_activeChange)
return aFont;
var addTraits = [_activeChange valueForKey:@"addTraits"];
if (addTraits)
aFont = [self convertFont:aFont toHaveTrait:addTraits];
return aFont;
}
- (CPFont)convertFont:(CPFont)aFont toHaveTrait:(CPFontTraitMask)addTraits
{
if (!aFont)
return nil;
var shouldBeBold = ([aFont isBold] || (addTraits & CPBoldFontMask)) && !(addTraits & CPUnboldFontMask),
shouldBeItalic = ([aFont isItalic] || (addTraits & CPItalicFontMask)) && !(addTraits & CPUnitalicFontMask),
shouldBeSize = [aFont size];
// XXX On the current platform there will always be a bold/italic version of each font, but still leave
// || aFont in here for future platforms.
aFont = [CPFont _fontWithName:[aFont familyName] size:shouldBeSize bold:shouldBeBold italic:shouldBeItalic] || aFont;
return aFont;
}
- (CPFont)convertFont:(CPFont)aFont toFace:(CPString)aTypeface
{
if (!aFont)
return nil;
var shouldBeBold = [aFont isBold],
shouldBeItalic = [aFont isItalic],
shouldBeSize = [aFont size];
aFont = [CPFont _fontWithName:aTypeface size:shouldBeSize bold:shouldBeBold italic:shouldBeItalic] || aFont;
return aFont;
}
- (@action)addFontTrait:(id)sender
{
_activeChange = [CPDictionary dictionaryWithObject:[sender tag] forKey:@"addTraits"];
[self sendAction];
}
- (BOOL)sendAction
{
return [CPApp sendAction:_action to:_target from:self];
}
@end
var _CPFontDetectSpan,
_CPFontDetectReferenceFonts,
_CPFontDetectAllFonts = [
/* "04b_21","A Charming Font","Abadi MT Condensed","Abadi MT Condensed Extra Bold","Abadi MT Condensed Light","Academy Engraved LET","Agency FB","Alba","Alba Matter","Alba Super","Algerian",*/
/* "04b_21", "A Charming Font", "Abadi MT Condensed", "Abadi MT Condensed Extra Bold", "Abadi MT Condensed Light", "Academy Engraved LET", "Agency FB", "Alba", "Alba Matter", "Alba Super", "Algerian",*/
"American Typewriter",
/* "Andale Mono","Andale Mono IPA","Andy", */
"Apple Chancery","Arial","Arial Black","Arial Narrow","Arial Rounded MT Bold","Arial Unicode MS",
/* "Avant Garde","Avantgarde","Baby Kruffy","Base 02","Baskerville","Baskerville Old Face","Bauhaus 93","Beesknees ITC","Bell MT","Berlin Sans FB","Berlin Sans FB Demi","Bernard MT Condensed","Bickley Script",*/
"Big Caslon","Bitstream Vera Sans","Bitstream Vera Sans Mono","Bitstream Vera Serif",
/* "Blackadder ITC","Blackletter686 BT","Bodoni MT","Bodoni MT Black","Bodoni MT Condensed","Bodoni MT Poster Compressed","Book Antiqua","Bookman","Bookman Old Style","Bradley Hand ITC","Braggadocio","Britannic Bold","Broadway","Broadway BT",*/
/* "Andale Mono", "Andale Mono IPA", "Andy", */
"Apple Chancery", "Arial", "Arial Black", "Arial Narrow", "Arial Rounded MT Bold", "Arial Unicode MS",
/* "Avant Garde", "Avantgarde", "Baby Kruffy", "Base 02", "Baskerville", "Baskerville Old Face", "Bauhaus 93", "Beesknees ITC", "Bell MT", "Berlin Sans FB", "Berlin Sans FB Demi", "Bernard MT Condensed", "Bickley Script",*/
"Big Caslon", "Bitstream Vera Sans", "Bitstream Vera Sans Mono", "Bitstream Vera Serif",
/* "Blackadder ITC", "Blackletter686 BT", "Bodoni MT", "Bodoni MT Black", "Bodoni MT Condensed", "Bodoni MT Poster Compressed", "Book Antiqua", "Bookman", "Bookman Old Style", "Bradley Hand ITC", "Braggadocio", "Britannic Bold", "Broadway", "Broadway BT",*/
"Brush Script MT",
/* "BudHand","CAMPBELL","Calibri","Californian FB","Calisto MT","Calligraph421 BT",*/
/* "BudHand", "CAMPBELL", "Calibri", "Californian FB", "Calisto MT", "Calligraph421 BT",*/
"Cambria",
/* "Candara","Capitals",*/
"Caslon","Castellar","Cataneo BT","Centaur","Century Gothic","Century Schoolbook","Century Schoolbook L",
/* "Champignon","Charcoal","Charter","Charter BT","Chicago","Chick","Chiller","ClearlyU","Colonna MT",*/
"Comic Sans", "Comic Sans MS","Consolas","Constantia","Cooper Black","Copperplate","Copperplate Gothic Bold","Copperplate Gothic Light","Corbel","Courier","Courier New",
/* "Croobie","Curlz MT","Desdemona","Didot","DomBold BT","Edwardian Script ITC","Engravers MT","Eras Bold ITC","Eras Demi ITC","Eras Light ITC","Eras Medium ITC","Eurostile","FIRSTHOME","Fat","Felix Titling","Fine Hand","Fixed","Footlight MT Light","Forte","Franklin Gothic Book","Franklin Gothic Demi","Franklin Gothic Demi Cond","Franklin Gothic Heavy","Franklin Gothic Medium","Franklin Gothic Medium Cond","Freestyle Script","French Script MT","Freshbot","Frosty",*/
/* "Candara", "Capitals",*/
"Caslon", "Castellar", "Cataneo BT", "Centaur", "Century Gothic", "Century Schoolbook", "Century Schoolbook L",
/* "Champignon", "Charcoal", "Charter", "Charter BT", "Chicago", "Chick", "Chiller", "ClearlyU", "Colonna MT",*/
"Comic Sans", "Comic Sans MS", "Consolas", "Constantia", "Cooper Black", "Copperplate", "Copperplate Gothic Bold", "Copperplate Gothic Light", "Corbel", "Courier", "Courier New",
/* "Croobie", "Curlz MT", "Desdemona", "Didot", "DomBold BT", "Edwardian Script ITC", "Engravers MT", "Eras Bold ITC", "Eras Demi ITC", "Eras Light ITC", "Eras Medium ITC", "Eurostile", "FIRSTHOME", "Fat", "Felix Titling", "Fine Hand", "Fixed", "Footlight MT Light", "Forte", "Franklin Gothic Book", "Franklin Gothic Demi", "Franklin Gothic Demi Cond", "Franklin Gothic Heavy", "Franklin Gothic Medium", "Franklin Gothic Medium Cond", "Freestyle Script", "French Script MT", "Freshbot", "Frosty",*/
"Futura",
/* "GENUINE","Gadget","Garamond",*/
"Geneva","Georgia","Georgia Ref", "Geeza Pro", "Gigi","Gill Sans","Gill Sans MT","Gill Sans MT Condensed","Gill Sans MT Ext Condensed Bold","Gill Sans Ultra Bold","Gill Sans Ultra Bold Condensed",
/* "GlooGun","Gloucester MT Extra Condensed","Goudy Old Style","Goudy Stout","Haettenschweiler","Harlow Solid Italic","Harrington",*/
"Helvetica","Helvetica Narrow","Helvetica Neue","Herculanum","High Tower Text","Highlight LET","Hoefler Text","Impact","Imprint MT Shadow",
/* "Informal Roman","Jenkins v2.0","John Handy LET","Jokerman","Jokerman LET","Jokewood","Juice ITC","Kabel Ult BT","Kartika","Kino MT","Kristen ITC","Kunstler Script","La Bamba LET", */
"Lucida","Lucida Bright","Lucida Calligraphy","Lucida Console","Lucida Fax","Lucida Grande","Lucida Handwriting","Lucida Sans","Lucida Sans Typewriter","Lucida Sans Unicode",
/* "Luxi Mono","Luxi Sans","Luxi Serif","MARKETPRO","MS Reference Sans Serif","MS Reference Serif","Magneto","Maiandra GD", */
/* "GENUINE", "Gadget", "Garamond",*/
"Geneva", "Georgia", "Georgia Ref", "Geeza Pro", "Gigi", "Gill Sans", "Gill Sans MT", "Gill Sans MT Condensed", "Gill Sans MT Ext Condensed Bold", "Gill Sans Ultra Bold", "Gill Sans Ultra Bold Condensed",
/* "GlooGun", "Gloucester MT Extra Condensed", "Goudy Old Style", "Goudy Stout", "Haettenschweiler", "Harlow Solid Italic", "Harrington",*/
"Helvetica", "Helvetica Narrow", "Helvetica Neue", "Herculanum", "High Tower Text", "Highlight LET", "Hoefler Text", "Impact", "Imprint MT Shadow",
/* "Informal Roman", "Jenkins v2.0", "John Handy LET", "Jokerman", "Jokerman LET", "Jokewood", "Juice ITC", "Kabel Ult BT", "Kartika", "Kino MT", "Kristen ITC", "Kunstler Script", "La Bamba LET", */
"Lucida", "Lucida Bright", "Lucida Calligraphy", "Lucida Console", "Lucida Fax", "Lucida Grande", "Lucida Handwriting", "Lucida Sans", "Lucida Sans Typewriter", "Lucida Sans Unicode",
/* "Luxi Mono", "Luxi Sans", "Luxi Serif", "MARKETPRO", "MS Reference Sans Serif", "MS Reference Serif", "Magneto", "Maiandra GD", */
"Marker Felt",
/* "Matisse ITC","Matura MT Script Capitals","Mead Bold","Mekanik LET","Mercurius Script MT Bold", */
"Microsoft Sans Serif","Milano LET","Minion Web","MisterEarl BT","Mistral","Monaco","Monotype Corsiva","Monotype.com","New Century Schoolbook","New York","News Gothic MT",
/* "Niagara Engraved","Niagara Solid","Nimbus Mono L","Nimbus Roman No9 L","OCR A Extended","OCRB","Odessa LET","Old English Text MT","OldDreadfulNo7 BT","One Stroke Script LET","Onyx","Optima","Orange LET","Palace Script MT","Palatino","Palatino Linotype", */
/* "Matisse ITC", "Matura MT Script Capitals", "Mead Bold", "Mekanik LET", "Mercurius Script MT Bold", */
"Microsoft Sans Serif", "Milano LET", "Minion Web", "MisterEarl BT", "Mistral", "Monaco", "Monotype Corsiva", "Monotype.com", "New Century Schoolbook", "New York", "News Gothic MT",
/* "Niagara Engraved", "Niagara Solid", "Nimbus Mono L", "Nimbus Roman No9 L", "OCR A Extended", "OCRB", "Odessa LET", "Old English Text MT", "OldDreadfulNo7 BT", "One Stroke Script LET", "Onyx", "Optima", "Orange LET", "Palace Script MT", "Palatino", "Palatino Linotype", */
"Papyrus",
/* "ParkAvenue BT","Pepita MT","Perpetua","Perpetua Titling MT","Placard Condensed","Playbill","Poornut","Pristina","Pump Demi Bold LET","Pussycat","Quixley LET","Rage Italic","Rage Italic LET","Ravie","Rockwell","Rockwell Condensed","Rockwell Extra Bold","Ruach LET","Runic MT Condensed","Sand","Script MT Bold","Scruff LET","Segoe UI","Showcard Gothic","Skia","Smudger LET","Snap ITC","Square721 BT","Staccato222 BT","Stencil","Sylfaen", */
"Tahoma","Techno","Tempus Sans ITC","Terminal","Textile","Times","Times New Roman","Tiranti Solid LET","Trebuchet MS",
/* "Tw Cen MT","Tw Cen MT Condensed","Tw Cen MT Condensed Extra Bold","URW Antiqua T","URW Bookman L","URW Chancery L","URW Gothic L","URW Palladio L","Univers","University Roman LET","Utopia", */
"Verdana","Verdana Ref", /* "Victorian LET","Viner Hand ITC","Vivaldi","Vladimir Script","Vrinda","Weltron Urban","Westwood LET","Wide Latin","Zapf Chancery", */
/* "ParkAvenue BT", "Pepita MT", "Perpetua", "Perpetua Titling MT", "Placard Condensed", "Playbill", "Poornut", "Pristina", "Pump Demi Bold LET", "Pussycat", "Quixley LET", "Rage Italic", "Rage Italic LET", "Ravie", "Rockwell", "Rockwell Condensed", "Rockwell Extra Bold", "Ruach LET", "Runic MT Condensed", "Sand", "Script MT Bold", "Scruff LET", "Segoe UI", "Showcard Gothic", "Skia", "Smudger LET", "Snap ITC", "Square721 BT", "Staccato222 BT", "Stencil", "Sylfaen", */
"Tahoma", "Techno", "Tempus Sans ITC", "Terminal", "Textile", "Times", "Times New Roman", "Tiranti Solid LET", "Trebuchet MS",
/* "Tw Cen MT", "Tw Cen MT Condensed", "Tw Cen MT Condensed Extra Bold", "URW Antiqua T", "URW Bookman L", "URW Chancery L", "URW Gothic L", "URW Palladio L", "Univers", "University Roman LET", "Utopia", */
"Verdana", "Verdana Ref", /* "Victorian LET", "Viner Hand ITC", "Vivaldi", "Vladimir Script", "Vrinda", "Weltron Urban", "Westwood LET", "Wide Latin", "Zapf Chancery", */
"Zapfino"];
// Compare against the reference fonts. Return true if it produces a different size than at least one of them.
+15 -2
View File
@@ -23,6 +23,16 @@
@import "CPColor.j"
@import "CPGraphicsContext.j"
CPCalibratedWhiteColorSpace = @"CalibratedWhiteColorSpace";
CPCalibratedBlackColorSpace = @"CalibratedBlackColorSpace";
CPCalibratedRGBColorSpace = @"CalibratedRGBColorSpace";
CPDeviceWhiteColorSpace = @"DeviceWhiteColorSpace";
CPDeviceBlackColorSpace = @"DeviceBlackColorSpace";
CPDeviceRGBColorSpace = @"DeviceRGBColorSpace";
CPDeviceCMYKColorSpace = @"DeviceCMYKColorSpace";
CPNamedColorSpace = @"NamedColorSpace";
CPPatternColorSpace = @"PatternColorSpace";
CPCustomColorSpace = @"CustomColorSpace";
function CPDrawTiledRects(
/* CGRect */ boundsRect,
@@ -70,7 +80,10 @@ function CPDrawColorTiledRects(
if (_CGRectIsEmpty(slice))
continue;
var minX, maxX, minY, maxY;
var minX,
maxX,
minY,
maxY;
if (side == CPMinXEdge || side == CPMaxXEdge)
{
@@ -105,4 +118,4 @@ function CPDrawColorTiledRects(
CGContextRestoreGState(context);
return resultRect;
}
}
+34 -1
View File
@@ -25,7 +25,8 @@
@import "CGContext.j"
var CPGraphicsContextCurrent = nil;
var CPGraphicsContextCurrent = nil,
CPGraphicsContextThreadStack = nil;
/*!
@ingroup appkit
@@ -52,6 +53,28 @@ var CPGraphicsContextCurrent = nil;
CPGraphicsContextCurrent = aGraphicsContext;
}
+ (void)saveGraphicsState
{
if (!CPGraphicsContextCurrent)
return;
if (!CPGraphicsContextThreadStack)
CPGraphicsContextThreadStack = [CPMutableArray array];
[CPGraphicsContextThreadStack addObject:CPGraphicsContextCurrent];
[CPGraphicsContextCurrent saveGraphicsState];
}
+ (void)restoreGraphicsState
{
var lastContext = [CPGraphicsContextThreadStack lastObject];
if (lastContext)
{
[lastContext restoreGraphicsState];
[CPGraphicsContextThreadStack removeLastObject];
}
}
/*!
Creates a graphics context with a provided port.
@param aContext the context to initialize with
@@ -99,4 +122,14 @@ var CPGraphicsContextCurrent = nil;
return YES;
}
- (void)saveGraphicsState
{
CGContextSaveGState(_graphicsPort);
}
- (void)restoreGraphicsState
{
CGContextRestoreGState(_graphicsPort);
}
@end
+46 -2
View File
@@ -21,13 +21,12 @@
*/
@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 "CPGeometry.j"
CPImageLoadStatusInitialized = 0;
CPImageLoadStatusLoading = 1;
@@ -158,6 +157,20 @@ function CPAppKitImage(aFilename, aSize)
return self;
}
/*!
Initializes the receiver with the specified data. The method loads the data into memory.
@param someData the CPData object representing the image
@return the initialized image
*/
- (id)initWithData:(CPData)someData
{
var base64 = [someData base64],
type = [base64 hasPrefix:@"/9j/4AAQSkZJRgABAQEASABIAAD/"] ? @"jpg" : @"png",
dataURL = "data:image/" + type + ";base64," + base64;
return [self initWithContentsOfFile:dataURL];
}
/*!
Returns the path of the file associated with this image.
*/
@@ -166,6 +179,37 @@ function CPAppKitImage(aFilename, aSize)
return _filename;
}
/*!
Returns the data associated with this image.
@discussion Returns nil if the reciever was not initialized with -initWithData: and the browser does not support the canvas feature;
*/
- (CPData)data
{
#if PLATFORM(DOM)
var dataURL;
if ([_filename hasPrefix:@"data:image"])
dataURL = _filename;
else if (CPFeatureIsCompatible(CPHTMLCanvasFeature))
{
var canvas = document.createElement("canvas"),
ctx = canvas.getContext("2d");
canvas.width = _image.width,
canvas.height = _image.height;
ctx.drawImage(_image, 0, 0);
dataURL = canvas.toDataURL("image/png");
}
else
return nil;
var base64 = dataURL.replace(/^data:image\/png;base64,/, "");
return [CPData dataWithBase64:base64];
#endif
}
/*!
Sets the size of the image.
@param the size of the image
+76 -39
View File
@@ -26,11 +26,6 @@
@import "CPImage.j"
@import "CPShadowView.j"
CPScaleProportionally = 0;
CPScaleToFit = 1;
CPScaleNone = 2;
CPImageAlignCenter = 0;
CPImageAlignTop = 1;
CPImageAlignTopLeft = 2;
@@ -64,11 +59,22 @@ var CPImageViewEmptyPlaceholderImage = nil;
+ (void)initialize
{
if (self !== [CPImageView class])
return;
var bundle = [CPBundle bundleForClass:[CPView class]];
CPImageViewEmptyPlaceholderImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"empty.png"]];
}
+ (Class)_binderClassForBinding:(CPString)theBinding
{
if (theBinding === CPValueBinding || theBinding === CPValueURLBinding || theBinding === CPValuePathBinding || theBinding === CPDataBinding)
return [CPImageViewValueBinder class];
return [super _binderClassForBinding:theBinding];
}
- (id)initWithFrame:(CGRect)aFrame
{
self = [super initWithFrame:aFrame];
@@ -232,7 +238,7 @@ var CPImageViewEmptyPlaceholderImage = nil;
[super setImageScaling:anImageScaling];
#if PLATFORM(DOM)
if ([self currentValueForThemeAttribute:@"image-scaling"] === CPScaleToFit)
if ([self currentValueForThemeAttribute:@"image-scaling"] === CPImageScaleAxesIndependently)
{
CPDOMDisplayServerSetStyleLeftTop(_DOMImageElement, NULL, 0.0, 0.0);
}
@@ -296,12 +302,12 @@ var CPImageViewEmptyPlaceholderImage = nil;
width = boundsWidth - insetWidth,
height = boundsHeight - insetHeight;
if (imageScaling === CPScaleToFit)
if (imageScaling === CPImageScaleAxesIndependently)
{
#if PLATFORM(DOM)
_DOMImageElement.width = ROUND(width);
_DOMImageElement.height = ROUND(height);
#endif
#if PLATFORM(DOM)
_DOMImageElement.width = ROUND(width);
_DOMImageElement.height = ROUND(height);
#endif
}
else
{
@@ -310,17 +316,19 @@ var CPImageViewEmptyPlaceholderImage = nil;
if (size.width == -1 && size.height == -1)
return;
if (imageScaling === CPScaleProportionally)
switch (imageScaling)
{
// The max size it can be is size.width x size.height, so only
// only proportion otherwise.
if (width >= size.width && height >= size.height)
{
width = size.width;
height = size.height;
}
else
{
case CPImageScaleProportionallyDown:
if (width >= size.width && height >= size.height)
{
width = size.width;
height = size.height;
break;
}
// intentionally fall through to the next case
case CPImageScaleProportionallyUpOrDown:
var imageRatio = size.width / size.height,
viewRatio = width / height;
@@ -328,26 +336,19 @@ var CPImageViewEmptyPlaceholderImage = nil;
width = height * imageRatio;
else
height = width / imageRatio;
}
break;
#if PLATFORM(DOM)
case CPImageScaleAxesIndependently:
case CPImageScaleNone:
width = size.width;
height = size.height;
break;
}
#if PLATFORM(DOM)
_DOMImageElement.width = ROUND(width);
_DOMImageElement.height = ROUND(height);
#endif
}
else
{
width = size.width;
height = size.height;
}
if (imageScaling == CPScaleNone)
{
#if PLATFORM(DOM)
_DOMImageElement.width = ROUND(size.width);
_DOMImageElement.height = ROUND(size.height);
#endif
}
#endif
var x,
y;
@@ -449,6 +450,39 @@ var CPImageViewEmptyPlaceholderImage = nil;
@end
@implementation CPImageViewValueBinder : CPBinder
{
}
- (void)_updatePlaceholdersWithOptions:(CPDictionary)options
{
[self _setPlaceholder:nil forMarker:CPMultipleValuesMarker isDefault:YES];
[self _setPlaceholder:nil forMarker:CPNoSelectionMarker isDefault:YES];
[self _setPlaceholder:nil forMarker:CPNotApplicableMarker isDefault:YES];
[self _setPlaceholder:nil forMarker:CPNullMarker isDefault:YES];
}
- (void)setPlaceholderValue:(id)aValue withMarker:(CPString)aMarker forBinding:(CPString)aBinding
{
[_source setImage:nil];
}
- (void)setValue:(id)aValue forBinding:(CPString)aBinding
{
var image;
if (aBinding === CPDataBinding)
image = [[CPImage alloc] initWithData:aValue];
else if (aBinding === CPValueURLBinding || aBinding === CPValuePathBinding)
image = [[CPImage alloc] initWithContentsOfFile:aValue];
else if (aBinding === CPValueBinding)
image = aValue;
[_source setImage:image];
}
@end
var CPImageViewImageKey = @"CPImageViewImageKey",
CPImageViewImageScalingKey = @"CPImageViewImageScalingKey",
CPImageViewImageAlignmentKey = @"CPImageViewImageAlignmentKey",
@@ -475,6 +509,9 @@ var CPImageViewImageKey = @"CPImageViewImageKey",
_DOMImageElement.setAttribute("draggable", "true");
_DOMImageElement.style["-khtml-user-drag"] = "element";
}
if (typeof(appkit_tag_dom_elements) !== "undefined" && !!appkit_tag_dom_elements)
_DOMImageElement.setAttribute("data-cappuccino-view", [self className]);
#endif
self = [super initWithCoder:aCoder];
@@ -488,7 +525,7 @@ var CPImageViewImageKey = @"CPImageViewImageKey",
[self setHasShadow:[aCoder decodeBoolForKey:CPImageViewHasShadowKey]];
[self setImageAlignment:[aCoder decodeIntForKey:CPImageViewImageAlignmentKey]];
if ([aCoder decodeBoolForKey:CPImageViewIsEditableKey] || NO)
if ([aCoder decodeBoolForKey:CPImageViewIsEditableKey])
[self setEditable:YES];
[self setNeedsLayout];
+2 -1
View File
@@ -28,6 +28,7 @@
CPStandardKeyBindings = {
@"@.": @"cancelOperation:",
@"@a": @"selectAll:",
@"^a": @"moveToBeginningOfParagraph:",
@"^$a": @"moveToBeginningOfParagraphAndModifySelection:",
@"^b": @"moveBackward:",
@@ -152,7 +153,7 @@ var CPKeyBindingCache = {};
+ (void)initialize
{
if ([self class] !== CPKeyBinding)
if (self !== [CPKeyBinding class])
return;
[self createKeyBindingsFromJSObject:CPStandardKeyBindings];
+77 -17
View File
@@ -131,7 +131,7 @@ var CPBindingOperationAnd = 0,
if (options)
[_info setObject:options forKey:CPOptionsKey];
[self _updatePlaceholdersWithOptions:options];
[self _updatePlaceholdersWithOptions:options forBinding:aName];
[aDestination addObserver:self forKeyPath:aKeyPath options:CPKeyValueObservingOptionNew context:aBinding];
@@ -149,15 +149,40 @@ var CPBindingOperationAnd = 0,
return self;
}
- (void)setValueFor:(CPString)aBinding
- (void)setValueFor:(CPString)theBinding
{
var destination = [_info objectForKey:CPObservedObjectKey],
keyPath = [_info objectForKey:CPObservedKeyPathKey],
options = [_info objectForKey:CPOptionsKey],
newValue = [destination valueForKeyPath:keyPath];
newValue = [destination valueForKeyPath:keyPath],
isPlaceholder = CPIsControllerMarker(newValue);
newValue = [self transformValue:newValue withOptions:options];
[_source setValue:newValue forKey:aBinding];
if (isPlaceholder)
{
if (newValue === CPNotApplicableMarker && [options objectForKey:CPRaisesForNotApplicableKeysBindingOption])
{
[CPException raise:CPGenericException
reason:@"Cannot transform non-applicable key on: " + _source + " key path: " + keyPath + " value: " + newValue];
}
var value = [self _placeholderForMarker:newValue];
[self setPlaceholderValue:value withMarker:newValue forBinding:theBinding];
}
else
{
var value = [self transformValue:newValue withOptions:options];
[self setValue:value forBinding:theBinding];
}
}
- (void)setPlaceholderValue:(id)aValue withMarker:(CPString)aMarker forBinding:(CPString)aBinding
{
[_source setValue:aValue forKey:aBinding];
}
- (void)setValue:(id)aValue forBinding:(CPString)aBinding
{
[_source setValue:aValue forKey:aBinding];
}
- (void)reverseSetValueFor:(CPString)aBinding
@@ -165,10 +190,18 @@ var CPBindingOperationAnd = 0,
var destination = [_info objectForKey:CPObservedObjectKey],
keyPath = [_info objectForKey:CPObservedKeyPathKey],
options = [_info objectForKey:CPOptionsKey],
newValue = [_source valueForKeyPath:aBinding];
newValue = [self valueForBinding:aBinding];
newValue = [self reverseTransformValue:newValue withOptions:options];
[self suppressSpecificNotificationFromObject:destination keyPath:keyPath];
[destination setValue:newValue forKeyPath:keyPath];
[self unsuppressSpecificNotificationFromObject:destination keyPath:keyPath];
}
- (id)valueForBinding:(CPString)aBinding
{
return [_source valueForKeyPath:aBinding];
}
- (void)observeValueForKeyPath:(CPString)aKeyPath ofObject:(id)anObject change:(CPDictionary)changes context:(id)context
@@ -288,6 +321,11 @@ var CPBindingOperationAnd = 0,
}
}
- (void)_updatePlaceholdersWithOptions:(CPDictionary)options forBinding:(CPString)aBinding
{
[self _updatePlaceholdersWithOptions:options];
}
- (void)_placeholderForMarker:aMarker
{
var placeholder = _placeholderForMarker[aMarker];
@@ -443,7 +481,7 @@ var CPBindingOperationAnd = 0,
@end
var resolveMultipleValues = function resolveMultipleValues(/*CPString*/key, /*CPDictionary*/bindings, /*GSBindingOperationKind*/operation)
var resolveMultipleValues = function(/*CPString*/key, /*CPDictionary*/bindings, /*GSBindingOperationKind*/operation)
{
var bindingName = key,
theBinding,
@@ -467,7 +505,7 @@ var resolveMultipleValues = function resolveMultipleValues(/*CPString*/key, /*CP
return !operation;
};
var invokeAction = function invokeAction(/*CPString*/targetKey, /*CPString*/argumentKey, /*CPDictionary*/bindings)
var invokeAction = function(/*CPString*/targetKey, /*CPString*/argumentKey, /*CPDictionary*/bindings)
{
var theBinding = [bindings objectForKey:targetKey],
infoDictionary = theBinding._info,
@@ -518,15 +556,37 @@ CPNotApplicableMarker = @"CPNotApplicableMarker";
CPNullMarker = @"CPNullMarker";
// Binding name constants
CPAlignmentBinding = @"alignment";
CPEditableBinding = @"editable";
CPEnabledBinding = @"enabled";
CPFontBinding = @"font";
CPHiddenBinding = @"hidden";
CPSelectedIndexBinding = @"selectedIndex";
CPTextColorBinding = @"textColor";
CPToolTipBinding = @"toolTip";
CPValueBinding = @"value";
CPAlignmentBinding = @"alignment";
CPContentArrayBinding = @"contentArray";
CPContentBinding = @"content";
CPContentObjectBinding = @"contentObject";
CPContentObjectsBinding = @"contentObjects";
CPContentValuesBinding = @"contentValues";
CPEditableBinding = @"editable";
CPEnabledBinding = @"enabled";
CPFontBinding = @"font";
CPFontNameBinding = @"fontName";
CPFontBoldBinding = @"fontBold";
CPHiddenBinding = @"hidden";
CPFilterPredicateBinding = @"filterPredicate";
CPMaxValueBinding = @"maxValue";
CPMinValueBinding = @"minValue";
CPPredicateBinding = @"predicate";
CPSelectedIndexBinding = @"selectedIndex";
CPSelectedLabelBinding = @"selectedLabel";
CPSelectedObjectBinding = @"selectedObject";
CPSelectedObjectsBinding = @"selectedObjects";
CPSelectedTagBinding = @"selectedTag";
CPSelectedValueBinding = @"selectedValue";
CPSelectedValuesBinding = @"selectedValues";
CPSelectionIndexesBinding = @"selectionIndexes";
CPTextColorBinding = @"textColor";
CPTitleBinding = @"title";
CPToolTipBinding = @"toolTip";
CPValueBinding = @"value";
CPValueURLBinding = @"valueURL";
CPValuePathBinding = @"valuePath";
CPDataBinding = @"data";
//Binding options constants
CPAllowsEditingMultipleValuesSelectionBindingOption = @"CPAllowsEditingMultipleValuesSelection";
+4 -1
View File
@@ -64,6 +64,9 @@ var _CPLevelIndicatorBezelColor = nil,
+ (void)initialize
{
if (self !== [CPLevelIndicator class])
return;
var bundle = [CPBundle bundleForClass:CPLevelIndicator];
_CPLevelIndicatorBezelColor = [CPColor colorWithPatternImage:[[CPThreePartImage alloc] initWithImageSlices:
@@ -253,7 +256,7 @@ var _CPLevelIndicatorBezelColor = nil,
var location = [self convertPoint:[anEvent locationInWindow] fromView:nil],
bounds = [self bounds],
oldValue = [self doubleValue];
oldValue = [self doubleValue],
newValue = oldValue;
// Moving the mouse outside of the widget to the left sets it
+3 -4
View File
@@ -80,7 +80,7 @@ var _CPMenuBarVisible = NO,
+ (void)initialize
{
if (self !== CPMenu)
if (self !== [CPMenu class])
return;
[[self class] setMenuBarAttributes:[CPDictionary dictionary]];
@@ -806,7 +806,7 @@ var _CPMenuBarVisible = NO,
[aMenu _menuWillOpen];
if (!aFont)
aFont = [CPFont systemFontOfSize:12.0];
aFont = [CPFont systemFontOfSize:[CPFont systemFontSize]];
var theWindow = [aView window],
menuWindow = [_CPMenuWindow menuWindowWithMenu:aMenu font:aFont];
@@ -976,8 +976,7 @@ var _CPMenuBarVisible = NO,
for (; index < count; ++index)
{
var item = _items[index],
modifierMask = [item keyEquivalentModifierMask];
var item = _items[index];
if ([anEvent _triggersKeyEquivalent:[item keyEquivalent] withModifierMask:[item keyEquivalentModifierMask]])
{
+4 -4
View File
@@ -34,12 +34,12 @@ var _CPMenuBarWindowBackgroundColor = nil,
+ (void)initialize
{
if (self != [_CPMenuBarWindow class])
if (self !== [_CPMenuBarWindow class])
return;
var bundle = [CPBundle bundleForClass:self];
_CPMenuBarWindowFont = [CPFont boldSystemFontOfSize:12.0];
_CPMenuBarWindowFont = [CPFont boldSystemFontOfSize:[CPFont systemFontSize]];
}
+ (CPFont)font
@@ -74,7 +74,7 @@ var _CPMenuBarWindowBackgroundColor = nil,
_titleField = [[CPTextField alloc] initWithFrame:CGRectMakeZero()];
[_titleField setFont:[CPFont boldSystemFontOfSize:13.0]];
[_titleField setFont:[CPFont boldSystemFontOfSize:[CPFont systemFontSize] + 1]];
[_titleField setAlignment:CPCenterTextAlignment];
[_titleField setTextShadowOffset:CGSizeMake(0, 1)];
@@ -335,7 +335,7 @@ var _CPMenuBarWindowBackgroundColor = nil,
- (CPFont)font
{
[CPFont systemFontOfSize:12.0];
[CPFont systemFontOfSize:[CPFont systemFontSize]];
}
- (void)tile
+58 -28
View File
@@ -5,13 +5,13 @@ _CPMenuManagerScrollingStateUp = -1;
_CPMenuManagerScrollingStateDown = 1;
_CPMenuManagerScrollingStateNone = 0;
var STICKY_TIME_INTERVAL = 500,
var STICKY_TIME_INTERVAL = 0.5,
SharedMenuManager = nil;
@implementation _CPMenuManager: CPObject
{
CPTimeInterval _startTime;
BOOL _hasMouseGoneUpAfterStartedTracking;
BOOL _mouseWasDragged;
int _scrollingState;
CGPoint _lastGlobalLocation;
@@ -66,7 +66,7 @@ var STICKY_TIME_INTERVAL = 500,
CPApp._activeMenu = menu;
_startTime = [anEvent timestamp];//new Date();
_startTime = [anEvent timestamp];
_scrollingState = _CPMenuManagerScrollingStateNone;
_constraintRect = aRect;
@@ -91,7 +91,7 @@ var STICKY_TIME_INTERVAL = 500,
return [self trackMenuBarButtonEvent:anEvent];
}
_hasMouseGoneUpAfterStartedTracking = NO;
_mouseWasDragged = NO;
[self trackEvent:anEvent];
}
@@ -127,7 +127,7 @@ var STICKY_TIME_INTERVAL = 500,
if (_keyBuffer)
{
if (([CPDate date] - _startTime) > (STICKY_TIME_INTERVAL + [activeMenu numberOfItems] / 2))
if (([anEvent timestamp] - _startTime) > (STICKY_TIME_INTERVAL + [activeMenu numberOfItems] / 2))
[self selectNextItemBeginningWith:_keyBuffer inMenu:menu clearBuffer:YES];
if (type === CPPeriodic)
@@ -137,10 +137,7 @@ var STICKY_TIME_INTERVAL = 500,
// Periodic events don't have a valid location.
var globalLocation = type === CPPeriodic ? _lastGlobalLocation : [anEvent globalLocation];
// Remember this for the next periodic event.
_lastGlobalLocation = globalLocation;
if (!_lastGlobalLocation)
if (!globalLocation)
return;
// Find which menu window the mouse is currently on top of
@@ -152,6 +149,14 @@ var STICKY_TIME_INTERVAL = 500,
activeItemIndex = activeMenuContainer ? [activeMenuContainer itemIndexAtPoint:menuLocation] : CPNotFound,
activeItem = activeItemIndex !== CPNotFound ? [activeMenu itemAtIndex:activeItemIndex] : nil;
// unhighlight when mouse is moved off the menu
if (_lastGlobalLocation && CGRectContainsPoint([activeMenuContainer globalFrame], _lastGlobalLocation)
&& !CGRectContainsPoint([activeMenuContainer globalFrame], globalLocation))
[activeMenu _highlightItemAtIndex:CPNotFound];
// Remember this for the next periodic event.
_lastGlobalLocation = globalLocation;
// If the item isn't enabled its as if we clicked on nothing.
if (![activeItem isEnabled] || [activeItem _isMenuBarButton])
{
@@ -161,7 +166,7 @@ var STICKY_TIME_INTERVAL = 500,
var mouseOverMenuView = [activeItem view];
if (type === CPScrollWheel)
if (type === CPScrollWheel && ![activeMenuContainer isMenuBar])
[activeMenuContainer scrollByDelta:[anEvent deltaY]];
if (type === CPPeriodic)
@@ -189,7 +194,7 @@ var STICKY_TIME_INTERVAL = 500,
var menuContainerWindow = activeMenuContainer;
if (![menuContainerWindow isKindOfClass:[CPWindow class]])
if (![menuContainerWindow isKindOfClass:CPWindow])
menuContainerWindow = [menuContainerWindow window];
[menuContainerWindow
@@ -211,10 +216,14 @@ var STICKY_TIME_INTERVAL = 500,
_lastMouseOverMenuView = nil;
}
[activeMenu _highlightItemAtIndex:activeItemIndex];
if (activeItemIndex != CPNotFound)
[activeMenu _highlightItemAtIndex:activeItemIndex];
if (type === CPMouseMoved || type === CPLeftMouseDragged || type === CPLeftMouseDown || type === CPPeriodic)
{
if (type === CPLeftMouseDragged)
_mouseWasDragged = YES;
var oldScrollingState = _scrollingState;
_scrollingState = [activeMenuContainer scrollingStateForPoint:globalLocation];
@@ -229,17 +238,35 @@ var STICKY_TIME_INTERVAL = 500,
}
else if (type === CPLeftMouseUp || type === CPRightMouseUp)
{
if (_hasMouseGoneUpAfterStartedTracking)
{
// Don't close the menu if the current item has a submenu
// and did not override it's default action
if ([activeItem action] === @selector(submenuAction:))
return;
/*
There are a few possibilites:
[trackingMenu cancelTracking];
1. The user clicks and releases without dragging within the sticky time.
This is considered a regular mouse click and not a drag. In this case
we allow the user to track the menu by moving the mouse. The next
mouse up will end tracking.
2. The user clicks and releases without dragging after the sticky time.
This is considered a drag and release and tracking ends.
3. The user clicks, drags and then releases. Tracking ends.
*/
if (_mouseWasDragged || ([anEvent timestamp] - _startTime > STICKY_TIME_INTERVAL))
{
/*
Close the menu if:
1. The mouse was dragged.
2. The mouse is released in the menubar.
3. The current item has a submenu with a custom action.
*/
if (_mouseWasDragged ||
[activeMenuContainer isMenuBar] ||
[activeItem action] !== @selector(submenuAction:))
{
[trackingMenu cancelTracking];
}
}
else
_hasMouseGoneUpAfterStartedTracking = YES;
}
}
@@ -252,7 +279,7 @@ var STICKY_TIME_INTERVAL = 500,
}
// If the item has a submenu, show it.
if ([activeItem hasSubmenu])// && [activeItem action] === @selector(submenuAction:))
if ([activeItem hasSubmenu]) // && [activeItem action] === @selector(submenuAction:))
{
var activeItemRect = [activeMenuContainer rectForItemAtIndex:activeItemIndex],
newMenuOrigin;
@@ -406,7 +433,7 @@ var STICKY_TIME_INTERVAL = 500,
break;
// If this menu is already being shown, unhighlight and return.
if (menu === newMenu)//&& [menu supermenu] === baseMenu)
if (menu === newMenu) //&& [menu supermenu] === baseMenu)
return [newMenu _highlightItemAtIndex:CPNotFound];
[menuContainer orderOut:self];
@@ -452,7 +479,7 @@ var STICKY_TIME_INTERVAL = 500,
var iter = [selectorNames objectEnumerator],
obj;
while (obj = [iter nextObject])
while ((obj = [iter nextObject]) !== nil)
{
var aSelector = CPSelectorFromString(obj);
@@ -464,7 +491,7 @@ var STICKY_TIME_INTERVAL = 500,
{
if (!_keyBuffer)
{
_startTime = [CPDate date];
_startTime = [anEvent timestamp];
_keyBuffer = character;
[CPEvent stopPeriodicEvents];
@@ -483,7 +510,7 @@ var STICKY_TIME_INTERVAL = 500,
var iter = [[menu itemArray] objectEnumerator],
obj;
while (obj = [iter nextObject])
while ((obj = [iter nextObject]) !== nil)
{
if ([obj isHidden] || ![obj isEnabled])
continue;
@@ -501,7 +528,7 @@ var STICKY_TIME_INTERVAL = 500,
_keyBuffer = Nil;
}
else
_startTime = [CPDate date];
_startTime = [CPEvent currentTimestamp];
}
- (void)scrollToBeginningOfDocument:(CPMenu)menu
@@ -645,8 +672,11 @@ var STICKY_TIME_INTERVAL = 500,
var index = menu._highlightedIndex - 1;
if (index < 0)
{
if (index != CPNotFound)
[menu _highlightItemAtIndex:[menu numberOfItems] - 1];
return;
}
[menu _highlightItemAtIndex:index];
var item = [menu highlightedItem];
+1 -3
View File
@@ -65,7 +65,7 @@ var STICKY_TIME_INTERVAL = 500,
+ (void)initialize
{
if (self != [_CPMenuWindow class])
if (self !== [_CPMenuWindow class])
return;
var bundle = [CPBundle bundleForClass:self];
@@ -110,8 +110,6 @@ var STICKY_TIME_INTERVAL = 500,
[_moreBelowView setFrameSize:[_CPMenuWindowMoreBelowImage size]];
[contentView addSubview:_moreBelowView];
[self setShadowStyle:CPWindowShadowStyleMenu];
}
return self;
+12 -13
View File
@@ -281,7 +281,7 @@ var CPMenuItemStringRepresentationDictionary = [CPDictionary dictionary];
*/
- (void)setFont:(CPFont)aFont
{
if (_font == aFont)
if ([_font isEqual:aFont])
return;
_font = aFont;
@@ -932,34 +932,33 @@ var CPMenuItemIsSeparatorKey = @"CPMenuItemIsSeparatorKey",
_action = [aCoder decodeObjectForKey:CPMenuItemActionKey];
_isEnabled = DEFAULT_VALUE(CPMenuItemIsEnabledKey, YES);
_isHidden = DEFAULT_VALUE(CPMenuItemIsHiddenKey, NO);
_tag = DEFAULT_VALUE(CPMenuItemTagKey, 0);
_state = DEFAULT_VALUE(CPMenuItemStateKey, CPOffState);
_isHidden = [aCoder decodeBoolForKey:CPMenuItemIsHiddenKey];
_tag = [aCoder decodeIntForKey:CPMenuItemTagKey];
_state = [aCoder decodeIntForKey:CPMenuItemStateKey];
_image = DEFAULT_VALUE(CPMenuItemImageKey, nil);
_alternateImage = DEFAULT_VALUE(CPMenuItemAlternateImageKey, nil);
_image = [aCoder decodeObjectForKey:CPMenuItemImageKey];
_alternateImage = [aCoder decodeObjectForKey:CPMenuItemAlternateImageKey];
// CPImage _onStateImage;
// CPImage _offStateImage;
// CPImage _mixedStateImage;
// This order matters because setSubmenu: needs _menu to be around.
_menu = DEFAULT_VALUE(CPMenuItemMenuKey, nil);
[self setSubmenu:DEFAULT_VALUE(CPMenuItemSubmenuKey, nil)];
_menu = [aCoder decodeObjectForKey:CPMenuItemMenuKey];
[self setSubmenu:[aCoder decodeObjectForKey:CPMenuItemSubmenuKey]];
_keyEquivalent = [aCoder decodeObjectForKey:CPMenuItemKeyEquivalentKey] || @"";
_keyEquivalentModifierMask = [aCoder decodeObjectForKey:CPMenuItemKeyEquivalentModifierMaskKey] || 0;
_keyEquivalentModifierMask = [aCoder decodeIntForKey:CPMenuItemKeyEquivalentModifierMaskKey];
// int _mnemonicLocation;
// BOOL _isAlternate;
// Default is 0.
[self setIndentationLevel:[aCoder decodeIntForKey:CPMenuItemIndentationLevelKey] || 0];
[self setIndentationLevel:[aCoder decodeIntForKey:CPMenuItemIndentationLevelKey]];
// CPString _toolTip;
_representedObject = DEFAULT_VALUE(CPMenuItemRepresentedObjectKey, nil);
_view = DEFAULT_VALUE(CPMenuItemViewKey, nil);
_representedObject = [aCoder decodeObjectForKey:CPMenuItemRepresentedObjectKey];
_view = [aCoder decodeObjectForKey:CPMenuItemViewKey];
}
return self;
+1 -3
View File
@@ -148,10 +148,8 @@ var SelectionColor = nil,
[_submenuIndicatorView setFrame:submenuViewFrame];
}
_minSize = CGSizeMake(x + HORIZONTAL_MARGIN, height);
[self setAutoresizesSubviews:NO];
[self setFrameSize:_minSize];
[self setFrameSize:CGSizeMake(x + HORIZONTAL_MARGIN, height)];
[self setAutoresizesSubviews:YES];
}
+14 -14
View File
@@ -6,14 +6,14 @@ var LEFT_MARGIN = 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 = [];
@@ -43,9 +43,9 @@ var SUBMENU_INDICATOR_COLOR = nil,
_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;
@@ -74,7 +74,7 @@ var SUBMENU_INDICATOR_COLOR = nil,
{
_stateView = [[CPImageView alloc] initWithFrame:CGRectMake(0.0, 0.0, 0.0, 0.0)];
[_stateView setImageScaling:CPScaleNone];
[_stateView setImageScaling:CPImageScaleNone];
[self addSubview:_stateView];
@@ -175,7 +175,7 @@ var SUBMENU_INDICATOR_COLOR = nil,
[_keyEquivalentView setTextShadowOffset:CGSizeMake(0, 1)];
[_keyEquivalentView setFrameOrigin:CGPointMake(x, VERTICAL_MARGIN)];
[_keyEquivalentView sizeToFit];
var keyEquivalentViewFrame = [_keyEquivalentView frame];
keyEquivalentViewFrame.origin.x = x;
@@ -215,7 +215,7 @@ var SUBMENU_INDICATOR_COLOR = nil,
keyEquivalentViewFrame.origin.y = FLOOR((height - CGRectGetHeight(keyEquivalentViewFrame)) / 2.0);
[_keyEquivalentView setFrame:keyEquivalentViewFrame];
}
if (hasSubmenu)
{
submenuViewFrame.origin.y = FLOOR((height - CGRectGetHeight(submenuViewFrame)) / 2.0);
@@ -223,7 +223,7 @@ var SUBMENU_INDICATOR_COLOR = nil,
}
_minSize = CGSizeMake(x + RIGHT_MARGIN, height);
[self setAutoresizesSubviews:NO];
[self setFrameSize:_minSize];
[self setAutoresizesSubviews:YES];
@@ -233,7 +233,7 @@ var SUBMENU_INDICATOR_COLOR = nil,
{
// FIXME: This should probably be even throw.
if (![_menuItem isEnabled])
return;
return;
if (shouldHighlight)
{
@@ -259,7 +259,7 @@ var SUBMENU_INDICATOR_COLOR = nil,
[_imageAndTextView setTextShadowColor:[self textShadowColor]];
[_keyEquivalentView setTextShadowColor:[self textShadowColor]];
}
if ([[_menuItem menu] showsStateColumn])
{
if (shouldHighlight)
@@ -290,15 +290,15 @@ var SUBMENU_INDICATOR_COLOR = nil,
{
var context = [[CPGraphicsContext currentContext] graphicsPort],
bounds = [self bounds];
CGContextBeginPath(context);
CGContextMoveToPoint(context, CGRectGetMinX(bounds), CGRectGetMinY(bounds));
CGContextAddLineToPoint(context, CGRectGetMaxX(bounds), CGRectGetMidY(bounds));
CGContextAddLineToPoint(context, CGRectGetMinX(bounds), CGRectGetMaxY(bounds));
CGContextClosePath(context);
CGContextSetFillColor(context, _color);
CGContextFillPath(context);
}
+2 -2
View File
@@ -40,7 +40,7 @@ var _CPMenuItemSelectionColor = nil,
+ (void)initialize
{
if (self != [_CPMenuItemView class])
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];
@@ -176,7 +176,7 @@ var _CPMenuItemSelectionColor = nil,
- (void)setFont:(CPFont)aFont
{
if (_font === aFont)
if ([_font isEqual:aFont])
return;
_font = aFont;
+8 -4
View File
@@ -51,6 +51,9 @@
+ (id)initialize
{
if (self !== [CPObjectController class])
return;
[self exposeBinding:@"editable"];
[self exposeBinding:@"contentObject"];
}
@@ -371,7 +374,7 @@ var CPObjectControllerContentKey = @"CPObjectControllerCo
[self setObjectClass:objectClass || [CPMutableDictionary class]];
[self setEditable:[aCoder decodeBoolForKey:CPObjectControllerIsEditableKey]];
[self setAutomaticallyPreparesContent:[aCoder decodeBoolForKey:CPObjectControllerAutomaticallyPreparesContentKey] || NO];
[self setAutomaticallyPreparesContent:[aCoder decodeBoolForKey:CPObjectControllerAutomaticallyPreparesContentKey]];
[self setContent:[aCoder decodeObjectForKey:CPObjectControllerContentKey]];
_observedKeys = [[CPCountedSet alloc] init];
@@ -579,6 +582,8 @@ var CPObjectControllerContentKey = @"CPObjectControllerCo
- (void)removeObjectAtIndex:(unsigned)anIndex
{
var currentObject = [self objectAtIndex:anIndex];
for (var i = 0, count = [_observationProxies count]; i < count; i++)
{
var proxy = [_observationProxies objectAtIndex:i],
@@ -588,7 +593,7 @@ var CPObjectControllerContentKey = @"CPObjectControllerCo
if (operator)
[self willChangeValueForKey:keyPath];
[anObject removeObserver:proxy forKeyPath:keyPath];
[currentObject removeObserver:proxy forKeyPath:keyPath];
if (operator)
[self didChangeValueForKey:keyPath];
@@ -777,8 +782,7 @@ var CPObjectControllerContentKey = @"CPObjectControllerCo
[proxy setNotifyObject:YES];
[_observationProxies addObject:proxy];
// We keep are reference to the observed objects
// because the removeObserver: will be called after the selection changes
// We keep a reference to the observed objects because removeObserver: will be called after the selection changes.
var observedObjects = [_controller selectedObjects];
_observedObjectsByKeyPath[aKeyPath] = observedObjects;
[observedObjects addObserver:proxy forKeyPath:aKeyPath options:options context:context];
+8 -8
View File
@@ -151,7 +151,6 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
_retargedChildIndex = nil;
_shouldRetargetChildIndex = NO;
_startHoverTime = nil;
[self setIndentationPerLevel:16.0];
[self setIndentationMarkerFollowsDataView:YES];
@@ -377,9 +376,8 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
var previousRowCount = [self numberOfRows];
itemInfo.isExpanded = YES;
// XXX Shouldn't the items reload before the notification is sent?
[self _noteItemDidExpand:anItem];
[self reloadItem:anItem reloadChildren:YES];
[self _noteItemDidExpand:anItem];
// Shift selection indexes below so that the same items remain selected.
var rowCountDelta = [self numberOfRows] - previousRowCount;
@@ -470,9 +468,8 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
}
itemInfo.isExpanded = NO;
// XXX Shouldn't the items reload before the notification is sent?
[self _noteItemDidCollapse:anItem];
[self reloadItem:anItem reloadChildren:YES];
[self _noteItemDidCollapse:anItem];
// Send selection notifications only after the items have loaded so that
// the new selection is consistent with the actual rows for any observers.
@@ -712,7 +709,8 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
return _CGRectMakeZero();
var dataViewFrame = [self _frameOfOutlineDataViewAtRow:aRow],
frame = _CGRectMake(_CGRectGetMinX(dataViewFrame) - 10, _CGRectGetMinY(dataViewFrame), 10, _CGRectGetHeight(dataViewFrame));
disclosureWidth = _CGRectGetWidth([_disclosureControlPrototype frame]),
frame = _CGRectMake(_CGRectGetMinX(dataViewFrame) - disclosureWidth, _CGRectGetMinY(dataViewFrame), disclosureWidth, _CGRectGetHeight(dataViewFrame));
return frame;
}
@@ -1365,7 +1363,7 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
[self collapseItem:item];
else
[self expandItem:item];
[self expandItem:item expandChildren:([[CPApp currentEvent] modifierFlags] & CPAlternateKeyMask)];
}
/*!
@@ -1891,7 +1889,9 @@ var _loadItemInfoForItem = function(/*CPOutlineView*/ anOutlineView, /*id*/ anIt
return [_outlineView._outlineViewDelegate outlineView:_outlineView menuForTableColumn:aTableColumn item:item]
}
return nil;
// We reimplement CPView menuForEvent: because we can't call it directly. CPTableView implements menuForEvent:
// to call this delegate method.
return [_outlineView menu] || [[_outlineView class] defaultMenu];
}
@end
+5
View File
@@ -114,4 +114,9 @@ CPDocModalWindowMask = 1 << 6;
return NO;
}
- (BOOL)canBecomeKeyWindow
{
return YES;
}
@end
+1 -1
View File
@@ -73,7 +73,7 @@ var CPPasteboards = nil,
*/
+ (void)initialize
{
if (self != [CPPasteboard class])
if (self !== [CPPasteboard class])
return;
[self setVersion:1.0];
+289 -26
View File
@@ -20,12 +20,13 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import <Foundation/CPGeometry.j>
@import "CPButton.j"
@import "CPGeometry.j"
@import "CPKeyValueBinding.j"
@import "CPMenu.j"
@import "CPMenuItem.j"
var VISIBLE_MARGIN = 7.0;
CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
@@ -246,22 +247,6 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
return _selectedIndex;
}
/*!
@ignore
*/
- (int)_selectedTag
{
return [[self selectedItem] tag];
}
/*!
@ignore
*/
- (void)_setSelectedTag:(int)aTag
{
[self selectItemWithTag:aTag];
}
// Setting the Current Selection
/*!
Selects the specified menu item.
@@ -587,10 +572,18 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
if ([indexes containsIndex:0] && [self pullsDown])
[self _firstItemDidChange];
// See whether the index has changed, despite the actual item not changing.
while ((index = [indexes indexGreaterThanIndex:index]) !== CPNotFound &&
index <= indexOfSelectedItem)
--indexOfSelectedItem;
if (![self pullsDown] && [indexes containsIndex:indexOfSelectedItem])
{
// If the selected item is removed the first item becomes selected.
indexOfSelectedItem = 0;
}
else
{
// See whether the index has changed, despite the actual item not changing.
while ((index = [indexes indexGreaterThanIndex:index]) !== CPNotFound &&
index <= indexOfSelectedItem)
--indexOfSelectedItem;
}
[self selectItemAtIndex:indexOfSelectedItem];
}
@@ -778,16 +771,286 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
- (void)_reverseSetBinding
{
var binderClass = [[self class] _binderClassForBinding:CPSelectedIndexBinding],
theBinding = [binderClass getBinding:CPSelectedIndexBinding forObject:self];
[theBinding reverseSetValueFor:@"objectValue"];
[_CPPopUpButtonSelectionBinder reverseSetValueForObject:self];
[super _reverseSetBinding];
}
@end
@implementation CPPopUpButton (BindingSupport)
+ (Class)_binderClassForBinding:(CPString)aBinding
{
if (aBinding == CPSelectedIndexBinding ||
aBinding == CPSelectedObjectBinding ||
aBinding == CPSelectedTagBinding ||
aBinding == CPSelectedValueBinding ||
aBinding == CPContentBinding ||
aBinding == CPContentObjectsBinding ||
aBinding == CPContentValuesBinding)
{
var capitalizedBinding = aBinding.charAt(0).toUpperCase() + aBinding.substr(1);
return [CPClassFromString(@"_CPPopUpButton" + capitalizedBinding + "Binder") class];
}
return [super _binderClassForBinding:aBinding];
}
@end
@implementation _CPPopUpButtonContentBinder : CPBinder
{
}
- (CPInteger)_getInsertNullOffset
{
var options = [_info objectForKey:CPOptionsKey];
return [options objectForKey:CPInsertsNullPlaceholderBindingOption] ? 1 : 0;
}
- (CPString)_getNullPlaceholder
{
var options = [_info objectForKey:CPOptionsKey],
placeholder = [options objectForKey:CPNullPlaceholderBindingOption] || @"";
if (placeholder === [CPNull null])
placeholder = @"";
return placeholder;
}
- (id)transformValue:(CPArray)contentArray withOptions:(CPDictionary)options
{
// Desactivate the full array transformation forced by super because we don't want this. We want individual transformations (see below).
return contentArray;
}
- (void)setValue:(CPArray)contentArray forBinding:(CPString)aBinding
{
[self _setContent:contentArray];
[self _setContentValuesIfNeeded:contentArray];
}
- (void)valueForBinding:(CPString)aBinding
{
return [self _content];
}
- (void)_setContent:(CPArray)aValue
{
var count = [aValue count],
options = [_info objectForKey:CPOptionsKey],
offset = [self _getInsertNullOffset];
if (count + offset != [_source numberOfItems])
{
[_source removeAllItems];
if (offset)
[_source addItemWithTitle:[self _getNullPlaceholder]];
for (var i = 0; i < count; i++)
{
var item = [[CPMenuItem alloc] initWithTitle:@"" action:NULL keyEquivalent:nil];
[self _setValue:[aValue objectAtIndex:i] forItem:item withOptions:options];
[_source addItem:item];
}
}
else
{
for (var i = 0; i < count; i++)
{
[self _setValue:[aValue objectAtIndex:i] forItem:[_source itemAtIndex:i + offset] withOptions:options];
}
}
}
- (void)_setContentValuesIfNeeded:(CPArray)values
{
var offset = [self _getInsertNullOffset];
if (![_source infoForBinding:CPContentValuesBinding])
{
if (offset)
[[_source itemAtIndex:0] setTitle:[self _getNullPlaceholder]];
var count = [values count];
for (var i = 0; i < count; i++)
[[_source itemAtIndex:i + offset] setTitle:[[values objectAtIndex:i] description]];
}
}
- (void)_setValue:(id)aValue forItem:(CPMenuItem)aMenuItem withOptions:(CPDictionary)options
{
var value = [self _transformValue:aValue withOptions:options];
[aMenuItem setRepresentedObject:value];
}
- (id)_transformValue:(id)aValue withOptions:(CPDictionary)options
{
return [super transformValue:aValue withOptions:options];
}
- (CPArray)_content
{
return [_source valueForKeyPath:@"itemArray.representedObject"];
}
@end
@implementation _CPPopUpButtonContentValuesBinder : _CPPopUpButtonContentBinder
{
}
- (void)setValue:(id)aValue forBinding:(CPString)aBinding
{
[super _setContent:aValue];
}
- (void)_setValue:(id)aValue forItem:(CPMenuItem)aMenuItem withOptions:(CPDictionary)options
{
if (aValue === [CPNull null])
aValue = nil;
var value = [self _transformValue:aValue withOptions:options];
[aMenuItem setTitle:value];
}
- (CPArray)_content
{
return [_source valueForKeyPath:@"itemArray.title"];
}
@end
var binderForObject = {};
@implementation _CPPopUpButtonSelectionBinder : CPBinder
{
CPString _selectionBinding @accessors;
}
- (id)initWithBinding:(CPString)aBinding name:(CPString)aName to:(id)aDestination keyPath:(CPString)aKeyPath options:(CPDictionary)options from:(id)aSource
{
self = [super initWithBinding:aBinding name:aName to:aDestination keyPath:aKeyPath options:options from:aSource];
if (self)
{
binderForObject[[aSource UID]] = self;
_selectionBinding = aName;
}
return self;
}
+ (void)reverseSetValueForObject:(id)aSource
{
var binder = binderForObject[[aSource UID]];
[binder reverseSetValueFor:[binder _selectionBinding]];
}
- (void)setPlaceholderValue:(id)aValue withMarker:(CPString)aMarker forBinding:(CPString)aBinding
{
[self setValue:aValue forBinding:aBinding];
}
- (CPInteger)_getInsertNullOffset
{
var options = [[CPBinder infoForBinding:CPContentBinding forObject:_source] objectForKey:CPOptionsKey];
return [options objectForKey:CPInsertsNullPlaceholderBindingOption] ? 1 : 0;
}
@end
@implementation _CPPopUpButtonSelectedIndexBinder : _CPPopUpButtonSelectionBinder
{
}
- (void)setValue:(id)aValue forBinding:(CPString)aBinding
{
[_source selectItemAtIndex:aValue + [self _getInsertNullOffset]];
}
- (id)valueForBinding:(CPString)aBinding
{
return [_source indexOfSelectedItem] - [self _getInsertNullOffset];
}
@end
@implementation _CPPopUpButtonSelectedObjectBinder : _CPPopUpButtonSelectionBinder
{
}
- (void)setValue:(id)aValue forBinding:(CPString)aBinding
{
var index = [_source indexOfItemWithRepresentedObject:aValue],
offset = [self _getInsertNullOffset];
// If the content binding has the option CPNullPlaceholderBindingOption and the object to select is nil, select the first item (i.e., the placeholder).
// Other cases to consider:
// 1. no binding:
// 1.1 there's no item with a represented object matching the object to select.
// 1.2 the object to select is nil/CPNull
// 2. there's a binding:
// 2.1 there's a CPNullPlaceholderBindingOption:
// 2.1.1 there's no item with a represented object matching the object to select?
// 2.1.2 the object to select is nil/CPNull
// 2.2 there's no CPNullPlaceholderBindingOption:
// 2.2.1 there's no item with a represented object matching the object to select?
// 2.2.2 the object to select is nil/CPNull
// More cases? Behaviour that depends on array controller settings?
if (offset === 1 && index === CPNotFound)
index = 0;
[_source selectItemAtIndex:index];
}
- (id)valueForBinding:(CPString)aBinding
{
return [[_source selectedItem] representedObject];
}
@end
@implementation _CPPopUpButtonSelectedTagBinder : _CPPopUpButtonSelectionBinder
{
}
- (void)setValue:(id)aValue forBinding:(CPString)aBinding
{
[_source selectItemWithTag:aValue];
}
- (id)valueForBinding:(CPString)aBinding
{
return [[_source selectedItem] tag];
}
@end
@implementation _CPPopUpButtonSelectedValueBinder : _CPPopUpButtonSelectionBinder
{
}
- (void)setValue:(id)aValue forBinding:(CPString)aBinding
{
[_source selectItemWithTitle:aValue];
}
- (id)valueForBinding:(CPString)aBinding
{
return [_source titleOfSelectedItem];
}
@end
var DEPRECATED_CPPopUpButtonMenuKey = @"CPPopUpButtonMenuKey",
DEPRECATED_CPPopUpButtonSelectedIndexKey = @"CPPopUpButtonSelectedIndexKey";
+91 -38
View File
@@ -68,7 +68,6 @@ var CPPopoverDelegate_popover_willShow_ = 1 << 0,
int _behavior @accessors(getter=behavior);
_CPAttachedWindow _attachedWindow;
BOOL _needsNewAttachedWindow;
int _implementedDelegateMethods;
}
@@ -79,16 +78,15 @@ var CPPopoverDelegate_popover_willShow_ = 1 << 0,
/*!
Initialize the CPPopover witn default values
@returns anInitialized CPPopover
@returns an initialized CPPopover
*/
- (CPPopover)init
{
if (self = [super init])
{
_animates = YES;
_appearance = CPPopoverAppearanceMinimal;
_behavior = CPPopoverBehaviorApplicationDefined;
_needsNewAttachedWindow = YES;
_animates = YES;
_appearance = CPPopoverAppearanceMinimal;
_behavior = CPPopoverBehaviorApplicationDefined;
}
return self;
@@ -106,7 +104,7 @@ var CPPopoverDelegate_popover_willShow_ = 1 << 0,
- (CGRect)positioningRect
{
if (![_attachedWindow isVisible])
return nil;
return CGRectMakeZero();
return [_attachedWindow frame];
}
@@ -128,7 +126,7 @@ var CPPopoverDelegate_popover_willShow_ = 1 << 0,
- (CGSize)contentSize
{
if (![_attachedWindow isVisible])
return nil;
return CGRectMakeZero();
return [[_contentViewController view] frameSize];
}
@@ -147,26 +145,26 @@ var CPPopoverDelegate_popover_willShow_ = 1 << 0,
@returns \c YES if visible
*/
- (BOOL)shown
- (BOOL)isShown
{
return [_attachedWindow isVisible];
}
/*!
Set the behaviour of the CPPopover. It can be:
Set the behavior of the CPPopover. It can be:
- \c CPPopoverBehaviorTransient: the popover will close if another control outside the popover becomes the responder
- \c CPPopoverBehaviorApplicationDefined: (DEFAULT) the application is responsible for closing the popover
@param aBehaviour the desired behaviour
@param aBehavior the desired behavior
*/
- (void)setBehaviour:(int)aBehaviour
- (void)setBehavior:(int)aBehavior
{
if (_behavior == aBehaviour)
if (_behavior == aBehavior)
return;
_behavior = aBehaviour;
_needsNewAttachedWindow = YES;
_behavior = aBehavior;
[_attachedWindow setStyleMask:[self styleMaskForBehavior]];
}
- (void)setDelegate:(id)aDelegate
@@ -205,17 +203,27 @@ Set the behaviour of the CPPopover. It can be:
*/
- (void)showRelativeToRect:(CGRect)positioningRect ofView:(CPView)positioningView preferredEdge:(CPRectEdge)preferredEdge
{
if (!positioningView)
[CPException raise:CPInvalidArgumentException reason:"positionView must not be nil"];
if (!_contentViewController)
[CPException raise:CPInternalInconsistencyException reason:@"contentViewController must not be nil"];
[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])
return;
if (_implementedDelegateMethods & CPPopoverDelegate_popover_willShow_)
[_delegate popoverWillShow:self];
if (!_attachedWindow || _needsNewAttachedWindow || [_attachedWindow isVisible])
if (!_attachedWindow)
{
var styleMask = (_behavior == CPPopoverBehaviorTransient) ? CPClosableOnBlurWindowMask : nil;
_attachedWindow = [[_CPAttachedWindow alloc] initWithContentRect:CGRectMakeZero() styleMask:styleMask];
_needsNewAttachedWindow = NO;
_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];
}
[_attachedWindow setAppearance:_appearance];
@@ -224,26 +232,32 @@ Set the behaviour of the CPPopover. It can be:
[_attachedWindow setMovableByWindowBackground:NO];
[_attachedWindow setFrame:[_attachedWindow frameRectForContentRect:[[_contentViewController view] frame]]];
[_attachedWindow setContentView:[_contentViewController view]];
[_attachedWindow positionRelativeToRect:positioningRect ofView:positioningView preferredEdge:preferredEdge];
if (positioningRect)
[_attachedWindow positionRelativeToRect:positioningRect preferredEdge:preferredEdge];
else if (positioningView)
[_attachedWindow positionRelativeToView:positioningView preferredEdge:preferredEdge];
else
[CPException raise:CPInvalidArgumentException reason:@"a value must be passed for positioningRect or positioningView"];
if (_implementedDelegateMethods & CPPopoverDelegate_popover_didShow_)
if (!_animates && _implementedDelegateMethods & CPPopoverDelegate_popover_didShow_)
[_delegate popoverDidShow:self];
}
- (unsigned)styleMaskForBehavior
{
return (_behavior == CPPopoverBehaviorTransient) ? CPClosableOnBlurWindowMask : 0;
}
/*!
Closes the popover
*/
- (void)close
{
if (_implementedDelegateMethods & CPPopoverDelegate_popover_shouldClose_)
if (![_delegate popoverShouldClose:self])
return;
[self _close];
}
/*!
Closes the popover
*/
- (void)_close
{
if ([_attachedWindow isClosing] || ![self isShown])
return;
if (_implementedDelegateMethods & CPPopoverDelegate_popover_willClose_)
[_delegate popoverWillClose:self];
@@ -261,11 +275,18 @@ Set the behaviour of the CPPopover. It can be:
/*!
Close the popover
@param aSender the sender of the action
@param sender the sender of the action
*/
- (IBAction)performClose:(id)aSender
- (IBAction)performClose:(id)sender
{
[self close];
if ([_attachedWindow isClosing])
return;
if (_implementedDelegateMethods & CPPopoverDelegate_popover_shouldClose_)
if (![_delegate popoverShouldClose:self])
return;
[self _close];
}
@@ -275,7 +296,7 @@ Set the behaviour of the CPPopover. It can be:
/*! @ignore */
- (BOOL)attachedWindowShouldClose:(_CPAttachedWindow)anAttachedWindow
{
[self close];
[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
@@ -290,6 +311,40 @@ Set the behaviour of the CPPopover. It can be:
[_delegate popoverDidClose:self];
}
/*! @ignore */
- (void)attachedWindowDidShow:(_CPAttachedWindow)anAttachedWindow
{
if (_implementedDelegateMethods & CPPopoverDelegate_popover_didShow_)
[_delegate popoverDidShow: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
{
[_attachedWindow orderOut:nil];
[self performClose:nil];
}
@end
@implementation CPPopover (Deprecated)
- (void)setBehaviour:(int)aBehavior
{
_CPReportLenientDeprecation(self, _cmd, @selector(setBehavior:));
[self setBehavior:aBehavior];
}
@end
var CPPopoverNeedsNewAttachedWindowKey = @"CPPopoverNeedsNewAttachedWindowKey",
@@ -307,12 +362,11 @@ var CPPopoverNeedsNewAttachedWindowKey = @"CPPopoverNeedsNewAttachedWindowKey",
if (self)
{
_needsNewAttachedWindow = [aCoder decodeBoolForKey:CPPopoverNeedsNewAttachedWindowKey];
_appearance = [aCoder decodeIntForKey:CPPopoverAppearanceKey];
_animates = [aCoder decodeBoolForKey:CPPopoverAnimatesKey];
_contentViewController = [aCoder decodeObjectForKey:CPPopoverContentViewControllerKey];
[self setDelegate:[aCoder decodeObjectForKey:CPPopoverDelegateKey]];
[self setBehaviour:[aCoder decodeIntForKey:CPPopoverBehaviorKey]];
[self setBehavior:[aCoder decodeIntForKey:CPPopoverBehaviorKey]];
}
return self;
}
@@ -321,7 +375,6 @@ var CPPopoverNeedsNewAttachedWindowKey = @"CPPopoverNeedsNewAttachedWindowKey",
{
[super encodeWithCoder:aCoder];
[aCoder encodeBool:_needsNewAttachedWindow forKey:CPPopoverNeedsNewAttachedWindowKey];
[aCoder encodeInt:_appearance forKey:CPPopoverAppearanceKey];
[aCoder encodeBool:_animates forKey:CPPopoverAnimatesKey];
[aCoder encodeObject:_contentViewController forKey:CPPopoverContentViewControllerKey];
+41 -24
View File
@@ -71,8 +71,6 @@ var CPProgressIndicatorSpinningStyleColors = nil,
BOOL _isDisplayedWhenStoppedSet;
BOOL _isDisplayedWhenStopped;
CPView _barView;
}
/*
@@ -80,7 +78,7 @@ var CPProgressIndicatorSpinningStyleColors = nil,
*/
+ (void)initialize
{
if (self != [CPProgressIndicator class])
if (self !== [CPProgressIndicator class])
return;
var bundle = [CPBundle bundleForClass:self];
@@ -88,9 +86,9 @@ var CPProgressIndicatorSpinningStyleColors = nil,
CPProgressIndicatorSpinningStyleColors = [];
CPProgressIndicatorSpinningStyleColors[CPMiniControlSize] = [CPColor colorWithPatternImage:[[CPImage alloc] initWithContentsOfFile:
[bundle pathForResource:@"CPProgressIndicator/CPProgressIndicatorSpinningStyleRegular.gif"] size:CGSizeMake(64.0, 64.0)]];
[bundle pathForResource:@"CPProgressIndicator/CPProgressIndicatorSpinningStyleMini.gif"] size:CGSizeMake(16.0, 16.0)]];
CPProgressIndicatorSpinningStyleColors[CPSmallControlSize] = [CPColor colorWithPatternImage:[[CPImage alloc] initWithContentsOfFile:
[bundle pathForResource:@"CPProgressIndicator/CPProgressIndicatorSpinningStyleRegular.gif"] size:CGSizeMake(64.0, 64.0)]];
[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)]];
@@ -122,11 +120,11 @@ var CPProgressIndicatorSpinningStyleColors = nil,
// Bar Style
var prefixes = [
CPProgressIndicatorClassName + @"BezelBorder" + CPProgressIndicatorStyleIdentifiers[CPProgressIndicatorBarStyle],
CPProgressIndicatorClassName + @"Bar" + CPProgressIndicatorStyleIdentifiers[CPProgressIndicatorBarStyle],
CPProgressIndicatorClassName + @"BezelBorder" + CPProgressIndicatorStyleIdentifiers[CPProgressIndicatorHUDBarStyle],
CPProgressIndicatorClassName + @"Bar" + CPProgressIndicatorStyleIdentifiers[CPProgressIndicatorHUDBarStyle]
];
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++)
{
@@ -410,27 +408,38 @@ var CPProgressIndicatorSpinningStyleColors = nil,
if (_style == CPProgressIndicatorSpinningStyle)
return;
if (!_barView)
{
_barView = [[CPView alloc] initWithFrame:CGRectMake(0.0, 0.0, 0.0, 16.0)];
[self addSubview:_barView];
}
var barView = [self layoutEphemeralSubviewNamed:"bar-view"
positioned:CPWindowBelow
relativeToEphemeralSubviewNamed:nil];
[_barView setBackgroundColor:_CPControlThreePartImagePattern(
[barView setBackgroundColor:_CPControlThreePartImagePattern(
NO,
CPProgressIndicatorStyleSizes,
CPProgressIndicatorClassName,
@"Bar",
CPProgressIndicatorStyleIdentifiers[_style],
_CPControlIdentifierForControlSize(_controlSize))];
}
var width = CGRectGetWidth([self bounds]),
barWidth = width * ((_doubleValue - _minValue) / (_maxValue - _minValue));
- (CPView)createEphemeralSubviewNamed:(CPString)aName
{
return [[CPView alloc] initWithFrame:_CGRectMakeZero()];
}
if (barWidth > 0.0 && barWidth < 4.0)
barWidth = 4.0;
- (CGRect)rectForEphemeralSubviewNamed:(CPString)aViewName
{
if (aViewName === @"bar-view" && _style !== CPProgressIndicatorSpinningStyle)
{
var width = CGRectGetWidth([self bounds]),
barWidth = width * ((_doubleValue - _minValue) / (_maxValue - _minValue));
[_barView setFrameSize:CGSizeMake(barWidth, 16.0)];
if (barWidth > 0.0 && barWidth < 4.0)
barWidth = 4.0;
return _CGRectMake(0, 0, barWidth, 16.0);
}
return nil;
}
/* @ignore */
@@ -440,9 +449,10 @@ var CPProgressIndicatorSpinningStyleColors = nil,
{
if (_style == CPProgressIndicatorSpinningStyle)
{
[_barView removeFromSuperview];
_barView = nil;
// This will cause the bar view to go away due to having a nil rect when _style == CPProgressIndicatorSpinningStyle.
[self layoutEphemeralSubviewNamed:"bar-view"
positioned:CPWindowBelow
relativeToEphemeralSubviewNamed:nil];
[self setBackgroundColor:CPProgressIndicatorSpinningStyleColors[_controlSize]];
}
@@ -481,6 +491,8 @@ var CPProgressIndicatorSpinningStyleColors = nil,
_isAnimating = [aCoder decodeObjectForKey:@"_isAnimating"];
_isDisplayedWhenStoppedSet = [aCoder decodeObjectForKey:@"_isDisplayedWhenStoppedSet"];
_isDisplayedWhenStopped = [aCoder decodeObjectForKey:@"_isDisplayedWhenStopped"];
[self updateBackgroundColor];
}
return self;
@@ -488,7 +500,12 @@ 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.
var backgroundColor = [self backgroundColor];
[self setBackgroundColor:nil];
[super encodeWithCoder:aCoder];
[self setBackgroundColor:backgroundColor];
[aCoder encodeObject:_minValue forKey:@"_minValue"];
[aCoder encodeObject:_maxValue forKey:@"_maxValue"];
+17
View File
@@ -181,6 +181,23 @@ var CPRadioRadioGroupKey = @"CPRadioRadioGroupKey";
[aCoder encodeObject:_radioGroup forKey:CPRadioRadioGroupKey];
}
- (CPImage)image
{
return [self currentValueForThemeAttribute:@"image"];
}
- (CPImage)alternateImage
{
return [self currentValueForThemeAttribute:@"image"];
}
- (BOOL)startTrackingAt:(CGPoint)aPoint
{
var startedTracking = [super startTrackingAt:aPoint];
[self highlight:YES];
return startedTracking;
}
@end
@implementation CPRadioGroup : CPObject
+73 -24
View File
@@ -82,6 +82,22 @@
}
/*! @cond */
+ (Class)_binderClassForBinding:(CPString)theBinding
{
if (theBinding == CPValueBinding)
return [CPPredicateEditorValueBinder class];
return [super _binderClassForBinding:theBinding];
}
- (id)_replacementKeyPathForBinding:(CPString)aBinding
{
if (aBinding == CPValueBinding)
return @"predicate";
return [super _replacementKeyPathForBinding:aBinding];
}
- (void)_initRuleEditorShared
{
[super _initRuleEditorShared];
@@ -157,28 +173,40 @@
return trees;
}
- (id)_mergeTree:(id)tree
- (CPMutableArray)_mergeTree:(CPArray)aTree
{
var merged = [CPMutableArray array],
titles = [CPMutableArray array],
count = [tree count];
var mergedTree = [CPMutableArray array];
if (aTree == nil)
return mergedTree;
for (var i = 0; i < count; i++)
var icount = [aTree count];
for (var i = 0; i < icount; i++)
{
var t = tree[i],
title = [CPString stringWithString:[t title]];
var anode = [aTree objectAtIndex:i],
jcount = [mergedTree count],
merged = NO;
if ([titles containsObject:title])
for (var j = 0; j < jcount; j++)
{
CPLogConsole("CPPredicateEditor does not support templates merging yet. Ignoring duplicate template: " + [t description]);
continue;
var mergednode = [mergedTree objectAtIndex:j];
if ([[mergednode title] isEqualToString:[anode title]])
{
var children1 = [mergednode children],
children2 = [anode children],
children12 = [children1 arrayByAddingObjectsFromArray:children2],
mergedChildren = [self _mergeTree:children12];
[mergednode setChildren:mergedChildren];
merged = YES;
}
}
[merged addObject:t];
[titles addObject:title];
if (!merged)
[mergedTree addObject:anode];
}
return merged;
return mergedTree;
}
- (id)_constructTreeForTemplate:(CPPredicateEditorRowTemplate)aTemplate
@@ -227,14 +255,19 @@
- (void)setObjectValue:(id)objectValue
{
if (![[objectValue predicateFormat] isEqualToString:[[super predicate] predicateFormat]]) // ??
var ov = [self objectValue];
if ((ov == nil) != (objectValue == nil) || ![ov isEqual:objectValue])
{
[self _setPredicate:objectValue];
[self _reflectPredicate:objectValue];
}
}
- (void)_reflectPredicate:(id)predicate
{
var animation = _currentAnimation;
_currentAnimation = nil;
_sendAction = NO;
if (predicate != nil)
{
@@ -311,9 +344,9 @@
treeChild = [rootItems objectAtIndex:i];
var currentView = [templateViews objectAtIndex:[treeChild indexIntoTemplate]],
menuItemIndex = [treeChild menuItemIndex];
title = [treeChild title];
if (menuItemIndex == -1 || [[treeChild title] isEqual:[currentView titleOfSelectedItem]])
if (title == nil || [title isEqual:[currentView titleOfSelectedItem]])
{
var node = [_CPPredicateEditorRowNode rowNodeFromTree:treeChild];
[node applyTemplate:aTemplate withViews:templateViews forOriginalTemplate:originalTemplate];
@@ -336,16 +369,15 @@
- (void)_updatePredicate
{
[self willChangeValueForKey:@"objectValue"];
[self _updatePredicateFromRows];
[self didChangeValueForKey:@"objectValue"];
}
- (void)_updatePredicateFromRows
{
var rootRowsArray = [super _rootRowsArray],
subpredicates = [CPMutableArray array],
count = count2 = [rootRowsArray count],
count,
count2 = count = [rootRowsArray count],
predicate;
while (count--)
@@ -362,7 +394,7 @@
else
predicate = [[CPCompoundPredicate alloc] initWithType:[self _compoundPredicateTypeForRootRows] subpredicates:subpredicates];
[super _setPredicate:predicate];
[self _setPredicate:predicate];
}
- (id)_predicateFromRowItem:(id)rowItem
@@ -373,12 +405,13 @@
if (rowType == CPRuleEditorRowTypeCompound)
{
var subrows = [rowItem valueForKey:_subrowsArrayKeyPath],
count = [subrows count];
count = [subrows count];
for (var i = 0; i < count; i++)
{
var subrow = [subrows objectAtIndex:i];
var predicate = [self _predicateFromRowItem:subrow];
var subrow = [subrows objectAtIndex:i],
predicate = [self _predicateFromRowItem:subrow];
[subpredicates addObject:predicate];
}
}
@@ -414,7 +447,6 @@
- (void)_sendRuleAction
{
[self _updatePredicate];
[super _sendRuleAction];
}
@@ -483,9 +515,11 @@ var CPPredicateTemplatesKey = @"CPPredicateTemplates";
- (id)initWithCoder:(id)aCoder
{
self = [super initWithCoder:aCoder];
if (self != nil)
{
var nibTemplates = [aCoder decodeObjectForKey:CPPredicateTemplatesKey];
if (nibTemplates != nil)
[self setRowTemplates:nibTemplates];
}
@@ -501,4 +535,19 @@ var CPPredicateTemplatesKey = @"CPPredicateTemplates";
@end
@implementation CPPredicateEditorValueBinder : CPBinder
{
}
- (void)setPlaceholderValue:(id)aValue withMarker:(CPString)aMarker forBinding:(CPString)aBinding
{
[_source _reflectPredicate:nil];
}
- (void)setValue:(id)aValue forBinding:(CPString)aBinding
{
[_source _reflectPredicate:aValue];
}
@end
/*! @endcond */
@@ -185,7 +185,8 @@ CPTransformableAttributeType = 1800;
if (![[self operators] containsObject:[predicate predicateOperatorType]])
return 0;
if (!_rightIsWildcard && ![[self rightExpressions] containsObject:[predicate rightExpression]]) return 0;
if (!_rightIsWildcard && ![[self rightExpressions] containsObject:[predicate rightExpression]])
return 0;
return 1;
}
@@ -280,7 +281,7 @@ CPTransformableAttributeType = 1800;
*/
- (CPArray)leftExpressions
{
if (_templateType ==1 && !_leftIsWildcard)
if (_templateType == 1 && !_leftIsWildcard)
{
var view = [_views objectAtIndex:0];
return [[view itemArray] valueForKey:@"representedObject"];
@@ -685,6 +686,7 @@ CPTransformableAttributeType = 1800;
[textField setBordered:YES];
[textField setEditable:YES];
[textField setFont:[CPFont systemFontOfSize:10]];
[textField setSendsActionOnEndEditing:YES];
return textField;
}
File diff suppressed because it is too large Load Diff
+17 -20
View File
@@ -14,25 +14,21 @@
+ (id)rowNodeFromTree:(id)aTree
{
var mapTable = {};
return [_CPPredicateEditorRowNode _rowNodeFromTree:aTree withTemplateTable:mapTable];
return [_CPPredicateEditorRowNode _rowNodeFromTree:aTree withTemplateTable:{}];
}
+ (id)_rowNodeFromTree:(id)aTree withTemplateTable:(id)templateTable
{
var node,
views,
var views,
copiedContainer;
node = [[_CPPredicateEditorRowNode alloc] init];
node.tree = aTree;
var uuid = [[aTree template] UID],
cachedNode = templateTable[uuid],
node = [[_CPPredicateEditorRowNode alloc] init];
var template = [aTree template],
uuid = [template UID];
[node setTree:aTree];
var cachedNode = templateTable[uuid];
if (cachedNode == nil)
if (!cachedNode)
{
views = [CPMutableArray array];
copiedContainer = [CPMutableArray array];
@@ -44,8 +40,8 @@
copiedContainer = [cachedNode copiedTemplateContainer];
}
node.templateViews = views;
node.copiedTemplateContainer = copiedContainer;
[node setTemplateViews:views];
[node setCopiedTemplateContainer:copiedContainer];
var nodeChildren = [CPMutableArray array],
treeChildren = [aTree children],
@@ -66,7 +62,9 @@
- (BOOL)applyTemplate:(id)template withViews:(id)views forOriginalTemplate:(id)originalTemplate
{
var t = [tree template];
var t = [tree template],
count = [children count];
if (t !== template)
{
[templateViews setArray:views];
@@ -74,8 +72,7 @@
[copiedTemplateContainer addObject:template];
}
var count = [children count];
for (var i; i < count; i++)
for (var i = 0; i < count; i++)
[children[i] applyTemplate:template withViews:views forOriginalTemplate:originalTemplate];
}
@@ -89,9 +86,8 @@
- (void)copyTemplateIfNecessary
{
if ([copiedTemplateContainer count] == 0)
if ([copiedTemplateContainer count] === 0)
{
CPLogConsole("COPYING TEMPLATE");
var copy = [[tree template] copy];
[copiedTemplateContainer addObject:copy];
[templateViews addObjectsFromArray:[copy templateViews]];
@@ -118,7 +114,8 @@
- (id)displayValue
{
var title = [self title];
if (title != nil)
if (title !== nil)
return title;
return [self templateView];
@@ -129,4 +126,4 @@
return [CPString stringWithFormat:@"<%@ %@ %@ tree:%@ tviews:%@", [self className],[self UID], [self title], [tree UID], [templateViews description]];
}
@end
@end
+13 -9
View File
@@ -7,7 +7,7 @@
@import <Foundation/CPDictionary.j>
@import <Foundation/CPString.j>
var regex = new RegExp("\"(.+)\"\\s*=\\s*\"(.+)\"\\s*;\\s*(//.+)?");
var LocalizerStringsRegex = new RegExp("\"(.+)\"\\s*=\\s*\"(.+)\"\\s*;\\s*(//.+)?");
@implementation _CPRuleEditorLocalizer : CPObject
{
@@ -24,9 +24,10 @@ var regex = new RegExp("\"(.+)\"\\s*=\\s*\"(.+)\"\\s*;\\s*(//.+)?");
- (void)reloadIfNeeded
{
if (connection != nil) // Connection waiting
if (connection !== nil) // Connection waiting
{
connection = nil;
var data = [CPURLConnection sendSynchronousRequest:request returningResponse:NULL];
[self loadContent:[data rawString]];
}
@@ -34,7 +35,7 @@ var regex = new RegExp("\"(.+)\"\\s*=\\s*\"(.+)\"\\s*;\\s*(//.+)?");
- (void)connection:(CPURLConnection)aConnection didReceiveData:(CPString)rawString
{
if (connection != nil && rawString != nil)
if (connection !== nil && rawString !== nil)
[self loadContent:rawString];
connection = nil;
@@ -49,10 +50,12 @@ var regex = new RegExp("\"(.+)\"\\s*=\\s*\"(.+)\"\\s*;\\s*(//.+)?");
for (var i = 0 ; i < count ; i++)
{
var line = [lines objectAtIndex:i];
if (line.length > 1)
{
var match = regex.exec(line);
if (match.length >= 3)
var match = LocalizerStringsRegex.exec(line);
if (match && match.length >= 3)
[dict setObject:match[2] forKey:match[1]];
}
}
@@ -64,12 +67,13 @@ var regex = new RegExp("\"(.+)\"\\s*=\\s*\"(.+)\"\\s*;\\s*(//.+)?");
{
[self reloadIfNeeded];
if (_dictionary != nil && aString != nil)
if (_dictionary !== nil && aString !== nil)
{
var localized = [_dictionary objectForKey:aString];
if (localized != nil)
return localized;
if (localized !== nil)
return localized;
}
return aString;
}
}
+72 -53
View File
@@ -3,62 +3,80 @@
* Copyright (c) 2011 Pear, Inc. All rights reserved.
*/
var GRADIENT_START_COLOR = "#fcfcfc",
GRADIENT_END_COLOR = "#dfdfdf",
BORDER_COLOR = "#BDBDBD";
var GRADIENT_NORMAL,
GRADIENT_HIGHLIGHTED,
IE_FILTER = "progid:DXImageTransform.Microsoft.gradient(startColorstr='#fcfcfc', endColorstr='#dfdfdf')";
GRADIENT_PROPERTY;
if (CPBrowserIsEngine(CPWebKitBrowserEngine))
{
GRADIENT_NORMAL = "-webkit-gradient(linear, left top, left bottom, from(" + GRADIENT_START_COLOR + "), to(" + GRADIENT_END_COLOR + "))",
GRADIENT_HIGHLIGHTED = "-webkit-gradient(linear, left top, left bottom, from(" + GRADIENT_END_COLOR + "), to(" + GRADIENT_START_COLOR + "))";
GRADIENT_PROPERTY = "background";
}
else if (CPBrowserIsEngine(CPGeckoBrowserEngine))
{
GRADIENT_NORMAL = "-moz-linear-gradient(top, " + GRADIENT_START_COLOR + ", " + GRADIENT_END_COLOR + ")",
GRADIENT_HIGHLIGHTED = "-moz-linear-gradient(top, " + GRADIENT_END_COLOR + ", " + GRADIENT_START_COLOR + ")";
GRADIENT_PROPERTY = "background";
}
else if (CPBrowserIsEngine(CPInternetExplorerBrowserEngine))
{
GRADIENT_NORMAL = "progid:DXImageTransform.Microsoft.gradient(startColorstr='" + GRADIENT_START_COLOR + "', endColorstr='" + GRADIENT_END_COLOR + "')";
GRADIENT_HIGHLIGHTED = "progid:DXImageTransform.Microsoft.gradient(startColorstr='" + GRADIENT_END_COLOR + "', endColorstr='" + GRADIENT_START_COLOR + "')";
GRADIENT_PROPERTY = "filter";
}else
{
GRADIENT_NORMAL = GRADIENT_START_COLOR;
GRADIENT_HIGHLIGHTED = GRADIENT_END_COLOR;
GRADIENT_PROPERTY = "background";
}
@implementation _CPRuleEditorPopUpButton : CPPopUpButton
{
CPInteger radius;
}
+ (void)initialize
- (void)_sharedInit
{
if (CPBrowserIsEngine(CPWebKitBrowserEngine))
{
GRADIENT_NORMAL = "-webkit-gradient(linear, left top, left bottom, from(rgb(252, 252, 252)), to(rgb(223, 223, 223)))";
GRADIENT_HIGHLIGHTED = "-webkit-gradient(linear, left top, left bottom, from(rgb(223, 223, 223)), to(rgb(252, 252, 252)))";
}
else if (CPBrowserIsEngine(CPGeckoBrowserEngine))
{
GRADIENT_NORMAL = "-moz-linear-gradient(top, rgb(252, 252, 252), rgb(223, 223, 223))";
GRADIENT_HIGHLIGHTED = "-moz-linear-gradient(top, rgb(223, 223, 223), rgb(252, 252, 252))";
}
[self setBordered:NO];
var style = _DOMElement.style;
style.border = "1px solid " + BORDER_COLOR;
style[GRADIENT_PROPERTY] = GRADIENT_NORMAL;
}
- (id)initWithFrame:(CGRect)aFrame
{
if (self = [super initWithFrame:aFrame])
{
var style = _DOMElement.style;
style.backgroundImage = GRADIENT_NORMAL;
style.border = "1px solid rgb(189, 189, 189)";
style.filter = IE_FILTER;
[self _sharedInit];
[self setTextColor:[CPColor colorWithWhite:101 / 255 alpha:1]];
[self setBordered:NO];
}
return self;
}
- (id)initWithCoder:(CPCoder)aCoder
{
self = [super initWithCoder:aCoder];
[self _sharedInit];
return self;
}
- (id)hitTest:(CPPoint)point
{
var slice = [self superview];
if (!CPRectContainsPoint([self frame], point) || ![self sliceIsEditable])
return nil;
return self;
}
- (void)setHighlighted:(BOOL)shouldHighlight
{
_DOMElement.style.backgroundImage = (shouldHighlight) ? GRADIENT_HIGHLIGHTED : GRADIENT_NORMAL;
}
- (BOOL)sliceIsEditable
{
return [[self superview] isEditable];
var superview = [self superview];
return ![superview isKindOfClass:[_CPRuleEditorViewSlice]] || [superview isEditable];
}
- (BOOL)trackMouse:(CPEvent)theEvent
@@ -80,13 +98,10 @@ var GRADIENT_NORMAL,
- (void)layoutSubviews
{
radius = FLOOR(CGRectGetHeight([self bounds])/2);
radius = FLOOR(CGRectGetHeight([self bounds]) / 2);
var style = _DOMElement.style,
radiusCSS = radius + "px";
//style.webkitBorderRadius = radiusCSS;
//style.mozBorderRadius = radiusCSS;
style.borderRadius = radiusCSS;
[super layoutSubviews];
@@ -94,20 +109,19 @@ var GRADIENT_NORMAL,
- (void)drawRect:(CGRect)aRect
{
var bounds = [self bounds],
context = [[CPGraphicsContext currentContext] graphicsPort];
var arrow_width = FLOOR(CGRectGetHeight(bounds)/3.5);
var context = [[CPGraphicsContext currentContext] graphicsPort],
bounds = [self bounds],
arrow_width = FLOOR(CGRectGetHeight(bounds) / 3.5);
CGContextTranslateCTM(context, CGRectGetWidth(bounds) - radius - arrow_width, CGRectGetHeight(bounds) / 2);
var arrowsPath = [CPBezierPath bezierPath];
[arrowsPath moveToPoint:CGPointMake(0, 1)];
[arrowsPath lineToPoint:CGPointMake(arrow_width, 1)];
[arrowsPath lineToPoint:CGPointMake(arrow_width/2, arrow_width + 1)];
[arrowsPath lineToPoint:CGPointMake(arrow_width / 2, arrow_width + 1)];
[arrowsPath closePath];
CGContextSetFillColor(context, [CPColor colorWithWhite:101/255 alpha:1]);
CGContextSetFillColor(context, [CPColor colorWithWhite:101 / 255 alpha:1]);
[arrowsPath fill];
CGContextScaleCTM(context, 1 , -1);
@@ -121,37 +135,42 @@ var GRADIENT_NORMAL,
CPInteger radius;
}
- (void)_sharedInit
{
[self setBordered:NO];
var style = _DOMElement.style;
style.border = "1px solid " + BORDER_COLOR;
style[GRADIENT_PROPERTY] = GRADIENT_NORMAL;
}
- (id)initWithFrame:(CGRect)aFrame
{
self = [super initWithFrame:aFrame];
if (self)
{
[self setFont:[CPFont boldFontWithName:@"Apple Symbol" size:12.0]];
[self setTextColor:[CPColor colorWithWhite:150/255 alpha:1]];
[self setAlignment:CPCenterTextAlignment];
[self setAutoresizingMask:CPViewMinXMargin];
[self setImagePosition:CPImageOnly];
[self setBordered:NO];
var style = _DOMElement.style;
style.border = "1px solid rgb(189, 189, 189)";
style.filter = IE_FILTER;
}
if (self = [super initWithFrame:aFrame])
[self _sharedInit];
return self;
}
- (id)initWithCoder:(CPCoder)aCoder
{
self = [super initWithCoder:aCoder];
[self _sharedInit];
return self;
}
- (void)layoutSubviews
{
radius = FLOOR(CGRectGetHeight([self bounds])/2);
radius = FLOOR(CGRectGetHeight([self bounds]) / 2);
var style = _DOMElement.style,
radiusCSS = radius + "px";
style.borderRadius = radiusCSS;
style.backgroundImage = ([self isHighlighted]) ? GRADIENT_HIGHLIGHTED : GRADIENT_NORMAL;
style[GRADIENT_PROPERTY] = ([self isHighlighted]) ? GRADIENT_HIGHLIGHTED : GRADIENT_NORMAL;
[super layoutSubviews];
}
@end
+5 -5
View File
@@ -45,7 +45,7 @@
{
var context = [[CPGraphicsContext currentContext] graphicsPort],
bounds = [self bounds],
maxX = CGRectGetWidth(bounds) - 2,
maxX = CGRectGetWidth(bounds),
maxY = CGRectGetHeight(bounds);
// Draw background
@@ -63,7 +63,7 @@
// Draw Top Border
CGContextBeginPath(context);
CGContextMoveToPoint(context, 1, 0);
CGContextMoveToPoint(context, 0, 0);
CGContextAddLineToPoint(context, maxX, 0);
CGContextClosePath(context);
CGContextSetStrokeColor(context, [_ruleEditor _sliceTopBorderColor]);
@@ -71,8 +71,8 @@
// Draw Bottom Border
CGContextBeginPath(context);
CGContextMoveToPoint(context, 1, maxY - 0.5);
CGContextAddLineToPoint(context, maxX, maxY - 0.5);
CGContextMoveToPoint(context, 0, maxY);
CGContextAddLineToPoint(context, maxX, maxY);
CGContextClosePath(context);
var bottomColor = (_rowIndex == [_ruleEditor _lastRow]) ? [_ruleEditor _sliceLastBottomBorderColor] : [_ruleEditor _sliceBottomBorderColor];
CGContextSetStrokeColor(context, bottomColor);
@@ -106,4 +106,4 @@
return [CPString stringWithFormat:@"<%@ %p index:%d indentation:%d>",[self className],self,[self rowIndex],[self indentation]];
}
@end
@end
+56 -34
View File
@@ -41,8 +41,8 @@ var CONTROL_HEIGHT = 16.,
_addButton = [self _createAddRowButton];
_subtractButton = [self _createDeleteRowButton];
//[_addButton setToolTip:[_ruleEditor _toolTipForAddSimpleRowButton]];
//[_subtractButton setToolTip:[_ruleEditor _toolTipForDeleteRowButton]];
[_addButton setToolTip:[_ruleEditor _toolTipForAddSimpleRowButton]];
[_subtractButton setToolTip:[_ruleEditor _toolTipForDeleteRowButton]];
[_addButton setHidden:!editable];
[_subtractButton setHidden:!editable];
[self addSubview:_addButton];
@@ -54,26 +54,36 @@ var CONTROL_HEIGHT = 16.,
[center addObserver:self selector:@selector(_textDidChange:) name:CPControlTextDidChangeNotification object:nil];
}
- (CPButton)_createAddRowButton
- (CPButton)_createRowButton
{
var button = [[_CPRuleEditorButton alloc] initWithFrame:CGRectMakeZero()];
[button setImage:[_ruleEditor _addImage]];
[button setFont:[CPFont boldFontWithName:@"Apple Symbol" size:12.0]];
[button setTextColor:[CPColor colorWithWhite:150 / 255 alpha:1]];
[button setAlignment:CPCenterTextAlignment];
[button setAutoresizingMask:CPViewMinXMargin];
[button setImagePosition:CPImageOnly];
return button;
}
- (CPButton)_createAddRowButton
{
var button = [self _createRowButton];
[button setImage:[_ruleEditor _addImage]];
[button setAction:@selector(_addOption:)];
[button setTarget:self];
[button setAutoresizingMask:CPViewMinXMargin];
return button;
}
- (CPButton)_createDeleteRowButton
{
var button = [[_CPRuleEditorButton alloc] initWithFrame:CGRectMakeZero()];
[button setImage:[_ruleEditor _removeImage]];
var button = [self _createRowButton];
[button setImage:[_ruleEditor _removeImage]];
[button setAction:@selector(_deleteOption:)];
[button setTarget:self];
[button setAutoresizingMask:CPViewMinXMargin];
return button;
}
@@ -87,12 +97,14 @@ var CONTROL_HEIGHT = 16.,
- (CPPopUpButton)_createPopUpButtonWithItems:(CPArray)itemsArray selectedItemIndex:(int)index
{
var title = [[itemsArray objectAtIndex:index] title];
var font = [_ruleEditor font],
var title = [[itemsArray objectAtIndex:index] title],
font = [_ruleEditor font],
width = [title sizeWithFont:font].width + 20,
rect = CGRectMake(0, 0, (width - width % 40) + 80, CONTROL_HEIGHT);
rect = CGRectMake(0, 0, (width - width % 40) + 80, CONTROL_HEIGHT),
var popup = [[_CPRuleEditorPopUpButton alloc] initWithFrame:rect];
popup = [[_CPRuleEditorPopUpButton alloc] initWithFrame:rect];
[popup setTextColor:[CPColor colorWithWhite:101 / 255 alpha:1]];
[popup setValue:font forThemeAttribute:@"font"];
var count = [itemsArray count];
@@ -109,15 +121,16 @@ var CONTROL_HEIGHT = 16.,
return [CPMenuItem separatorItem];
}
- (_CPRuleEditorTextField)_createStaticTextFieldWithStringValue:(CPString )text
- (_CPRuleEditorTextField)_createStaticTextFieldWithStringValue:(CPString)text
{
text = [[_ruleEditor standardLocalizer] localizedStringForString:text];
var textField = [[_CPRuleEditorTextField alloc] initWithFrame:CPMakeRect(0, 0, 200, CONTROL_HEIGHT)],
refont = [_ruleEditor font],
font = [CPFont fontWithName:[refont familyName] size:[refont size] + 2],
localizedText = [[_ruleEditor standardLocalizer] localizedStringForString:text];
var textField = [[_CPRuleEditorTextField alloc] initWithFrame:CPMakeRect(0, 0, 200, CONTROL_HEIGHT)];
var font = [_ruleEditor font];
font = [CPFont fontWithName:font._name size:font._size + 2];
[textField setValue:font forThemeAttribute:@"font"];
[textField setStringValue:text];
[textField setStringValue:localizedText];
[textField sizeToFit];
return textField;
@@ -182,9 +195,10 @@ var CONTROL_HEIGHT = 16.,
parent,
numberOfCriteria,
numberOfChildren,
firstResponderIndex;
firstResponderIndex,
var ruleItems = [CPMutableArray array];
ruleItems = [CPMutableArray array],
responder = [[self window] firstResponder];
[self _emptyRulePartSubviews];
@@ -192,7 +206,6 @@ var CONTROL_HEIGHT = 16.,
numberOfCriteria = [criteria count];
firstResponderIndex = numberOfCriteria - 1;
var responder = [[self window] firstResponder];
if (responder)
firstResponderIndex = [_ruleOptionViews indexOfObjectIdenticalTo:responder];
@@ -213,16 +226,16 @@ var CONTROL_HEIGHT = 16.,
numberOfChildren = [childItems count];
if (numberOfChildren > 1)
{
var menuItems = [CPMutableArray arrayWithCapacity:numberOfChildren];
var menuItems = [CPMutableArray arrayWithCapacity:numberOfChildren],
selectedIndex = [childItems indexOfObject:criterion];
var selectedIndex = [childItems indexOfObject:criterion];
if (selectedIndex == CPNotFound)
break;
for (var j = 0; j < numberOfChildren; ++j)
{
var childItem = [childItems objectAtIndex:j];
var childValue = [childValues objectAtIndex:j];
var childItem = [childItems objectAtIndex:j],
childValue = [childValues objectAtIndex:j];
if ([childValue isKindOfClass:[CPMenuItem class]])
{
@@ -250,8 +263,8 @@ var CONTROL_HEIGHT = 16.,
}
else
{
var value = [childValues objectAtIndex:0];
var type = [value valueType];
var value = [childValues objectAtIndex:0],
type = [value valueType];
if (type === 0)
ruleView = [self _createStaticTextFieldWithStringValue:value];
@@ -308,7 +321,6 @@ var CONTROL_HEIGHT = 16.,
- (void)layoutSubviews
{
// CPLogConsole(_cmd);
[self _relayoutSubviewsWidthChanged:YES];
}
@@ -319,11 +331,11 @@ var CONTROL_HEIGHT = 16.,
leftButtonMinX,
rowHeight = [_ruleEditor rowHeight],
count = [_ruleOptionViews count],
sliceFrame = [self frame];
sliceFrame = [self frame],
buttonFrame = CGRectMake(CGRectGetWidth(sliceFrame) - BUTTON_HEIGHT - [self _rowButtonsRightHorizontalPadding], ([_ruleEditor rowHeight] - BUTTON_HEIGHT) / 2 - 2, BUTTON_HEIGHT, BUTTON_HEIGHT);
var buttonFrame = CGRectMake(CGRectGetWidth(sliceFrame) - BUTTON_HEIGHT - [self _rowButtonsRightHorizontalPadding], ([_ruleEditor rowHeight] - BUTTON_HEIGHT)/2 - 2, BUTTON_HEIGHT, BUTTON_HEIGHT);
[_addButton setFrame:buttonFrame];
buttonFrame.origin.x -= BUTTON_HEIGHT + [self _rowButtonsInterviewHorizontalPadding];
[_subtractButton setFrame:buttonFrame];
@@ -339,7 +351,16 @@ var CONTROL_HEIGHT = 16.,
var ruleOptionView = _ruleOptionViews[i],
optionFrame = _ruleOptionFrames[i];
optionFrame.origin.y = (rowHeight - CGRectGetHeight(optionFrame))/2 - 2;
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;
@@ -418,7 +439,7 @@ var CONTROL_HEIGHT = 16.,
- (float)_rowButtonsRightHorizontalPadding
{
return 10.;
return ([[_ruleEditor superview] isKindOfClass:[CPClipView class]]) ? 18. : 10.;
}
- (void)_setRowTypeToAddFromPlusButton:(int)type
@@ -473,13 +494,14 @@ var CONTROL_HEIGHT = 16.,
- (void)_sendRuleAction:(id)sender
{
[_ruleEditor _updatePredicate];
[_ruleEditor _sendRuleAction];
}
- (void)_textDidChange:(CPNotification)aNotif
{
if ([[aNotif object] superview] == self && [_ruleEditor _sendsActionOnIncompleteTextChange])
[_ruleEditor _sendRuleAction];
[self _sendRuleAction:nil];
}
@end
+30 -11
View File
@@ -125,6 +125,9 @@ var CPScrollerStyleGlobal = CPScrollerStyleOverlay,
+ (void)initialize
{
if (self !== [CPScrollView class])
return;
var globalValue = [[CPBundle mainBundle] objectForInfoDictionaryKey:@"CPScrollersGlobalStyle"];
if (globalValue == nil || globalValue == -1)
@@ -169,10 +172,10 @@ var CPScrollerStyleGlobal = CPScrollerStyleOverlay,
scrollerWidth = [CPScroller scrollerWidth];
if (hFlag)
frameSize.height -= scrollerWidth;
frameSize.height += scrollerWidth;
if (vFlag)
frameSize.width -= scrollerWidth;
frameSize.width += scrollerWidth;
return frameSize;
}
@@ -210,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];
@@ -751,35 +754,42 @@ Notifies the delegate when the scroll view has finished scrolling.
{
[_horizontalScroller setStyle:_scrollerStyle];
[_horizontalScroller unsetThemeState:CPThemeStateSelected];
switch (_scrollerKnobStyle)
{
case CPScrollerKnobStyleLight:
[_horizontalScroller unsetThemeState:CPThemeStateScrollerKnobDark];
[_horizontalScroller setThemeState:CPThemeStateScrollerKnobLight];
break;
case CPScrollerKnobStyleDark:
[_horizontalScroller unsetThemeState:CPThemeStateScrollerKnobLight];
[_horizontalScroller setThemeState:CPThemeStateScrollerKnobDark];
break;
default:
[_horizontalScroller unsetThemeState:CPThemeStateScrollerKnobLight];
[_horizontalScroller unsetThemeState:CPThemeStateScrollerKnobDark];
}
}
if (_hasVerticalScroller)
{
[_verticalScroller setStyle:_scrollerStyle];
[_verticalScroller unsetThemeState:CPThemeStateSelected];
switch (_scrollerKnobStyle)
{
case CPScrollerKnobStyleLight:
[_verticalScroller unsetThemeState:CPThemeStateScrollerKnobDark];
[_verticalScroller setThemeState:CPThemeStateScrollerKnobLight];
break;
case CPScrollerKnobStyleDark:
[_verticalScroller unsetThemeState:CPThemeStateScrollerKnobLight];
[_verticalScroller setThemeState:CPThemeStateScrollerKnobDark];
break;
default:
[_verticalScroller unsetThemeState:CPThemeStateScrollerKnobLight];
[_verticalScroller unsetThemeState:CPThemeStateScrollerKnobDark];
@@ -790,6 +800,7 @@ Notifies the delegate when the scroll view has finished scrolling.
{
if (_timerScrollersHide)
[_timerScrollersHide invalidate];
_timerScrollersHide = [CPTimer scheduledTimerWithTimeInterval:CPScrollViewFadeOutTime target:self selector:@selector(_hideScrollers:) userInfo:nil repeats:NO];
[[self bottomCornerView] setHidden:YES];
}
@@ -870,6 +881,7 @@ Notifies the delegate when the scroll view has finished scrolling.
var frame = [self _insetBounds];
frame.size.height = _CGRectGetHeight([headerView frame]);
if (SHOULD_SHOW_CORNER_VIEW())
frame.size.width -= _CGRectGetWidth([self _cornerViewFrame]);
@@ -1230,6 +1242,7 @@ Notifies the delegate when the scroll view has finished scrolling.
if (_timerScrollersHide)
[_timerScrollersHide invalidate]
_timerScrollersHide = [CPTimer scheduledTimerWithTimeInterval:CPScrollViewFadeOutTime target:self selector:@selector(_hideScrollers:) userInfo:nil repeats:NO];
}
@@ -1496,21 +1509,27 @@ var CPScrollViewContentViewKey = @"CPScrollViewContentView",
_scrollTimer = nil;
_implementedDelegateMethods = 0;
// Due to the anything goes nature of decoding, our subviews may not exist yet, so layout at the end of the run loop when we're sure everything is in a correct state.
[[CPRunLoop currentRunLoop] performSelector:@selector(_updateCornerAndHeaderView) target:self argument:_contentView order:0 modes:[CPDefaultRunLoopMode]];
[self setScrollerStyle:[aCoder decodeIntForKey:CPScrollViewScrollerStyleKey] || CPScrollerStyleGlobal];
[self setScrollerKnobStyle:[aCoder decodeIntForKey:CPScrollViewScrollerKnobStyleKey] || CPScrollerKnobStyleDefault];
_scrollerStyle = [aCoder decodeObjectForKey:CPScrollViewScrollerStyleKey] || CPScrollerStyleGlobal;
_scrollerKnobStyle = [aCoder decodeObjectForKey:CPScrollViewScrollerKnobStyleKey] || CPScrollerKnobStyleDefault;
[[CPNotificationCenter defaultCenter] addObserver:self
selector:@selector(_didReceiveDefaultStyleChange:)
name:CPScrollerStyleGlobalChangeNotification
object:nil];
selector:@selector(_didReceiveDefaultStyleChange:)
name:CPScrollerStyleGlobalChangeNotification
object:nil];
}
return self;
}
/*!
Do final init that can only be done when we are sure all subviews have been initialized.
*/
- (void)awakeFromCib
{
[self _updateScrollerStyle];
[self _updateCornerAndHeaderView];
}
- (void)encodeWithCoder:(CPCoder)aCoder
{
[super encodeWithCoder:aCoder];
+7 -2
View File
@@ -771,6 +771,7 @@ CPThemeStateScrollerKnobDark = CPThemeState("scroller-knob-dark");
if (_timerFadeOut)
[_timerFadeOut invalidate];
_timerFadeOut = [CPTimer scheduledTimerWithTimeInterval:1.2 target:self selector:@selector(_performFadeOut:) userInfo:nil repeats:NO];
}
@@ -796,10 +797,12 @@ var CPScrollerControlSizeKey = @"CPScrollerControlSize",
if (self = [super initWithCoder:aCoder])
{
_controlSize = CPRegularControlSize;
if ([aCoder containsValueForKey:CPScrollerControlSizeKey])
_controlSize = [aCoder decodeIntForKey:CPScrollerControlSizeKey];
_knobProportion = 1.0;
if ([aCoder containsValueForKey:CPScrollerKnobProportionKey])
_knobProportion = [aCoder decodeFloatForKey:CPScrollerKnobProportionKey];
@@ -809,8 +812,10 @@ var CPScrollerControlSizeKey = @"CPScrollerControlSize",
_allowFadingOut = YES;
_isMouseOver = NO;
var paramAnimFadeOut = [CPDictionary dictionaryWithObjects:[self, CPViewAnimationFadeOutEffect]
forKeys:[CPViewAnimationTargetKey, CPViewAnimationEffectKey]];
var paramAnimFadeOut = [CPDictionary dictionaryWithObjects:[self, CPViewAnimationFadeOutEffect]
forKeys:[CPViewAnimationTargetKey, CPViewAnimationEffectKey]];
_animationScroller = [[CPViewAnimation alloc] initWithDuration:0.2 animationCurve:CPAnimationEaseInOut];
[_animationScroller setViewAnimations:[paramAnimFadeOut]];
[_animationScroller setDelegate:self];
+9 -4
View File
@@ -72,7 +72,7 @@ var RECENT_SEARCH_PREFIX = @" ";
+ (void)initialize
{
if (self != [CPSearchField class])
if (self !== [CPSearchField class])
return;
var bundle = [CPBundle bundleForClass:self];
@@ -173,7 +173,7 @@ var RECENT_SEARCH_PREFIX = @" ";
searchButtonImage = (_searchMenuTemplate === nil) ? CPSearchFieldSearchImage : CPSearchFieldFindImage;
[button setBordered:NO];
[button setImageScaling:CPScaleToFit];
[button setImageScaling:CPImageScaleAxesIndependently];
[button setImage:searchButtonImage];
[button setAutoresizingMask:CPViewMaxXMargin];
}
@@ -215,7 +215,7 @@ var RECENT_SEARCH_PREFIX = @" ";
{
var button = [self cancelButton];
[button setBordered:NO];
[button setImageScaling:CPScaleToFit];
[button setImageScaling:CPImageScaleAxesIndependently];
[button setImage:CPSearchFieldCancelImage];
[button setAlternateImage:CPSearchFieldCancelPressedImage];
[button setAutoresizingMask:CPViewMinXMargin];
@@ -501,7 +501,12 @@ var RECENT_SEARCH_PREFIX = @" ";
if (_CGRectContainsPoint([self searchButtonRectForBounds:[self bounds]], point))
{
if (_searchMenuTemplate == nil)
[self _sendAction:self];
{
if ([_searchButton target] && [_searchButton action])
[_searchButton mouseDown:anEvent];
else
[self _sendAction:self];
}
else
[self _showMenu];
}
+7 -4
View File
@@ -55,7 +55,7 @@ CPSegmentSwitchTrackingMomentary = 2;
+ (id)themeAttributes
{
return [CPDictionary dictionaryWithObjects:[CPCenterTextAlignment, CPCenterVerticalTextAlignment, CPImageLeft, CPScaleNone, _CGInsetMakeZero(), _CGInsetMakeZero(), [CPNull null], [CPNull null], [CPNull null], [CPNull null], 1.0, 24.0]
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"]];
}
@@ -366,11 +366,14 @@ CPSegmentSwitchTrackingMomentary = 2;
@param aSegment the segment to enable/disable
@throws CPRangeException if \c aSegment is out of bounds
*/
- (void)setEnabled:(BOOL)isEnabled forSegment:(unsigned)aSegment
- (void)setEnabled:(BOOL)shouldBeEnabled forSegment:(unsigned)aSegment
{
[_segments[aSegment] setEnabled:isEnabled];
if ([_segments[aSegment] enabled] === shouldBeEnabled)
return;
if (isEnabled)
[_segments[aSegment] setEnabled:shouldBeEnabled];
if (shouldBeEnabled)
_themeStates[aSegment] &= ~CPThemeStateDisabled;
else
_themeStates[aSegment] |= CPThemeStateDisabled;
+1 -1
View File
@@ -61,7 +61,7 @@
_blurRadius = aBlurRadius;
_color = aColor;
_cssString = [_color cssString] + " " + Math.round(anOffset.width) + @"px " + Math.round(anOffset.height) + @"px " + Math.round(_blurRadius) + @"px";
_cssString = [_color cssString] + " " + ROUND(anOffset.width) + @"px " + ROUND(anOffset.height) + @"px " + ROUND(_blurRadius) + @"px";
}
return self;
+1 -1
View File
@@ -54,7 +54,7 @@ var LIGHT_LEFT_INSET = 3.0,
+ (void)initialize
{
if (self != [CPShadowView class])
if (self !== [CPShadowView class])
return;
var bundle = [CPBundle bundleForClass:[self class]];
+141 -141
View File
@@ -60,7 +60,7 @@
- (id)initWithPickerMask:(int)mask colorPanel:(CPColorPanel)owningColorPanel
{
return [super initWithPickerMask:mask colorPanel: owningColorPanel];
return [super initWithPickerMask:mask colorPanel:owningColorPanel];
}
- (id)initView
@@ -70,156 +70,156 @@
_contentView = [[CPView alloc] initWithFrame:aFrame];
[_contentView setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
_rgbLabel = [[CPTextField alloc] initWithFrame: CGRectMake(0, 10, 100, 20)];
[_rgbLabel setStringValue: "Red, Green, Blue"];
_rgbLabel = [[CPTextField alloc] initWithFrame:CGRectMake(0, 10, 100, 20)];
[_rgbLabel setStringValue:"Red, Green, Blue"];
[_rgbLabel setTextColor:[CPColor blackColor]];
_redLabel = [[CPTextField alloc] initWithFrame: CGRectMake(0, 37, 15, 20)];
[_redLabel setStringValue: "R"];
_redLabel = [[CPTextField alloc] initWithFrame:CGRectMake(0, 37, 15, 20)];
[_redLabel setStringValue:"R"];
[_redLabel setTextColor:[CPColor blackColor]];
_redSlider = [[CPSlider alloc] initWithFrame: CGRectMake(15, 35, aFrame.size.width - 70, 20)];
[_redSlider setMaxValue: 1.0];
[_redSlider setMinValue: 0.0];
[_redSlider setTarget: self];
[_redSlider setAction: @selector(sliderChanged:)];
[_redSlider setAutoresizingMask: CPViewWidthSizable];
_redSlider = [[CPSlider alloc] initWithFrame:CGRectMake(15, 35, aFrame.size.width - 70, 20)];
[_redSlider setMaxValue:1.0];
[_redSlider setMinValue:0.0];
[_redSlider setTarget:self];
[_redSlider setAction:@selector(sliderChanged:)];
[_redSlider setAutoresizingMask:CPViewWidthSizable];
// red value input box
_redValue = [[CPTextField alloc] initWithFrame: CGRectMake(aFrame.size.width - 45, 30, 45, 28)];
[_redValue setAutoresizingMask: CPViewMinXMargin];
[_redValue setEditable: YES];
[_redValue setBezeled: YES];
[_redValue setDelegate: self];
[_contentView addSubview: _redValue];
_redValue = [[CPTextField alloc] initWithFrame:CGRectMake(aFrame.size.width - 45, 30, 45, 28)];
[_redValue setAutoresizingMask:CPViewMinXMargin];
[_redValue setEditable:YES];
[_redValue setBezeled:YES];
[_redValue setDelegate:self];
[_contentView addSubview:_redValue];
_greenLabel = [[CPTextField alloc] initWithFrame: CGRectMake(0, 63, 15, 20)];
[_greenLabel setStringValue: "G"];
_greenLabel = [[CPTextField alloc] initWithFrame:CGRectMake(0, 63, 15, 20)];
[_greenLabel setStringValue:"G"];
[_greenLabel setTextColor:[CPColor blackColor]];
_greenSlider = [[CPSlider alloc] initWithFrame: CGRectMake(15, 61, aFrame.size.width - 70, 20)];
[_greenSlider setMaxValue: 1.0];
[_greenSlider setMinValue: 0.0];
[_greenSlider setTarget: self];
[_greenSlider setAction: @selector(sliderChanged:)];
[_greenSlider setAutoresizingMask: CPViewWidthSizable];
_greenSlider = [[CPSlider alloc] initWithFrame:CGRectMake(15, 61, aFrame.size.width - 70, 20)];
[_greenSlider setMaxValue:1.0];
[_greenSlider setMinValue:0.0];
[_greenSlider setTarget:self];
[_greenSlider setAction:@selector(sliderChanged:)];
[_greenSlider setAutoresizingMask:CPViewWidthSizable];
// green value input box
_greenValue = [[CPTextField alloc] initWithFrame: CGRectMake(aFrame.size.width - 45, 56, 45, 28)];
[_greenValue setAutoresizingMask: CPViewMinXMargin];
[_greenValue setEditable: YES];
[_greenValue setBezeled: YES];
[_greenValue setDelegate: self];
[_contentView addSubview: _greenValue];
_greenValue = [[CPTextField alloc] initWithFrame:CGRectMake(aFrame.size.width - 45, 56, 45, 28)];
[_greenValue setAutoresizingMask:CPViewMinXMargin];
[_greenValue setEditable:YES];
[_greenValue setBezeled:YES];
[_greenValue setDelegate:self];
[_contentView addSubview:_greenValue];
_blueLabel = [[CPTextField alloc] initWithFrame: CGRectMake(0, 90, 15, 20)];
[_blueLabel setStringValue: "B"];
_blueLabel = [[CPTextField alloc] initWithFrame:CGRectMake(0, 90, 15, 20)];
[_blueLabel setStringValue:"B"];
[_blueLabel setTextColor:[CPColor blackColor]];
_blueSlider = [[CPSlider alloc] initWithFrame: CGRectMake(15, 87, aFrame.size.width - 70, 20)];
[_blueSlider setMaxValue: 1.0];
[_blueSlider setMinValue: 0.0];
[_blueSlider setTarget: self];
[_blueSlider setAction: @selector(sliderChanged:)];
[_blueSlider setAutoresizingMask: CPViewWidthSizable];
_blueSlider = [[CPSlider alloc] initWithFrame:CGRectMake(15, 87, aFrame.size.width - 70, 20)];
[_blueSlider setMaxValue:1.0];
[_blueSlider setMinValue:0.0];
[_blueSlider setTarget:self];
[_blueSlider setAction:@selector(sliderChanged:)];
[_blueSlider setAutoresizingMask:CPViewWidthSizable];
// blue value input box
_blueValue = [[CPTextField alloc] initWithFrame: CGRectMake(aFrame.size.width - 45, 82, 45, 28)];
[_blueValue setAutoresizingMask: CPViewMinXMargin];
[_blueValue setEditable: YES];
[_blueValue setBezeled: YES];
[_blueValue setDelegate: self];
[_contentView addSubview: _blueValue];
_blueValue = [[CPTextField alloc] initWithFrame:CGRectMake(aFrame.size.width - 45, 82, 45, 28)];
[_blueValue setAutoresizingMask:CPViewMinXMargin];
[_blueValue setEditable:YES];
[_blueValue setBezeled:YES];
[_blueValue setDelegate:self];
[_contentView addSubview:_blueValue];
_hsbLabel = [[CPTextField alloc] initWithFrame: CGRectMake(0, 120, 190, 20)];
[_hsbLabel setStringValue: "Hue, Saturation, Brightness"];
_hsbLabel = [[CPTextField alloc] initWithFrame:CGRectMake(0, 120, 190, 20)];
[_hsbLabel setStringValue:"Hue, Saturation, Brightness"];
[_hsbLabel setTextColor:[CPColor blackColor]];
_hueLabel = [[CPTextField alloc] initWithFrame: CGRectMake(0, 145, 15, 20)];
[_hueLabel setStringValue: "H"];
_hueLabel = [[CPTextField alloc] initWithFrame:CGRectMake(0, 145, 15, 20)];
[_hueLabel setStringValue:"H"];
[_hueLabel setTextColor:[CPColor blackColor]];
_hueSlider = [[CPSlider alloc] initWithFrame: CGRectMake(15, 143, aFrame.size.width - 70, 20)];
[_hueSlider setMaxValue: 359.0];
[_hueSlider setMinValue: 0.0];
[_hueSlider setTarget: self];
[_hueSlider setAction: @selector(sliderChanged:)];
[_hueSlider setAutoresizingMask: CPViewWidthSizable];
_hueSlider = [[CPSlider alloc] initWithFrame:CGRectMake(15, 143, aFrame.size.width - 70, 20)];
[_hueSlider setMaxValue:359.0];
[_hueSlider setMinValue:0.0];
[_hueSlider setTarget:self];
[_hueSlider setAction:@selector(sliderChanged:)];
[_hueSlider setAutoresizingMask:CPViewWidthSizable];
// hue value input box
_hueValue = [[CPTextField alloc] initWithFrame: CGRectMake(aFrame.size.width - 45, 138, 45, 28)];
[_hueValue setAutoresizingMask: CPViewMinXMargin];
[_hueValue setEditable: YES];
[_hueValue setBezeled: YES];
[_hueValue setDelegate: self];
[_contentView addSubview: _hueValue];
_hueValue = [[CPTextField alloc] initWithFrame:CGRectMake(aFrame.size.width - 45, 138, 45, 28)];
[_hueValue setAutoresizingMask:CPViewMinXMargin];
[_hueValue setEditable:YES];
[_hueValue setBezeled:YES];
[_hueValue setDelegate:self];
[_contentView addSubview:_hueValue];
_saturationLabel = [[CPTextField alloc] initWithFrame: CGRectMake(0, 170, 15, 20)];
[_saturationLabel setStringValue: "S"];
_saturationLabel = [[CPTextField alloc] initWithFrame:CGRectMake(0, 170, 15, 20)];
[_saturationLabel setStringValue:"S"];
[_saturationLabel setTextColor:[CPColor blackColor]];
_saturationSlider = [[CPSlider alloc] initWithFrame: CGRectMake(15, 168, aFrame.size.width - 70, 20)];
[_saturationSlider setMaxValue: 100.0];
[_saturationSlider setMinValue: 0.0];
[_saturationSlider setTarget: self];
[_saturationSlider setAction: @selector(sliderChanged:)];
[_saturationSlider setAutoresizingMask: CPViewWidthSizable];
_saturationSlider = [[CPSlider alloc] initWithFrame:CGRectMake(15, 168, aFrame.size.width - 70, 20)];
[_saturationSlider setMaxValue:100.0];
[_saturationSlider setMinValue:0.0];
[_saturationSlider setTarget:self];
[_saturationSlider setAction:@selector(sliderChanged:)];
[_saturationSlider setAutoresizingMask:CPViewWidthSizable];
// saturation value input box
_saturationValue = [[CPTextField alloc] initWithFrame: CGRectMake(aFrame.size.width - 45, 164, 45, 28)];
[_saturationValue setAutoresizingMask: CPViewMinXMargin];
[_saturationValue setEditable: YES];
[_saturationValue setBezeled: YES];
[_saturationValue setDelegate: self];
[_contentView addSubview: _saturationValue];
_saturationValue = [[CPTextField alloc] initWithFrame:CGRectMake(aFrame.size.width - 45, 164, 45, 28)];
[_saturationValue setAutoresizingMask:CPViewMinXMargin];
[_saturationValue setEditable:YES];
[_saturationValue setBezeled:YES];
[_saturationValue setDelegate:self];
[_contentView addSubview:_saturationValue];
_brightnessLabel = [[CPTextField alloc] initWithFrame: CGRectMake(0, 196, 15, 20)];
[_brightnessLabel setStringValue: "B"];
_brightnessLabel = [[CPTextField alloc] initWithFrame:CGRectMake(0, 196, 15, 20)];
[_brightnessLabel setStringValue:"B"];
[_brightnessLabel setTextColor:[CPColor blackColor]];
_brightnessSlider = [[CPSlider alloc] initWithFrame: CGRectMake(15, 194, aFrame.size.width - 70, 20)];
[_brightnessSlider setMaxValue: 100.0];
[_brightnessSlider setMinValue: 0.0];
[_brightnessSlider setTarget: self];
[_brightnessSlider setAction: @selector(sliderChanged:)];
[_brightnessSlider setAutoresizingMask: CPViewWidthSizable];
_brightnessSlider = [[CPSlider alloc] initWithFrame:CGRectMake(15, 194, aFrame.size.width - 70, 20)];
[_brightnessSlider setMaxValue:100.0];
[_brightnessSlider setMinValue:0.0];
[_brightnessSlider setTarget:self];
[_brightnessSlider setAction:@selector(sliderChanged:)];
[_brightnessSlider setAutoresizingMask:CPViewWidthSizable];
// brightness value input box
_brightnessValue = [[CPTextField alloc] initWithFrame: CGRectMake(aFrame.size.width - 45, 190, 45, 28)];
[_brightnessValue setAutoresizingMask: CPViewMinXMargin];
[_brightnessValue setEditable: YES];
[_brightnessValue setBezeled: YES];
[_brightnessValue setDelegate: self];
[_contentView addSubview: _brightnessValue];
_brightnessValue = [[CPTextField alloc] initWithFrame:CGRectMake(aFrame.size.width - 45, 190, 45, 28)];
[_brightnessValue setAutoresizingMask:CPViewMinXMargin];
[_brightnessValue setEditable:YES];
[_brightnessValue setBezeled:YES];
[_brightnessValue setDelegate:self];
[_contentView addSubview:_brightnessValue];
_hexLabel = [[CPTextField alloc] initWithFrame: CGRectMake(0, 230, 30, 20)];
[_hexLabel setStringValue: "Hex"];
_hexLabel = [[CPTextField alloc] initWithFrame:CGRectMake(0, 230, 30, 20)];
[_hexLabel setStringValue:"Hex"];
[_hexLabel setTextColor:[CPColor blackColor]];
//hex input box
_hexValue = [[CPTextField alloc] initWithFrame: CGRectMake(32, 225, 80, 28)];
[_hexValue setEditable: YES];
[_hexValue setBezeled: YES];
[_hexValue setDelegate: self];
[_contentView addSubview: _hexValue];
_hexValue = [[CPTextField alloc] initWithFrame:CGRectMake(32, 225, 80, 28)];
[_hexValue setEditable:YES];
[_hexValue setBezeled:YES];
[_hexValue setDelegate:self];
[_contentView addSubview:_hexValue];
[_contentView addSubview: _rgbLabel];
[_contentView addSubview: _redLabel];
[_contentView addSubview: _greenLabel];
[_contentView addSubview: _blueLabel];
[_contentView addSubview: _redSlider];
[_contentView addSubview: _greenSlider];
[_contentView addSubview: _blueSlider];
[_contentView addSubview:_rgbLabel];
[_contentView addSubview:_redLabel];
[_contentView addSubview:_greenLabel];
[_contentView addSubview:_blueLabel];
[_contentView addSubview:_redSlider];
[_contentView addSubview:_greenSlider];
[_contentView addSubview:_blueSlider];
[_contentView addSubview: _hsbLabel];
[_contentView addSubview: _hueLabel];
[_contentView addSubview: _saturationLabel];
[_contentView addSubview: _brightnessLabel];
[_contentView addSubview: _hueSlider];
[_contentView addSubview: _saturationSlider];
[_contentView addSubview: _brightnessSlider];
[_contentView addSubview:_hsbLabel];
[_contentView addSubview:_hueLabel];
[_contentView addSubview:_saturationLabel];
[_contentView addSubview:_brightnessLabel];
[_contentView addSubview:_hueSlider];
[_contentView addSubview:_saturationSlider];
[_contentView addSubview:_brightnessSlider];
[_contentView addSubview: _hexLabel];
[_contentView addSubview:_hexLabel];
}
- (CPView)provideNewView:(BOOL)initialRequest
@@ -250,35 +250,35 @@
{
case _hueSlider:
case _saturationSlider:
case _brightnessSlider: newColor = [CPColor colorWithHue: [_hueSlider floatValue]
saturation: [_saturationSlider floatValue]
brightness: [_brightnessSlider floatValue]
alpha: alpha];
case _brightnessSlider: newColor = [CPColor colorWithHue:[_hueSlider floatValue]
saturation:[_saturationSlider floatValue]
brightness:[_brightnessSlider floatValue]
alpha:alpha];
[self updateRGBSliders: newColor];
[self updateRGBSliders:newColor];
break;
case _redSlider:
case _greenSlider:
case _blueSlider: newColor = [CPColor colorWithCalibratedRed: [_redSlider floatValue]
green: [_greenSlider floatValue]
blue: [_blueSlider floatValue]
alpha: alpha];
case _blueSlider: newColor = [CPColor colorWithCalibratedRed:[_redSlider floatValue]
green:[_greenSlider floatValue]
blue:[_blueSlider floatValue]
alpha:alpha];
[self updateHSBSliders: newColor];
[self updateHSBSliders:newColor];
break;
}
[self updateLabels];
[self updateHex: newColor];
[colorPanel setColor: newColor];
[self updateHex:newColor];
[colorPanel setColor:newColor];
}
- (void)setColor:(CPColor)aColor
{
[self updateRGBSliders: aColor];
[self updateHSBSliders: aColor];
[self updateHex: aColor];
[self updateRGBSliders:aColor];
[self updateHSBSliders:aColor];
[self updateHex:aColor];
[self updateLabels];
}
@@ -307,13 +307,13 @@
- (void)updateLabels
{
[_hueValue setStringValue: ROUND([_hueSlider floatValue])];
[_saturationValue setStringValue: ROUND([_saturationSlider floatValue])];
[_brightnessValue setStringValue: ROUND([_brightnessSlider floatValue])];
[_hueValue setStringValue:ROUND([_hueSlider floatValue])];
[_saturationValue setStringValue:ROUND([_saturationSlider floatValue])];
[_brightnessValue setStringValue:ROUND([_brightnessSlider floatValue])];
[_redValue setStringValue: ROUND([_redSlider floatValue] * 255)];
[_greenValue setStringValue: ROUND([_greenSlider floatValue] * 255)];
[_blueValue setStringValue: ROUND([_blueSlider floatValue] * 255)];
[_redValue setStringValue:ROUND([_redSlider floatValue] * 255)];
[_greenValue setStringValue:ROUND([_greenSlider floatValue] * 255)];
[_blueValue setStringValue:ROUND([_blueSlider floatValue] * 255)];
}
- (CPImage)provideNewButtonImage
@@ -333,12 +333,12 @@
if (field === _hexValue)
{
var newColor = [CPColor colorWithHexString: value];
var newColor = [CPColor colorWithHexString:value];
if (newColor)
{
[self setColor: newColor];
[[self colorPanel] setColor: newColor];
[self setColor:newColor];
[[self colorPanel] setColor:newColor];
}
}
else
@@ -346,27 +346,27 @@
switch (field)
{
case _redValue: [_redSlider setFloatValue:MAX(MIN(ROUND(value), 255) / 255.0, 0)];
[self sliderChanged: _redSlider];
[self sliderChanged:_redSlider];
break;
case _greenValue: [_greenSlider setFloatValue:MAX(MIN(ROUND(value), 255) / 255.0, 0)];
[self sliderChanged: _greenSlider];
[self sliderChanged:_greenSlider];
break;
case _blueValue: [_blueSlider setFloatValue:MAX(MIN(ROUND(value), 255) / 255.0, 0)];
[self sliderChanged: _blueSlider];
[self sliderChanged:_blueSlider];
break;
case _hueValue: [_hueSlider setFloatValue:MAX(MIN(ROUND(value), 360), 0)];
[self sliderChanged: _hueSlider];
[self sliderChanged:_hueSlider];
break;
case _saturationValue: [_saturationSlider setFloatValue:MAX(MIN(ROUND(value), 100), 0)];
[self sliderChanged: _saturationSlider];
[self sliderChanged:_saturationSlider];
break;
case _brightnessValue: [_brightnessSlider setFloatValue:MAX(MIN(ROUND(value), 100), 0)];
[self sliderChanged: _brightnessSlider];
[self sliderChanged:_brightnessSlider];
break;
}
}
+152 -51
View File
@@ -89,7 +89,7 @@ var CPSplitViewHorizontalImage = nil,
CPString _autosaveName;
BOOL _shouldAutosave;
BOOL _needsRestoreFromAutosave;
CGSize _shouldRestoreFromAutosaveUnlessFrameSize;
BOOL _needsResizeSubviews;
int _suppressResizeNotificationsMask;
@@ -113,12 +113,13 @@ var CPSplitViewHorizontalImage = nil,
*/
+ (void)initialize
{
if (self != [CPSplitView class])
if (self !== [CPSplitView class])
return;
var bundle = [CPBundle bundleForClass:self];
CPSplitViewHorizontalImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPSplitView/CPSplitViewHorizontal.png"] size:CPSizeMake(5.0, 10.0)];
CPSplitViewVerticalImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPSplitView/CPSplitViewVertical.png"] size:CPSizeMake(10.0, 5.0)];
CPSplitViewHorizontalImage = CPImageInBundle("CPSplitView/CPSplitViewHorizontal.png", CGSizeMake(5.0, 10.0), bundle);
CPSplitViewVerticalImage = CPImageInBundle("CPSplitView/CPSplitViewVertical.png", CGSizeMake(10.0, 5.0), bundle);
}
- (id)initWithFrame:(CGRect)aFrame
@@ -178,14 +179,17 @@ var CPSplitViewHorizontalImage = nil,
count = _subviews.length;
if ([self isVertical])
{
for (; index < count; ++index)
[_subviews[index] setFrame:CGRectMake(ROUND((eachSize + dividerThickness) * index), 0, eachSize, frame.size.height)];
}
else
{
for (; index < count; ++index)
[_subviews[index] setFrame:CGRectMake(0, ROUND((eachSize + dividerThickness) * index), frame.size.width, eachSize)];
}
[self setNeedsDisplay:YES];
[self _postNotificationDidResize];
}
@@ -261,7 +265,6 @@ var CPSplitViewHorizontalImage = nil,
rect = CGRectMakeZero();
rect.size = [self frame].size;
rect.size[_sizeComponent] = [self dividerThickness];
rect.origin[_originComponent] = frame.origin[_originComponent] + frame.size[_sizeComponent];
@@ -370,28 +373,33 @@ var CPSplitViewHorizontalImage = nil,
_needsResizeSubviews = NO;
[self resizeSubviewsWithOldSize:[self _calculateSize]];
}
- (CGSize)_calculateSize
{
var subviews = [self subviews],
count = subviews.length,
oldSize = CGSizeMakeZero();
size = CGSizeMakeZero();
if ([self isVertical])
{
oldSize.width += [self dividerThickness] * (count - 1);
oldSize.height = CGRectGetHeight([self frame]);
size.width += [self dividerThickness] * (count - 1);
size.height = CGRectGetHeight([self frame]);
}
else
{
oldSize.width = CGRectGetWidth([self frame]);
oldSize.height += [self dividerThickness] * (count - 1);
size.width = CGRectGetWidth([self frame]);
size.height += [self dividerThickness] * (count - 1);
}
while (count--)
oldSize[_sizeComponent] += [subviews[count] frame].size[_sizeComponent];
size[_sizeComponent] += [subviews[count] frame].size[_sizeComponent];
[self resizeSubviewsWithOldSize:oldSize];
return size;
}
- (BOOL)cursorAtPoint:(CPPoint)aPoint hitDividerAtIndex:(int)anIndex
- (BOOL)cursorAtPoint:(CGPoint)aPoint hitDividerAtIndex:(int)anIndex
{
var frame = [_subviews[anIndex] frame],
startPosition = frame.origin[_originComponent] + frame.size[_sizeComponent],
@@ -444,9 +452,13 @@ var CPSplitViewHorizontalImage = nil,
if (type == CPLeftMouseUp)
{
// We disabled autosaving during tracking.
_shouldAutosave = YES;
if (_currentDivider != CPNotFound)
{
_currentDivider = CPNotFound;
[self _autosave];
[self _updateResizeCursor:anEvent];
}
@@ -455,10 +467,11 @@ var CPSplitViewHorizontalImage = nil,
if (type == CPLeftMouseDown)
{
var point = [self convertPoint:[anEvent locationInWindow] fromView:nil];
var point = [self convertPoint:[anEvent locationInWindow] fromView:nil],
count = [_subviews count] - 1;
_currentDivider = CPNotFound;
var count = [_subviews count] - 1;
for (var i = 0; i < count; i++)
{
var frame = [_subviews[i] frame],
@@ -472,19 +485,19 @@ var CPSplitViewHorizontalImage = nil,
{
var minPosition = [self minPossiblePositionOfDividerAtIndex:i],
maxPosition = [self maxPossiblePositionOfDividerAtIndex:i],
_preCollapsePosition = [_preCollapsePositions objectForKey:"" + i] || 0;
preCollapsePosition = [_preCollapsePositions objectForKey:"" + i] || 0;
if ([_delegate splitView:self canCollapseSubview:_subviews[i]] && [_delegate splitView:self shouldCollapseSubview:_subviews[i] forDoubleClickOnDividerAtIndex:i])
{
if ([self isSubviewCollapsed:_subviews[i]])
[self setPosition:_preCollapsePosition ? _preCollapsePosition : (minPosition + (maxPosition - minPosition) / 2) ofDividerAtIndex:i];
[self setPosition:preCollapsePosition ? preCollapsePosition : (minPosition + (maxPosition - minPosition) / 2) ofDividerAtIndex:i];
else
[self setPosition:minPosition ofDividerAtIndex:i];
}
else if ([_delegate splitView:self canCollapseSubview:_subviews[i + 1]] && [_delegate splitView:self shouldCollapseSubview:_subviews[i + 1] forDoubleClickOnDividerAtIndex:i])
{
if ([self isSubviewCollapsed:_subviews[i + 1]])
[self setPosition:_preCollapsePosition ? _preCollapsePosition : (minPosition + (maxPosition - minPosition) / 2) ofDividerAtIndex:i];
[self setPosition:preCollapsePosition ? preCollapsePosition : (minPosition + (maxPosition - minPosition) / 2) ofDividerAtIndex:i];
else
[self setPosition:maxPosition ofDividerAtIndex:i];
}
@@ -494,6 +507,8 @@ var CPSplitViewHorizontalImage = nil,
_currentDivider = i;
_initialOffset = startPosition - point[_originComponent];
// Don't autosave during a resize. We'll wait until it's done.
_shouldAutosave = NO;
[self _postNotificationWillResize];
}
}
@@ -574,9 +589,11 @@ var CPSplitViewHorizontalImage = nil,
if (sizeA === 0)
canGrow = YES; // Subview is collapsed.
else if (!canShrink &&
[_delegate respondsToSelector:@selector(splitView:canCollapseSubview:)] &&
[_delegate splitView:self canCollapseSubview:_subviews[i]])
[_delegate respondsToSelector:@selector(splitView:canCollapseSubview:)] &&
[_delegate splitView:self canCollapseSubview:_subviews[i]])
{
canShrink = YES; // Subview is collapsible.
}
if (sizeB === 0)
{
@@ -586,9 +603,11 @@ var CPSplitViewHorizontalImage = nil,
canShrink = YES;
}
else if (!canGrow &&
[_delegate respondsToSelector:@selector(splitView:canCollapseSubview:)] &&
[_delegate splitView:self canCollapseSubview:_subviews[i + 1]])
[_delegate respondsToSelector:@selector(splitView:canCollapseSubview:)] &&
[_delegate splitView:self canCollapseSubview:_subviews[i + 1]])
{
canGrow = YES; // Right/lower subview is collapsible.
}
if (_isVertical && canShrink && canGrow)
cursor = [CPCursor resizeLeftRightCursor];
@@ -665,6 +684,7 @@ var CPSplitViewHorizontalImage = nil,
if ([_delegate respondsToSelector:@selector(splitView:constrainMinCoordinate:ofSubviewAt:)])
{
var proposedActualMin = [_delegate splitView:self constrainMinCoordinate:proposedMin ofSubviewAt:dividerIndex];
if (_IS_NUMERIC(proposedActualMin))
actualMin = proposedActualMin;
}
@@ -672,6 +692,7 @@ var CPSplitViewHorizontalImage = nil,
if ([_delegate respondsToSelector:@selector(splitView:constrainMaxCoordinate:ofSubviewAt:)])
{
var proposedActualMax = [_delegate splitView:self constrainMaxCoordinate:proposedMax ofSubviewAt:dividerIndex];
if (_IS_NUMERIC(proposedActualMax))
actualMax = proposedActualMax;
}
@@ -685,6 +706,7 @@ var CPSplitViewHorizontalImage = nil,
if ([_delegate respondsToSelector:@selector(splitView:canCollapseSubview:)])
if ([_delegate splitView:self canCollapseSubview:viewA])
realPosition = proposedMin;
// We can also collapse to the right.
if (position > proposedMax - (proposedMax - actualMax) / 2)
if ([_delegate respondsToSelector:@selector(splitView:canCollapseSubview:)])
@@ -701,21 +723,26 @@ var CPSplitViewHorizontalImage = nil,
*/
- (void)setPosition:(float)position ofDividerAtIndex:(int)dividerIndex
{
// Any manual changes to the divider position should override anything we are restoring from
// autosave.
_shouldRestoreFromAutosaveUnlessFrameSize = nil;
SPLIT_VIEW_SUPPRESS_RESIZE_NOTIFICATIONS(YES);
[self _adjustSubviewsWithCalculatedSize];
var realPosition = [self _realPositionForPosition:position ofDividerAtIndex:dividerIndex];
var viewA = _subviews[dividerIndex],
var realPosition = [self _realPositionForPosition:position ofDividerAtIndex:dividerIndex],
viewA = _subviews[dividerIndex],
frameA = [viewA frame],
viewB = _subviews[dividerIndex + 1],
frameB = [viewB frame],
_preCollapsePosition = 0;
preCollapsePosition = 0,
preSize = frameA.size[_sizeComponent];
var preSize = frameA.size[_sizeComponent];
frameA.size[_sizeComponent] = realPosition - frameA.origin[_originComponent];
if (preSize !== 0 && frameA.size[_sizeComponent] === 0)
_preCollapsePosition = preSize;
preCollapsePosition = preSize;
if (preSize !== frameA.size[_sizeComponent])
{
SPLIT_VIEW_MAYBE_POST_WILL_RESIZE();
@@ -724,11 +751,15 @@ var CPSplitViewHorizontalImage = nil,
}
preSize = frameB.size[_sizeComponent];
var preOrigin = frameB.origin[_originComponent];
frameB.size[_sizeComponent] = frameB.origin[_originComponent] + frameB.size[_sizeComponent] - realPosition - [self dividerThickness];
if (preSize !== 0 && frameB.size[_sizeComponent] === 0)
_preCollapsePosition = frameB.origin[_originComponent];
preCollapsePosition = frameB.origin[_originComponent];
frameB.origin[_originComponent] = realPosition + [self dividerThickness];
if (preSize !== frameB.size[_sizeComponent] || preOrigin !== frameB.origin[_originComponent])
{
SPLIT_VIEW_MAYBE_POST_WILL_RESIZE();
@@ -736,31 +767,28 @@ var CPSplitViewHorizontalImage = nil,
SPLIT_VIEW_MAYBE_POST_DID_RESIZE();
}
if (_preCollapsePosition)
[_preCollapsePositions setObject:_preCollapsePosition forKey:"" + dividerIndex];
if (preCollapsePosition)
[_preCollapsePositions setObject:preCollapsePosition forKey:"" + dividerIndex];
[self setNeedsDisplay:YES];
if (SPLIT_VIEW_DID_SUPPRESS_RESIZE_NOTIFICATION())
[self _postNotificationDidResize];
SPLIT_VIEW_SUPPRESS_RESIZE_NOTIFICATIONS(NO);
}
- (void)setFrameSize:(CGSize)aSize
{
if (_needsRestoreFromAutosave)
if (_shouldRestoreFromAutosaveUnlessFrameSize)
_shouldAutosave = NO;
else
[self _adjustSubviewsWithCalculatedSize];
[super setFrameSize:aSize];
if (_needsRestoreFromAutosave)
{
_needsRestoreFromAutosave = NO;
[self _restoreFromAutosave];
if (_shouldRestoreFromAutosaveUnlessFrameSize)
_shouldAutosave = YES;
}
[self setNeedsDisplay:YES];
}
@@ -773,6 +801,11 @@ var CPSplitViewHorizontalImage = nil,
return;
}
[self adjustSubviews];
}
- (void)adjustSubviews
{
var count = [_subviews count];
if (!count)
@@ -784,6 +817,7 @@ var CPSplitViewHorizontalImage = nil,
var index = 0,
bounds = [self bounds],
boundsSize = bounds.size[_sizeComponent],
oldSize = [self _calculateSize],
dividerThickness = [self dividerThickness],
totalDividers = count - 1,
oldFlexibleSpace = 0,
@@ -810,8 +844,8 @@ var CPSplitViewHorizontalImage = nil,
size = [view frame].size[_sizeComponent];
isSizableMap[index] = isSizable;
viewSizes.push(size);
if (isSizable)
{
oldFlexibleSpace += size;
@@ -831,6 +865,7 @@ var CPSplitViewHorizontalImage = nil,
}
var remainingFixedPanes = count - totalSizablePanes;
for (index = 0; index < count; ++index)
{
var view = _subviews[index],
@@ -858,11 +893,8 @@ var CPSplitViewHorizontalImage = nil,
targetSize = newFlexibleSpace / totalSizablePanes;
targetSize = MAX(0, ROUND(targetSize));
viewFrame.size[_sizeComponent] = targetSize;
[view setFrame:viewFrame];
bounds.origin[_originComponent] += targetSize + dividerThickness;
}
@@ -1002,13 +1034,31 @@ The sum of the views and the sum of the dividers should be equal to the size of
- (void)_postNotificationWillResize
{
[[CPNotificationCenter defaultCenter] postNotificationName:CPSplitViewWillResizeSubviewsNotification object:self];
var userInfo = nil;
if (_currentDivider !== CPNotFound)
userInfo = [CPDictionary dictionaryWithObject:_currentDivider forKey:@"CPSplitViewDividerIndex"];
[[CPNotificationCenter defaultCenter] postNotificationName:CPSplitViewWillResizeSubviewsNotification
object:self
userInfo:userInfo];
}
- (void)_postNotificationDidResize
{
var userInfo = nil;
if (_currentDivider !== CPNotFound)
userInfo = [CPDictionary dictionaryWithObject:_currentDivider forKey:@"CPSplitViewDividerIndex"];
[[CPNotificationCenter defaultCenter] postNotificationName:CPSplitViewDidResizeSubviewsNotification
object:self
userInfo:userInfo];
// TODO Cocoa always autosaves on "viewDidEndLiveResize". If Cappuccino adds support for this we
// should do the same.
[self _autosave];
[[CPNotificationCenter defaultCenter] postNotificationName:CPSplitViewDidResizeSubviewsNotification object:self];
}
/*!
@@ -1020,13 +1070,14 @@ The sum of the views and the sum of the dividers should be equal to the size of
{
if (_autosaveName == autosaveName)
return;
_autosaveName = autosaveName;
}
/*!
Get the name under which the split view divider position is automatically saved to CPUserDefaults.
@return the name to save under or nil if no auto save is active
@return the name to save under or nil if no autosave is active
*/
- (CPString)autosaveName
{
@@ -1038,7 +1089,7 @@ The sum of the views and the sum of the dividers should be equal to the size of
*/
- (void)_autosave
{
if (!_shouldAutosave || !autosaveName)
if (_shouldRestoreFromAutosaveUnlessFrameSize || !_shouldAutosave || !_autosaveName)
return;
var userDefaults = [CPUserDefaults standardUserDefaults],
@@ -1059,6 +1110,22 @@ The sum of the views and the sum of the dividers should be equal to the size of
[userDefaults setObject:preCollapseArray forKey:autosavePrecollapseName];
}
/*!
This is called sometime later after a split view has been restored from a Cib.
See notes in initWithCoder.
@ignore
*/
- (void)_restoreFromAutosaveIfNeeded
{
if (_shouldRestoreFromAutosaveUnlessFrameSize && !_CGSizeEqualToSize([self frameSize], _shouldRestoreFromAutosaveUnlessFrameSize))
{
[self _restoreFromAutosave];
}
_shouldRestoreFromAutosaveUnlessFrameSize = nil;
}
/*!
@ignore
*/
@@ -1079,6 +1146,7 @@ The sum of the views and the sum of the dividers should be equal to the size of
position = 0;
_shouldAutosave = NO;
for (var i = 0, count = [frames count] - 1; i < count; i++)
{
var frame = CPRectFromString(frames[i]);
@@ -1088,12 +1156,14 @@ The sum of the views and the sum of the dividers should be equal to the size of
position += dividerThickness;
}
_shouldAutosave = YES;
}
if (preCollapseArray)
{
_preCollapsePositions = [CPMutableDictionary new];
for (var i = 0, count = [preCollapseArray count]; i < count; i++)
[_preCollapsePositions setObject:preCollapseArray[i] forKey:i + ""];
}
@@ -1106,6 +1176,7 @@ The sum of the views and the sum of the dividers should be equal to the size of
{
if (!theAutosaveName)
return nil;
return @"CPSplitView Subview Frames " + theAutosaveName;
}
@@ -1116,6 +1187,7 @@ The sum of the views and the sum of the dividers should be equal to the size of
{
if (!theAutosaveName)
return nil;
return @"CPSplitView Subview Precollapse Positions " + theAutosaveName;
}
@@ -1135,6 +1207,34 @@ var CPSplitViewDelegateKey = "CPSplitViewDelegateKey",
*/
- (id)initWithCoder:(CPCoder)aCoder
{
// We need to restore this property before calling super's initWithCoder:.
_autosaveName = [aCoder decodeObjectForKey:CPSplitViewAutosaveNameKey];
/*
It is common for the main window of a Cappuccino app window to be resized to match the browser
window size at the end of the UI being loaded from a cib. But at decoding time (now) whatever
window size was originally saved will be in place, so if we try to restore the autosaved divider
positions now they might be constrained to the wrong positions due to the difference in frame size,
and in addition they might move later when the window is resized.
The workaround is to restore the position once now (so it's approximately correct during loading),
and then once more in the next runloop cycle when any `setFullPlatformWindow` calls are done.
(However if the frame size doesn't change before the next cycle, we should not restore the position
again because that would overwrite any changes the app developer might have made in user code.)
The other consideration is that any parent split views need to be restored before any child
subviews, otherwise the parent restore will also change the positioning of the child.
*/
if (_autosaveName)
{
// Schedule /before/ [super initWithCoder:]. This way this instance's _restoreFromAutosaveIfNeeded
// will happen before that of any subviews loaded by [super initWithCoder:].
[[CPRunLoop currentRunLoop] performSelector:@selector(_restoreFromAutosaveIfNeeded) target:self argument:nil order:0 modes:[CPDefaultRunLoopMode]];
}
self = [super initWithCoder:aCoder];
if (self)
@@ -1154,12 +1254,13 @@ var CPSplitViewDelegateKey = "CPSplitViewDelegateKey",
_isPaneSplitter = [aCoder decodeBoolForKey:CPSplitViewIsPaneSplitterKey];
[self _setVertical:[aCoder decodeBoolForKey:CPSplitViewIsVerticalKey]];
[self setAutosaveName:[aCoder decodeObjectForKey:CPSplitViewAutosaveNameKey]];
// We have to wait until we know our frame size before restoring, or the frame resize later will throw
// away the restored size.
if (_autosaveName)
_needsRestoreFromAutosave = YES;
{
[self _restoreFromAutosave];
// Remember the frame size we had at this point so that we can restore again if it changes
// before the next runloop cycle. See above notes.
_shouldRestoreFromAutosaveUnlessFrameSize = [self frameSize];
}
}
return self;
+41 -8
View File
@@ -76,6 +76,22 @@
return [CPStepper stepperWithInitialValue:0.0 minValue:0.0 maxValue:59.0];
}
+ (Class)_binderClassForBinding:(CPString)theBinding
{
if (theBinding == CPValueBinding || theBinding == CPMinValueBinding || theBinding == CPMaxValueBinding)
return [_CPStepperValueBinder class];
return [super _binderClassForBinding:theBinding];
}
- (id)_replacementKeyPathForBinding:(CPString)aBinding
{
if (aBinding == CPValueBinding)
return @"doubleValue";
return [super _replacementKeyPathForBinding:aBinding];
}
/*!
Initializes a CPStepper.
@param aFrame the frame of the control
@@ -144,8 +160,8 @@
minSize = _CGSizeMake(upSize.width, upSize.height + downSize.height),
frame = _CGRectMakeCopy(aFrame);
frame.size.width = Math.max(minSize.width, frame.size.width);
frame.size.height = Math.max(minSize.height, frame.size.height);
frame.size.width = MAX(minSize.width, frame.size.width);
frame.size.height = MAX(minSize.height, frame.size.height);
[super setFrame:frame];
}
@@ -211,8 +227,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]];
}
/*!
@@ -250,6 +265,24 @@
@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
var CPStepperMinValue = @"CPStepperMinValue",
CPStepperMaxValue = @"CPStepperMaxValue",
CPStepperValueWraps = @"CPStepperValueWraps",
@@ -263,10 +296,10 @@ var CPStepperMinValue = @"CPStepperMinValue",
if (self = [super initWithCoder:aCoder])
{
_increment = [aCoder decodeIntForKey:CPStepperIncrement];
_minValue = [aCoder decodeIntForKey:CPStepperMinValue] || 0;
_maxValue = [aCoder decodeIntForKey:CPStepperMaxValue] || 0;
_valueWraps = [aCoder decodeBoolForKey:CPStepperValueWraps] || NO;
_autorepeat = [aCoder decodeBoolForKey:CPStepperAutorepeat] || NO;
_minValue = [aCoder decodeIntForKey:CPStepperMinValue];
_maxValue = [aCoder decodeIntForKey:CPStepperMaxValue];
_valueWraps = [aCoder decodeBoolForKey:CPStepperValueWraps];
_autorepeat = [aCoder decodeBoolForKey:CPStepperAutorepeat];
[self _init];
}
+38 -32
View File
@@ -79,18 +79,15 @@ var CPTabViewDidSelectTabViewItemSelector = 1,
{
_selectedIndex = CPNotFound;
_tabs = [[CPSegmentedControl alloc] initWithFrame:CGRectMake(0, 0, 0, 0)];
_tabs = [[CPSegmentedControl alloc] initWithFrame:_CGRectMake(0, 0, 0, 0)];
[_tabs setHitTests:NO];
var height = [_tabs valueForThemeAttribute:@"default-height"];
[_tabs setFrameSize:CGSizeMake(0, height)];
[_tabs setFrameSize:_CGSizeMake(0, height)];
_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];
}
@@ -273,7 +270,7 @@ var CPTabViewDidSelectTabViewItemSelector = 1,
Selects the item at the specified index.
@param anIndex the index of the item to display.
*/
- (void)selectTabViewItemAtIndex:(unsigned)anIndex
- (BOOL)selectTabViewItemAtIndex:(unsigned)anIndex
{
if (anIndex === _selectedIndex)
return;
@@ -281,7 +278,7 @@ var CPTabViewDidSelectTabViewItemSelector = 1,
var aTabViewItem = [self tabViewItemAtIndex:anIndex];
if ((_delegateSelectors & CPTabViewShouldSelectTabViewItemSelector) && ![_delegate tabView:self shouldSelectTabViewItem:aTabViewItem])
return;
return NO;
if (_delegateSelectors & CPTabViewWillSelectTabViewItemSelector)
[_delegate tabView:self willSelectTabViewItem:aTabViewItem];
@@ -291,6 +288,8 @@ var CPTabViewDidSelectTabViewItemSelector = 1,
if (_delegateSelectors & CPTabViewDidSelectTabViewItemSelector)
[_delegate tabView:self didSelectTabViewItem:aTabViewItem];
return YES;
}
/*!
@@ -341,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)
{
@@ -371,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];
}
}
/*!
@@ -431,31 +441,28 @@ var CPTabViewDidSelectTabViewItemSelector = 1,
{
var segmentIndex = [_tabs testSegment:[_tabs convertPoint:[anEvent locationInWindow] fromView:nil]];
if (segmentIndex != CPNotFound)
{
[self selectTabViewItemAtIndex:segmentIndex];
if (segmentIndex != CPNotFound && [self selectTabViewItemAtIndex:segmentIndex])
[_tabs trackSegment:anEvent];
}
}
- (void)_repositionTabs
{
var horizontalCenterOfSelf = CGRectGetWidth([self bounds]) / 2,
verticalCenterOfTabs = CGRectGetHeight([_tabs bounds]) / 2;
var horizontalCenterOfSelf = _CGRectGetWidth([self bounds]) / 2,
verticalCenterOfTabs = _CGRectGetHeight([_tabs bounds]) / 2;
if (_type === CPBottomTabsBezelBorder)
[_tabs setCenter:CGPointMake(horizontalCenterOfSelf, CGRectGetHeight([self bounds]) - verticalCenterOfTabs)];
[_tabs setCenter:_CGPointMake(horizontalCenterOfSelf, _CGRectGetHeight([self bounds]) - verticalCenterOfTabs)];
else
[_tabs setCenter:CGPointMake(horizontalCenterOfSelf, verticalCenterOfTabs)];
[_tabs setCenter:_CGPointMake(horizontalCenterOfSelf, verticalCenterOfTabs)];
}
- (void)_setSelectedIndex:(CPNumber)index
{
_selectedIndex = index;
[self _setContentViewForItem:[_items objectAtIndex:_selectedIndex]];
[self _setContentViewFromItem:[_items objectAtIndex:_selectedIndex]];
}
- (void)_setContentViewForItem:(CPTabViewItem)anItem
- (void)_setContentViewFromItem:(CPTabViewItem)anItem
{
[_box setContentView:[anItem view]];
}
@@ -472,9 +479,7 @@ var CPTabViewDidSelectTabViewItemSelector = 1,
}
if (_selectedIndex === CPNotFound)
{
[self selectFirstTabViewItem:self];
}
}
@end
@@ -500,7 +505,6 @@ var CPTabViewItemsKey = "CPTabViewItemsKey",
[_items makeObjectsPerformSelector:@selector(_setTabView:) withObject:self];
[self _updateItems];
[self _repositionTabs];
[self setDelegate:[aCoder decodeObjectForKey:CPTabViewDelegateKey]];
@@ -509,6 +513,8 @@ var CPTabViewItemsKey = "CPTabViewItemsKey",
[self selectTabViewItem:selected];
[self setTabViewType:[aCoder decodeIntForKey:CPTabViewTypeKey]];
[self setNeedsLayout];
}
return self;
+1 -1
View File
@@ -138,7 +138,7 @@ CPPressedTab = 2;
_view = aView;
if ([_tabView selectedTabViewItem] == self)
[_tabView _setContentViewForItem:self];
[_tabView _setContentViewFromItem:self];
}
/*!
+37 -8
View File
@@ -494,16 +494,23 @@ CPTableColumnUserResizingMask = 1 << 1;
*/
- (CPSortDescriptor)sortDescriptorPrototype
{
return _sortDescriptorPrototype;
if (_sortDescriptorPrototype)
return _sortDescriptorPrototype;
var binderClass = [[self class] _binderClassForBinding:CPValueBinding],
binding = [binderClass getBinding:CPValueBinding forObject:self];
return [binding _defaultSortDescriptorPrototype];
}
/*!
If NO the tablecolumn will no longer be visible in the tableview
If YES the tablecolumn will be visible in the tableview.
If YES the tablecolumn will no longer be visible in the tableview.
If NO the tablecolumn will be visible in the tableview.
*/
- (void)setHidden:(BOOL)shouldBeHidden
{
shouldBeHidden = !!shouldBeHidden
if (_isHidden === shouldBeHidden)
return;
@@ -569,6 +576,30 @@ CPTableColumnUserResizingMask = 1 << 1;
[tableView reloadDataForRowIndexes:rowIndexes columnIndexes:columnIndexes];
}
- (CPSortDescriptor)_defaultSortDescriptorPrototype
{
if (![self createsSortDescriptor])
return nil;
var keyPath = [_info objectForKey:CPObservedKeyPathKey],
dotIndex = keyPath.indexOf(".");
if (dotIndex === CPNotFound)
return nil;
var firstPart = keyPath.substring(0, dotIndex),
key = keyPath.substring(dotIndex + 1);
return [CPSortDescriptor sortDescriptorWithKey:key ascending:YES];
}
- (BOOL)createsSortDescriptor
{
var options = [_info objectForKey:CPOptionsKey],
optionValue = [options objectForKey:CPCreatesSortDescriptorBindingOption];
return optionValue === nil ? YES : [optionValue boolValue];
}
@end
@implementation CPTableColumn (Bindings)
@@ -678,8 +709,11 @@ CPTableColumnUserResizingMask = 1 << 1;
bindingInfo = binding._info,
destination = [bindingInfo objectForKey:CPObservedObjectKey],
keyPath = [bindingInfo objectForKey:CPObservedKeyPathKey],
options = [bindingInfo objectForKey:CPOptionsKey],
dotIndex = keyPath.lastIndexOf(".");
newValue = [binding reverseTransformValue:newValue withOptions:options];
if (dotIndex === CPNotFound)
[[destination valueForKeyPath:keyPath] replaceObjectAtIndex:aRow withObject:newValue];
else
@@ -696,11 +730,6 @@ CPTableColumnUserResizingMask = 1 << 1;
}
}
//- (void)objectValue
//{
// return nil;
//}
@end
var CPTableColumnIdentifierKey = @"CPTableColumnIdentifierKey",
+63 -5
View File
@@ -39,8 +39,8 @@
+ (id)themeAttributes
{
return [CPDictionary dictionaryWithObjects:[[CPNull null], [CPNull null], CGInsetMakeZero(), [CPNull null], [CPNull null], [CPNull null], CGSizeMakeZero()]
forKeys:[@"background-color", @"text-alignment", @"text-inset", @"text-color", @"text-font", @"text-shadow-color", @"text-shadow-offset"]];
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"]];
}
- (void)initWithFrame:(CGRect)frame
@@ -74,10 +74,11 @@
[_textField setFrame:_CGRectMake(inset.right, inset.top, bounds.size.width - inset.right - inset.left, bounds.size.height - inset.top - inset.bottom)];
[_textField setTextColor:[self currentValueForThemeAttribute:@"text-color"]];
[_textField setFont:[self currentValueForThemeAttribute:@"text-font"]];
[_textField setFont:[self currentValueForThemeAttribute:@"font"]];
[_textField setTextShadowColor:[self currentValueForThemeAttribute:@"text-shadow-color"]];
[_textField setTextShadowOffset:[self currentValueForThemeAttribute:@"text-shadow-offset"]];
[_textField setAlignment:[self currentValueForThemeAttribute:@"text-alignment"]];
[_textField setLineBreakMode:[self currentValueForThemeAttribute:@"line-break-mode"]];
}
- (void)setStringValue:(CPString)string
@@ -102,7 +103,52 @@
- (void)setFont:(CPFont)aFont
{
[self setValue:aFont forThemeAttribute:"text-font"];
[self setValue:aFont forThemeAttribute:@"font"];
}
- (CPFont)font
{
return [self currentValueForThemeAttribute:@"font"]
}
- (void)setAlignment:(CPTextAlignment)alignment
{
[self setValue:alignment forThemeAttribute:@"text-alignment"];
}
- (CPTextAlignment)alignment
{
return [self currentValueForThemeAttribute:@"text-alignment"]
}
- (void)setLineBreakMode:(CPLineBreakMode)mode
{
[self setValue:mode forThemeAttribute:@"line-break-mode"];
}
- (CPLineBreakMode)lineBreakMode
{
return [self currentValueForThemeAttribute:@"line-break-mode"]
}
- (void)setTextColor:(CPColor)aColor
{
[self setValue:aColor forThemeAttribute:@"text-color"];
}
- (CPColor)textColor
{
return [self currentValueForThemeAttribute:@"text-color"]
}
- (void)setTextShadowColor:(CPColor)aColor
{
[self setValue:aColor forThemeAttribute:@"text-shadow-color"];
}
- (CPColor)textShadowColor
{
return [self currentValueForThemeAttribute:@"text-shadow-color"]
}
- (void)_setIndicatorImage:(CPImage)anImage
@@ -122,6 +168,10 @@
var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringValueKey",
_CPTableColumnHeaderViewFontKey = @"_CPTableColumnHeaderViewFontKey",
_CPTableColumnHeaderViewTextColorKey = @"_CPTableColumnHeaderViewTextColorKey",
_CPTableColumnHeaderViewTextShadowColorKey = @"_CPTableColumnHeaderViewTextShadowColorKey",
_CPTableColumnHeaderViewAlignmentKey = @"_CPTableColumnHeaderViewAlignmentKey",
_CPTableColumnHeaderViewLineBreakModeKey = @"_CPTableColumnHeaderViewLineBreakModeKey",
_CPTableColumnHeaderViewImageKey = @"_CPTableColumnHeaderViewImageKey";
@implementation _CPTableColumnHeaderView (CPCoding)
@@ -134,6 +184,10 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal
[self _setIndicatorImage:[aCoder decodeObjectForKey:_CPTableColumnHeaderViewImageKey]];
[self setStringValue:[aCoder decodeObjectForKey:_CPTableColumnHeaderViewStringValueKey]];
[self setFont:[aCoder decodeObjectForKey:_CPTableColumnHeaderViewFontKey]];
[self setTextColor:[aCoder decodeObjectForKey:_CPTableColumnHeaderViewTextColorKey]];
[self setTextShadowColor:[aCoder decodeObjectForKey:_CPTableColumnHeaderViewTextShadowColorKey]];
[self setAlignment:[aCoder decodeIntForKey:_CPTableColumnHeaderViewAlignmentKey]];
[self setLineBreakMode:[aCoder decodeIntForKey:_CPTableColumnHeaderViewLineBreakModeKey]];
}
return self;
@@ -145,7 +199,11 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal
[aCoder encodeObject:[_textField text] forKey:_CPTableColumnHeaderViewStringValueKey];
[aCoder encodeObject:[_textField image] forKey:_CPTableColumnHeaderViewImageKey];
[aCoder encodeObject:[_textField font] forKey:_CPTableColumnHeaderViewFontKey];
[aCoder encodeObject:[self font] forKey:_CPTableColumnHeaderViewFontKey];
[aCoder encodeObject:[self textColor] forKey:_CPTableColumnHeaderViewTextColorKey];
[aCoder encodeObject:[self textShadowColor] forKey:_CPTableColumnHeaderViewTextShadowColorKey];
[aCoder encodeInt:[self alignment] forKey:_CPTableColumnHeaderViewAlignmentKey];
[aCoder encodeInt:[self lineBreakMode] forKey:_CPTableColumnHeaderViewLineBreakModeKey];
}
@end
+153 -57
View File
@@ -29,6 +29,7 @@
@import "CPTableColumn.j"
@import "_CPCornerView.j"
@import "CPScroller.j"
@import "CPCompatibility.j"
CPTableViewColumnDidMoveNotification = @"CPTableViewColumnDidMoveNotification";
@@ -221,6 +222,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
SEL _doubleAction;
CPInteger _clickedRow;
CPInteger _clickedColumn;
unsigned _columnAutoResizingStyle;
int _lastTrackedRowIndex;
@@ -239,6 +241,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
BOOL _disableAutomaticResizing @accessors(property=disableAutomaticResizing);
BOOL _lastColumnShouldSnap;
BOOL _implementsCustomDrawRow;
BOOL _contentBindingExpicitelySet;
CPTableColumn _draggedColumn;
CPArray _differedColumnDataToRemove;
@@ -257,8 +260,8 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
*/
+ (id)themeAttributes
{
return [CPDictionary dictionaryWithObjects:[[CPNull null], [CPNull null], [CPNull null], [CPNull null], [CPNull null], [CPNull null], [CPNull null]]
forKeys:["alternating-row-colors", "grid-color", "highlighted-grid-color", "selection-color", "sourcelist-selection-color", "sort-image", "sort-image-reversed"]];
return [CPDictionary dictionaryWithObjects:[[CPNull null], [CPNull null], [CPNull null], [CPNull null], [CPNull null], [CPNull null], [CPNull null], [CPNull null]]
forKeys:["alternating-row-colors", "grid-color", "highlighted-grid-color", "selection-color", "sourcelist-selection-color", "sort-image", "sort-image-reversed", "selection-radius"]];
}
- (id)initWithFrame:(CGRect)aFrame
@@ -305,6 +308,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
_retargetedDropOperation = nil;
_dragOperationDefaultMask = nil;
_destinationDragStyle = CPTableViewDraggingDestinationFeedbackStyleRegular;
_contentBindingExpicitelySet = NO;
[self setBackgroundColor:[CPColor whiteColor]];
[self _init];
@@ -321,8 +325,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
*/
- (void)_init
{
_tableViewFlags = 0;
_lastSelectedRow = -1;
_lastSelectedRow = _clickedColumn = _clickedRow = -1;
_selectedColumnIndexes = [CPIndexSet indexSet];
_selectedRowIndexes = [CPIndexSet indexSet];
@@ -335,19 +338,17 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
if (!_alternatingRowBackgroundColors)
_alternatingRowBackgroundColors = [[CPColor whiteColor], [CPColor colorWithHexString:@"e4e7ff"]];
_selectionHighlightColor = [CPColor colorWithHexString:@"5f83b9"];
_tableColumnRanges = [];
_dirtyTableColumnRangeIndex = 0;
_numberOfHiddenColumns = 0;
_objectValues = { };
_dataViewsForTableColumns = { };
_dataViews = [];
_numberOfRows = 0;
_exposedRows = [CPIndexSet indexSet];
_exposedColumns = [CPIndexSet indexSet];
_cachedDataViews = { };
_cachedRowHeights = [];
_groupRows = [CPIndexSet indexSet];
@@ -542,8 +543,12 @@ NOT YET IMPLEMENTED
}
/*
* - clickedColumn
Returns the index of the the column the user clicked to trigger an action, or -1 if no column was clicked.
*/
- (CPInteger)clickedColumn
{
return _clickedColumn;
}
/*!
Returns the index of the the row the user clicked to trigger an action, or -1 if no row was clicked.
@@ -727,7 +732,7 @@ NOT YET IMPLEMENTED
- (void)setAlternatingRowBackgroundColors:(CPArray)alternatingRowBackgroundColors
{
[self setValue:alternatingRowBackgroundColors forThemeAttribute:"alternating-row-colors"];
[self setValue:alternatingRowBackgroundColors forThemeAttribute:@"alternating-row-colors"];
[self setNeedsDisplay:YES];
}
@@ -785,7 +790,7 @@ NOT YET IMPLEMENTED
*/
- (void)setSelectionHighlightColor:(CPColor)aColor
{
[self setValue:aColor forThemeAttribute:"selection-color"];
[self setValue:aColor forThemeAttribute:@"selection-color"];
[self setNeedsDisplay:YES];
}
@@ -811,7 +816,7 @@ NOT YET IMPLEMENTED
*/
- (void)setSelectionGradientColors:(CPDictionary)aDictionary
{
[self setValue:aDictionary forThemeAttribute:"sourcelist-selection-color"];
[self setValue:aDictionary forThemeAttribute:@"sourcelist-selection-color"];
[self setNeedsDisplay:YES];
}
@@ -835,7 +840,7 @@ NOT YET IMPLEMENTED
*/
- (void)setGridColor:(CPColor)aColor
{
[self setValue:aColor forThemeAttribute:"grid-color"];
[self setValue:aColor forThemeAttribute:@"grid-color"];
[self setNeedsDisplay:YES];
}
@@ -979,6 +984,13 @@ NOT YET IMPLEMENTED
columnIndexes = [CPIndexSet indexSetWithIndexesInRange:CPMakeRange(fromIndex, toIndex)];
[self reloadDataForRowIndexes:rowIndexes columnIndexes:columnIndexes];
// Notify even if programmatically moving a column as in Cocoa.
// TODO Only notify when a column drag operation ends, not each time a column reaches a new slot?
[[CPNotificationCenter defaultCenter] postNotificationName:CPTableViewColumnDidMoveNotification
object:self
userInfo:[CPDictionary dictionaryWithObjects:[fromIndex, toIndex]
forKeys:[@"CPOldColumn", @"CPNewColumn"]]];
}
/*!
@@ -1261,7 +1273,7 @@ NOT YET IMPLEMENTED
*/
- (int)selectedColumn
{
[_selectedColumnIndexes lastIndex];
return [_selectedColumnIndexes lastIndex];
}
/*!
@@ -2638,7 +2650,7 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
if (_allowsColumnSelection)
{
[self _noteSelectionIsChanging];
if (modifierFlags & CPCommandKeyMask)
if (modifierFlags & CPPlatformActionKeyMask)
{
if ([self isColumnSelected:clickedColumn])
[self deselectColumn:clickedColumn];
@@ -2689,7 +2701,7 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
oldMainSortDescriptor = [[self sortDescriptors] objectAtIndex: 0];
// Remove every main descriptor equivalents (normally only one)
while ((descriptor = [e nextObject]) != nil)
while ((descriptor = [e nextObject]) !== nil)
{
if ([[descriptor key] isEqual: [newMainSortDescriptor key]])
[outdatedDescriptors addObject:descriptor];
@@ -2729,7 +2741,7 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
*/
- (CPImage)_tableHeaderSortImage
{
return [self currentValueForThemeAttribute:"sort-image"];
return [self currentValueForThemeAttribute:@"sort-image"];
}
/*!
@@ -2737,7 +2749,7 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
*/
- (CPImage)_tableHeaderReverseSortImage
{
return [self currentValueForThemeAttribute:"sort-image-reversed"];
return [self currentValueForThemeAttribute:@"sort-image-reversed"];
}
/*!
@@ -2827,11 +2839,8 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
var dataView = [self _newDataViewForRow:row tableColumn:tableColumn];
[dataView setFrame:[self frameOfDataViewAtColumn:columnIndex row:row]];
[dataView setObjectValue:[self _objectValueForTableColumn:tableColumn row:row]];
// If the column uses content bindings, allow them to override the objectValueForTableColumn.
[tableColumn _prepareDataView:dataView forRow:row];
[self _setObjectValueForTableColumn:tableColumn row:row forView:dataView];
[view addSubview:dataView];
row = [theDraggedRows indexGreaterThanIndex:row];
@@ -2872,19 +2881,14 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
dataViewFrame.origin.y = ( _CGRectGetMinY(dataViewFrame) - _CGRectGetMinY([self exposedRect]) ) + 23.0;
[dataView setFrame:dataViewFrame];
[dataView setObjectValue:[self _objectValueForTableColumn:tableColumn row:row]];
[self _setObjectValueForTableColumn:tableColumn row:row forView:dataView];
[dragView addSubview:dataView];
row = [_exposedRows indexGreaterThanIndex:row];
}
// Add the column header view
var headerFrame = [headerView frame];
headerFrame.origin = _CGPointMakeZero();
var columnHeaderView = [[_CPTableColumnHeaderView alloc] initWithFrame:headerFrame];
[columnHeaderView setStringValue:[headerView stringValue]];
[columnHeaderView setThemeState:[headerView themeState]];
// Add a copy of the header view.
var columnHeaderView = [CPKeyedUnarchiver unarchiveObjectWithData:[CPKeyedArchiver archivedDataWithRootObject:headerView]];
[dragView addSubview:columnHeaderView];
[dragView setBackgroundColor:[CPColor whiteColor]];
@@ -3271,11 +3275,8 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
isTextField = [dataView isKindOfClass:[CPTextField class]];
[dataView setFrame:[self frameOfDataViewAtColumn:column row:row]];
[dataView setObjectValue:[self _objectValueForTableColumn:tableColumn row:row]];
// This gives the table column an opportunity to apply its bindings.
// It will override the value set above if there is a binding.
[tableColumn _prepareDataView:dataView forRow:row];
[self _setObjectValueForTableColumn:tableColumn row:row forView:dataView];
if (isColumnSelected || [self isRowSelected:row])
[dataView setThemeState:CPThemeStateSelectedDataView];
@@ -3333,6 +3334,30 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
}
}
- (void)_setObjectValueForTableColumn:(CPTableColumn)aTableColumn row:(CPInteger)aRow forView:(CPView)aDataView
{
if (_implementedDataSourceMethods & CPTableViewDataSource_tableView_objectValueForTableColumn_row_)
[aDataView setObjectValue:[self _objectValueForTableColumn:aTableColumn row:aRow]];
// This gives the table column an opportunity to apply its bindings.
// It will override the value set above if there is a binding.
if (_contentBindingExpicitelySet)
[self _prepareContentBindedDataView:aDataView forRow:aRow];
else
// For both cell-based and view-based
[aTableColumn _prepareDataView:aDataView forRow:aRow];
}
- (void)_prepareContentBindedDataView:(CPView)dataView forRow:(CPInteger)aRow
{
var binder = [CPTableContentBinder getBinding:@"content" forObject:self],
content = [binder content],
rowContent = [content objectAtIndex:aRow];
[dataView setObjectValue:rowContent];
}
/*!
@ignore
*/
@@ -3356,12 +3381,15 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
rowIndex = 0,
rowsCount = rowArray.length;
for (; rowIndex < rowsCount; ++rowIndex)
if (dataViewsForTableColumn)
{
var row = rowArray[rowIndex],
dataView = dataViewsForTableColumn[row];
for (; rowIndex < rowsCount; ++rowIndex)
{
var row = rowArray[rowIndex],
dataView = dataViewsForTableColumn[row];
[dataView setFrame:[self frameOfDataViewAtColumn:column row:row]];
[dataView setFrame:[self frameOfDataViewAtColumn:column row:row]];
}
}
}
}
@@ -3373,6 +3401,14 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
*/
- (void)_commitDataViewObjectValue:(id)sender
{
/*
makeFirstResponder at the end of this method causes the dataview to resign.
If the dataview resigning triggers the action (as CPTextField does), we come right
back here and start an infinite loop. So we have to check this flag first.
*/
if ([sender respondsToSelector:@selector(sendsActionOnEndEditing)] && [sender sendsActionOnEndEditing] && _editingCellIndex === nil)
return;
_editingCellIndex = nil;
if (_implementedDataSourceMethods & CPTableViewDataSource_tableView_setObjectValue_forTableColumn_row_)
@@ -3696,7 +3732,8 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
[_selectedColumnIndexes getIndexes:indexes maxCount:-1 inIndexRange:exposedRange];
}
var count = count2 = [indexes count];
var count,
count2 = count = [indexes count];
if (!count)
return;
@@ -3768,7 +3805,25 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
CGContextStrokePath(context);
}
else
CGContextAddRect(context, rowRect);
{
var radius = [self currentValueForThemeAttribute:@"selection-radius"];
if (radius > 0)
{
var minX = CGRectGetMinX(rowRect),
maxX = CGRectGetMaxX(rowRect),
minY = CGRectGetMinY(rowRect),
maxY = CGRectGetMaxY(rowRect);
CGContextMoveToPoint(context, minX + radius, minY);
CGContextAddArcToPoint(context, maxX, minY, maxX, minY + radius, radius);
CGContextAddArcToPoint(context, maxX, maxY, maxX - radius, maxY, radius);
CGContextAddArcToPoint(context, minX, maxY, minX, maxY - radius, radius);
CGContextAddArcToPoint(context, minX, minY, minX + radius, minY, radius);
}
else
CGContextAddRect(context, rowRect);
}
}
CGContextClosePath(context);
@@ -3817,7 +3872,7 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
}
CGContextClosePath(context);
CGContextSetStrokeColor(context, [self currentValueForThemeAttribute:"highlighted-grid-color"]);
CGContextSetStrokeColor(context, [self currentValueForThemeAttribute:@"highlighted-grid-color"]);
CGContextStrokePath(context);
}
@@ -3986,6 +4041,9 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
*/
- (BOOL)startTrackingAt:(CGPoint)aPoint
{
// Try to become the first responder, but if we can't, that's okay.
[[self window] makeFirstResponder:self];
var row = [self rowAtPoint:aPoint];
// If the user clicks outside a row then deselect everything.
@@ -4013,7 +4071,6 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
if (row >= 0 && !(_implementedDataSourceMethods & CPTableViewDataSource_tableView_writeRowsWithIndexes_toPasteboard_))
[self _updateSelectionWithMouseAtRow:row];
[[self window] makeFirstResponder:self];
return YES;
}
@@ -4139,7 +4196,7 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
_isSelectingSession = NO;
var CLICK_TIME_DELTA = 1000,
columnIndex,
columnIndex = -1,
column,
rowIndex,
shouldEdit = YES;
@@ -4147,6 +4204,7 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
if (_implementedDataSourceMethods & CPTableViewDataSource_tableView_writeRowsWithIndexes_toPasteboard_)
{
rowIndex = [self rowAtPoint:aPoint];
if (rowIndex !== -1)
{
if ([_draggedRowIndexes count] > 0)
@@ -4168,12 +4226,15 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
|| [self infoForBinding:@"content"]))
{
columnIndex = [self columnAtPoint:lastPoint];
if (columnIndex !== -1)
{
column = _tableColumns[columnIndex];
if ([column isEditable])
{
rowIndex = [self rowAtPoint:aPoint];
if (rowIndex !== -1)
{
if (_implementedDelegateMethods & CPTableViewDelegate_tableView_shouldEditTableColumn_row_)
@@ -4193,6 +4254,7 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
if ([[CPApp currentEvent] clickCount] === 2 && _doubleAction)
{
_clickedRow = [self rowAtPoint:aPoint];
_clickedColumn = [self columnAtPoint:lastPoint];
[self sendAction:_doubleAction to:_target];
}
}
@@ -4702,6 +4764,14 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
@implementation CPTableView (Bindings)
+ (id)_binderClassForBinding:(CPString)aBinding
{
if (aBinding == @"content")
return [CPTableContentBinder class];
return [super _binderClassForBinding:aBinding];
}
/*!
@ignore
*/
@@ -4719,17 +4789,45 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
- (void)_establishBindingsIfUnbound:(id)destination
{
if ([[self infoForBinding:@"content"] objectForKey:CPObservedObjectKey] !== destination)
[self bind:@"content" toObject:destination withKeyPath:@"arrangedObjects" options:nil];
{
[super bind:@"content" toObject:destination withKeyPath:@"arrangedObjects" options:nil];
_contentBindingExpicitelySet = NO;
}
if ([[self infoForBinding:@"selectionIndexes"] objectForKey:CPObservedObjectKey] !== destination)
[self bind:@"selectionIndexes" toObject:destination withKeyPath:@"selectionIndexes" options:nil];
// If the content binding was set manually assume the user is taking manual control of establishing bindings.
if (!_contentBindingExpicitelySet)
{
if ([[self infoForBinding:@"selectionIndexes"] objectForKey:CPObservedObjectKey] !== destination)
[self bind:@"selectionIndexes" toObject:destination withKeyPath:@"selectionIndexes" options:nil];
//[self bind:@"sortDescriptors" toObject:destination withKeyPath:@"sortDescriptors" options:nil];
if ([[self infoForBinding:@"sortDescriptors"] objectForKey:CPObservedObjectKey] !== destination)
[self bind:@"sortDescriptors" toObject:destination withKeyPath:@"sortDescriptors" options:nil];
}
}
- (void)setContent:(CPArray)content
- (void)bind:(CPString)aBinding toObject:(id)anObject withKeyPath:(CPString)aKeyPath options:(CPDictionary)options
{
[self reloadData];
[super bind:aBinding toObject:anObject withKeyPath:aKeyPath options:options];
if (aBinding == @"content")
_contentBindingExpicitelySet = YES;
}
@end
@implementation CPTableContentBinder : CPBinder
{
id _content @accessors(property=content);
}
- (void)setValueFor:(id)aBinding
{
var destination = [_info objectForKey:CPObservedObjectKey],
keyPath = [_info objectForKey:CPObservedKeyPathKey];
_content = [destination valueForKey:keyPath];
[_source reloadData];
}
@end
@@ -4777,15 +4875,14 @@ var CPTableViewDataSourceKey = @"CPTableViewDataSourceKey",
_tableColumns = [aCoder decodeObjectForKey:CPTableViewTableColumnsKey] || [];
[_tableColumns makeObjectsPerformSelector:@selector(setTableView:) withObject:self];
if ([aCoder containsValueForKey:CPTableViewRowHeightKey])
_rowHeight = [aCoder decodeFloatForKey:CPTableViewRowHeightKey];
else
_rowHeight = 23.0;
_rowHeight = [aCoder decodeFloatForKey:CPTableViewRowHeightKey] || 23.0;
_intercellSpacing = [aCoder decodeSizeForKey:CPTableViewIntercellSpacingKey];
_intercellSpacing = [aCoder decodeSizeForKey:CPTableViewIntercellSpacingKey] || _CGSizeMake(3.0, 2.0);
if (_CGSizeEqualToSize(_intercellSpacing, _CGSizeMakeZero()))
_intercellSpacing = _CGSizeMake(3.0, 2.0);
[self setGridColor:[aCoder decodeObjectForKey:CPTableViewGridColorKey]];
_gridStyleMask = [aCoder decodeIntForKey:CPTableViewGridStyleMaskKey] || CPTableViewGridNone;
_gridStyleMask = [aCoder decodeIntForKey:CPTableViewGridStyleMaskKey];
_usesAlternatingRowBackgroundColors = [aCoder decodeObjectForKey:CPTableViewUsesAlternatingBackgroundKey];
[self setAlternatingRowBackgroundColors:[aCoder decodeObjectForKey:CPTableViewAlternatingRowColorsKey]];
@@ -4852,9 +4949,8 @@ var CPTableViewDataSourceKey = @"CPTableViewDataSourceKey",
while (index != CPNotFound)
{
var indexSet = (switchFlag) ? otherSet : self;
otherIndex = [indexSet indexGreaterThanOrEqualToIndex:index];
var indexSet = (switchFlag) ? otherSet : self,
otherIndex = [indexSet indexGreaterThanOrEqualToIndex:index];
if (otherIndex == index)
{
+150 -82
View File
@@ -46,7 +46,8 @@ var CPTextFieldDOMInputElement = nil,
CPTextFieldInputIsActive = NO,
CPTextFieldCachedSelectStartFunction = nil,
CPTextFieldCachedDragFunction = nil,
CPTextFieldBlurFunction = nil;
CPTextFieldBlurFunction = nil,
CPTextFieldInputFunction = nil;
#endif
@@ -211,6 +212,25 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
};
if (CPFeatureIsCompatible(CPInputOnInputEventFeature))
{
CPTextFieldInputFunction = function(anEvent)
{
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];
[CPTextFieldInputOwner keyUp:cappEvent];
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
}
CPTextFieldDOMInputElement.oninput = CPTextFieldInputFunction;
}
//FIXME make this not onblur
CPTextFieldDOMInputElement.onblur = CPTextFieldBlurFunction;
@@ -288,6 +308,11 @@ 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];
@@ -470,30 +495,47 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
- (BOOL)becomeFirstResponder
{
#if PLATFORM(DOM)
// FIXME Why do we care about who's the first responder in a different window?
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.
[self _setObserveWindowKeyNotifications:YES];
_isEditing = NO;
if ([[self window] isKeyWindow])
[self _becomeFirstKeyResponder];
return YES;
}
/*!
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
{
[self setThemeState:CPThemeStateEditing];
[self _updatePlaceholderState];
[self setNeedsLayout];
_isEditing = NO;
_stringValue = [self stringValue];
#if PLATFORM(DOM)
var element = [self _inputElement],
font = [self currentValueForThemeAttribute:@"font"];
// generate the font metric
[font _getMetrics];
font = [self currentValueForThemeAttribute:@"font"],
lineHeight = [font defaultLineHeightForFont];
element.value = _stringValue;
element.style.color = [[self currentValueForThemeAttribute:@"text-color"] cssString];
element.style.font = [font cssString];
if (CPFeatureIsCompatible(CPInputSetFontOutsideOfDOM))
element.style.font = [font cssString];
element.style.zIndex = 1000;
switch ([self alignment])
@@ -511,36 +553,46 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
switch (verticalAlign)
{
case CPTopVerticalTextAlignment:
var topPoint = (_CGRectGetMinY(contentRect) + 1) + "px"; // for the same reason we have a -1 for the left, we also have a + 1 here
var topPoint = _CGRectGetMinY(contentRect) + "px";
break;
case CPCenterVerticalTextAlignment:
var topPoint = (_CGRectGetMidY(contentRect) - (font._lineHeight / 2) + 1) + "px";
var topPoint = (_CGRectGetMidY(contentRect) - (lineHeight / 2)) + "px";
break;
case CPBottomVerticalTextAlignment:
var topPoint = (_CGRectGetMaxY(contentRect) - font._lineHeight) + "px";
var topPoint = (_CGRectGetMaxY(contentRect) - lineHeight) + "px";
break;
default:
var topPoint = (_CGRectGetMinY(contentRect) + 1) + "px";
var topPoint = _CGRectGetMinY(contentRect) + "px";
break;
}
element.style.top = topPoint;
element.style.left = (_CGRectGetMinX(contentRect) - 1) + "px"; // why -1?
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 = font._lineHeight + "px"; // private ivar for the line height of the DOM text at this particular size
element.style.height = ROUND(lineHeight) + "px";
element.style.lineHeight = ROUND(lineHeight) + "px";
element.style.verticalAlign = @"top";
_DOMElement.appendChild(element);
// The font change above doesn't work for some browsers if the element isn't already .appendChild'ed.
if (!CPFeatureIsCompatible(CPInputSetFontOutsideOfDOM))
element.style.font = [font cssString];
window.setTimeout(function()
{
element.focus();
// Select the text if the textfield became first responder through keyboard interaction
if (!_willBecomeFirstResponderByClick)
[self selectText:self];
[self _selectText:self immediately:YES];
_willBecomeFirstResponderByClick = NO;
@@ -561,15 +613,11 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
[[self window] platformWindow]._DOMBodyElement.onselectstart = function () {};
}
#endif
return YES;
}
/* @ignore */
- (BOOL)resignFirstResponder
{
[self unsetThemeState:CPThemeStateEditing];
#if PLATFORM(DOM)
var element = [self _inputElement],
@@ -585,24 +633,44 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
// even if the value has not changed.
if ([self _valueIsValid:newValue] === NO)
{
[self setThemeState:CPThemeStateEditing];
element.focus();
return NO;
}
#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;
[self textDidEndEditing:[CPNotification notificationWithName:CPControlTextDidEndEditingNotification object:self userInfo:nil]];
if ([self sendsActionOnEndEditing])
[self sendAction:[self action] to:[self target]];
[self textDidBlur:[CPNotification notificationWithName:CPTextFieldDidBlurNotification object:self userInfo:nil]];
return YES;
}
- (void)_resignFirstKeyResponder
{
[self unsetThemeState:CPThemeStateEditing];
// Cache the formatted string
_stringValue = [self stringValue];
_willBecomeFirstResponderByClick = NO;
[self _updatePlaceholderState];
[self setNeedsLayout];
#if PLATFORM(DOM)
var element = [self _inputElement];
CPTextFieldInputResigning = YES;
if (CPTextFieldInputIsActive)
@@ -629,20 +697,32 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
}
#endif
}
// post CPControlTextDidEndEditingNotification
if (_isEditing)
- (void)_setObserveWindowKeyNotifications:(BOOL)shouldObserve
{
if (shouldObserve)
{
_isEditing = NO;
[self textDidEndEditing:[CPNotification notificationWithName:CPControlTextDidEndEditingNotification object:self userInfo:nil]];
if ([self sendsActionOnEndEditing])
[self sendAction:[self action] to:[self target]];
[[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]];
}
}
[self textDidBlur:[CPNotification notificationWithName:CPTextFieldDidBlurNotification object:self userInfo:nil]];
- (void)_windowDidResignKey:(CPNotification)aNotification
{
if (![[self window] isKeyWindow])
[self _resignFirstKeyResponder];
}
return YES;
- (void)_windowDidBecomeKey:(CPNotification)aNotification
{
if ([[self window] isKeyWindow] && [[self window] firstResponder] === self)
[self _becomeFirstKeyResponder];
}
- (BOOL)_valueIsValid:(CPString)aValue
@@ -656,7 +736,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
var acceptInvalidValue = NO;
if ([_delegate respondsToSelector:@selector(control:didFailToFormatString:errorDescription:)])
acceptInvalidValue = [_delegate control:self didFailToFormatString:[self _inputElement] errorDescription:error];
acceptInvalidValue = [_delegate control:self didFailToFormatString:aValue errorDescription:error];
if (acceptInvalidValue === NO)
return NO;
@@ -1048,8 +1128,16 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
textSize = [text sizeWithFont:font inWidth:textSize.width];
}
else
{
textSize = [text sizeWithFont:font];
// Account for possible fractional pixels at right edge
textSize.width += 1;
}
// Account for possible fractional pixels at bottom edge
textSize.height += 1;
frameSize.height = textSize.height + contentInset.top + contentInset.bottom;
if ([self isBezeled])
@@ -1075,24 +1163,36 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
*/
- (void)selectText:(id)sender
{
// FIXME Should this really make the text field the first responder?
[self _selectText:sender immediately:NO];
}
- (void)_selectText:(id)sender immediately:(BOOL)immediately
{
// Selecting the text in a field makes it the first responder
if (([self isEditable] || [self isSelectable]))
{
var wind = [self window];
#if PLATFORM(DOM)
var element = [self _inputElement];
if ([[self window] firstResponder] === self)
window.setTimeout(function() { element.select(); }, 0);
else if ([self window] !== nil && [[self window] makeFirstResponder:self])
window.setTimeout(function() {[self selectText:sender];}, 0);
if ([wind firstResponder] === self)
{
if (immediately)
element.select();
else
window.setTimeout(function() { element.select(); }, 0);
}
else if (wind !== nil && [wind makeFirstResponder:self])
[self _selectText:sender immediately:immediately];
#else
// Even if we can't actually select the text we need to preserve the first
// responder side effect.
if ([self window] !== nil && [[self window] firstResponder] !== self)
[[self window] makeFirstResponder:self];
if (wind !== nil && [wind firstResponder] !== self)
[wind makeFirstResponder:self];
#endif
}
}
- (void)copy:(id)sender
@@ -1119,7 +1219,8 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
[self copy:sender];
[self deleteBackward:sender];
}
else
// If we don't have an oninput listener, we won't detect the change made by the cut and need to fake a key up "soon".
else if (!CPFeatureIsCompatible(CPInputOnInputEventFeature))
[CPTimer scheduledTimerWithTimeInterval:0.0 target:self selector:@selector(keyUp:) userInfo:nil repeats:NO];
}
@@ -1141,7 +1242,8 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
[self setStringValue:newValue];
[self setSelectedRange:CPMakeRange(selectedRange.location + pasteString.length, 0)];
}
else
// If we don't have an oninput listener, we won't detect the change made by the cut and need to fake a key up "soon".
else if (!CPFeatureIsCompatible(CPInputOnInputEventFeature))
[CPTimer scheduledTimerWithTimeInterval:0.0 target:self selector:@selector(keyUp:) userInfo:nil repeats:NO];
}
@@ -1307,30 +1409,14 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
{
var contentInset = [self currentValueForThemeAttribute:@"content-inset"];
if (!contentInset)
return bounds;
bounds.origin.x += contentInset.left;
bounds.origin.y += contentInset.top;
bounds.size.width -= contentInset.left + contentInset.right;
bounds.size.height -= contentInset.top + contentInset.bottom;
return bounds;
return _CGRectInsetByInset(bounds, contentInset);
}
- (CGRect)bezelRectForBounds:(CGRect)bounds
{
var bezelInset = [self currentValueForThemeAttribute:@"bezel-inset"];
if (_CGInsetIsEmpty(bezelInset))
return bounds;
bounds.origin.x += bezelInset.left;
bounds.origin.y += bezelInset.top;
bounds.size.width -= bezelInset.left + bezelInset.right;
bounds.size.height -= bezelInset.top + bezelInset.bottom;
return bounds;
return _CGRectInsetByInset(bounds, bezelInset);
}
- (CGRect)rectForEphemeralSubviewNamed:(CPString)aName
@@ -1357,7 +1443,6 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
else
{
var view = [[_CPImageAndTextView alloc] initWithFrame:_CGRectMakeZero()];
//[view setImagePosition:CPNoImage];
[view setHitTests:NO];
@@ -1513,32 +1598,15 @@ var CPTextFieldIsEditableKey = "CPTextFieldIsEditableKey",
[self _setPlaceholder:@"" forMarker:CPNullMarker isDefault:YES];
}
- (void)setValueFor:(CPString)theBinding
- (void)setPlaceholderValue:(id)aValue withMarker:(CPString)aMarker forBinding:(CPString)aBinding
{
var destination = [_info objectForKey:CPObservedObjectKey],
keyPath = [_info objectForKey:CPObservedKeyPathKey],
options = [_info objectForKey:CPOptionsKey],
newValue = [destination valueForKeyPath:keyPath],
isPlaceholder = CPIsControllerMarker(newValue);
[_source setPlaceholderString:aValue];
[_source setObjectValue:nil];
}
if (isPlaceholder)
{
if (newValue === CPNotApplicableMarker && [options objectForKey:CPRaisesForNotApplicableKeysBindingOption])
{
[CPException raise:CPGenericException
reason:@"can't transform non applicable key on: " + _source + " value: " + newValue];
}
newValue = [self _placeholderForMarker:newValue];
[_source setPlaceholderString:newValue];
[_source setObjectValue:nil];
}
else
{
newValue = [self transformValue:newValue withOptions:options];
[_source setObjectValue:newValue];
}
- (void)setValue:(id)aValue forBinding:(CPString)aBinding
{
[_source setObjectValue:aValue];
}
@end
+4 -1
View File
@@ -255,7 +255,7 @@ var CPThemesByName = { },
attributeNames = [attributes keyEnumerator],
objectThemeClass = [anObject themeClass];
while (attributeName = [attributeNames nextObject])
while ((attributeName = [attributeNames nextObject]) !== nil)
[self _recordAttribute:[attributes objectForKey:attributeName] forClass:objectThemeClass];
}
@@ -418,6 +418,9 @@ CPThemeStateEditing = CPThemeState("editing");
CPThemeStateVertical = CPThemeState("vertical");
CPThemeStateDefault = CPThemeState("default");
CPThemeStateCircular = CPThemeState("circular");
CPThemeStateAutocompleting = CPThemeState("autocompleting");
CPThemeStateMainWindow = CPThemeState("mainWindow");
CPThemeStateKeyWindow = CPThemeState("keyWindow");
@implementation _CPThemeAttribute : CPObject
{
+580 -473
View File
File diff suppressed because it is too large Load Diff
+126 -40
View File
@@ -58,9 +58,6 @@ CPToolbarSizeModeSmall = 2;
var CPToolbarsByIdentifier = nil,
CPToolbarConfigurationsByIdentifier = nil;
var TOOLBAR_REGULAR_HEIGHT = 59.0,
TOOLBAR_SMALL_HEIGHT = 46.0;
/*!
@ingroup appkit
@class CPToolbar
@@ -91,11 +88,12 @@ var TOOLBAR_REGULAR_HEIGHT = 59.0,
@implementation CPToolbar : CPObject
{
CPString _identifier;
CPToolbarDisplayMode _displayMode;
CPToolbarDisplayMode _displayMode @accessors(property=displayMode);
BOOL _showsBaselineSeparator;
BOOL _allowsUserCustomization;
BOOL _isVisible;
int _sizeMode @accessors(property=sizeMode);
int _desiredHeight;
id _delegate;
@@ -116,7 +114,7 @@ var TOOLBAR_REGULAR_HEIGHT = 59.0,
/* @ignore */
+ (void)initialize
{
if (self != [CPToolbar class])
if (self !== [CPToolbar class])
return;
CPToolbarsByIdentifier = [CPDictionary dictionary];
@@ -137,6 +135,19 @@ var TOOLBAR_REGULAR_HEIGHT = 59.0,
[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:@""];
@@ -158,6 +169,7 @@ var TOOLBAR_REGULAR_HEIGHT = 59.0,
_identifier = anIdentifier;
_isVisible = YES;
_sizeMode = CPToolbarSizeModeDefault;
_desiredHeight = 0;
[CPToolbar _addToolbar:self forIdentifier:_identifier];
}
@@ -229,7 +241,13 @@ var TOOLBAR_REGULAR_HEIGHT = 59.0,
- (void)_setWindow:(CPWindow)aWindow
{
if (_window)
[[CPNotificationCenter defaultCenter] removeObserver:self object:_window];
_window = aWindow;
if (_window)
[[CPNotificationCenter defaultCenter] addObserver:self selector:@selector(_autoValidateVisibleItems) name:_CPWindowDidChangeFirstResponderNotification object:aWindow];
}
/*!
@@ -246,6 +264,15 @@ var TOOLBAR_REGULAR_HEIGHT = 59.0,
[self _reloadToolbarItems];
}
- (void)setDisplayMode:(CPToolbarDisplayMode)aDisplayMode
{
if (_displayMode === aDisplayMode)
return;
_displayMode = aDisplayMode;
[self _reloadToolbarItems];
}
/* @ignore */
- (void)_loadConfiguration
{
@@ -254,7 +281,18 @@ var TOOLBAR_REGULAR_HEIGHT = 59.0,
- (CGRect)_toolbarViewFrame
{
return CPRectMake(0.0, 0.0, 1200.0, _sizeMode != CPToolbarSizeModeSmall ? TOOLBAR_REGULAR_HEIGHT : TOOLBAR_SMALL_HEIGHT);
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];
}
/* @ignore */
@@ -282,13 +320,17 @@ var TOOLBAR_REGULAR_HEIGHT = 59.0,
// _defaultItems may have been loaded from Cib
_itemIdentifiers = [_defaultItems valueForKey:@"itemIdentifier"] || [];
if (_delegate)
if ([_delegate respondsToSelector:@selector(toolbarDefaultItemIdentifiers:)])
{
var itemIdentifiersFromDelegate = [[_delegate toolbarDefaultItemIdentifiers:self] mutableCopy];
var itemIdentifiersFromDelegate = [_delegate toolbarDefaultItemIdentifiers:self];
// If we get items both from the Cib and from the delegate method, put the delegate items before the
// Cib ones.
if (itemIdentifiersFromDelegate)
_itemIdentifiers = [_itemIdentifiers arrayByAddingObjectsFromArray:itemIdentifiersFromDelegate];
_itemIdentifiers = [itemIdentifiersFromDelegate arrayByAddingObjectsFromArray:_itemIdentifiers];
}
// If we didn't load from a cib and the delegate hasn't been set yet, we'll just work with an empty list
// at this point.
var index = 0,
count = [_itemIdentifiers count];
@@ -357,12 +399,26 @@ var TOOLBAR_REGULAR_HEIGHT = 59.0,
each visible toolbar item.
*/
- (void)validateVisibleItems
{
[self _validateVisibleItems:NO]
}
- (void)_autoValidateVisibleItems
{
[self _validateVisibleItems:YES]
}
- (void)_validateVisibleItems:(BOOL)isAutovalidation
{
var toolbarItems = [self visibleItems],
count = [toolbarItems count];
while (count--)
[toolbarItems[count] validate];
{
var item = [toolbarItems objectAtIndex:count];
if (!isAutovalidation || [item autovalidates])
[item validate];
}
}
/* @ignore */
@@ -536,8 +592,7 @@ var _CPToolbarViewBackgroundColor = nil,
_CPToolbarViewExtraItemsImage = nil,
_CPToolbarViewExtraItemsAlternateImage = nil;
var TOOLBAR_TOP_MARGIN = 5.0,
TOOLBAR_ITEM_MARGIN = 10.0,
var TOOLBAR_ITEM_MARGIN = 10.0,
TOOLBAR_EXTRA_ITEMS_WIDTH = 20.0;
var _CPToolbarItemInfoMake = function(anIndex, aView, aLabel, aMinWidth)
@@ -575,9 +630,9 @@ var _CPToolbarItemInfoMake = function(anIndex, aView, aLabel, aMinWidth)
var bundle = [CPBundle bundleForClass:self];
_CPToolbarViewExtraItemsImage = [[CPImage alloc] initWithContentsOfFile: [bundle pathForResource:"_CPToolbarView/_CPToolbarViewExtraItemsImage.png"] size:CPSizeMake(10.0, 15.0)];
_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)];
_CPToolbarViewExtraItemsAlternateImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:"_CPToolbarView/_CPToolbarViewExtraItemsAlternateImage.png"] size:_CGSizeMake(10.0, 15.0)];
}
- (id)initWithFrame:(CGRect)aFrame
@@ -591,7 +646,7 @@ var _CPToolbarItemInfoMake = function(anIndex, aView, aLabel, aMinWidth)
_labelColor = [CPColor blackColor];
_labelShadowColor = [CPColor colorWithWhite:1.0 alpha:0.75];
_additionalItemsButton = [[CPPopUpButton alloc] initWithFrame:CGRectMake(0.0, 0.0, 10.0, 15.0) pullsDown:YES];
_additionalItemsButton = [[CPPopUpButton alloc] initWithFrame:_CGRectMake(0.0, 0.0, 10.0, 15.0) pullsDown:YES];
[_additionalItemsButton setBordered:NO];
[_additionalItemsButton setImagePosition:CPImageOnly];
@@ -643,7 +698,7 @@ var _CPToolbarItemInfoMake = function(anIndex, aView, aLabel, aMinWidth)
{
// We begin by recalculating the visible items.
var items = [_toolbar items],
itemsWidth = CGRectGetWidth([self bounds]),
itemsWidth = _CGRectGetWidth([self bounds]),
minWidth = _minWidth,
// FIXME: This should be a CPSet.
invisibleItemsSortedByPriority = [];
@@ -693,6 +748,24 @@ var _CPToolbarItemInfoMake = function(anIndex, aView, aLabel, aMinWidth)
height = minSize.height;
}
// 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"],
newDesiredHeight = height ? height + contentInset.top + contentInset.bottom : 0;
if (newDesiredHeight != _toolbar._desiredHeight)
{
// FIXME Probably the toolbar view shouldn't be telling the toolbar which height it should be. Maybe refactor
// to just have the toolbar scan the toolbar items whenever the items change.
_toolbar._desiredHeight = newDesiredHeight;
[self setFrame:[_toolbar _toolbarViewFrame]];
[_toolbar._window _noteToolbarChanged];
// The above will cause tile to be called again.
return;
}
// Determine all the items that have flexible width.
// Also determine the height of the toolbar.
var count = _visibleItems.length,
@@ -712,7 +785,7 @@ var _CPToolbarItemInfoMake = function(anIndex, aView, aLabel, aMinWidth)
// static width (min==max). This handles the case where the user did setView:
// with a view of a different size than minSize/maxSize
else
[view setFrameSize:CGSizeMake(minSize.width, height)];
[view setFrameSize:_CGSizeMake(minSize.width, height)];
[view setHidden:NO];
}
@@ -747,21 +820,23 @@ var _CPToolbarItemInfoMake = function(anIndex, aView, aLabel, aMinWidth)
remainingSpace += proposedWidth - constrainedWidth;
}
[view setFrameSize:CGSizeMake(constrainedWidth, height)];
[view setFrameSize:_CGSizeMake(constrainedWidth, height)];
}
}
// Now that all the visible items are the correct width, give them their final frames.
var index = 0,
count = _visibleItems.length,
x = TOOLBAR_ITEM_MARGIN;
x = contentInset.left,
contentInset = [_toolbar _valueForThemeAttribute:@"content-inset"],
y = contentInset.top;
for (; index < count; ++index)
{
var view = [self viewForItem:_visibleItems[index]],
viewWidth = CGRectGetWidth([view frame]);
viewWidth = _CGRectGetWidth([view frame]);
[view setFrame:CGRectMake(x, 0.0, viewWidth, height)];
[view setFrame:_CGRectMake(x, y, viewWidth, height)];
x += viewWidth + TOOLBAR_ITEM_MARGIN;
}
@@ -795,7 +870,7 @@ var _CPToolbarItemInfoMake = function(anIndex, aView, aLabel, aMinWidth)
if (needsAdditionalItemsButton)
{
[_additionalItemsButton setFrameOrigin:CGPointMake(itemsWidth + 5.0, (CGRectGetHeight([self bounds]) - CGRectGetHeight([_additionalItemsButton frame])) / 2.0)];
[_additionalItemsButton setFrameOrigin:_CGPointMake(itemsWidth + 5.0, (_CGRectGetHeight([self bounds]) - _CGRectGetHeight([_additionalItemsButton frame])) / 2.0)];
[self addSubview:_additionalItemsButton];
@@ -906,8 +981,7 @@ var _CPToolbarItemVisibilityPriorityCompare = function(lhs, rhs)
return CPOrderedDescending;
};
var TOP_MARGIN = 5.0,
LABEL_MARGIN = 2.0;
var LABEL_MARGIN = 2.0;
@implementation _CPToolbarItemView : CPControl
{
@@ -934,12 +1008,12 @@ var TOP_MARGIN = 5.0,
{
_toolbarItem = aToolbarItem;
_labelField = [[CPTextField alloc] initWithFrame:CGRectMakeZero()];
_labelField = [[CPTextField alloc] initWithFrame:_CGRectMakeZero()];
[_labelField setFont:[CPFont systemFontOfSize:11.0]];
[_labelField setTextColor:[self FIXME_labelColor]];
[_labelField setTextShadowColor:[self FIXME_labelShadowColor]];
[_labelField setTextShadowOffset:CGSizeMake(0.0, 1.0)];
[_labelField setTextShadowOffset:_CGSizeMake(0.0, 1.0)];
[_labelField setAutoresizingMask:CPViewWidthSizable | CPViewMinXMargin];
[self addSubview:_labelField];
@@ -986,11 +1060,11 @@ var TOP_MARGIN = 5.0,
if (identifier === CPToolbarSeparatorItemIdentifier)
{
_view = [[CPView alloc] initWithFrame:CGRectMake(0.0, 0.0, 2.0, 32.0)];
_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)];
sizes[@"CPToolbarItemSeparator"] = [_CGSizeMake(2.0, 26.0), _CGSizeMake(2.0, 1.0), _CGSizeMake(2.0, 26.0)];
[_view setBackgroundColor:_CPControlThreePartImagePattern(YES, sizes, @"CPToolbarItem", @"Separator")];
[self addSubview:_view];
@@ -1024,7 +1098,7 @@ var TOP_MARGIN = 5.0,
{
_imageView = [[CPImageView alloc] initWithFrame:[self bounds]];
[_imageView setImageScaling:CPScaleProportionally];
[_imageView setImageScaling:CPImageScaleProportionallyDown];
[self addSubview:_imageView];
}
@@ -1042,8 +1116,13 @@ var TOP_MARGIN = 5.0,
_labelSize = [_labelField frame].size;
_minSize = CGSizeMake(MAX(_labelSize.width, minSize.width), _labelSize.height + minSize.height + LABEL_MARGIN + TOP_MARGIN);
_maxSize = CGSizeMake(MAX(_labelSize.width, maxSize.width), 100000000.0);
var iconOnly = [[_toolbarItem toolbar] displayMode] === CPToolbarDisplayModeIconOnly,
labelOnly = [[_toolbarItem toolbar] displayMode] === CPToolbarDisplayModeLabelOnly;
[_labelField setHidden:iconOnly];
[_view setHidden:labelOnly];
_minSize = _CGSizeMake(MAX(_labelSize.width, minSize.width), (labelOnly ? 0 : minSize.height) + (iconOnly ? 0 : _labelSize.height + LABEL_MARGIN));
_maxSize = _CGSizeMake(MAX(_labelSize.width, maxSize.width), 100000000.0);
[_toolbar tile];
}
@@ -1060,20 +1139,23 @@ var TOP_MARGIN = 5.0,
width = _CGRectGetWidth(bounds);
if (identifier === CPToolbarSeparatorItemIdentifier)
return [_view setFrame:CGRectMake(ROUND((width - 2.0) / 2.0), 0.0, 2.0, _CGRectGetHeight(bounds))];
return [_view setFrame:_CGRectMake(ROUND((width - 2.0) / 2.0), 0.0, 2.0, _CGRectGetHeight(bounds))];
// The view is centred in the available space above the label.
var view = _view || _imageView,
itemMaxSize = [_toolbarItem maxSize],
height = _CGRectGetHeight(bounds) - _labelSize.height - LABEL_MARGIN - TOP_MARGIN,
iconOnly = [[_toolbarItem toolbar] displayMode] === CPToolbarDisplayModeIconOnly,
height = _CGRectGetHeight(bounds) - (iconOnly ? 0 : _labelSize.height),
viewWidth = MIN(itemMaxSize.width, width),
viewHeight = MIN(itemMaxSize.height, height);
[view setFrame:CGRectMake( ROUND((width - viewWidth) / 2.0),
TOP_MARGIN + ROUND((height - viewHeight) / 2.0),
viewWidth,
viewHeight)];
[view setFrame:_CGRectMake(ROUND((width - viewWidth) / 2.0),
ROUND((height - viewHeight) / 2.0),
viewWidth,
viewHeight)];
[_labelField setFrameOrigin:CGPointMake(ROUND((width - _labelSize.width) / 2.0), TOP_MARGIN + height + LABEL_MARGIN)];
// Label is always drawn at the bottom of the view. So if the view is really tall but the icon is tiny, the icon is centred above the label while the label remains on the bottom.
[_labelField setFrameOrigin:_CGPointMake(ROUND((width - _labelSize.width) / 2.0), _CGRectGetHeight(bounds) - _labelSize.height)];
}
- (void)mouseDown:(CPEvent)anEvent
@@ -1093,6 +1175,10 @@ var TOP_MARGIN = 5.0,
- (void)setEnabled:(BOOL)shouldBeEnabled
{
// Tiling is very expensive so try to avoid it. The CPToolbarItem should already be careful to not notifying about its enabled state needlessly.
if ([self isEnabled] === shouldBeEnabled)
return;
[super setEnabled:shouldBeEnabled];
if (shouldBeEnabled)
@@ -1136,7 +1222,7 @@ var TOP_MARGIN = 5.0,
if (alternateImage)
[_imageView setImage:alternateImage];
[_labelField setTextShadowOffset:CGSizeMakeZero()];
[_labelField setTextShadowOffset:_CGSizeMakeZero()];
}
else
{
@@ -1145,7 +1231,7 @@ var TOP_MARGIN = 5.0,
if (image)
[_imageView setImage:image];
[_labelField setTextShadowOffset:CGSizeMake(0.0, 1.0)];
[_labelField setTextShadowOffset:_CGSizeMake(0.0, 1.0)];
}
[_labelField setTextShadowColor:[self FIXME_labelShadowColor]];
+32 -6
View File
@@ -275,6 +275,9 @@ CPToolbarPrintItemIdentifier = @"CPToolbarPrintItem";
*/
- (void)setEnabled:(BOOL)shouldBeEnabled
{
if (_isEnabled === shouldBeEnabled)
return;
if ([_view respondsToSelector:@selector(setEnabled:)])
[_view setEnabled:shouldBeEnabled];
@@ -457,26 +460,49 @@ CPToolbarItemVisibilityPriorityUser
if (_view)
{
if ([target respondsToSelector:@selector(validateToolbarItem:)])
[self setEnabled:[target validateToolbarItem:self]];
{
var shouldBeEnabled = [target validateToolbarItem:self];
if (_isEnabled !== shouldBeEnabled)
[self setEnabled:shouldBeEnabled];
}
return;
}
if (!action)
return [self setEnabled:NO];
{
if (_isEnabled)
return [self setEnabled:NO];
return;
}
if (target && ![target respondsToSelector:action])
return [self setEnabled:NO];
{
if (_isEnabled)
return [self setEnabled:NO];
return;
}
target = [CPApp targetForAction:action to:target from:self];
if (!target)
return [self setEnabled:NO];
{
if (_isEnabled)
return [self setEnabled:NO];
return;
}
if ([target respondsToSelector:@selector(validateToolbarItem:)])
[self setEnabled:[target validateToolbarItem:self]];
{
var shouldBeEnabled = [target validateToolbarItem:self];
if (_isEnabled !== shouldBeEnabled)
[self setEnabled:shouldBeEnabled];
}
else
[self setEnabled:YES];
{
if (!_isEnabled)
[self setEnabled:YES];
}
}
- (BOOL)autovalidates
+347 -75
View File
@@ -21,14 +21,14 @@
*/
@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 "CPGeometry.j"
@import "CPGraphicsContext.j"
@import "CPResponder.j"
@import "CPTheme.j"
@@ -98,6 +98,7 @@ var CPViewFlags = { },
CPViewHasCustomDrawRect = 1 << 0,
CPViewHasCustomLayoutSubviews = 1 << 1;
/*!
@ingroup appkit
@class CPView
@@ -189,7 +190,10 @@ var CPViewFlags = { },
unsigned _viewClassFlags;
// ToolTips
CPString _toolTip @accessors(property=toolTip);
CPString _toolTip @accessors(getter=toolTip);
Function _toolTipFunctionIn;
Function _toolTipFunctionOut;
BOOL _toolTipInstalled;
}
/*
@@ -215,7 +219,7 @@ var CPViewFlags = { },
CachedNotificationCenter = [CPNotificationCenter defaultCenter];
}
- (void)setupViewFlags
- (void)_setupViewFlags
{
var theClass = [self class],
classUID = [theClass UID];
@@ -236,6 +240,13 @@ var CPViewFlags = { },
_viewClassFlags = CPViewFlags[classUID];
}
- (void)_setupToolTipHandlers
{
_toolTipInstalled = NO;
_toolTipFunctionIn = function(e) { [_CPToolTip scheduleToolTipForView:self]; }
_toolTipFunctionOut = function(e) { [_CPToolTip invalidateCurrentToolTipIfNeeded]; };
}
+ (CPSet)keyPathsForValuesAffectingFrame
{
return [CPSet setWithObjects:@"frameOrigin", @"frameSize"];
@@ -302,7 +313,8 @@ var CPViewFlags = { },
_theme = [CPTheme defaultTheme];
_themeState = CPThemeStateNormal;
[self setupViewFlags];
[self _setupToolTipHandlers];
[self _setupViewFlags];
[self _loadThemeAttributes];
}
@@ -310,6 +322,82 @@ var CPViewFlags = { },
return self;
}
/*!
Sets the tooltip for the receiver.
@param aToolTip the tooltip
*/
- (void)setToolTip:(CPString)aToolTip
{
if (_toolTip == aToolTip)
return;
if (aToolTip && ![aToolTip isKindOfClass:CPString])
aToolTip = [aToolTip description];
_toolTip = aToolTip;
if (_toolTip)
[self _installToolTipEventHandlers];
else
[self _uninstallToolTipEventHandlers];
}
/*! @ignore
Install the handlers for the tooltip
*/
- (void)_installToolTipEventHandlers
{
if (_toolTipInstalled)
return;
#if PLATFORM(DOM)
if (_DOMElement.addEventListener)
{
_DOMElement.addEventListener("mouseover", _toolTipFunctionIn, NO);
_DOMElement.addEventListener("keypress", _toolTipFunctionOut, NO);
_DOMElement.addEventListener("mouseout", _toolTipFunctionOut, NO);
}
else if (_DOMElement.attachEvent)
{
_DOMElement.attachEvent("onmouseover", _toolTipFunctionIn);
_DOMElement.attachEvent("onkeypress", _toolTipFunctionOut);
_DOMElement.attachEvent("onmouseout", _toolTipFunctionOut);
}
#endif
_toolTipInstalled = YES;
}
/*! @ignore
Uninstall the handlers for the tooltip
*/
- (void)_uninstallToolTipEventHandlers
{
if (!_toolTipInstalled)
return;
#if PLATFORM(DOM)
if (_DOMElement.removeEventListener)
{
_DOMElement.removeEventListener("mouseover", _toolTipFunctionIn, NO);
_DOMElement.removeEventListener("keypress", _toolTipFunctionOut, NO);
_DOMElement.removeEventListener("mouseout", _toolTipFunctionOut, NO);
}
else if (_DOMElement.detachEvent)
{
_DOMElement.detachEvent("onmouseover", _toolTipFunctionIn);
_DOMElement.detachEvent("onkeypress", _toolTipFunctionOut);
_DOMElement.detachEvent("onmouseout", _toolTipFunctionOut);
}
#endif
_toolTipInstalled = NO;
}
/*!
Returns the container view of the receiver
@return the receiver's containing view
@@ -369,6 +457,9 @@ var CPViewFlags = { },
/* @ignore */
- (void)_insertSubview:(CPView)aSubview atIndex:(int)anIndex
{
if (aSubview === self)
[CPException raise:CPInvalidArgumentException reason:"can't add a view as a subview of itself"];
// We will have to adjust the z-index of all views starting at this index.
var count = _subviews.length;
@@ -475,7 +566,7 @@ var CPViewFlags = { },
*/
- (void)replaceSubview:(CPView)aSubview with:(CPView)aView
{
if (aSubview._superview != self)
if (aSubview._superview !== self)
return;
var index = [_subviews indexOfObjectIdenticalTo:aSubview];
@@ -531,7 +622,7 @@ var CPViewFlags = { },
var addedSubview = nil,
addedSubviewEnumerator = [addedSubviews objectEnumerator];
while (addedSubview = [addedSubviewEnumerator nextObject])
while ((addedSubview = [addedSubviewEnumerator nextObject]) !== nil)
[self addSubview:addedSubview];
// If the order is fine, no need to reorder.
@@ -560,6 +651,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.
@@ -587,6 +681,8 @@ var CPViewFlags = { },
[self viewDidMoveToWindow];
[[self window] _dirtyKeyViewLoop];
[self didChangeValueForKey:@"window"];
}
/*!
@@ -639,7 +735,7 @@ var CPViewFlags = { },
}
/*!
Called when the receiver is about to be remove one of its subviews.
Called when the receiver is about to remove one of its subviews.
@param aView the view that will be removed
*/
- (void)willRemoveSubview:(CPView)aView
@@ -710,7 +806,7 @@ var CPViewFlags = { },
/*!
Sets the frame size of the receiver to the dimensions and origin of the provided rectangle in the coordinate system
of the superview. The method also posts an CPViewFrameDidChangeNotification to the notification
of the superview. The method also posts a CPViewFrameDidChangeNotification to the notification
center if the receiver is configured to do so. If the frame is the same as the current frame, the method simply
returns (and no notification is posted).
@param aFrame the rectangle specifying the new origin and size of the receiver
@@ -763,7 +859,7 @@ var CPViewFlags = { },
}
/*!
Returns the center of the receiver's frame to the provided point. The point is defined in the superview's coordinate system.
Returns the center of the receiver's frame in the superview's coordinate system.
@return CGPoint the center point of the receiver's frame
*/
- (CGPoint)center
@@ -848,32 +944,90 @@ var CPViewFlags = { },
}
else
{
var images = [[_backgroundColor patternImage] imageSlices];
var images = [[_backgroundColor patternImage] imageSlices],
partIndex = 0;
if (_backgroundType === BackgroundVerticalThreePartImage)
{
var top = _DOMImageSizes[0] ? _DOMImageSizes[0].height : 0,
bottom = _DOMImageSizes[2] ? _DOMImageSizes[2].height : 0;
// Make sure to repeat the top and bottom pieces horizontally if they're not the exact width needed.
CPDOMDisplayServerSetStyleSize(_DOMImageParts[0], size.width, _DOMImageSizes[0].height);
CPDOMDisplayServerSetStyleSize(_DOMImageParts[1], size.width, size.height - _DOMImageSizes[0].height - _DOMImageSizes[2].height);
CPDOMDisplayServerSetStyleSize(_DOMImageParts[2], size.width, _DOMImageSizes[2].height);
if (top)
{
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], size.width, top);
partIndex++;
}
if (_DOMImageSizes[1])
{
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], size.width, size.height - top - bottom);
partIndex++;
}
if (bottom)
{
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], size.width, bottom);
}
}
else if (_backgroundType === BackgroundHorizontalThreePartImage)
{
var left = _DOMImageSizes[0] ? _DOMImageSizes[0].width : 0,
right = _DOMImageSizes[2] ? _DOMImageSizes[2].width : 0;
// Make sure to repeat the left and right pieces vertically if they're not the exact height needed.
CPDOMDisplayServerSetStyleSize(_DOMImageParts[0], _DOMImageSizes[0].width, size.height);
CPDOMDisplayServerSetStyleSize(_DOMImageParts[1], size.width - _DOMImageSizes[0].width - _DOMImageSizes[2].width, size.height);
CPDOMDisplayServerSetStyleSize(_DOMImageParts[2], _DOMImageSizes[2].width, size.height);
if (left)
{
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], left, size.height);
partIndex++;
}
if (_DOMImageSizes[1])
{
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], size.width - left - right, size.height);
partIndex++;
}
if (right)
{
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], right, size.height);
}
}
else if (_backgroundType === BackgroundNinePartImage)
{
var width = size.width - _DOMImageSizes[0].width - _DOMImageSizes[2].width,
height = size.height - _DOMImageSizes[0].height - _DOMImageSizes[6].height;
var left = _DOMImageSizes[0] ? _DOMImageSizes[0].width : 0,
right = _DOMImageSizes[2] ? _DOMImageSizes[2].width : 0,
top = _DOMImageSizes[0] ? _DOMImageSizes[0].height : 0,
bottom = _DOMImageSizes[6] ? _DOMImageSizes[6].height : 0,
width = size.width - left - right,
height = size.height - top - bottom;
CPDOMDisplayServerSetStyleSize(_DOMImageParts[1], width, _DOMImageSizes[0].height);
CPDOMDisplayServerSetStyleSize(_DOMImageParts[3], _DOMImageSizes[3].width, height);
CPDOMDisplayServerSetStyleSize(_DOMImageParts[4], width, height);
CPDOMDisplayServerSetStyleSize(_DOMImageParts[5], _DOMImageSizes[5].width, height);
CPDOMDisplayServerSetStyleSize(_DOMImageParts[7], width, _DOMImageSizes[7].height);
if (_DOMImageSizes[0])
partIndex++;
if (_DOMImageSizes[1])
{
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], width, top);
partIndex++;
}
if (_DOMImageSizes[2])
partIndex++;
if (_DOMImageSizes[3])
{
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], _DOMImageSizes[3].width, height);
partIndex++;
}
if (_DOMImageSizes[4])
{
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], width, height);
partIndex++;
}
if (_DOMImageSizes[5])
{
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], _DOMImageSizes[5].width, height);
partIndex++;
}
if (_DOMImageSizes[6])
partIndex++;
if (_DOMImageSizes[7])
{
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], width, _DOMImageSizes[7].height);
}
}
}
}
@@ -1369,7 +1523,7 @@ var CPViewFlags = { },
*/
- (CPView)hitTest:(CPPoint)aPoint
{
if (_isHidden || !_hitTests || !CPRectContainsPoint(_frame, aPoint))
if (_isHidden || !_hitTests || !_CGRectContainsPoint(_frame, aPoint))
return nil;
var view = nil,
@@ -1445,17 +1599,18 @@ var CPViewFlags = { },
colorHasAlpha = colorExists && [_backgroundColor alphaComponent] < 1.0,
supportsRGBA = CPFeatureIsCompatible(CPCSSRGBAFeature),
colorNeedsDOMElement = colorHasAlpha && !supportsRGBA,
amount = 0;
amount = 0,
slices;
if ([patternImage isThreePartImage])
{
_backgroundType = [patternImage isVertical] ? BackgroundVerticalThreePartImage : BackgroundHorizontalThreePartImage;
amount = 3 - _DOMImageParts.length;
amount = 3;
}
else if ([patternImage isNinePartImage])
{
_backgroundType = BackgroundNinePartImage;
amount = 9 - _DOMImageParts.length;
amount = 9;
}
else
{
@@ -1463,6 +1618,34 @@ var CPViewFlags = { },
amount = (colorNeedsDOMElement ? 1 : 0) - _DOMImageParts.length;
}
// Prepare multipart image data and reduce number of required DOM parts by number of empty slices in the multipart image to save needless DOM elements.
if (_backgroundType === BackgroundVerticalThreePartImage || _backgroundType === BackgroundHorizontalThreePartImage || _backgroundType === BackgroundNinePartImage)
{
slices = [patternImage imageSlices];
// We won't need more divs than there are slices.
amount = MIN(amount, slices.length);
for (var i = 0, count = slices.length; i < count; i++)
{
var image = slices[i],
size = [image size];
if (!size || (size.width == 0 && size.height == 0))
size = nil;
_DOMImageSizes[i] = size;
// If there's a nil slice or a slice with no size, it won't need a div.
if (!size)
amount--;
}
// Now that we know how many divs we really need, compare that to number we actually have.
amount -= _DOMImageParts.length;
}
// Make sure the number of divs we have match our needs.
if (amount > 0)
{
while (amount--)
@@ -1504,70 +1687,148 @@ var CPViewFlags = { },
}
else
{
var slices = [patternImage imageSlices],
count = MIN(_DOMImageParts.length, slices.length),
frameSize = _frame.size;
var frameSize = _frame.size,
partIndex = 0;
while (count--)
for (var i = 0; i < slices.length; i++)
{
var image = slices[count],
size = _DOMImageSizes[count] = image ? [image size] : _CGSizeMakeZero();
var size = _DOMImageSizes[i];
CPDOMDisplayServerSetStyleSize(_DOMImageParts[count], size.width, size.height);
if (!size)
continue;
_DOMImageParts[count].style.background = image ? "url(\"" + [image filename] + "\")" : "";
var image = slices[i];
// // If image was nil, size should have been nil too.
// assert(image != nil);
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], size.width, size.height);
_DOMImageParts[partIndex].style.background = "url(\"" + [image filename] + "\")";
if (!supportsRGBA)
{
if (CPFeatureIsCompatible(CPOpacityRequiresFilterFeature))
try { _DOMImageParts[count].style.removeAttribute("filter") } catch (anException) { }
try { _DOMImageParts[partIndex].style.removeAttribute("filter") } catch (anException) { }
else
_DOMImageParts[count].style.opacity = 1.0;
_DOMImageParts[partIndex].style.opacity = 1.0;
}
partIndex++;
}
if (_backgroundType == BackgroundNinePartImage)
{
var width = frameSize.width - _DOMImageSizes[0].width - _DOMImageSizes[2].width,
height = frameSize.height - _DOMImageSizes[0].height - _DOMImageSizes[6].height;
var left = _DOMImageSizes[0] ? _DOMImageSizes[0].width : 0,
right = _DOMImageSizes[2] ? _DOMImageSizes[2].width : 0,
top = _DOMImageSizes[0] ? _DOMImageSizes[0].height : 0,
bottom = _DOMImageSizes[6] ? _DOMImageSizes[6].height : 0,
width = frameSize.width - left - right,
height = frameSize.height - top - bottom;
CPDOMDisplayServerSetStyleSize(_DOMImageParts[1], width, _DOMImageSizes[0].height);
CPDOMDisplayServerSetStyleSize(_DOMImageParts[3], _DOMImageSizes[3].width, height);
CPDOMDisplayServerSetStyleSize(_DOMImageParts[4], width, height);
CPDOMDisplayServerSetStyleSize(_DOMImageParts[5], _DOMImageSizes[5].width, height);
CPDOMDisplayServerSetStyleSize(_DOMImageParts[7], width, _DOMImageSizes[7].height);
partIndex = 0;
CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[0], NULL, 0.0, 0.0);
CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[1], NULL, _DOMImageSizes[0].width, 0.0);
CPDOMDisplayServerSetStyleRightTop(_DOMImageParts[2], NULL, 0.0, 0.0);
CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[3], NULL, 0.0, _DOMImageSizes[1].height);
CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[4], NULL, _DOMImageSizes[0].width, _DOMImageSizes[0].height);
CPDOMDisplayServerSetStyleRightTop(_DOMImageParts[5], NULL, 0.0, _DOMImageSizes[1].height);
CPDOMDisplayServerSetStyleLeftBottom(_DOMImageParts[6], NULL, 0.0, 0.0);
CPDOMDisplayServerSetStyleLeftBottom(_DOMImageParts[7], NULL, _DOMImageSizes[6].width, 0.0);
CPDOMDisplayServerSetStyleRightBottom(_DOMImageParts[8], NULL, 0.0, 0.0);
if (_DOMImageSizes[0])
{
CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[partIndex], NULL, 0.0, 0.0);
partIndex++;
}
if (_DOMImageSizes[1])
{
CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[partIndex], NULL, left, 0.0);
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], width, _DOMImageSizes[1].height);
partIndex++;
}
if (_DOMImageSizes[2])
{
CPDOMDisplayServerSetStyleRightTop(_DOMImageParts[partIndex], NULL, 0.0, 0.0);
partIndex++;
}
if (_DOMImageSizes[3])
{
CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[partIndex], NULL, 0.0, top);
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], _DOMImageSizes[3].width, height);
partIndex++;
}
if (_DOMImageSizes[4])
{
CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[partIndex], NULL, left, top);
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], width, height);
partIndex++;
}
if (_DOMImageSizes[5])
{
CPDOMDisplayServerSetStyleRightTop(_DOMImageParts[partIndex], NULL, 0.0, top);
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], _DOMImageSizes[5].width, height);
partIndex++;
}
if (_DOMImageSizes[6])
{
CPDOMDisplayServerSetStyleLeftBottom(_DOMImageParts[partIndex], NULL, 0.0, 0.0);
partIndex++;
}
if (_DOMImageSizes[7])
{
CPDOMDisplayServerSetStyleLeftBottom(_DOMImageParts[partIndex], NULL, left, 0.0);
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], width, _DOMImageSizes[7].height);
partIndex++;
}
if (_DOMImageSizes[8])
{
CPDOMDisplayServerSetStyleRightBottom(_DOMImageParts[partIndex], NULL, 0.0, 0.0);
}
}
else if (_backgroundType == BackgroundVerticalThreePartImage)
{
// Make sure to repeat the top and bottom pieces horizontally if they're not the exact width needed.
CPDOMDisplayServerSetStyleSize(_DOMImageParts[0], frameSize.width, _DOMImageSizes[0].height);
CPDOMDisplayServerSetStyleSize(_DOMImageParts[1], frameSize.width, frameSize.height - _DOMImageSizes[0].height - _DOMImageSizes[2].height);
CPDOMDisplayServerSetStyleSize(_DOMImageParts[2], frameSize.width, _DOMImageSizes[2].height);
var top = _DOMImageSizes[0] ? _DOMImageSizes[0].height : 0,
bottom = _DOMImageSizes[2] ? _DOMImageSizes[2].height : 0;
CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[0], NULL, 0.0, 0.0);
CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[1], NULL, 0.0, _DOMImageSizes[0].height);
CPDOMDisplayServerSetStyleLeftBottom(_DOMImageParts[2], NULL, 0.0, 0.0);
partIndex = 0;
// Make sure to repeat the top and bottom pieces horizontally if they're not the exact width needed.
if (top)
{
CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[partIndex], NULL, 0.0, 0.0);
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], frameSize.width, top);
partIndex++;
}
if (_DOMImageSizes[1])
{
CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[partIndex], NULL, 0.0, top);
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], frameSize.width, frameSize.height - top - bottom);
partIndex++;
}
if (bottom)
{
CPDOMDisplayServerSetStyleLeftBottom(_DOMImageParts[partIndex], NULL, 0.0, 0.0);
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], frameSize.width, bottom);
}
}
else if (_backgroundType == BackgroundHorizontalThreePartImage)
{
// Make sure to repeat the left and right pieces vertically if they're not the exact height needed.
CPDOMDisplayServerSetStyleSize(_DOMImageParts[0], _DOMImageSizes[0].width, frameSize.height);
CPDOMDisplayServerSetStyleSize(_DOMImageParts[1], frameSize.width - _DOMImageSizes[0].width - _DOMImageSizes[2].width, frameSize.height);
CPDOMDisplayServerSetStyleSize(_DOMImageParts[2], _DOMImageSizes[2].width, frameSize.height);
var left = _DOMImageSizes[0] ? _DOMImageSizes[0].width : 0,
right = _DOMImageSizes[2] ? _DOMImageSizes[2].width : 0;
CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[0], NULL, 0.0, 0.0);
CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[1], NULL, _DOMImageSizes[0].width, 0.0);
CPDOMDisplayServerSetStyleRightTop(_DOMImageParts[2], NULL, 0.0, 0.0);
partIndex = 0;
// Make sure to repeat the left and right pieces vertically if they're not the exact height needed.
if (left)
{
CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[partIndex], NULL, 0.0, 0.0);
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], left, frameSize.height);
partIndex++;
}
if (_DOMImageSizes[1])
{
CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[partIndex], NULL, left, 0.0);
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], frameSize.width - left - right, frameSize.height);
partIndex++;
}
if (right)
{
CPDOMDisplayServerSetStyleRightTop(_DOMImageParts[partIndex], NULL, 0.0, 0.0);
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], right, frameSize.height);
}
}
}
#endif
@@ -1953,6 +2214,11 @@ setBoundsOrigin:
_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))
_DOMElement.style.webkitTransform = 'translateX(0)';
CPDOMDisplayServerAppendChild(_DOMElement, _DOMContentsElement);
#endif
_graphicsContext = [CPGraphicsContext graphicsContextWithGraphicsPort:graphicsPort flipped:YES];
@@ -2704,6 +2970,7 @@ var CPViewAutoresizingMaskKey = @"CPViewAutoresizingMask",
CPViewBoundsKey = @"CPViewBoundsKey",
CPViewFrameKey = @"CPViewFrameKey",
CPViewHitTestsKey = @"CPViewHitTestsKey",
CPViewToolTipKey = @"CPViewToolTipKey",
CPViewIsHiddenKey = @"CPViewIsHiddenKey",
CPViewOpacityKey = @"CPViewOpacityKey",
CPViewSubviewsKey = @"CPViewSubviewsKey",
@@ -2758,7 +3025,13 @@ var CPViewAutoresizingMaskKey = @"CPViewAutoresizingMask",
_autoresizesSubviews = ![aCoder containsValueForKey:CPViewAutoresizesSubviewsKey] || [aCoder decodeBoolForKey:CPViewAutoresizesSubviewsKey];
_hitTests = ![aCoder containsValueForKey:CPViewHitTestsKey] || [aCoder decodeObjectForKey:CPViewHitTestsKey];
_hitTests = ![aCoder containsValueForKey:CPViewHitTestsKey] || [aCoder decodeBoolForKey:CPViewHitTestsKey];
[self _setupToolTipHandlers];
_toolTip = [aCoder decodeObjectForKey:CPViewToolTipKey];
if (_toolTip)
[self _installToolTipEventHandlers];
// DOM SETUP
#if PLATFORM(DOM)
@@ -2778,10 +3051,7 @@ var CPViewAutoresizingMaskKey = @"CPViewAutoresizingMask",
}
#endif
if ([aCoder containsValueForKey:CPViewIsHiddenKey])
[self setHidden:[aCoder decodeBoolForKey:CPViewIsHiddenKey]];
else
_isHidden = NO;
[self setHidden:[aCoder decodeBoolForKey:CPViewIsHiddenKey]];
if ([aCoder containsValueForKey:CPViewOpacityKey])
[self setAlphaValue:[aCoder decodeIntForKey:CPViewOpacityKey]];
@@ -2789,8 +3059,7 @@ var CPViewAutoresizingMaskKey = @"CPViewAutoresizingMask",
_opacity = 1.0;
[self setBackgroundColor:[aCoder decodeObjectForKey:CPViewBackgroundColorKey]];
[self setupViewFlags];
[self _setupViewFlags];
_theme = [CPTheme defaultTheme];
_themeClass = [aCoder decodeObjectForKey:CPViewThemeClassKey];
@@ -2871,6 +3140,9 @@ var CPViewAutoresizingMaskKey = @"CPViewAutoresizingMask",
if (_isHidden)
[aCoder encodeBool:_isHidden forKey:CPViewIsHiddenKey];
if (_toolTip)
[aCoder encodeObject:_toolTip forKey:CPViewToolTipKey];
var nextKeyView = [self nextKeyView];
if (nextKeyView !== nil && ![nextKeyView isEqual:self])
+28 -4
View File
@@ -67,6 +67,7 @@ var CPViewControllerCachedCibs;
CPView _view @accessors(property=view);
BOOL _isLoading;
BOOL _isLazy;
BOOL _isViewLoaded @accessors(getter=isViewLoaded);
id _representedObject @accessors(property=representedObject);
CPString _title @accessors(property=title);
@@ -78,8 +79,10 @@ var CPViewControllerCachedCibs;
+ (void)initialize
{
if (self === CPViewController)
CPViewControllerCachedCibs = [CPDictionary dictionary];
if (self !== [CPViewController class])
return;
CPViewControllerCachedCibs = [CPDictionary dictionary];
}
/*!
@@ -204,17 +207,24 @@ var CPViewControllerCachedCibs;
[cibOwner viewControllerDidLoadCib:self];
_isLoading = NO;
[self viewDidLoad];
[self _viewDidLoad];
}
else if (_isLazy)
{
_isLazy = NO;
[self viewDidLoad];
[self _viewDidLoad];
}
return _view;
}
- (void)_viewDidLoad
{
[self willChangeValueForKey:"isViewLoaded"];
[self viewDidLoad];
isViewLoaded = YES;
[self didChangeValueForKey:"isViewLoaded"];
}
/*!
This method is called after the view controller has loaded its associated views into memory.
@@ -240,7 +250,21 @@ var CPViewControllerCachedCibs;
*/
- (void)setView:(CPView)aView
{
var willChangeIsViewLoaded = (_isViewLoaded == NO && aView != nil) || (_isViewLoaded == YES && aView == nil);
if (willChangeIsViewLoaded)
[self willChangeValueForKey:"isViewLoaded"];
_view = aView;
_isViewLoaded = aView !== nil;
if (willChangeIsViewLoaded)
[self didChangeValueForKey:"isViewLoaded"];
}
- (BOOL)automaticallyNotifiesObserversOfIsViewLoaded
{
return NO;
}
@end
+5
View File
@@ -1032,6 +1032,11 @@ CPWebViewAppKitScrollMaxPollCount = 3;
var documentURL = [CPURL URLWithString:window.location.href];
if ([documentURL isFileURL] && CPFeatureIsCompatible(CPSOPDisabledFromFileURLs))
return YES;
// Relative URLs always pass the SOP.
if (![self scheme] && ![self host] && ![self port])
return YES;
return ([documentURL scheme] == [self scheme] && [documentURL host] == [self host] && [documentURL port] == [self port]);
}
+593 -187
View File
File diff suppressed because it is too large Load Diff
+54 -44
View File
@@ -25,7 +25,11 @@
#define ALIGN_STROKE(point) (FLOOR(point) === (point) ? (point) + halfStrokeWidth : (point))
#define ALIGN_COORD(point) (FLOOR(point))
var _CPAttachedWindowViewDefaultCursorSize = CGSizeMake(16, 10);
var _CPAttachedWindowViewDefaultCursorSize = CGSizeMake(16, 10),
_CPAttachedWindowViewRadius = 5.0,
_CPAttachedWindowViewStrokeWidth = 1.0,
_CPAttachedWindowViewShadowSize = CGSizeMake(0, 6),
_CPAttachedWindowViewShadowBlur = 15.0;
/*!
@ignore
@@ -34,13 +38,12 @@ var _CPAttachedWindowViewDefaultCursorSize = CGSizeMake(16, 10);
*/
@implementation _CPAttachedWindowView : _CPWindowView
{
BOOL _mouseDownPressed @accessors(getter=isMouseDownPressed, setter=setMouseDownPressed:);
float _arrowOffsetX @accessors(property=arrowOffsetX);
float _arrowOffsetY @accessors(property=arrowOffsetY);
int _appearance @accessors(property=appearance);
unsigned _preferredEdge @accessors(property=preferredEdge);
float _arrowOffsetX @accessors(property=arrowOffsetX);
float _arrowOffsetY @accessors(property=arrowOffsetY);
int _appearance @accessors(property=appearance);
unsigned _preferredEdge @accessors(property=preferredEdge);
CGSize _cursorSize;
CGSize _cursorSize;
}
/*!
@@ -50,15 +53,20 @@ var _CPAttachedWindowViewDefaultCursorSize = CGSizeMake(16, 10);
*/
- (CGRect)contentRectForFrameRect:(CGRect)aFrameRect
{
var contentRect = CGRectMakeCopy(aFrameRect);
var contentRect = CGRectMakeCopy(aFrameRect),
modifierX = 16,
modifierY = 19;
// @todo change border art and remove this pixel perfect adaptation
// return CGRectInset(contentRect, 20, 20);
//
// @comment: If we use this, each time we open the popover, the content
// view is reduced a little over and over
// return CGRectInset(contentRect, modifierX, modifierY);
contentRect.origin.x += 18;
contentRect.origin.y += 17;
contentRect.size.width -= 35;
contentRect.size.height -= 37;
contentRect.origin.x += modifierX;
contentRect.origin.y += modifierY;
contentRect.size.width -= modifierX * 2;
contentRect.size.height -= modifierY * 2;
return contentRect;
}
@@ -70,15 +78,21 @@ var _CPAttachedWindowViewDefaultCursorSize = CGSizeMake(16, 10);
*/
+ (CGRect)frameRectForContentRect:(CGRect)aContentRect
{
var frameRect = CGRectMakeCopy(aContentRect);
var frameRect = CGRectMakeCopy(aContentRect),
modifierX = 16,
modifierY = 19;
// @todo change border art and remove this pixel perfect adaptation
//return CGRectOffset(frameRect, 20, 20);
// @comment: If we use this, each time we open the popover, the content
//
// view is reduced a little over and over
// return CGRectOffset(frameRect, modifierX, modifierY);
frameRect.origin.x -= modifierX;
frameRect.origin.y -= modifierY;
frameRect.size.width += modifierX * 2;
frameRect.size.height += modifierY * 2;
frameRect.origin.x -= 18;
frameRect.origin.y -= 17;
frameRect.size.width += 35;
frameRect.size.height += 37;
return frameRect;
}
@@ -91,8 +105,6 @@ var _CPAttachedWindowViewDefaultCursorSize = CGSizeMake(16, 10);
{
_arrowOffsetX = 0.0;
_arrowOffsetY = 0.0;
// @TODO: make this themable
_appearance = CPPopoverAppearanceMinimal;
_cursorSize = CGSizeMakeCopy(_CPAttachedWindowViewDefaultCursorSize);
}
@@ -116,7 +128,6 @@ var _CPAttachedWindowViewDefaultCursorSize = CGSizeMake(16, 10);
{
_cursorSize = CGSizeMakeCopy(_CPAttachedWindowViewDefaultCursorSize);
[self setNeedsDisplay:YES];
_mouseDownPressed = NO;
}
/*!
@@ -127,28 +138,41 @@ var _CPAttachedWindowViewDefaultCursorSize = CGSizeMake(16, 10);
[super drawRect:aRect];
var context = [[CPGraphicsContext currentContext] graphicsPort],
radius = 5,
radius = _CPAttachedWindowViewRadius,
arrowWidth = _cursorSize.width,
arrowHeight = _cursorSize.height,
strokeWidth = 1,
strokeWidth = _CPAttachedWindowViewStrokeWidth,
halfStrokeWidth = strokeWidth / 2.0,
strokeColor,
shadowColor = [[CPColor blackColor] colorWithAlphaComponent:.2],
shadowSize = CGSizeMake(0, 6),
shadowBlur = 15,
shadowSize = _CPAttachedWindowViewShadowSize,
shadowBlur = _CPAttachedWindowViewShadowBlur,
gradient,
frame = [self bounds];
if (_appearance == CPPopoverAppearanceMinimal)
{
gradient = CGGradientCreateWithColorComponents(CGColorSpaceCreateDeviceRGB(), [(254.0 / 255), (254.0 / 255), (254.0 / 255), 0.93,
(231.0 / 255), (231.0 / 255), (231.0 / 255), 0.93], [0,1], 2);
gradient = CGGradientCreateWithColorComponents(
CGColorSpaceCreateDeviceRGB(),
[
(254.0 / 255), (254.0 / 255), (254.0 / 255), 0.93,
(231.0 / 255), (231.0 / 255), (231.0 / 255), 0.93
],
[0, 1],
2
);
strokeColor = [CPColor colorWithHexString:@"B8B8B8"];
}
else
{
gradient = CGGradientCreateWithColorComponents(CGColorSpaceCreateDeviceRGB(), [(38.0 / 255), (38.0 / 255), (38.0 / 255), 0.93,
(18.0 / 255), (18.0 / 255), (18.0 / 255), 0.93], [0,1], 2);
gradient = CGGradientCreateWithColorComponents(
CGColorSpaceCreateDeviceRGB(),
[
(38.0 / 255), (38.0 / 255), (38.0 / 255), 0.93,
(18.0 / 255), (18.0 / 255), (18.0 / 255), 0.93
],
[0, 1],
2);
strokeColor = [CPColor colorWithHexString:@"222222"];
}
@@ -367,22 +391,8 @@ var _CPAttachedWindowViewDefaultCursorSize = CGSizeMake(16, 10);
}
CGContextClosePath(context);
//Draw it
CGContextStrokePath(context);
CGContextFillPath(context);
}
- (void)mouseDown:(CPEvent)anEvent
{
_mouseDownPressed = YES;
[super mouseDown:anEvent];
}
- (void)mouseUp:(CPEvent)anEvent
{
_mouseDownPressed = NO;
[super mouseUp:anEvent];
}
@end
@@ -38,7 +38,7 @@ var _CPToolbarViewBackgroundColor = nil;
_CPToolbarViewBackgroundColor = CPColorWithImages([
["_CPToolbarView/toolbar-background-top.png", 1, 1, bundle],
["_CPToolbarView/toolbar-background-center.png", 1, 57.0, bundle],
["_CPToolbarView/toolbar-background-bottom.png", 1, 1, bundle],
["_CPToolbarView/toolbar-background-bottom.png", 1, 1, bundle]
], CPColorPatternIsVertical);
}
+8 -2
View File
@@ -24,7 +24,7 @@ var _CPStandardWindowViewBodyBackgroundColor = nil;
if (self)
{
var theClass = [self class],
bounds = [self bounds];
bounds = [self bounds];
_bodyView = [[CPView alloc] initWithFrame:_CGRectMake(0.0, 0.0, _CGRectGetWidth(bounds), _CGRectGetHeight(bounds))];
@@ -54,4 +54,10 @@ var _CPStandardWindowViewBodyBackgroundColor = nil;
return aContentRect;
}
@end
- (void)_enableSheet:(BOOL)enable
{
// do nothing, already a sheet
}
@end
+59 -57
View File
@@ -21,24 +21,24 @@
*/
@import "CPTextField.j"
@import "_CPTitleableWindowView.j"
var _CPHUDWindowViewBackgroundColor = nil,
_CPHUDWindowViewThemeValues = nil,
CPHUDCloseButtonImage = nil;
var HUD_TITLEBAR_HEIGHT = 26.0;
@implementation _CPHUDWindowView : _CPWindowView
@implementation _CPHUDWindowView : _CPTitleableWindowView
{
CPView _toolbarView;
CPTextField _titleField;
CPButton _closeButton;
}
+ (void)initialize
{
if (self != [_CPHUDWindowView class])
if (self !== [_CPHUDWindowView class])
return;
var bundle = [CPBundle bundleForClass:self];
@@ -60,28 +60,23 @@ var HUD_TITLEBAR_HEIGHT = 26.0;
_CPHUDWindowViewCloseImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"HUDTheme/WindowClose.png"] size:CPSizeMake(18.0, 18.0)];
_CPHUDWindowViewCloseActiveImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"HUDTheme/WindowCloseActive.png"] size:CPSizeMake(18.0, 18.0)];
_CPHUDWindowViewThemeValues = [
[@"title-font", [CPFont systemFontOfSize:[CPFont systemFontSize] - 1]],
[@"title-text-color", [CPColor colorWithWhite:255.0 / 255.0 alpha:0.75]],
[@"title-text-color", [CPColor colorWithWhite:255.0 / 255.0 alpha:1], CPThemeStateKeyWindow],
[@"title-text-shadow-color", [CPColor blackColor]],
[@"title-text-shadow-offset", CGSizeMake(0.0, 1.0)],
[@"title-alignment", CPCenterTextAlignment],
// FIXME: Make this to CPLineBreakByTruncatingMiddle once it's implemented.
[@"title-line-break-mode", CPLineBreakByTruncatingTail],
[@"title-vertical-alignment", CPCenterVerticalTextAlignment]
];
}
+ (CGRect)contentRectForFrameRect:(CGRect)aFrameRect
+ (int)titleBarHeight
{
var contentRect = CGRectMakeCopy(aFrameRect),
titleBarHeight = HUD_TITLEBAR_HEIGHT;
contentRect.origin.y += titleBarHeight;
contentRect.size.height -= titleBarHeight;
return contentRect;
}
+ (CGRect)frameRectForContentRect:(CGRect)aContentRect
{
var frameRect = CGRectMakeCopy(aContentRect),
titleBarHeight = HUD_TITLEBAR_HEIGHT;
frameRect.origin.y -= titleBarHeight;
frameRect.size.height += titleBarHeight;
return frameRect;
return HUD_TITLEBAR_HEIGHT;
}
- (CGRect)contentRectForFrameRect:(CGRect)aFrameRect
@@ -105,7 +100,7 @@ var HUD_TITLEBAR_HEIGHT = 26.0;
if ([[[self window] toolbar] isVisible])
{
toolbarHeight = CGRectGetHeight([[self toolbarView] frame]);
var toolbarHeight = CGRectGetHeight([[self toolbarView] frame]);
frameRect.origin.y -= toolbarHeight;
frameRect.size.height += toolbarHeight;
@@ -120,37 +115,18 @@ var HUD_TITLEBAR_HEIGHT = 26.0;
if (self)
{
// Until windows become properly themable, just set these values here in the subclass.
[self registerThemeValues:_CPHUDWindowViewThemeValues];
var bounds = [self bounds];
[self setBackgroundColor:_CPHUDWindowViewBackgroundColor];
_titleField = [[CPTextField alloc] initWithFrame:CGRectMakeZero()];
[_titleField setHitTests:NO];
[_titleField setFont:[CPFont systemFontOfSize:11.0]];
[_titleField setTextColor:[CPColor whiteColor]];
[_titleField setTextShadowColor:[CPColor blackColor]];
[_titleField setTextShadowOffset:CGSizeMake(0.0, 1.0)];
[_titleField setAutoresizingMask:CPViewWidthSizable];
// FIXME: Make this to CPLineBreakByTruncatingMiddle once it's implemented.
[_titleField setLineBreakMode:CPLineBreakByTruncatingTail];
[_titleField setAlignment:CPCenterTextAlignment];
[_titleField setStringValue:@"Untitled"];
[_titleField sizeToFit];
[_titleField setAutoresizingMask:CPViewWidthSizable];
[_titleField setStringValue:@""];
[_titleField setFrame:CGRectMake(20.0, 3.0, CGRectGetWidth([self bounds]) - 40.0, CGRectGetHeight([_titleField frame]))];
[self addSubview:_titleField];
if (_styleMask & CPClosableWindowMask)
{
var closeSize = [_CPHUDWindowViewCloseImage size];
_closeButton = [[CPButton alloc] initWithFrame:CGRectMake(8.0, 5.0, closeSize.width, closeSize.height)];
_closeButton = [[CPButton alloc] initWithFrame:CGRectMake(8.0, 4.0, closeSize.width, closeSize.height)];
[_closeButton setBordered:NO];
@@ -161,6 +137,8 @@ var HUD_TITLEBAR_HEIGHT = 26.0;
}
[self setResizeIndicatorOffset:CGSizeMake(5.0, 5.0)];
[self tile];
}
return self;
@@ -172,11 +150,6 @@ var HUD_TITLEBAR_HEIGHT = 26.0;
[_closeButton setAction:@selector(performClose:)];
}
- (void)setTitle:(CPString)aTitle
{
[_titleField setStringValue:aTitle];
}
- (_CPToolbarView)toolbarView
{
return _toolbarView;
@@ -194,7 +167,7 @@ var HUD_TITLEBAR_HEIGHT = 26.0;
- (CGSize)toolbarOffset
{
return CGSizeMake(0.0, HUD_TITLEBAR_HEIGHT);
return _CGSizeMake(0.0, [[self class] titleBarHeight]);
}
- (void)tile
@@ -203,14 +176,43 @@ var HUD_TITLEBAR_HEIGHT = 26.0;
var theWindow = [self window],
bounds = [self bounds],
width = CGRectGetWidth(bounds);
width = _CGRectGetWidth(bounds);
[_titleField setFrame:CGRectMake(20.0, 3.0, width - 40.0, CGRectGetHeight([_titleField frame]))];
[_titleField setFrame:_CGRectMake(20.0, 0, width - 40.0, [self toolbarOffset].height)];
var maxY = [self toolbarMaxY];
if ([_titleField isHidden])
maxY -= ([self toolbarOffset]).height;
[[theWindow contentView] setFrameOrigin:CGPointMake(0.0, maxY, width, CGRectGetHeight(bounds) - maxY)];
var contentRect = _CGRectMake(0.0, maxY, width, _CGRectGetHeight(bounds) - maxY);
[[theWindow contentView] setFrame:contentRect];
}
- (void)_enableSheet:(BOOL)enable
{
[super _enableSheet:enable];
[_closeButton setHidden:enable];
[_titleField setHidden:enable];
// resize the window
var theWindow = [self window],
frame = [theWindow frame],
dy = ([self toolbarOffset]).height;
if (enable)
dy = -dy;
var newHeight = _CGRectGetMaxY(frame) + dy,
newWidth = _CGRectGetMaxX(frame);
frame.size.height += dy;
[self setFrameSize:_CGSizeMake(newWidth, newHeight)];
[self tile];
[theWindow setFrame:frame display:NO animate:NO];
[theWindow setMovableByWindowBackground:!enable];
}
@end
+76 -107
View File
@@ -21,7 +21,7 @@
*/
@import "CPTextField.j"
@import "_CPWindowView.j"
@import "_CPTitleableWindowView.j"
var GRADIENT_HEIGHT = 41.0;
@@ -98,31 +98,44 @@ var _CPTexturedWindowHeadGradientColor = nil,
var _CPStandardWindowViewBodyBackgroundColor = nil,
_CPStandardWindowViewDividerBackgroundColor = nil,
_CPStandardWindowViewTitleBackgroundColor = nil,
_CPStandardWindowViewCloseButtonImage = nil,
_CPStandardWindowViewCloseButtonHighlightedImage = nil,
_CPStandardWindowViewCloseButtonUnsavedImage = nil,
_CPStandardWindowViewCloseButtonUnsavedHighlightedImage = nil,
_CPStandardWindowViewMinimizeButtonImage = nil,
_CPStandardWindowViewMinimizeButtonHighlightedImage = nil;
_CPStandardWindowViewMinimizeButtonHighlightedImage = nil,
_CPStandardWindowViewThemeValues = nil;
var STANDARD_GRADIENT_HEIGHT = 41.0,
STANDARD_TITLEBAR_HEIGHT = 25.0;
var STANDARD_GRADIENT_HEIGHT = 41.0;
@implementation _CPStandardWindowView : _CPWindowView
@implementation _CPStandardWindowView : _CPTitleableWindowView
{
_CPTexturedWindowHeadView _headView;
CPView _dividerView;
CPView _bodyView;
CPView _toolbarView;
CPTextField _titleField;
CPButton _closeButton;
CPButton _minimizeButton;
BOOL _isDocumentEdited;
}
+ (void)initialize
{
_CPStandardWindowViewThemeValues = [
[@"title-font", [CPFont boldSystemFontOfSize:CPFontCurrentSystemSize]],
[@"title-text-color", [CPColor colorWithWhite:22.0 / 255.0 alpha:0.75]],
[@"title-text-color", [CPColor colorWithWhite:22.0 / 255.0 alpha:1], CPThemeStateKeyWindow],
[@"title-text-shadow-color", [CPColor whiteColor]],
[@"title-text-shadow-offset", CGSizeMake(0.0, 1.0)],
[@"title-alignment", CPCenterTextAlignment],
// FIXME: Make this to CPLineBreakByTruncatingMiddle once it's implemented.
[@"title-line-break-mode", CPLineBreakByTruncatingTail],
[@"title-vertical-alignment", CPCenterVerticalTextAlignment]
];
}
+ (CPColor)bodyBackgroundColor
{
if (!_CPStandardWindowViewBodyBackgroundColor)
@@ -139,79 +152,15 @@ var STANDARD_GRADIENT_HEIGHT = 41.0,
return _CPStandardWindowViewDividerBackgroundColor;
}
+ (CPColor)titleColor
{
if (!_CPStandardWindowViewTitleBackgroundColor)
_CPStandardWindowViewTitleBackgroundColor = [CPColor colorWithCalibratedRed:44.0 / 255.0 green:44.0 / 255.0 blue:44.0 / 255.0 alpha:1.0];
return _CPStandardWindowViewTitleBackgroundColor;
}
+ (CGRect)contentRectForFrameRect:(CGRect)aFrameRect
{
var contentRect = CGRectMakeCopy(aFrameRect),
titleBarHeight = [self titleBarHeight] + 1.0;
contentRect.origin.y += titleBarHeight;
contentRect.size.height -= titleBarHeight;
return contentRect;
}
+ (CGRect)frameRectForContentRect:(CGRect)aContentRect
{
var frameRect = CGRectMakeCopy(aContentRect),
titleBarHeight = [self titleBarHeight] + 1.0;
frameRect.origin.y -= titleBarHeight;
frameRect.size.height += titleBarHeight;
return frameRect;
}
+ (float)titleBarHeight
{
return STANDARD_TITLEBAR_HEIGHT;
}
- (CGRect)contentRectForFrameRect:(CGRect)aFrameRect
{
var contentRect = [[self class] contentRectForFrameRect:aFrameRect],
theToolbar = [[self window] toolbar];
if ([theToolbar isVisible])
{
var toolbarHeight = CGRectGetHeight([[theToolbar _toolbarView] frame]);
contentRect.origin.y += toolbarHeight;
contentRect.size.height -= toolbarHeight;
}
return contentRect;
}
- (CGRect)frameRectForContentRect:(CGRect)aContentRect
{
var frameRect = [[self class] frameRectForContentRect:aContentRect],
theToolbar = [[self window] toolbar];
if ([theToolbar isVisible])
{
toolbarHeight = CGRectGetHeight([[theToolbar _toolbarView] frame]);
frameRect.origin.y -= toolbarHeight;
frameRect.size.height += toolbarHeight;
}
return frameRect;
}
- (id)initWithFrame:(CPRect)aFrame styleMask:(unsigned)aStyleMask
{
self = [super initWithFrame:aFrame styleMask:aStyleMask];
if (self)
{
// Until windows become properly themable, just set these values here in the subclass.
[self registerThemeValues:_CPStandardWindowViewThemeValues];
var theClass = [self class],
bounds = [self bounds];
@@ -220,7 +169,7 @@ var STANDARD_GRADIENT_HEIGHT = 41.0,
[_headView setAutoresizingMask:CPViewWidthSizable];;
[_headView setHitTests:NO];
[self addSubview:_headView];
[self addSubview:_headView positioned:CPWindowBelow relativeTo:_titleField];
_dividerView = [[CPView alloc] initWithFrame:CGRectMake(0.0, CGRectGetMaxY([_headView frame]), CGRectGetWidth(bounds), 1.0)];
@@ -242,24 +191,6 @@ var STANDARD_GRADIENT_HEIGHT = 41.0,
[self setResizeIndicatorOffset:CGSizeMake(2.0, 2.0)];
_titleField = [[CPTextField alloc] initWithFrame:CGRectMakeZero()];
[_titleField setFont:[CPFont boldSystemFontOfSize:12.0]];
[_titleField setAutoresizingMask:CPViewWidthSizable];
// FIXME: Make this to CPLineBreakByTruncatingMiddle once it's implemented.
[_titleField setLineBreakMode:CPLineBreakByTruncatingTail];
[_titleField setAlignment:CPCenterTextAlignment];
[_titleField setTextShadowColor:[CPColor whiteColor]];
[_titleField setTextShadowOffset:CGSizeMake(0.0, 1.0)];
[_titleField setStringValue:@"Untitled"];
[_titleField sizeToFit];
[_titleField setAutoresizingMask:CPViewWidthSizable];
[_titleField setStringValue:@""];
[self addSubview:_titleField];
if (_styleMask & CPClosableWindowMask)
{
if (!_CPStandardWindowViewCloseButtonImage)
@@ -272,7 +203,7 @@ var STANDARD_GRADIENT_HEIGHT = 41.0,
_CPStandardWindowViewCloseButtonUnsavedHighlightedImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPWindow/Standard/CPWindowStandardCloseButtonUnsavedHighlighted.png"] size:CGSizeMake(16.0, 16.0)];
}
_closeButton = [[CPButton alloc] initWithFrame:CGRectMake(8.0, 7.0, 16.0, 16.0)];
_closeButton = [[CPButton alloc] initWithFrame:CGRectMake(8.0, 6.0, 16.0, 16.0)];
[_closeButton setBordered:NO];
[self _updateCloseButton];
@@ -326,14 +257,20 @@ var STANDARD_GRADIENT_HEIGHT = 41.0,
var theWindow = [self window],
bounds = [self bounds],
width = CGRectGetWidth(bounds);
width = _CGRectGetWidth(bounds);
[_headView setFrameSize:CGSizeMake(width, [self toolbarMaxY])];
[_dividerView setFrame:CGRectMake(0.0, CGRectGetMaxY([_headView frame]), width, 1.0)];
[_headView setFrameSize:_CGSizeMake(width, [self toolbarMaxY])];
[_dividerView setFrame:_CGRectMake(0.0, _CGRectGetMaxY([_headView frame]), width, 1.0)];
var dividerMaxY = CGRectGetMaxY([_dividerView frame]);
var dividerMaxY = 0,
dividerMinY = 0;
if (![_dividerView isHidden])
{
dividerMinY = _CGRectGetMinY([_dividerView frame]);
dividerMaxY = _CGRectGetMaxY([_dividerView frame]);
}
[_bodyView setFrame:CGRectMake(0.0, dividerMaxY, width, CGRectGetHeight(bounds) - dividerMaxY)];
[_bodyView setFrame:_CGRectMake(0.0, dividerMaxY, width, _CGRectGetHeight(bounds) - dividerMaxY)];
var leftOffset = 8;
@@ -342,10 +279,13 @@ var STANDARD_GRADIENT_HEIGHT = 41.0,
if (_minimizeButton)
leftOffset += 19.0;
[_titleField setFrame:CGRectMake(leftOffset, 5.0, width - leftOffset * 2.0, CGRectGetHeight([_titleField frame]))];
[_titleField setFrame:_CGRectMake(leftOffset, 0, width - leftOffset * 2.0, [[self class] titleBarHeight])];
[[theWindow contentView] setFrameOrigin:CGPointMake(0.0, CGRectGetMaxY([_dividerView frame]))];
var contentRect = _CGRectMake(0.0, dividerMaxY, width, _CGRectGetHeight([_bodyView frame]));
[[theWindow contentView] setFrame:contentRect];
}
/*
- (void)setAnimatingToolbar:(BOOL)isAnimatingToolbar
{
@@ -394,17 +334,46 @@ var STANDARD_GRADIENT_HEIGHT = 41.0,
[self _updateCloseButton];
}
- (void)setTitle:(CPString)aTitle
- (BOOL)couldBeMoveEvent:(CPEvent)anEvent
{
[_titleField setStringValue:aTitle];
if (![_headView isHidden])
if (CGRectContainsPoint([_headView frame], [self convertPoint:[anEvent locationInWindow] fromView:nil]))
return YES;
return [super couldBeMoveEvent:anEvent];
}
- (void)mouseDown:(CPEvent)anEvent
- (void)_enableSheet:(BOOL)enable
{
if (CGRectContainsPoint([_headView frame], [self convertPoint:[anEvent locationInWindow] fromView:nil]))
return [self trackMoveWithEvent:anEvent];
[super _enableSheet:enable];
[super mouseDown:anEvent];
[_headView setHidden:enable];
[_dividerView setHidden:enable];
[_closeButton setHidden:enable];
[_minimizeButton setHidden:enable];
[_titleField setHidden:enable];
if (enable)
[_bodyView setBackgroundColor:[_CPDocModalWindowView bodyBackgroundColor]];
else
[_bodyView setBackgroundColor:[[self class] bodyBackgroundColor]];
// resize the window
var theWindow = [self window],
frame = [theWindow frame];
var dy = _CGRectGetHeight([_headView frame]) + _CGRectGetHeight([_dividerView frame]);
if (enable)
dy = -dy;
var newHeight = _CGRectGetMaxY(frame) + dy,
newWidth = _CGRectGetMaxX(frame);
frame.size.height += dy;
[self setFrameSize:_CGSizeMake(newWidth, newHeight)];
[self tile];
[theWindow setFrame:frame display:NO animate:NO];
}
@end
+114
View File
@@ -0,0 +1,114 @@
/*
* _CPTitleableWindowView.j
* AppKit
*
* Created by Alexander Ljungberg.
* Copyright 2012, SlevenBits Ltd.
*
* 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 "_CPWindowView.j"
var STANDARD_TITLEBAR_HEIGHT = 25.0;
@implementation _CPTitleableWindowView : _CPWindowView
{
CPTextField _titleField;
}
+ (int)titleBarHeight
{
return STANDARD_TITLEBAR_HEIGHT;
}
+ (CGRect)contentRectForFrameRect:(CGRect)aFrameRect
{
var contentRect = CGRectMakeCopy(aFrameRect),
titleBarHeight = [[self class] titleBarHeight];
contentRect.origin.y += titleBarHeight;
contentRect.size.height -= titleBarHeight;
return contentRect;
}
+ (CGRect)frameRectForContentRect:(CGRect)aContentRect
{
var frameRect = CGRectMakeCopy(aContentRect),
titleBarHeight = [[self class] titleBarHeight];
frameRect.origin.y -= titleBarHeight;
frameRect.size.height += titleBarHeight;
return frameRect;
}
- (id)initWithFrame:(CPRect)aFrame styleMask:(unsigned)aStyleMask
{
self = [super initWithFrame:aFrame styleMask:aStyleMask];
if (self)
{
_titleField = [[CPTextField alloc] initWithFrame:CGRectMakeZero()];
[_titleField setHitTests:NO];
[_titleField setStringValue:@"Untitled"];
[_titleField sizeToFit];
[_titleField setAutoresizingMask:CPViewWidthSizable];
[_titleField setStringValue:@""];
[_titleField setFrame:CGRectMake(20.0, 3.0, CGRectGetWidth([self bounds]) - 40.0, CGRectGetHeight([_titleField frame]))];
[self addSubview:_titleField];
[self setNeedsLayout];
}
return self;
}
- (void)setTitle:(CPString)aTitle
{
[_titleField setStringValue:aTitle];
}
- (void)tile
{
[super tile];
var theWindow = [self window],
bounds = [self bounds],
width = CGRectGetWidth(bounds);
// The vertical alignment of the title is set by the theme, so just give it all available space. By default
// the title will vertically centre within.
[_titleField setFrame:_CGRectMake(20.0, 0, width - 40.0, [[self class] titleBarHeight])];
}
- (void)layoutSubviews
{
[super layoutSubviews];
[_titleField setTextColor:[self currentValueForThemeAttribute:@"title-text-color"]];
[_titleField setFont:[self currentValueForThemeAttribute:@"title-font"]];
[_titleField setAlignment:[self currentValueForThemeAttribute:@"title-alignment"]];
[_titleField setVerticalAlignment:[self currentValueForThemeAttribute:@"title-vertical-alignment"]];
[_titleField setLineBreakMode:[self currentValueForThemeAttribute:@"title-line-break-mode"]];
[_titleField setTextShadowColor:[self currentValueForThemeAttribute:@"title-text-shadow-color"]];
[_titleField setTextShadowOffset:[self currentValueForThemeAttribute:@"title-text-shadow-offset"]];
}
@end
+377 -36
View File
@@ -24,7 +24,18 @@
@import "CPView.j"
var _CPWindowViewResizeIndicatorImage = nil;
var _CPWindowViewResizeIndicatorImage = nil,
_CPWindowViewCornerResizeRectWidth = 10,
_CPWindowViewResizeRegionNone = -1,
_CPWindowViewResizeRegionTopLeft = 0,
_CPWindowViewResizeRegionTop = 1,
_CPWindowViewResizeRegionTopRight = 2,
_CPWindowViewResizeRegionRight = 3,
_CPWindowViewResizeRegionBottomRight = 4,
_CPWindowViewResizeRegionBottom = 5,
_CPWindowViewResizeRegionBottomLeft = 6,
_CPWindowViewResizeRegionLeft = 7;
@implementation _CPWindowView : CPView
{
@@ -38,37 +49,73 @@ var _CPWindowViewResizeIndicatorImage = nil;
// BOOL _isAnimatingToolbar;
CGRect _resizeFrame;
int _resizeRegion;
CGPoint _mouseDraggedPoint;
CGRect _cachedScreenFrame;
CPView _sheetShadowView;
}
+ (void)initialize
{
if (self != [_CPWindowView class])
if (self !== [_CPWindowView class])
return;
_CPWindowViewResizeIndicatorImage = [[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:[CPWindow class]] pathForResource:@"_CPWindowView/_CPWindowViewResizeIndicator.png"] size:CGSizeMake(12.0, 12.0)];
_CPWindowViewResizeIndicatorImage = [[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:[CPWindow class]] pathForResource:@"_CPWindowView/_CPWindowViewResizeIndicator.png"] size:_CGSizeMake(12.0, 12.0)];
}
+ (CGRect)contentRectForFrameRect:(CGRect)aFrameRect
{
return CGRectMakeCopy(aFrameRect);
return _CGRectMakeCopy(aFrameRect);
}
+ (CGRect)frameRectForContentRect:(CGRect)aContentRect
{
return CGRectMakeCopy(aContentRect);
return _CGRectMakeCopy(aContentRect);
}
+ (CPString)defaultThemeClass
{
return "window";
}
+ (id)themeAttributes
{
return [CPDictionary dictionaryWithObjects:[[CPColor blackColor], [CPFont systemFontOfSize:CPFontCurrentSystemSize], [CPNull null], _CGSizeMakeZero(), CPCenterTextAlignment, CPLineBreakByTruncatingTail, CPTopVerticalTextAlignment]
forKeys:[@"title-text-color", @"title-font", @"title-text-shadow-color", @"title-text-shadow-offset", @"title-alignment", @"title-line-break-mode", @"title-vertical-alignment"]];
}
- (CGRect)contentRectForFrameRect:(CGRect)aFrameRect
{
return [[self class] contentRectForFrameRect:aFrameRect];
var contentRect = [[self class] contentRectForFrameRect:aFrameRect],
theToolbar = [[self window] toolbar];
if ([theToolbar isVisible])
{
var toolbarHeight = _CGRectGetHeight([[theToolbar _toolbarView] frame]);
contentRect.origin.y += toolbarHeight;
contentRect.size.height -= toolbarHeight;
}
return contentRect;
}
- (CGRect)frameRectForContentRect:(CGRect)aContentRect
{
return [[self class] frameRectForContentRect:aContentRect];
var frameRect = [[self class] frameRectForContentRect:aContentRect],
theToolbar = [[self window] toolbar];
if ([theToolbar isVisible])
{
var toolbarHeight = _CGRectGetHeight([[theToolbar _toolbarView] frame]);
frameRect.origin.y -= toolbarHeight;
frameRect.size.height += toolbarHeight;
}
return frameRect;
}
- (id)initWithFrame:(CPRect)aFrame styleMask:(unsigned)aStyleMask
@@ -78,8 +125,8 @@ var _CPWindowViewResizeIndicatorImage = nil;
if (self)
{
_styleMask = aStyleMask;
_resizeIndicatorOffset = CGSizeMakeZero();
_toolbarOffset = CGSizeMakeZero();
_resizeIndicatorOffset = _CGSizeMakeZero();
_toolbarOffset = _CGSizeMakeZero();
}
return self;
@@ -100,49 +147,301 @@ var _CPWindowViewResizeIndicatorImage = nil;
- (void)mouseDown:(CPEvent)anEvent
{
var theWindow = [self window];
var theWindow = [self window],
couldResize = _styleMask & CPResizableWindowMask;
if ((_styleMask & CPResizableWindowMask) && _resizeIndicator)
couldResize = couldResize && (
(CPWindowResizeStyle === CPWindowResizeStyleModern) ||
((CPWindowResizeStyle === CPWindowResizeStyleLegacy) && _resizeIndicator));
if (couldResize)
{
// FIXME: This should be better
var frame = [_resizeIndicator frame];
var theWindow = [self window],
windowFrame = [theWindow frame],
shouldResize = NO;
if (CGRectContainsPoint(frame, [self convertPoint:[anEvent locationInWindow] fromView:nil]))
if (CPWindowResizeStyle === CPWindowResizeStyleModern)
{
var globalPoint = [theWindow convertBaseToGlobal:[anEvent locationInWindow]];
_resizeRegion = [self resizeRegionForPoint:globalPoint];
shouldResize = _resizeRegion !== _CPWindowViewResizeRegionNone;
}
else
{
// Extend the resize frame to the edge of the window frame
var resizeFrame = [_resizeIndicator frame];
resizeFrame.size.width = _CGRectGetWidth(windowFrame) - _CGRectGetMinX(resizeFrame);
resizeFrame.size.height = _CGRectGetHeight(windowFrame) - _CGRectGetMinY(resizeFrame);
var localPoint = [self convertPoint:[anEvent locationInWindow] fromView:nil];
shouldResize = CGRectContainsPoint(resizeFrame, localPoint);
// When in legacy mode, the only possible resize region is lower right
_resizeRegion = shouldResize ? _CPWindowViewResizeRegionBottomRight : _CPWindowViewResizeRegionNone;
}
if (shouldResize)
return [self trackResizeWithEvent:anEvent];
}
if ([theWindow isMovable] && [theWindow isMovableByWindowBackground])
if ([self couldBeMoveEvent:anEvent])
[self trackMoveWithEvent:anEvent];
else
[super mouseDown:anEvent];
}
- (BOOL)couldBeMoveEvent:(CPEvent)anEvent
{
var theWindow = [self window];
return [theWindow isMovable] && [theWindow isMovableByWindowBackground];
}
/*
aPoint should be in global coordinates
*/
- (int)resizeRegionForPoint:(CGPoint)aPoint
{
/*
There are 8 possible resize rects, 1 for each side and 1 for each corner.
The four corner rects are the same size, and the top/bottom and left/right
rects are the same size. So to save calculations, we can just create
3 rects and move them around to do hit testing. Start with the corners
and then do left/right and top/bottom.
*/
var frame = [[self window] frame],
rect = _CGRectMake(frame.origin.x - CPWindowResizeSlop,
frame.origin.y - CPWindowResizeSlop,
_CPWindowViewCornerResizeRectWidth + CPWindowResizeSlop,
_CPWindowViewCornerResizeRectWidth + CPWindowResizeSlop);
if (_CGRectContainsPoint(rect, aPoint))
return _CPWindowViewResizeRegionTopLeft;
rect.origin.x = _CGRectGetMaxX(frame) - _CPWindowViewCornerResizeRectWidth;
if (_CGRectContainsPoint(rect, aPoint))
return _CPWindowViewResizeRegionTopRight;
rect.origin.y = _CGRectGetMaxY(frame) - _CPWindowViewCornerResizeRectWidth;
if (_CGRectContainsPoint(rect, aPoint))
return _CPWindowViewResizeRegionBottomRight;
rect.origin.x = frame.origin.x - CPWindowResizeSlop;
if (_CGRectContainsPoint(rect, aPoint))
return _CPWindowViewResizeRegionBottomLeft;
rect = _CGRectMake(rect.origin.x,
frame.origin.y + _CPWindowViewCornerResizeRectWidth,
CPWindowResizeSlop * 2,
_CGRectGetHeight(frame) - (_CPWindowViewCornerResizeRectWidth * 2));
if (_CGRectContainsPoint(rect, aPoint))
return _CPWindowViewResizeRegionLeft;
rect.origin.x = _CGRectGetMaxX(frame) - CPWindowResizeSlop;
if (_CGRectContainsPoint(rect, aPoint))
return _CPWindowViewResizeRegionRight;
rect = _CGRectMake(frame.origin.x + _CPWindowViewCornerResizeRectWidth,
frame.origin.y - CPWindowResizeSlop,
_CGRectGetWidth(frame) - (_CPWindowViewCornerResizeRectWidth * 2),
CPWindowResizeSlop * 2);
if (_CGRectContainsPoint(rect, aPoint))
return _CPWindowViewResizeRegionTop;
rect.origin.y = _CGRectGetMaxY(frame) - CPWindowResizeSlop;
if (_CGRectContainsPoint(rect, aPoint))
return _CPWindowViewResizeRegionBottom;
return _CPWindowViewResizeRegionNone;
}
/*
aPoint is in window coordinates
*/
- (void)setCursorForLocation:(CGPoint)aPoint resizing:(BOOL)isResizing
{
if (!(_styleMask & CPResizableWindowMask) ||
(CPWindowResizeStyle !== CPWindowResizeStyleModern))
return;
var theWindow = [self window],
resizeRegion = isResizing ? _resizeRegion : [self resizeRegionForPoint:[theWindow convertBaseToGlobal:aPoint]],
minSize = nil,
maxSize = nil,
frameSize;
if (resizeRegion !== _CPWindowViewResizeRegionNone)
{
minSize = [theWindow minSize];
maxSize = [theWindow maxSize];
frameSize = [theWindow frame].size;
}
switch (resizeRegion)
{
case _CPWindowViewResizeRegionTopLeft:
if (minSize && _CGSizeEqualToSize(frameSize, minSize))
[[CPCursor resizeNorthwestCursor] set];
else if (maxSize && _CGSizeEqualToSize(frameSize, maxSize))
[[CPCursor resizeSoutheastCursor] set];
else
[[CPCursor resizeNorthwestSoutheastCursor] set];
break;
case _CPWindowViewResizeRegionTop:
if (minSize && (frameSize.height === minSize.height))
[[CPCursor resizeUpCursor] set];
else if (maxSize && (frameSize.height === maxSize.height))
[[CPCursor resizeDownCursor] set];
else
[[CPCursor resizeNorthSouthCursor] set];
break;
case _CPWindowViewResizeRegionTopRight:
if (minSize && _CGSizeEqualToSize(frameSize, minSize))
[[CPCursor resizeNortheastCursor] set];
else if (maxSize && _CGSizeEqualToSize(frameSize, maxSize))
[[CPCursor resizeSouthwestCursor] set];
else
[[CPCursor resizeNortheastSouthwestCursor] set];
break;
case _CPWindowViewResizeRegionRight:
if (minSize && (frameSize.width === minSize.width))
[[CPCursor resizeRightCursor] set];
else if (maxSize && (frameSize.width === maxSize.width))
[[CPCursor resizeLeftCursor] set];
else
[[CPCursor resizeEastWestCursor] set];
break;
case _CPWindowViewResizeRegionBottomRight:
if (minSize && _CGSizeEqualToSize(frameSize, minSize))
[[CPCursor resizeSoutheastCursor] set];
else if (maxSize && _CGSizeEqualToSize(frameSize, maxSize))
[[CPCursor resizeNorthwestCursor] set];
else
[[CPCursor resizeNorthwestSoutheastCursor] set];
break;
case _CPWindowViewResizeRegionBottom:
if (minSize && (frameSize.height === minSize.height))
[[CPCursor resizeDownCursor] set];
else if (maxSize && (frameSize.height === maxSize.height))
[[CPCursor resizeUpCursor] set];
else
[[CPCursor resizeNorthSouthCursor] set];
break;
case _CPWindowViewResizeRegionBottomLeft:
if (minSize && _CGSizeEqualToSize(frameSize, minSize))
[[CPCursor resizeSouthwestCursor] set];
else if (maxSize && _CGSizeEqualToSize(frameSize, maxSize))
[[CPCursor resizeNortheastCursor] set];
else
[[CPCursor resizeNortheastSouthwestCursor] set];
break;
case _CPWindowViewResizeRegionLeft:
if (minSize && (frameSize.width === minSize.width))
[[CPCursor resizeLeftCursor] set];
else if (maxSize && (frameSize.width === maxSize.width))
[[CPCursor resizeRightCursor] set];
else
[[CPCursor resizeEastWestCursor] set];
break;
default:
[[CPCursor arrowCursor] set];
}
}
- (void)trackResizeWithEvent:(CPEvent)anEvent
{
var location = [anEvent locationInWindow],
type = [anEvent type];
var type = [anEvent type];
if (type === CPLeftMouseUp)
return;
var theWindow = [self window];
var location = [anEvent locationInWindow],
theWindow = [self window],
globalLocation = [theWindow convertBaseToGlobal:location],
frame = [theWindow frame];
if (type === CPLeftMouseDown)
{
var frame = [theWindow frame];
_resizeFrame = CGRectMake(location.x, location.y, CGRectGetWidth(frame), CGRectGetHeight(frame));
_mouseDraggedPoint = _CGPointMakeCopy(globalLocation);
_resizeFrame = _CGRectMakeCopy(frame);
}
else if (type === CPLeftMouseDragged)
{
var newSize = CGSizeMake(CGRectGetWidth(_resizeFrame) + location.x - CGRectGetMinX(_resizeFrame), CGRectGetHeight(_resizeFrame) + location.y - CGRectGetMinY(_resizeFrame));
var diffX = globalLocation.x - _mouseDraggedPoint.x,
diffY = globalLocation.y - _mouseDraggedPoint.y,
newX = _CGRectGetMinX(_resizeFrame),
newY = _CGRectGetMinY(_resizeFrame),
newWidth = _CGRectGetWidth(_resizeFrame),
newHeight = _CGRectGetHeight(_resizeFrame),
minSize = [theWindow minSize],
maxSize = [theWindow maxSize];
if (theWindow._isSheet && theWindow._parentView && (theWindow._frame.size.width !== newSize.width))
[theWindow._parentView _setAttachedSheetFrameOrigin];
// Calculate x and width first
switch (_resizeRegion)
{
case _CPWindowViewResizeRegionTopLeft:
case _CPWindowViewResizeRegionLeft:
case _CPWindowViewResizeRegionBottomLeft:
if (minSize && diffX > 0)
diffX = MIN(newWidth - minSize.width, diffX);
else if (maxSize && diffX < 0)
diffX = MAX(newWidth - maxSize.width, diffX);
[theWindow setFrameSize:newSize];
newX += diffX,
newWidth -= diffX;
break;
case _CPWindowViewResizeRegionTopRight:
case _CPWindowViewResizeRegionRight:
case _CPWindowViewResizeRegionBottomRight:
newWidth += diffX;
break;
}
// Now calculate y and height
switch (_resizeRegion)
{
case _CPWindowViewResizeRegionTopLeft:
case _CPWindowViewResizeRegionTop:
case _CPWindowViewResizeRegionTopRight:
if (minSize && diffY > 0)
diffY = MIN(newHeight - minSize.height, diffY);
else if (maxSize && diffY < 0)
diffY = MAX(newHeight - maxSize.height, diffY);
newY += diffY,
newHeight -= diffY;
break;
case _CPWindowViewResizeRegionBottomLeft:
case _CPWindowViewResizeRegionBottom:
case _CPWindowViewResizeRegionBottomRight:
newHeight += diffY;
break;
}
if (theWindow._isSheet && theWindow._parentView && (frame.size.width !== newWidth))
[theWindow._parentView _setAttachedSheetFrameOrigin];
[theWindow setFrame:_CGRectMake(newX, newY, newWidth, newHeight)];
[self setCursorForLocation:location resizing:YES];
}
[CPApp setTarget:self selector:@selector(trackResizeWithEvent:) forNextEventMatchingMask:CPLeftMouseDraggedMask | CPLeftMouseUpMask untilDate:nil inMode:nil dequeue:YES];
@@ -166,8 +465,8 @@ var _CPWindowViewResizeIndicatorImage = nil;
var restrictedPoint = CGPointMake(0, 0);
restrictedPoint.x = MIN(MAX(aPoint.x, -_frame.size.width + 4.0), CGRectGetMaxX(visibleFrame) - 4.0);
restrictedPoint.y = MIN(MAX(aPoint.y, minPointY), CGRectGetMaxY(visibleFrame) - 8.0);
restrictedPoint.x = MIN(MAX(aPoint.x, -_frame.size.width + 4.0), _CGRectGetMaxX(visibleFrame) - 4.0);
restrictedPoint.y = MIN(MAX(aPoint.y, minPointY), _CGRectGetMaxY(visibleFrame) - 8.0);
return restrictedPoint;
}
@@ -184,13 +483,11 @@ var _CPWindowViewResizeIndicatorImage = nil;
_cachedScreenFrame = nil;
return;
}
else if (type === CPLeftMouseDown)
{
_mouseDraggedPoint = [[self window] convertBaseToGlobal:[anEvent locationInWindow]];
_cachedScreenFrame = [[CPPlatformWindow primaryPlatformWindow] visibleFrame];
}
else if (type === CPLeftMouseDragged)
{
var theWindow = [self window],
@@ -198,7 +495,6 @@ var _CPWindowViewResizeIndicatorImage = nil;
location = [theWindow convertBaseToGlobal:[anEvent locationInWindow]],
origin = [self _pointWithinScreenFrame:CGPointMake(_CGRectGetMinX(frame) + (location.x - _mouseDraggedPoint.x),
_CGRectGetMinY(frame) + (location.y - _mouseDraggedPoint.y))];
[theWindow setFrameOrigin:origin];
_mouseDraggedPoint = [self _pointWithinScreenFrame:location];
@@ -207,14 +503,25 @@ var _CPWindowViewResizeIndicatorImage = nil;
[CPApp setTarget:self selector:@selector(trackMoveWithEvent:) forNextEventMatchingMask:CPLeftMouseDraggedMask | CPLeftMouseUpMask untilDate:nil inMode:nil dequeue:YES];
}
- (void)setFrameSize:(CGSize)newSize
{
[super setFrameSize:newSize];
// reposition sheet if the parent window resizes or moves
var theWindow = [self window];
if ([theWindow attachedSheet])
[theWindow _setAttachedSheetFrameOrigin];
}
- (void)setShowsResizeIndicator:(BOOL)shouldShowResizeIndicator
{
if (shouldShowResizeIndicator)
if (shouldShowResizeIndicator && CPWindowResizeStyle === CPWindowResizeStyleLegacy)
{
var size = [_CPWindowViewResizeIndicatorImage size],
boundsSize = [self frame].size;
_resizeIndicator = [[CPImageView alloc] initWithFrame:CGRectMake(boundsSize.width - size.width - _resizeIndicatorOffset.width, boundsSize.height - size.height - _resizeIndicatorOffset.height, size.width, size.height)];
_resizeIndicator = [[CPImageView alloc] initWithFrame:_CGRectMake(boundsSize.width - size.width - _resizeIndicatorOffset.width, boundsSize.height - size.height - _resizeIndicatorOffset.height, size.width, size.height)];
[_resizeIndicator setImage:_CPWindowViewResizeIndicatorImage];
[_resizeIndicator setAutoresizingMask:CPViewMinXMargin | CPViewMinYMargin];
@@ -283,7 +590,7 @@ var _CPWindowViewResizeIndicatorImage = nil;
if (!_toolbarView || [_toolbarView isHidden])
return [self toolbarOffset].height;
return CGRectGetMaxY([_toolbarView frame]);
return _CGRectGetMaxY([_toolbarView frame]);
}
- (_CPToolbarView)toolbarView
@@ -295,14 +602,14 @@ var _CPWindowViewResizeIndicatorImage = nil;
{
var theWindow = [self window],
bounds = [self bounds],
width = CGRectGetWidth(bounds);
width = _CGRectGetWidth(bounds);
if ([[theWindow toolbar] isVisible])
{
var toolbarView = [self toolbarView],
toolbarOffset = [self toolbarOffset];
[toolbarView setFrame:CGRectMake(toolbarOffset.width, toolbarOffset.height, width, CGRectGetHeight([toolbarView frame]))];
[toolbarView setFrame:_CGRectMake(toolbarOffset.width, toolbarOffset.height, width, _CGRectGetHeight([toolbarView frame]))];
}
if ([self showsResizeIndicator])
@@ -350,6 +657,23 @@ var _CPWindowViewResizeIndicatorImage = nil;
[self tile];
}
- (void)noteKeyWindowStateChanged
{
if ([[self window] isKeyWindow])
[self setThemeState:CPThemeStateKeyWindow];
else
[self unsetThemeState:CPThemeStateKeyWindow];
}
- (void)noteMainWindowStateChanged
{
if ([[self window] isMainWindow])
[self setThemeState:CPThemeStateMainWindow];
else
[self unsetThemeState:CPThemeStateMainWindow];
}
/*
- (void)setAnimatingToolbar:(BOOL)isAnimatingToolbar
{
@@ -370,4 +694,21 @@ var _CPWindowViewResizeIndicatorImage = nil;
[self addSubview:_resizeIndicator];
}
- (void)_enableSheet:(BOOL)enable
{
if (enable)
{
var bundle = [CPBundle bundleForClass:[CPWindow class]];
_sheetShadowView = [[CPView alloc] initWithFrame:_CGRectMake(0, 0, _CGRectGetWidth([self bounds]), 8)];
[_sheetShadowView setAutoresizingMask:CPViewWidthSizable];
[_sheetShadowView setBackgroundColor:[CPColor colorWithPatternImage:[[CPImage alloc]
initWithContentsOfFile:[bundle pathForResource:@"CPWindow/CPWindowAttachedSheetShadow.png"] size:_CGSizeMake(9, 8)]]];
[self addSubview:_sheetShadowView];
}
else
{
[_sheetShadowView removeFromSuperview];
}
}
@end
+76 -16
View File
@@ -33,7 +33,7 @@
@class CPWindowController
An instance of a CPWindowController manages a CPWindow. Windows are typically loaded via a cib,
but they can also manage windows created in code. A CPWindowController can manage a window by
but they can also manage windows created in code. A CPWindowController can manage a window by
itself or work with AppKits's document-based architecture.
In a Document based app, a CPWindowController instance is created and managed by a CPDocument subclass.
@@ -181,8 +181,7 @@
if (!_window)
{
var reason = [CPString stringWithFormat:@"Window for %@ could not be loaded from Cib or no window specified. \
Override loadWindow to load the window manually.", self];
var reason = [CPString stringWithFormat:@"Window for %@ could not be loaded from Cib or no window specified. Override loadWindow to load the window manually.", self];
[CPException raise:CPInternalInconsistencyException reason:reason];
}
@@ -286,7 +285,7 @@
// Change of document means toolbar items may no longer make sense.
// FIXME: DOCUMENT ARCHITECTURE Should we setToolbar: as well?
[[[self window] toolbar] validateVisibleItems];
[[[self window] toolbar] _autoValidateVisibleItems];
}
- (void)setSupportsMultipleDocuments:(BOOL)shouldSupportMultipleDocuments
@@ -333,6 +332,41 @@
- (void)setViewControllerContainerView:(CPView)aView
{
if (!_viewControllerContainerView && !aView)
return;
var viewController = [self viewController],
viewControllerView = [viewController isViewLoaded] ? [viewController view] : nil,
contentView = [[self window] contentView];
if (aView)
{
[aView setFrame:[contentView frame]];
[aView setAutoresizingMask:[contentView autoresizingMask]];
if (viewControllerView)
{
[viewControllerView removeFromSuperview];
[aView addSubview:viewControllerView];
}
[[self window] setContentView:aView];
}
else if (viewControllerView)
{
[viewControllerView removeFromSuperview];
[viewControllerView setFrame:[contentView frame]];
[viewControllerView setAutoresizingMask:[contentView autoresizingMask]]
[[self window] setContentView:viewControllerView];
}
else
{
var view = [[CPView alloc] init];
[view setFrame:[contentView frame]];
[view setAutoresizingMask:[contentView autoresizingMask]];
[[self window] setContentView:view]
}
_viewControllerContainerView = aView;
}
@@ -343,21 +377,47 @@
- (void)setViewController:(CPViewController)aViewController
{
var containerView = [self viewControllerContainerView] || [[self window] contentView],
view = [_viewController view],
frame = view ? [view frame] : [containerView bounds];
if (!_viewController && !aViewController)
return;
[view removeFromSuperview];
var containerView = [self viewControllerContainerView],
newView = [aViewController isViewLoaded] ? [aViewController view] : nil;
if (containerView)
{
var oldView = [_viewController isViewLoaded] ? [_viewController view] : nil;
if (oldView)
{
[newView setFrame:[oldView frame]];
[newView setAutoresizingMask:[oldView autoresizingMask]];
}
if (oldView && newView)
[containerView replaceSubview:oldView with:newView];
else if (oldView)
[oldView removeFromSuperview];
else if (newView)
[containerView addSubview:newView];
}
else if (newView)
{
var contentView = [[self window] contentView];
[newView setFrame:[contentView frame]];
[newView setAutoresizingMask:[contentView autoresizingMask]];
[[self window] setContentView:newView];
}
else
{
var view = [[CPView alloc] init],
contentView = [[self window] contentView];
[view setFrame:[contentView frame]];
[view setAutoresizingMask:[contentView autoresizingMask]];
[[self window] setContentView:view]
}
_viewController = aViewController;
view = [_viewController view];
if (view)
{
[view setFrame:frame];
[containerView addSubview:view];
}
}
- (CPViewController)viewController
+6 -2
View File
@@ -61,6 +61,10 @@ var CPCibObjectDataKey = @"CPCibObjectDataKey";
if (self)
{
_data = [CPURLConnection sendSynchronousRequest:[CPURLRequest requestWithURL:aURL] returningResponse:nil];
if (!_data)
return nil;
_awakenCustomResources = YES;
}
@@ -137,7 +141,7 @@ var CPCibObjectDataKey = @"CPCibObjectDataKey";
var key = nil,
keyEnumerator = [replacementClasses keyEnumerator];
while (key = [keyEnumerator nextObject])
while ((key = [keyEnumerator nextObject]) !== nil)
[unarchiver setClass:[replacementClasses objectForKey:key] forClassName:key];
}
@@ -162,7 +166,7 @@ var CPCibObjectDataKey = @"CPCibObjectDataKey";
- (BOOL)instantiateCibWithOwner:(id)anOwner topLevelObjects:(CPArray)topLevelObjects
{
return [self instantiateCibWithExternalNameTable:[CPDictionary dictionaryWithObjectsAndKeys:anOwner, CPCibOwner, topLevelObjects, CPCibTopLevelObjects]];
return [self instantiateCibWithExternalNameTable:[CPDictionary dictionaryWithObjects:[anOwner, topLevelObjects] forKeys:[CPCibOwner, CPCibTopLevelObjects]]];
}
@end
+59
View File
@@ -0,0 +1,59 @@
/*
* CPCibHelpConnector.j
* AppKit
*
* Created by Antoine Mercadal.
* Copyright 2012, The Cappuccino Project.
*
* 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 "CPCibConnector.j"
@implementation CPCibHelpConnector : CPCibConnector
{
id _destination;
id _file;
id _marker;
}
- (id)initWithCoder:(CPCoder)aCoder
{
if (self = [super initWithCoder:aCoder])
{
_destination = [aCoder decodeObjectForKey:@"_destination"];
_file = [aCoder decodeObjectForKey:@"_file"];
_marker = [aCoder decodeObjectForKey:@"_marker"];
}
return self;
}
- (void)encodeWithCoder:(CPCoder)aCoder
{
[super encodeWithCoder:aCoder];
[aCoder encodeObject:_destination forKey:@"_destination"];
[aCoder encodeObject:_file forKey:@"_file"];
[aCoder encodeObject:_marker forKey:@"_marker"];
}
- (void)establishConnection
{
[_destination setToolTip:_marker];
}
@end
@@ -0,0 +1,64 @@
/*
* CPCibRuntimeAttributesConnector.j
* AppKit
*
* Created by Aparajita Fishman.
* Copyright 2012, The Cappuccino Project.
*
* 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 "CPCibConnector.j"
var CPCibRuntimeAttributesConnectorObjectKey = @"CPCibRuntimeAttributesConnectorObjectKey",
CPCibRuntimeAttributesConnectorKeyPathsKey = @"CPCibRuntimeAttributesConnectorKeyPathsKey",
CPCibRuntimeAttributesConnectorValuesKey = @"CPCibRuntimeAttributesConnectorValuesKey";
@implementation CPCibRuntimeAttributesConnector : CPCibConnector
{
id _keyPaths;
id _values;
}
- (id)initWithCoder:(CPCoder)aCoder
{
if (self = [super initWithCoder:aCoder])
{
_source = [aCoder decodeObjectForKey:CPCibRuntimeAttributesConnectorObjectKey];
_keyPaths = [aCoder decodeObjectForKey:CPCibRuntimeAttributesConnectorKeyPathsKey];
_values = [aCoder decodeObjectForKey:CPCibRuntimeAttributesConnectorValuesKey];
}
return self;
}
- (void)encodeWithCoder:(CPCoder)aCoder
{
[super encodeWithCoder:aCoder];
[aCoder encodeObject:_source forKey:CPCibRuntimeAttributesConnectorObjectKey];
[aCoder encodeObject:_keyPaths forKey:CPCibRuntimeAttributesConnectorKeyPathsKey];
[aCoder encodeObject:_values forKey:CPCibRuntimeAttributesConnectorValuesKey];
}
- (void)establishConnection
{
var count = [_keyPaths count];
while (count--)
[_source setValue:_values[count] forKeyPath:_keyPaths[count]];
}
@end
+2 -2
View File
@@ -61,14 +61,14 @@ var _CPCibClassSwapperClassNameKey = @"_CPCibClassSwapperClassNameKey",
if (!object)
{
CPLog.error("Unable to find class " + theClassName + " in cib file.");
CPLog.error("Unable to find class " + theClassName + " referenced in cib file.");
object = [self allocObjectWithCoder:aCoder className:[aCoder decodeObjectForKey:_CPCibClassSwapperOriginalClassNameKey]];
}
}
if (!object)
[CPException raise:CPInvalidArgumentException reason:@"Unable to find class " + theClassName + " in cib file."];
[CPException raise:CPInvalidArgumentException reason:@"Unable to find class " + theClassName + " referenced in cib file."];
return object;
}
+33 -1
View File
@@ -43,6 +43,11 @@ var _CPCibCustomResourceClassNameKey = @"_CPCibCustomResourceClassNameKey",
return [[self alloc] initWithClassName:@"CPImage" resourceName:aResourceName properties:[CPDictionary dictionaryWithObject:aSize forKey:@"size"]];
}
+ (id)imageResourceWithName:(CPString)aResourceName size:(CGSize)aSize bundleClass:(CPString)aBundleClass
{
return [[self alloc] initWithClassName:@"CPImage" resourceName:aResourceName properties:[CPDictionary dictionaryWithObjects:[aSize, aBundleClass] forKeys:[@"size", @"bundleClass"]]];
}
- (id)initWithClassName:(CPString)aClassName resourceName:(CPString)aResourceName properties:(CPDictionary)properties
{
self = [super init];
@@ -89,12 +94,32 @@ var _CPCibCustomResourceClassNameKey = @"_CPCibCustomResourceClassNameKey",
else if (_resourceName == "CPRemoveTemplate")
return [[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:[CPButtonBar class]] pathForResource:@"minus_button.png"] size:CGSizeMake(11, 4)];
return [[CPImage alloc] initWithContentsOfFile:[[aCoder bundle] pathForResource:_resourceName] size:_properties.valueForKey(@"size")];
return [self imageFromBundle:[aCoder bundle]];
}
return self;
}
- (CPImage)imageFromBundle:(CPBundle)aBundle
{
if (!aBundle)
{
var bundleClass = _properties.valueForKey(@"bundleClass");
if (bundleClass)
{
bundleClass = CPClassFromString(bundleClass);
if (bundleClass)
aBundle = [CPBundle bundleForClass:bundleClass];
}
else
aBundle = [CPBundle mainBundle];
}
return [[CPImage alloc] initWithContentsOfFile:[aBundle pathForResource:_resourceName] size:_properties.valueForKey(@"size")];
}
@end
@implementation _CPCibCustomResource (CPImage)
@@ -129,4 +154,11 @@ var _CPCibCustomResourceClassNameKey = @"_CPCibCustomResourceClassNameKey",
return nil;
}
- (CPString)description
{
var image = [self imageFromBundle:nil];
return [image description];
}
@end
+26 -6
View File
@@ -29,6 +29,8 @@
@import "CPCibControlConnector.j"
@import "CPCibOutletConnector.j"
@import "CPCibBindingConnector.j"
@import "CPCibRuntimeAttributesConnector.j"
@import "CPCibHelpConnector.j"
@implementation _CPCibObjectData : CPObject
@@ -106,7 +108,7 @@
var object = nil,
objectEnumerator = [_visibleWindows objectEnumerator];
while (object = [objectEnumerator nextObject])
while ((object = [objectEnumerator nextObject]) !== nil)
[_replacementObjects[[object UID]] makeKeyAndOrderFront:self];
}
@@ -232,15 +234,15 @@ var _CPCibObjectDataNamesKeysKey = @"_CPCibObjectDataNamesKeysKey
{
_replacementObjects[[object UID]] = instantiatedObject;
if ([instantiatedObject isKindOfClass:[CPView class]])
if ([instantiatedObject isKindOfClass:CPView])
{
var clipView = [instantiatedObject superview];
if ([clipView isKindOfClass:[CPClipView class]])
if ([clipView isKindOfClass:CPClipView])
{
var scrollView = [clipView superview];
if ([scrollView isKindOfClass:[CPScrollView class]])
if ([scrollView isKindOfClass:CPScrollView])
[scrollView setDocumentView:instantiatedObject];
}
}
@@ -257,11 +259,29 @@ var _CPCibObjectDataNamesKeysKey = @"_CPCibObjectDataNamesKeysKey
_replacementObjects[[_fileOwner UID]] = anOwner;
var index = 0,
count = _connections.length;
count = _connections.length,
runtimeAttributeConnectors = [],
connection = nil;
for (; index < count; ++index)
{
var connection = _connections[index];
connection = _connections[index];
if ([connection isKindOfClass:CPCibRuntimeAttributesConnector])
// Defer runtime attribute connections until after all other connections are made
runtimeAttributeConnectors.push(connection);
else
{
[connection replaceObjects:_replacementObjects];
[connection establishConnection];
}
}
count = runtimeAttributeConnectors.length;
for (index = 0; index < count; ++index)
{
connection = runtimeAttributeConnectors[index];
[connection replaceObjects:_replacementObjects];
[connection establishConnection];
+86 -66
View File
@@ -4,29 +4,20 @@
@import "CGGeometry.j"
@import "CPWindow.j"
CPWindowPositionFlexibleRight = 1 << 19;
CPWindowPositionFlexibleLeft = 1 << 20;
CPWindowPositionFlexibleBottom = 1 << 21;
CPWindowPositionFlexibleTop = 1 << 22;
var _CPCibWindowTemplateMinSizeKey = @"_CPCibWindowTemplateMinSizeKey",
_CPCibWindowTemplateMaxSizeKey = @"_CPCibWindowTemplateMaxSizeKey",
_CPCibWindowTemplateViewClassKey = @"_CPCibWindowTemplateViewClassKey",
_CPCibWindowTemplateWindowClassKey = @"_CPCibWindowTemplateWindowClassKey",
_CPCibWindowTemplateWindowRectKey = @"_CPCibWindowTemplateWindowRectKey",
_CPCibWindowTemplateWindowStyleMaskKey = @"_CPCibWindowTempatStyleMaskKey",
_CPCibWindowTemplateWindowTitleKey = @"_CPCibWindowTemplateWindowTitleKey",
_CPCibWindowTemplateWindowViewKey = @"_CPCibWindowTemplateWindowViewKey",
_CPCibWindowTemplateWindowAutorecalculatesKeyViewLoop = @"_CPCibWindowTemplateWindowAutorecalculatesKeyViewLoop",
_CPCibWindowTemplateWindowIsFullPlatformWindowKey = @"_CPCibWindowTemplateWindowIsFullPlatformWindowKey";
@implementation _CPCibWindowTemplate : CPObject
{
CGSize _minSize;
CGSize _maxSize;
//CGSize _screenRect;
CGRect _screenRect;
id _viewClass;
//unsigned _wtFlags;
unsigned _wtFlags;
CPString _windowClass;
CGRect _windowRect;
unsigned _windowStyleMask;
@@ -52,67 +43,18 @@ var _CPCibWindowTemplateMinSizeKey = @"_CPCibWindowTemp
_windowView = [[CPView alloc] initWithFrame:CGRectMake(0.0, 0.0, 400.0, 200.0)];
_windowIsFullPlatformWindow = NO;
_wtFlags = CPPositionProportionalHorizontal | CPPositionProportionalVertical;
}
return self;
}
- (id)initWithCoder:(CPCoder)aCoder
{
self = [super init];
if (self)
{
if ([aCoder containsValueForKey:_CPCibWindowTemplateMinSizeKey])
_minSize = [aCoder decodeSizeForKey:_CPCibWindowTemplateMinSizeKey];
if ([aCoder containsValueForKey:_CPCibWindowTemplateMaxSizeKey])
_maxSize = [aCoder decodeSizeForKey:_CPCibWindowTemplateMaxSizeKey];
_viewClass = [aCoder decodeObjectForKey:_CPCibWindowTemplateViewClassKey];
_windowClass = [aCoder decodeObjectForKey:_CPCibWindowTemplateWindowClassKey];
_windowRect = [aCoder decodeRectForKey:_CPCibWindowTemplateWindowRectKey];
_windowStyleMask = [aCoder decodeIntForKey:_CPCibWindowTemplateWindowStyleMaskKey];
_windowTitle = [aCoder decodeObjectForKey:_CPCibWindowTemplateWindowTitleKey];
_windowView = [aCoder decodeObjectForKey:_CPCibWindowTemplateWindowViewKey];
_windowAutorecalculatesKeyViewLoop = !![aCoder decodeObjectForKey:_CPCibWindowTemplateWindowAutorecalculatesKeyViewLoop];
_windowIsFullPlatformWindow = !![aCoder decodeObjectForKey:_CPCibWindowTemplateWindowIsFullPlatformWindowKey];
}
return self;
}
- (void)encodeWithCoder:(CPCoder)aCoder
{
if (_minSize)
[aCoder encodeSize:_minSize forKey:_CPCibWindowTemplateMinSizeKey];
if (_maxSize)
[aCoder encodeSize:_maxSize forKey:_CPCibWindowTemplateMaxSizeKey];
[aCoder encodeObject:_viewClass forKey:_CPCibWindowTemplateViewClassKey];
[aCoder encodeObject:_windowClass forKey:_CPCibWindowTemplateWindowClassKey];
[aCoder encodeRect:_windowRect forKey:_CPCibWindowTemplateWindowRectKey];
[aCoder encodeInt:_windowStyleMask forKey:_CPCibWindowTemplateWindowStyleMaskKey];
[aCoder encodeObject:_windowTitle forKey:_CPCibWindowTemplateWindowTitleKey];
[aCoder encodeObject:_windowView forKey:_CPCibWindowTemplateWindowViewKey];
if (_windowAutorecalculatesKeyViewLoop)
[aCoder encodeObject:_windowAutorecalculatesKeyViewLoop forKey:_CPCibWindowTemplateWindowAutorecalculatesKeyViewLoop];
if (_windowIsFullPlatformWindow)
[aCoder encodeObject:_windowIsFullPlatformWindow forKey:_CPCibWindowTemplateWindowIsFullPlatformWindowKey];
}
- (CPString)customClassName
{
return _windowClass;
}
- (void)setCustomClassName:(CPString)aClassName
{
_windowClass = aClassName;
@@ -155,7 +97,85 @@ var _CPCibWindowTemplateMinSizeKey = @"_CPCibWindowTemp
[theWindow setAutorecalculatesKeyViewLoop:_windowAutorecalculatesKeyViewLoop];
[theWindow setFullBridge:_windowIsFullPlatformWindow];
theWindow._positioningMask = _wtFlags;
theWindow._positioningScreenRect = _screenRect;
return theWindow;
}
@end
var _CPCibWindowTemplateMinSizeKey = @"_CPCibWindowTemplateMinSizeKey",
_CPCibWindowTemplateMaxSizeKey = @"_CPCibWindowTemplateMaxSizeKey",
_CPCibWindowTemplateViewClassKey = @"_CPCibWindowTemplateViewClassKey",
_CPCibWindowTemplateWTFlagsKey = @"_CPCibWindowTemplateWTFlagsKey",
_CPCibWindowTemplateWindowClassKey = @"_CPCibWindowTemplateWindowClassKey",
_CPCibWindowTemplateWindowRectKey = @"_CPCibWindowTemplateWindowRectKey",
_CPCibWindowTemplateScreenRectKey = @"_CPCibWindowTemplateScreenRectKey",
_CPCibWindowTemplateWindowStyleMaskKey = @"_CPCibWindowTempatStyleMaskKey",
_CPCibWindowTemplateWindowTitleKey = @"_CPCibWindowTemplateWindowTitleKey",
_CPCibWindowTemplateWindowViewKey = @"_CPCibWindowTemplateWindowViewKey",
_CPCibWindowTemplateWindowAutorecalculatesKeyViewLoop = @"_CPCibWindowTemplateWindowAutorecalculatesKeyViewLoop",
_CPCibWindowTemplateWindowIsFullPlatformWindowKey = @"_CPCibWindowTemplateWindowIsFullPlatformWindowKey";
@implementation _CPCibWindowTemplate (Coding)
- (id)initWithCoder:(CPCoder)aCoder
{
self = [super init];
if (self)
{
if ([aCoder containsValueForKey:_CPCibWindowTemplateMinSizeKey])
_minSize = [aCoder decodeSizeForKey:_CPCibWindowTemplateMinSizeKey];
if ([aCoder containsValueForKey:_CPCibWindowTemplateMaxSizeKey])
_maxSize = [aCoder decodeSizeForKey:_CPCibWindowTemplateMaxSizeKey];
_viewClass = [aCoder decodeObjectForKey:_CPCibWindowTemplateViewClassKey];
_windowClass = [aCoder decodeObjectForKey:_CPCibWindowTemplateWindowClassKey];
_wtFlags = [aCoder decodeIntForKey:_CPCibWindowTemplateWTFlagsKey];
_windowRect = [aCoder decodeRectForKey:_CPCibWindowTemplateWindowRectKey];
_screenRect = [aCoder decodeRectForKey:_CPCibWindowTemplateScreenRectKey];
_windowStyleMask = [aCoder decodeIntForKey:_CPCibWindowTemplateWindowStyleMaskKey];
_windowTitle = [aCoder decodeObjectForKey:_CPCibWindowTemplateWindowTitleKey];
_windowView = [aCoder decodeObjectForKey:_CPCibWindowTemplateWindowViewKey];
_windowAutorecalculatesKeyViewLoop = [aCoder decodeBoolForKey:_CPCibWindowTemplateWindowAutorecalculatesKeyViewLoop];
_windowIsFullPlatformWindow = [aCoder decodeBoolForKey:_CPCibWindowTemplateWindowIsFullPlatformWindowKey];
}
return self;
}
- (void)encodeWithCoder:(CPCoder)aCoder
{
if (_minSize)
[aCoder encodeSize:_minSize forKey:_CPCibWindowTemplateMinSizeKey];
if (_maxSize)
[aCoder encodeSize:_maxSize forKey:_CPCibWindowTemplateMaxSizeKey];
[aCoder encodeObject:_viewClass forKey:_CPCibWindowTemplateViewClassKey];
[aCoder encodeObject:_windowClass forKey:_CPCibWindowTemplateWindowClassKey];
[aCoder encodeInt:_wtFlags forKey:_CPCibWindowTemplateWTFlagsKey];
[aCoder encodeRect:_windowRect forKey:_CPCibWindowTemplateWindowRectKey];
[aCoder encodeRect:_screenRect forKey:_CPCibWindowTemplateScreenRectKey];
[aCoder encodeInt:_windowStyleMask forKey:_CPCibWindowTemplateWindowStyleMaskKey];
[aCoder encodeObject:_windowTitle forKey:_CPCibWindowTemplateWindowTitleKey];
[aCoder encodeObject:_windowView forKey:_CPCibWindowTemplateWindowViewKey];
if (_windowAutorecalculatesKeyViewLoop)
[aCoder encodeObject:_windowAutorecalculatesKeyViewLoop forKey:_CPCibWindowTemplateWindowAutorecalculatesKeyViewLoop];
if (_windowIsFullPlatformWindow)
[aCoder encodeObject:_windowIsFullPlatformWindow forKey:_CPCibWindowTemplateWindowIsFullPlatformWindowKey];
}
@end
+1 -1
View File
@@ -20,7 +20,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "CGGeometry.h"
#include "../../Foundation/_CGGeometry.h"
#define _CGAffineTransformMake(a_, b_, c_, d_, tx_, ty_) { a:a_, b:b_, c:c_, d:d_, tx:tx_, ty:ty_ }
#define _CGAffineTransformMakeIdentity() _CGAffineTransformMake(1.0, 0.0, 0.0, 1.0, 0.0, 0.0)
+1 -1
View File
@@ -193,7 +193,7 @@ function CGColorSpaceRetain(aColorSpace)
}
// FIXME: We should refer to some default values.
#define STANDARDIZE(components, index, minimum, maximum, multiplier) \
#define STANDARDIZE(components, index, minimum, maximum, multiplier) \
{ \
if (index > components.length) \
{ \
+10
View File
@@ -321,6 +321,16 @@ function CGContextClosePath(aContext)
CGPathCloseSubpath(aContext.path);
}
/*!
Return YES if the current path in the given context is empty.
@param aContext the CGContext to examine
@return BOOL
*/
function CGContextIsPathEmpty(aContext)
{
return (!aContext.path || CGPathIsEmpty(aContext.path));
}
/*!
Moves the current location of aContext to the given x and y coordinates
@param aContext the CGContext to move
+2 -2
View File
@@ -129,7 +129,7 @@ function CGContextAddPath(aContext, aPath)
break;
case kCGPathElementAddArc: _CGContextAddArcCanvas(aContext, element.x, element.y, element.radius, element.startAngle, element.endAngle, element.clockwise);
break;
case kCGPathElementAddArcTo: //_CGContextAddArcToPointCanvas(aContext, element.cp1x, element.cp1.y, element.cp2.x, element.cp2y, element.radius);
case kCGPathElementAddArcToPoint: _CGContextAddArcToPointCanvas(aContext, element.p1x, element.p1y, element.p2x, element.p2y, element.radius);
break;
}
}
@@ -323,7 +323,7 @@ function CGContextTranslateCTM(aContext, tx, ty)
#define rotate_scale(a, b, c, d) \
var sign = (a * d < 0.0 || b * c > 0.0) ? -1.0 : 1.0;\
a1 = (Math.atan2(sign * b, sign * a) + Math.atan2(-c, d)) / 2.0,\
a1 = (ATAN2(sign * b, sign * a) + ATAN2(-c, d)) / 2.0,\
cos = COS(a1),\
sin = SIN(a1);\
\
+2 -2
View File
@@ -215,7 +215,7 @@ function CGContextDrawPath(aContext, aMode)
COORD(start.x), ',', COORD(start.y), " ",
COORD(end.x), ',', COORD(end.y));
break;
case kCGPathElementAddArcTo: break;
case kCGPathElementAddArcToPoint: break;
}
// TODO: Following is broken for curves due to
@@ -332,4 +332,4 @@ function CGContextDrawLinearGradient(aContext, aGradient, aStartPoint, anEndPoin
// aContext.buffer += vml.join("");
// else
// aContext.DOMElement.innerHTML = vml.join("");
}
}
+3 -266
View File
@@ -2,8 +2,8 @@
* CGGeometry.j
* AppKit
*
* Created by Francisco Tolmasky.
* Copyright 2008, 280 North, Inc.
* Created by Alexander Ljungberg.
* Copyright 2012, SlevenBits Ltd.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -20,267 +20,4 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#define _function(inline) function inline { return _##inline; }
_function(CGPointMake(x, y))
_function(CGPointMakeZero())
_function(CGPointMakeCopy(aPoint))
_function(CGPointCreateCopy(aPoint))
_function(CGPointEqualToPoint(lhsPoint, rhsPoint))
_function(CGStringFromPoint(aPoint))
_function(CGSizeMake(width, height))
_function(CGSizeMakeZero())
_function(CGSizeMakeCopy(aSize))
_function(CGSizeCreateCopy(aSize))
_function(CGSizeEqualToSize(lhsSize, rhsSize))
_function(CGStringFromSize(aSize))
_function(CGRectMake(x, y, width, height))
_function(CGRectMakeZero())
_function(CGRectMakeCopy(aRect))
_function(CGRectCreateCopy(aRect))
_function(CGRectEqualToRect(lhsRect, rhsRect))
_function(CGStringFromRect(aRect))
_function(CGRectOffset(aRect, dX, dY))
_function(CGRectInset(aRect, dX, dY))
_function(CGRectGetHeight(aRect))
_function(CGRectGetMaxX(aRect))
_function(CGRectGetMaxY(aRect))
_function(CGRectGetMidX(aRect))
_function(CGRectGetMidY(aRect))
_function(CGRectGetMinX(aRect))
_function(CGRectGetMinY(aRect))
_function(CGRectGetWidth(aRect))
_function(CGRectIsEmpty(aRect))
_function(CGRectIsNull(aRect))
_function(CGRectContainsPoint(aRect, aPoint))
_function(CGInsetMake(top, right, bottom, left))
_function(CGInsetMakeZero())
_function(CGInsetMakeCopy(anInset))
_function(CGInsetIsEmpty(anInset))
_function(CGInsetEqualToInset(lhsInset, rhsInset))
CGMinXEdge = 0;
CGMinYEdge = 1;
CGMaxXEdge = 2;
CGMaxYEdge = 3;
CGRectNull = _CGRectMake(Infinity, Infinity, 0.0, 0.0);
/*!
@addtogroup appkit
@{
*/
/*!
Creates two rectangles -- slice and rem -- from inRect, by dividing inRect
with a line that's parallel to the side of inRect specified by edge.
The size of slice is determined by amount, which specifies the distance from edge.
slice and rem must not be NULL, must not be the same object, and must not be the
same object as inRect.
@group CGRect
*/
function CGRectDivide(inRect, slice, rem, amount, edge)
{
slice.origin = _CGPointMakeCopy(inRect.origin);
slice.size = _CGSizeMakeCopy(inRect.size);
rem.origin = _CGPointMakeCopy(inRect.origin);
rem.size = _CGSizeMakeCopy(inRect.size);
switch (edge)
{
case CGMinXEdge:
slice.size.width = amount;
rem.origin.x += amount;
rem.size.width -= amount;
break;
case CGMaxXEdge:
slice.origin.x = _CGRectGetMaxX(slice) - amount;
slice.size.width = amount;
rem.size.width -= amount;
break;
case CGMinYEdge:
slice.size.height = amount;
rem.origin.y += amount;
rem.size.height -= amount;
break;
case CGMaxYEdge:
slice.origin.y = _CGRectGetMaxY(slice) - amount;
slice.size.height = amount;
rem.size.height -= amount;
}
}
/*!
Returns a \c BOOL indicating whether CGRect \c lhsRect
contains CGRect \c rhsRect.
@group CGRect
@param lhsRect the CGRect to test if \c rhsRect is inside of
@param rhsRect the CGRect to test if it fits inside \c lhsRect.
@return BOOL \c YES if \c rhsRect fits inside \c lhsRect.
*/
function CGRectContainsRect(lhsRect, rhsRect)
{
var union = CGRectUnion(lhsRect, rhsRect);
return _CGRectEqualToRect(union, lhsRect);
}
/*!
Returns \c YES if the two rectangles intersect
@group CGRect
@param lhsRect the first CGRect
@param rhsRect the second CGRect
@return BOOL \c YES if the two rectangles have any common spaces, and \c NO, otherwise.
*/
function CGRectIntersectsRect(lhsRect, rhsRect)
{
var intersection = CGRectIntersection(lhsRect, rhsRect);
return !_CGRectIsEmpty(intersection);
}
/*!
Makes the origin and size of a CGRect all integers. Specifically, by making
the southwest corner the origin (rounded down), and the northeast corner a CGSize (rounded up).
@param aRect the rectangle to operate on
@return CGRect the modified rectangle (same as the input)
@group CGRect
*/
function CGRectIntegral(aRect)
{
aRect = CGRectStandardize(aRect);
// Store these out separately, if not the GetMaxes will return incorrect values.
var x = FLOOR(_CGRectGetMinX(aRect)),
y = FLOOR(_CGRectGetMinY(aRect));
aRect.size.width = CEIL(_CGRectGetMaxX(aRect)) - x;
aRect.size.height = CEIL(_CGRectGetMaxY(aRect)) - y;
aRect.origin.x = x;
aRect.origin.y = y;
return aRect;
}
/*!
Returns the intersection of the two provided rectangles as a new rectangle.
@param lhsRect the first rectangle used for calculation
@param rhsRect the second rectangle used for calculation
@return CGRect the intersection of the two rectangles
@group CGRect
*/
function CGRectIntersection(lhsRect, rhsRect)
{
var intersection = _CGRectMake(
MAX(_CGRectGetMinX(lhsRect), _CGRectGetMinX(rhsRect)),
MAX(_CGRectGetMinY(lhsRect), _CGRectGetMinY(rhsRect)),
0, 0);
intersection.size.width = MIN(_CGRectGetMaxX(lhsRect), _CGRectGetMaxX(rhsRect)) - _CGRectGetMinX(intersection);
intersection.size.height = MIN(_CGRectGetMaxY(lhsRect), _CGRectGetMaxY(rhsRect)) - _CGRectGetMinY(intersection);
return _CGRectIsEmpty(intersection) ? _CGRectMakeZero() : intersection;
}
/*
*/
function CGRectStandardize(aRect)
{
var width = _CGRectGetWidth(aRect),
height = _CGRectGetHeight(aRect),
standardized = _CGRectMakeCopy(aRect);
if (width < 0.0)
{
standardized.origin.x += width;
standardized.size.width = -width;
}
if (height < 0.0)
{
standardized.origin.y += height;
standardized.size.height = -height;
}
return standardized;
}
function CGRectUnion(lhsRect, rhsRect)
{
var lhsRectIsNull = !lhsRect || lhsRect === CGRectNull,
rhsRectIsNull = !rhsRect || rhsRect === CGRectNull;
if (lhsRectIsNull)
return rhsRectIsNull ? CGRectNull : rhsRect;
if (rhsRectIsNull)
return lhsRectIsNull ? CGRectNull : lhsRect;
var minX = MIN(_CGRectGetMinX(lhsRect), _CGRectGetMinX(rhsRect)),
minY = MIN(_CGRectGetMinY(lhsRect), _CGRectGetMinY(rhsRect)),
maxX = MAX(_CGRectGetMaxX(lhsRect), _CGRectGetMaxX(rhsRect)),
maxY = MAX(_CGRectGetMaxY(lhsRect), _CGRectGetMaxY(rhsRect));
return _CGRectMake(minX, minY, maxX - minX, maxY - minY);
}
function CGPointFromString(aString)
{
var comma = aString.indexOf(',');
return { x:parseInt(aString.substr(1, comma - 1)), y:parseInt(aString.substring(comma + 1, aString.length)) };
}
function CGSizeFromString(aString)
{
var comma = aString.indexOf(',');
return { width:parseInt(aString.substr(1, comma - 1)), height:parseInt(aString.substring(comma + 1, aString.length)) };
}
function CGRectFromString(aString)
{
var comma = aString.indexOf(',', aString.indexOf(',') + 1);
return { origin:CGPointFromString(aString.substr(1, comma - 1)), size:CGSizeFromString(aString.substring(comma + 2, aString.length)) };
}
function CGPointFromEvent(anEvent)
{
return _CGPointMake(anEvent.clientX, anEvent.clientY);
}
function CGInsetFromString(aString)
{
var numbers = aString.substr(1, aString.length - 2).split(',');
return _CGInsetMake(parseFloat(numbers[0]), parseFloat(numbers[1]), parseFloat(numbers[2]), parseFloat(numbers[3]));
}
CGInsetFromCPString = CGInsetFromString;
function CPStringFromCGInset(anInset)
{
return '{' + anInset.top + ", " + anInset.left + ", " + anInset.bottom + ", " + anInset.right + '}';
}
/*!
@}
*/
@import <Foundation/_CGGeometry.j>

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