Compare commits

...
655 Commits
Author SHA1 Message Date
Alexander Ljungberg 099ee1e249 RC1 bootstrap. 2012-03-26 21:09:37 +01:00
Alexander Ljungberg aba7fd5527 Make CPPopUpButton selectedTag private API to match Cocoa. 2012-03-26 19:55:50 +01:00
Alexander Ljungberg 68c794bf9d This will be Cappuccino 0.9.6. 2012-03-26 19:55:17 +01:00
Alexander Ljungberg ca9b3a7dbf Demonstrate that pop up button test is using tags. 2012-03-25 22:01:16 +01:00
Alexander Ljungberg 4eba585286 Fix manual pop up button test. 2012-03-25 21:40:52 +01:00
Alexander Ljungberg 4172ecfdf2 Merge branch 'master' of github.com:cappuccino/cappuccino 2012-03-25 14:15:39 +01:00
Alexander Ljungberg da80176935 Minor optimisation. 2012-03-25 14:15:18 +01:00
Alexander Ljungberg f50802b85b Fixes #1164. Support CPOutlineView selectionShouldChangeInOutlineView: delegate method. 2012-03-25 13:58:41 +01:00
Alexander Ljungberg 5351bf7e12 Select outline view item parent with left key.
If there's a single item selected and it's not expanded, pressing the left arrow key on the keyboard now selects the item's parent unless the delegate vetoes.
2012-03-25 13:47:32 +01:00
Aparajita Fishman 96a038559e CPPopover fixes
- Removed animationStyle for now.
- Made sure that popoverDidClose is not called until animation is finished.
- Don't create a new attached window unless: there isn't one; the popover behavior has changed; the current attached window is still visible.
- Don't call popoverWillShow if there is not content view controller.
-  Removed unused _shown instance variable.
- Removed redundant !_attachedWindow checks followed by _attachedWindow message that returns a BOOL.
- Documentation tweaks.
- Fixed up some demo issues.
2012-03-24 20:56:31 -07:00
Aparajita Fishman c321084990 Whitespace 2012-03-24 17:57:13 -07:00
aparajita e13d070439 Merge pull request #1483 from cacaodev/CFPropertyList-XML-date-deserialization
CPDate deserialization from XML Property List, with test.
2012-03-24 17:49:37 -07:00
Aparajita Fishman 1a8fc7f07f CPPopover fixes/enhancements
- Lion-style popovers now zoom open just like their Lion counterparts (except for opacity, the browser couldn't handle that at the same time).
- Fixed a number of subtle drawing issues caused by not aligning path points correctly.
- The anchor arrow deals correctly with corner cases where the middle of the reference rect is not within the corners of the popover.
- Code cleanup: factored redundant code, removed unused code.
- Added corner cases to the demo app, changed demo app to reuse a single popover.
2012-03-23 19:53:46 -07:00
cacaodev 9ef95e1f68 Support for decoding date type in XML 1.0, with test. 2012-03-23 22:28:42 +01:00
aparajita 28ed2f9bd0 Merge pull request #1482 from cacaodev/CPViewController-bundle-fix
CPViewController The cib should be initialized with bundle information.
2012-03-23 09:30:23 -07:00
cacaodev 93f51eaa42 CPViewController The cib should be initialized with bundle information. 2012-03-23 10:09:48 +01:00
Aparajita Fishman 7c807dd887 Moved animationStyle to dedicated methods so they can be documented 2012-03-23 01:57:24 -07:00
Aparajita Fishman 429b42d3e0 Implement what is documented, that loadView without a cib name will create an empty view 2012-03-23 01:49:44 -07:00
Aparajita Fishman 08f013171e CPPopover tweaks:
- Added animationStyle (Lion/iOS) to CPPopover. iOS style does not zoom open, it just appears.
- Tweaked the Lion animation a bit to be a bit less rushed and match Mac OS X timing better.
- Fixed some typos.
2012-03-23 01:49:01 -07:00
Aparajita Fishman d620032d0d Switch from CPRect/Point to CGRect/Point functions 2012-03-22 18:58:41 -07:00
Alexander Ljungberg 3bc5605633 Merge branch 'master' of github.com:cappuccino/cappuccino 2012-03-23 00:35:00 +00:00
Alexander Ljungberg 3a0068186a Implement stopping support for CPArray enumerateObjectsUsingBlock:. 2012-03-23 00:34:09 +00:00
Alexander Ljungberg e19a782954 Test CPArray enumerateObjectsUsingBlock:. 2012-03-23 00:26:05 +00:00
Aparajita Fishman 88783efa7b Needed an _isLazy flag to get correct behavior 2012-03-22 15:43:18 -07:00
Aparajita Fishman a249588f52 UIKit does NOT call viewDidLoad from setView, made this explicit in the docs
viewDidLoad is meant to deal with asynchronous *lazy* instantiation of a view via a cib or loadView. setView is neither asynchronous nor lazy.
2012-03-22 14:22:20 -07:00
Alexander Ljungberg 2951a83e73 CPArray enumerateObjectsWithOptions:usingBlock:. 2012-03-22 17:05:59 +00:00
Aparajita Fishman b99ece088d Prevent doxygen from parsing @implementation within comments 2012-03-21 12:48:12 -07:00
Aparajita Fishman ebd797d6d7 Documented need to use CPColorWithImages() instead of PatternColor() 2012-03-20 13:48:50 -07:00
aparajita fa7a68f3f8 Merge pull request #1479 from aparajita/DOM-class
Put view class in the DOM
2012-03-20 13:02:55 -07:00
Aparajita Fishman 8167c46cfc Added documentation for registerThemeValues methods 2012-03-20 12:51:30 -07:00
Aparajita Fishman 9456810c7e Add registerThemeValues methods in CPView, allows runtime registration of theme values using same format used in ThemeDescriptors.j 2012-03-20 12:21:05 -07:00
Alexander Ljungberg 79f2ec5d17 Refs #1480. Change NSSortDescriptors to CPSortDescriptors in docs. 2012-03-19 21:03:04 +00:00
Alexander Ljungberg 38a0a261c0 Merge pull request #1480 from Kentzo/cappuccino
---
2012-03-19 20:57:52 +00:00
Ilya Kulakov 91eb23ba87 Implement -sortedArrayUsingDescriptors: for CPSet. 2012-03-20 03:43:49 +07:00
Aparajita Fishman 706129bcbd Implement a mechanism to display a DOM element's CPView class 2012-03-18 16:19:01 -07:00
Aparajita Fishman 97b77e9b7b Changed to using data-cappuccino-view attribute 2012-03-18 15:33:19 -07:00
Alexander Ljungberg 3b85a67faf Fixed: table column divider lines were drawn on top of the header bottom line. 2012-03-18 18:01:24 +00:00
Alexander Ljungberg f2571e6536 Don't draw a table corner view if there is no vertical scrollbar.
This could either be due to autohiding or they usage of overlay scrollbars. Not showing it matches Cocoa and makes sense because it takes up space for no reason without the scrollbar.
2012-03-18 17:56:20 +00:00
Alexander Ljungberg bec8a4b1c6 Fixed: scroll views with a bezel border had two strange dots in the upper corners instead of a Lion-like bezel. 2012-03-18 16:56:04 +00:00
Alexander Ljungberg 028fb03ef1 Slightly optimise scroll view border drawing code. 2012-03-18 16:41:39 +00:00
Alexander Ljungberg 65aa08a9d9 Format code. 2012-03-18 16:38:51 +00:00
Alexander Ljungberg 22058a7a93 New corner view test which tests more cases and demonstrates the actual code rather than a category. 2012-03-18 16:30:46 +00:00
Alexander Ljungberg 90514bd3cb Test table view notifications for deselectAll. Verify absence of CPTableViewSelectionIsChangingNotification when changing programmatically. 2012-03-18 15:21:09 +00:00
Alexander Ljungberg bd7d258fcd Slightly less shiny outline view disclosure triangle. Subtle is more Cocoa like. 2012-03-18 14:15:40 +00:00
Alexander Ljungberg c21e40e819 Simplify. 2012-03-18 14:13:15 +00:00
Alexander Ljungberg e0c8ae6335 Minor outline view optimisation: don't apply a context rotation of 0 degrees. 2012-03-18 14:02:14 +00:00
Alexander Ljungberg e9d5d33cb2 Fixed: blurry outline view disclosure triangle.
The triangle centring was such that for a regular size disclosure control the right pointing triangle (collapsed state) was not drawn on integral coordinates.
2012-03-18 14:00:38 +00:00
Alexander Ljungberg 0d9b49df85 Optimise CPIndexSet. 2012-03-18 00:44:02 +00:00
Alexander Ljungberg db5e5d7da6 Test stopping CPIndexSet enumeration. 2012-03-18 00:39:07 +00:00
Alexander Ljungberg 44236795b5 CPIndexSet enumerateIndexesInRange:options:usingBlock:. 2012-03-17 18:18:08 +00:00
Alexander Ljungberg a26bca5dbe CPIndexSet enumerateIndexesWithOptions:usingBlock:. 2012-03-17 18:03:21 +00:00
Alexander Ljungberg 872b446695 CPIndexSet enumerateIndexesUsingBlock:. 2012-03-17 17:36:31 +00:00
Alexander Ljungberg 2b0ed8234c Format code. 2012-03-17 17:19:37 +00:00
Aparajita Fishman 39ec1cfd27 Put the view's class in the DOM for easier debugging 2012-03-16 13:25:13 -07:00
Alexander Ljungberg b7dcd24e11 Adjust size of spinner progress indicators properly in nib2cib. 2012-03-16 18:36:09 +00:00
Alexander Ljungberg 5097030143 Fixed: spinner style progress indicators were nib2cibbed to progress bars. 2012-03-16 18:23:47 +00:00
Alexander Ljungberg 516fac037f Merge branch 'master' of github.com:cappuccino/cappuccino 2012-03-15 00:14:39 +00:00
Alexander Ljungberg 1bf632a575 Rename shouldShowOutlineViewForItem to shouldShowOutlineDisclosureControlForItem.
ShouldShowOutlineView is not a great delegate method name for a control called an outline view. The original Cocoa name refers to an 'OutlineCell' which we don't have so that's not appropriate either.
2012-03-15 00:14:25 +00:00
Alexander Ljungberg 6137aa8637 Optimise shouldShowOutlineView. 2012-03-14 23:23:12 +00:00
Alexander Ljungberg 4be4506ffc Implement outline view outlineView:shouldShowOutlineViewForItem: delegate method (corresponding to shouldShowOutlineCellForItem in Cocoa). 2012-03-14 23:08:01 +00:00
aparajita d3c368ba92 Merge pull request #1477 from cacaodev/CFBundle-loadStatus-fix
CFBundle: isLoaded() should return a bool
2012-03-14 14:27:04 -07:00
cacaodev 9b0d03b024 CFBundle: isLoaded() should return a bool 2012-03-14 21:10:35 +01:00
Alexander Ljungberg c21d2fd017 Fixed: toolbar search fields created in IB were cut in half height-wise due to a too small max size. 2012-03-14 16:02:25 +00:00
Alexander Ljungberg 2940b5e787 Fixed: nib2cibbed search fields had the bottom pixel cut off. 2012-03-14 15:58:35 +00:00
Alexander Ljungberg cf18bcaaf9 Clean up. 2012-03-14 15:50:07 +00:00
Alexander Ljungberg c4eaf083b4 Code formatting. Don't shadow compressor function name. 2012-03-13 20:29:38 +00:00
Alexander Ljungberg df6b592d11 Refs #1474. Allow -T argument before -- in objjc and document it in help.
Seems like all options should be before -- really.
2012-03-13 20:27:20 +00:00
Alexander Ljungberg 109e8b1e33 Merge pull request #1474 from ternarylabs/cappuccino
---
2012-03-13 20:06:33 +00:00
Alexander Ljungberg 85c88d7c93 Whitespace. 2012-03-13 20:03:11 +00:00
Alexander Ljungberg d8e5fa3087 Merge pull request #1441 from cacaodev/cappuccino
---

With manual test.
See comments in the code about how to make bindings adoptions easier and avoid repeating code.
2012-03-13 19:58:29 +00:00
cacaodev 697a7b308a CPColorWell : Implements CPValueBinding (color), supports markers.
With manual test.
2012-03-13 20:35:31 +01:00
Alexander Ljungberg dcc031f23a Fixed: small size toolbars in bridge windows didn't show the bottom shadow line.
Switched to using a somewhat vertically resizable three part image. The centre image part is being compressed which normally would look poor but you can't tell since it's a gradient.
2012-03-13 14:45:33 +00:00
Alexander Ljungberg 061ea47953 Test N-part image layout. 2012-03-13 13:51:01 +00:00
Alexander Ljungberg f0e5161b7b Tile narrow vertical three part images horizontally, and short horizontal three part images vertically.
This allows you to use a 1px wide vertical three part image to stretch to any width.
2012-03-13 13:36:52 +00:00
Alexander Ljungberg eada36af26 More minor formatting. 2012-03-12 21:01:27 +00:00
Alexander Ljungberg a02c687df9 Fix missing semicolon. 2012-03-12 20:14:11 +00:00
Alexander Ljungberg e636087f4a Fixed decodeBytesForKey in theory.
There's no way to encode bytes today in the first place.
2012-03-12 20:06:23 +00:00
Alexander Ljungberg 4876f77914 Refs #1476. Format code. 2012-03-12 20:05:18 +00:00
Alexander Ljungberg ed6bed9bf7 Format code. 2012-03-12 19:43:28 +00:00
Alexander Ljungberg 87cb2eb19d Merge pull request #1476 from cacaodev/cappuccino
---

 In nib2cib, this typo was preventing from decoding base64 data included in nib files.
2012-03-12 19:20:01 +00:00
Alexander Ljungberg 53334251b8 Fix a typo in CPGradient comment and attempt to better explain what's going on. 2012-03-12 12:04:34 +00:00
Alexander Ljungberg a069f2945b Optimise. 2012-03-11 22:13:05 +00:00
Alexander Ljungberg 5a0e1d7bb3 Support any angle in CPGradient drawInRect:angle:. 2012-03-11 19:40:22 +00:00
Alexander Ljungberg ed1d77c86d Skeleton CPGraphicsContext isFlipped. 2012-03-11 19:39:25 +00:00
Alexander Ljungberg 74054442a2 CPGradient initWithColors:. 2012-03-11 19:38:02 +00:00
Alexander Ljungberg 59ef8329c0 Handle CPGradient colorSpace argument. 2012-03-11 15:37:45 +00:00
Alexander Ljungberg 20cffaa7fe Fix CPGradient angle. 2012-03-11 14:07:17 +00:00
Alexander Ljungberg ebeb1040e8 Simplify CPGrahicsTest slightly by connecting delegates in IB. 2012-03-11 14:06:31 +00:00
Alexander Ljungberg cdb919dea3 Add reference renderings to CPGraphicsTest. Add visual tests of CPGradient. 2012-03-11 13:13:50 +00:00
Alexander Ljungberg c509e6131a Fixed: CPGradient reversed its colours. 2012-03-11 13:12:17 +00:00
Alexander Ljungberg db6a4d7042 Stub out CPView inLiveResize.
CPWindow should send `viewWillStartLiveResize` and `viewWillEndLiveResize` to make this work.
2012-03-10 12:43:47 +00:00
Alexander Ljungberg a32b5ea72b nib2cib support for table view background colour. 2012-03-10 12:02:17 +00:00
Alexander Ljungberg 58a2fce110 Code formatting. 2012-03-10 12:01:40 +00:00
Alexander Ljungberg 3d9ae42dbf Starter CPGradient with drawInRect:angle:. 2012-03-10 11:55:13 +00:00
Alexander Ljungberg c4a16d10bc Starter CPColorSpace implementation. 2012-03-10 11:53:47 +00:00
Alexander Ljungberg eeca40c6f0 Implemented CPColor colorWithSRGBRed:green:blue:alpha:. 2012-03-10 11:52:49 +00:00
Alexander Ljungberg 2a031e82a4 Constrain CPColor components to [0.0, 1.0]. 2012-03-10 10:11:35 +00:00
cacaodev 0e6ce205ab CPPropertyListSerializationTest for CPPropertyListXMLFormat_v1_0 format 2012-03-09 20:52:08 +01:00
Alexander Ljungberg 9acbe0f2f8 Fix incorrect parameter type. 2012-03-09 19:49:58 +00:00
Alexander Ljungberg 3ee9c1a439 Fixed misplaced var, formatting. 2012-03-09 19:17:28 +00:00
Alexander Ljungberg 0eeff20af6 Code formatting. 2012-03-09 16:52:21 +00:00
Alexander Ljungberg a1cf9f1cd4 Table view cell layout test. 2012-03-09 15:36:21 +00:00
cacaodev 3897f422fe Use setter 2012-03-09 15:22:19 +01:00
cacaodev 9d785d1a3c CFPropertyList typo: CFData has _bytes, not bytes. In nib2cib, this typo was preventing from decoding base64 data included in nib files 2012-03-09 14:39:53 +01:00
Alexander Ljungberg 66f818872c Simplify shadow view code. 2012-03-09 12:50:52 +00:00
Alexander Ljungberg 342bacb25c Manual test for CPImageView with and without shadow. 2012-03-09 12:49:38 +00:00
Alexander Ljungberg 8e81be0319 Clean up. 2012-03-09 12:06:30 +00:00
Alexander Ljungberg 3acfa142bc Merge pull request #1475 from miLibris/cappuccino
---

Remove CPShadowView constants in CPImageView
2012-03-09 12:00:05 +00:00
Alexander Ljungberg 94a58c810e Calculate a default key view loop for windows loading from cibs even if autorecalculatesKeyViewLoop is NO. 2012-03-08 12:23:05 +00:00
Alexander Ljungberg 757a2bf400 nib2cib support for CPWindow autorecalculatesKeyViewLoop. 2012-03-08 12:05:12 +00:00
Luc Vauvillier b18fbd685b CPImageView : Remove shadow vars dependency 2012-03-08 12:49:31 +01:00
Alexander Ljungberg 56b5a9ec22 Make CPWindow autorecalculatesKeyViewLoop default to NO rather than null. 2012-03-08 11:39:59 +00:00
Georges Auberger 70432f0198 Added -T directive to enable ObjectiveJ.Preprocessor.Flags.IncludeTypeSignatures flag on preprocessor 2012-03-07 22:10:16 -08:00
Alexander Ljungberg 0736f86f32 Fixed: "[CPString count] unrecognized selector" error when binding an array controller's content array to a key of another AC's selection.
This change also avoids wrapping a selection proxy in a KVO array proxy, which isn't helpful and probably hurts performance.
2012-03-07 16:49:41 +00:00
Alexander Ljungberg 107d739489 Add support for checkbox placeholder bindings options. 2012-03-07 14:33:32 +00:00
Alexander Ljungberg 32a86a911f Allow custom binders to set default placeholders.
This makes it easier to write custom binders.
2012-03-07 14:31:53 +00:00
Alexander Ljungberg 9a32733f88 Fixed: incorrect bindings option in array controller test. 2012-03-07 13:04:20 +00:00
Alexander Ljungberg 0f655e3264 Fixed: sending CPWindow setAutorecalculatesKeyViewLoop:NO caused the window to recalculate the key view loop.
Although the intention might have been to do 'one final calculation run to provide a sensible default', the result is unintuitive and does not match Cocoa's behaviour.

If the key view loop has been manually set up and the user then calls `setAutorecalculatesKeyViewLoop:NO` they don't expect their work to be overwritten.
2012-03-01 20:35:20 +00:00
Alexander Ljungberg 55a4afa341 Merge pull request #1471 from tfc/cappuccino
---

...and fixed my last documentation commit for CPSplitView.
2012-03-01 18:15:53 +00:00
Jacek Galowicz 3b5aa1a2ab CPScrollView: Documented delegate methods 2012-03-01 18:44:51 +01:00
Jacek Galowicz 658e569251 Fix of last commit
My commit 1d8092e431 added some
documentation, but destroyed the order of the text.
2012-03-01 18:41:44 +01:00
Alexander Ljungberg 4eacfd83d6 Refs #1469. Formatting. 2012-03-01 10:48:07 +00:00
Alexander Ljungberg ad0fd0a34e Merge pull request #1469 from tfc/cappuccino
---

This regards CPSplitViews new delegate method
- (BOOL)splitView: (CPSplitView)aSplitView shouldAdjustSizeOfSubview: (CPView)aSubView
which was introduced in b27a3cdbe5 by Alexander Ljungberg.
2012-03-01 10:44:51 +00:00
Jacek Galowicz 1d8092e431 Added a documentation line for CPSplitView.
This regards CPSplitView's new delegate method
- (BOOL)splitView: (CPSplitView)aSplitView shouldAdjustSizeOfSubview: (CPView)aSubView
which was introduced in b27a3cdbe5 by Alexander Ljungberg.
2012-03-01 08:46:06 +01:00
Alexander Ljungberg 87cc62d1d8 Fixed with nib2cib: CPBox title position 'none' was converted to 'on top'. 2012-02-24 20:53:02 +00:00
Alexander Ljungberg a16388b57d Allow toolbar size to be changed even after the toolbar has been created. 2012-02-24 20:38:05 +00:00
Alexander Ljungberg 98e54d2e09 Support for "small" size toolbars (CPToolbar sizeMode).
Support only in nib2cib and coding ATM. Calling setSizeMode: on an existing toolbar will not have an effect.
2012-02-24 20:10:36 +00:00
Alexander Ljungberg bd02ec057c Style fix. 2012-02-24 19:44:26 +00:00
Alexander Ljungberg 6ac804d37c CPWorkspace openFile and openURL. 2012-02-24 19:44:13 +00:00
Alexander Ljungberg 4b764dc8b4 Throw an exception when trying to set a null minimum item size for a collection view. 2012-02-17 16:25:16 +00:00
Alexander Ljungberg 3a8ad56d4b Fixed: don't crash when loading a collection view with no item prototype view from a cib. 2012-02-17 16:23:59 +00:00
Alexander Ljungberg f5bee48d98 Merge branch 'master' of github.com:cappuccino/cappuccino 2012-02-17 14:26:56 +00:00
Alexander Ljungberg 24fbfbee60 Unit test for previous fix. 2012-02-17 14:26:28 +00:00
Alexander Ljungberg a1bc5ad4d3 Fixed: app would freeze on collection view setSelectionIndexes:nil. 2012-02-17 14:23:21 +00:00
Alexander Ljungberg 4aa3824a2a Minor collection view optimisation. 2012-02-17 14:05:03 +00:00
Aparajita Fishman 37d92c1182 Revert "Merge pull request #1438 from aradabaugh/master", it broke a few things
This reverts commit e081dbf127, reversing
changes made to 71e8f0201a.
2012-02-16 08:21:31 -08:00
Antoine Mercadal a0eadc6c4a Merge branch 'CPStepper-nib2cib' of https://github.com/cacaodev/cappuccino into stepper-nib2cib 2012-02-11 16:08:27 +01:00
Alexander Ljungberg fdf672cf0a Include a toolbar in NibAppRemixed as a (very minimal) example. 2012-02-10 19:57:50 +00:00
Alexander Ljungberg b8dacb1ffa Fixed with nib2cib: toolbars with default items such as NSToolbarShowColorsItem didn't convert right. 2012-02-10 19:57:00 +00:00
Alexander Ljungberg 81a99dd190 Merge pull request #1454 from cacaodev/cappuccino
---
2012-02-10 15:47:30 +00:00
cacaodev 6a42d601c5 CPTabView: remove duplicate code. 2012-02-10 16:31:45 +01:00
cacaodev 59ce74a3df CPTabView : _selectedIndex was undefined after decoding an empty tab view (no items).
A visible bug was that the first item added was not immediately selected. Updated CPTabViewNib example, shows the bug fixed.
2012-02-10 16:29:50 +01:00
Alexander Ljungberg eacee00fc8 Merge branch 'master' of github.com:cappuccino/cappuccino 2012-02-08 15:58:00 +00:00
Alexander Ljungberg fe70a5541e Fixes #1450: a scroll view with non hiding legacy scrollbars would crash if the document view had a size of 0 pixels in either dimension. 2012-02-08 15:52:59 +00:00
Alexander Ljungberg c9d4089b9a Throw an exception when trying to set a scroller's knob proportion to NaN or Inifinity. 2012-02-08 14:54:50 +00:00
Alexander Ljungberg 8fdb872605 Clean up. 2012-02-08 13:48:43 +00:00
Antoine Mercadal 8b28041cf0 Merge pull request #1449 from cacaodev/CPControllerSelectionProxy-typos
CPControllerSelectionProxy: accidental globals.
2012-02-07 08:37:59 -08:00
cacaodev 4d3f8c3c8c CPStepper: nib2cib support, with test. 2012-02-07 16:38:48 +01:00
Antoine Mercadal f8cb4a15cb Merge pull request #1446 from cacaodev/CPArrayController-setSelectionIndexes-fix
CPArrayController : setAvoidsEmptySelection:YES should not apply when setting an empty selection explicitely. With tests.
2012-02-03 01:30:01 -08:00
Randall Luecke dd7d36da43 call layoutSubviews when the tableview lays out its subviews. 2012-02-02 19:34:11 -05:00
cacaodev 12201d38f3 CPArrayController : setAvoidsEmptySelection:YES should not apply when setting an empty selection explicitely. With tests. 2012-02-03 00:48:49 +01:00
Randall Luecke 3b4ad1d583 Remove 2nd call to setHeaderView: 2012-02-02 17:06:31 -05:00
cacaodev d44df8a9da CPControllerSelectionProxy: accidental globals. 2012-02-02 10:50:26 +01:00
Ross Boucher ab88f72827 Merge pull request #1445 from cacaodev/CPFont-cleaning
CPFont: fix typo in fontWithName:size: caching, rearrange constructor methods. With test.
2012-02-01 12:58:03 -08:00
cacaodev 75a00e8c4a CPFont: fix typo in fontWithName:size: caching, rearrange constructor methods. With test. 2012-02-01 14:05:37 +01:00
Randy Luecke 76c5500488 Merge pull request #1444 from lynnchin/patch-1
Update line 171 to remove "%s" to populate the result string.
2012-02-01 00:15:24 -08:00
lynnchin 8cb7c05c88 Update line 171 to remove "%s" to populate the result string. 2012-02-01 19:13:59 +11:00
Randy Luecke e081dbf127 Merge pull request #1438 from aradabaugh/master
Enable additional buttonTypes for CPButton
2012-01-31 22:23:42 -08:00
Ross Boucher 71e8f0201a Merge pull request #1443 from rafnocx/master
CPFont.j typo (line 180)
2012-01-31 20:04:28 -08:00
rafnocx c9ecb20b50 fix CPFont constructor (line 180) possible typo 2012-02-01 13:14:56 +11:00
Randall Luecke 7dc213995c Added CPObject's performSelector:withObject: and tests 2012-01-31 16:35:49 -05:00
aradabaugh bea34a9b35 Removes duplicate action for radioGroup. 2012-01-30 00:26:46 -07:00
aradabaugh 5ae405a89b Add visual test for CPButton buttonTypes. 2012-01-30 00:17:58 -07:00
Alexander Ljungberg 66fcbe7871 Visual CPSplitView test. 2012-01-27 20:58:54 +00:00
Alexander Ljungberg b27a3cdbe5 Rewritten split view resizing which plays well with a mix of fixed size and non-fixed size panes. 2012-01-27 20:44:38 +00:00
Alexander Ljungberg 9d7b822409 Add support for split view shouldAdjustSizeOfSubview: delegate method. 2012-01-27 17:04:04 +00:00
Alexander Ljungberg ab3f260757 Fixed: CPSplitView tried to auto save even without an auto save name. 2012-01-27 16:38:17 +00:00
Alexander Ljungberg b26b0a321b Reinstate defensive coding for numeric parameters in CPTableView. 2012-01-27 14:54:10 +00:00
Alexander Ljungberg 9536858599 Unit test CPSplitView. 2012-01-27 14:47:00 +00:00
Alexander Ljungberg c7d3ccb13a Add missing header to CPTabView. 2012-01-27 12:33:07 +00:00
Alexander Ljungberg a081f98fd1 Refs #1440. Whitespace cleanup. 2012-01-27 12:32:11 +00:00
Alexander Ljungberg 7096ea549e Merge pull request #1440 from cacaodev/cappuccino
---

- selectedTabViewItem should return nil when there are no items (i.e. _selectedIndex == CPNotFound).
Added an empty Tab View to CPTabViewNib test app.
Needs a jake sudo-install for changes to take effect.
2012-01-27 12:26:27 +00:00
Alexander Ljungberg 8e007985a1 Merge branch 'master' of github.com:cappuccino/cappuccino 2012-01-27 12:20:17 +00:00
Alexander Ljungberg e03e774113 Format delegate signatures in collection view documentation. 2012-01-27 12:19:52 +00:00
cacaodev 7a41282912 CPTabView: Fix a bug where a CPTabView would not reflect immediately the replacement of the selected item's view.
Updated CPTabViewNib to show a setView: on the current item.

If the view changes on a non selected item, the tabView content will be
updated when this item is selected.
2012-01-26 14:45:42 +01:00
cacaodev c8f8c01d2f CPTabView : _setTabView: on newly decoded CPTabViewItems
A CPTabViewItem needs to know about its tabView.
2012-01-26 14:34:52 +01:00
cacaodev 7f6db7bf98 CPTabView: Fix a bug where -selectedTabViewItem was raising instead of returning nil when no tab items (i.e. _selectedItemIndex = -1) and causing nib2cib to fail.
Added An empty Tab View to CPTabViewNib test app.
Needs a jake sudo-install for changes to take effects.
2012-01-26 10:44:46 +01:00
aradabaugh e058efb622 Correcting minor whitespace styling. 2012-01-25 11:40:15 -07:00
aradabaugh c14643849f Minor style change. 2012-01-24 22:51:32 -07:00
aradabaugh edd09ef06a Enables additional buttonTypes for CPButton 2012-01-24 22:50:01 -07:00
Randy Luecke d06fccf157 Merge pull request #1436 from aradabaugh/master
Fixes CPShadowView shadowViewEnclosingView to use self instead of shadowView
2012-01-20 12:37:38 -08:00
aradabaugh 6bc3d49ba2 Correcting use of self in CPShadowView shadowViewEnclosingView: 2012-01-20 13:33:24 -07:00
aradabaugh a8d8736899 Fixes CPShadowView shadowViewEnclosingView to use self instead of shadowView. 2012-01-20 00:33:40 -07:00
Randall Luecke b1e4a43cd3 Fixed and finished the documentation for CPSet and CPMutableSet. 2012-01-19 01:19:20 -05:00
Antoine Mercadal eafbebcebb fix crash when setting title while to content view is set 2012-01-16 14:19:09 +01:00
Antoine Mercadal 0c72c52ba2 improve manual test of CPBox 2012-01-14 12:31:28 +01:00
Antoine Mercadal e8194d9c2e Fix some sizing problem with CPBox titles. close #1431 2012-01-14 12:31:12 +01:00
Antoine Mercadal f0e1b67197 Merge remote-tracking branch 'upstream/master' 2012-01-13 13:56:16 +01:00
Antoine Mercadal 7ba27cf617 Add manual test for CPBox title 2012-01-13 13:52:31 +01:00
Antoine Mercadal c9f765645c Support for CPBox title in nib2cib 2012-01-13 13:52:12 +01:00
Antoine Mercadal 5daa8cb289 Support for title in CPBox. close #1428 2012-01-13 13:51:50 +01:00
Aparajita Fishman 789d832808 Tab -> spaces 2012-01-12 18:44:19 +06:30
Antoine Mercadal d7971322cb Merge pull request #1291 from miLibris/CPTheme-coding-fixes
_CPThemeAttribute fix : encode missing _defaultTheme value
2012-01-06 07:21:09 -08:00
Antoine Mercadal 6ddeb167b3 Merge pull request #1424 from anddam/master
Edit in press utility.
2012-01-06 07:20:30 -08:00
Andrea D'Amore c1be09c692 press: fixing basedir being added twice to png destination path 2012-01-06 15:25:54 +01:00
Aparajita Fishman 1c2a304ee5 Assignment of function is a statement and should be semicolon terminated. Some miscellaneous linting as well. 2012-01-05 17:51:37 -10:00
Antoine Mercadal 1a51acf2fc fix doc style under Windows. Thanks to @jakemarsh (fork removed). close #1401 2012-01-03 17:21:02 +01:00
Antoine Mercadal 47a5296f0b Merge pull request #1405 from applicaster/linux_rhino
Compilation problems on ubuntu
2012-01-03 07:47:32 -08:00
Antoine Mercadal 1189e8c849 Merge pull request #1422 from cacaodev/CPPredicate
CPCompoundPredicate -isEqual: typo.
2012-01-02 03:22:02 -08:00
cacaodev ce2316a8ee CPCompoundPredicate: Fixed typo in -isEqual:. With test. 2011-12-31 16:19:38 +01:00
Alexander Ljungberg ec9ddc0819 Merge pull request #1421 from cacaodev/cappuccino
---
2011-12-31 13:27:45 +01:00
cacaodev a5bd55dcac Rename CPExpression_* classes in NSExpression.j (nib2cib) 2011-12-31 09:33:12 +01:00
Alexander Ljungberg b0b1bd88a6 Fix clean up, clean up more. 2011-12-29 20:18:40 +01:00
Alexander Ljungberg 75d5619abd Clean up. 2011-12-29 20:12:11 +01:00
Alexander Ljungberg 522a641690 Merge pull request #1420 from cacaodev/cappuccino
---

Added isEqual:
Renamed CPExpression classes
Fixed -filteredArrayUsingPredicate: for proxy arrays.
2011-12-29 20:04:35 +01:00
cacaodev b39f509263 CPArray (CPPredicate): -filteredArrayUsingPredicate: and -filterUsingPredicate:
Use CPArray methods (not js array) because the receiver can be a CPArray subclass. With tests.

Fixes the bug reported here: https://groups.google.com/forum/?pli=1#!topic/objectivej/8q9hqbZZUv0
2011-12-29 17:16:53 +01:00
cacaodev 1ea95bf6e0 CPExpression: renamed private classes to follow naming rules. 2011-12-17 16:10:06 +01:00
cacaodev 08d690b65d Completed isEqual: support for CPExpression & CPPredicate subclasses 2011-12-17 15:37:43 +01:00
Randy Luecke 80f5ab09f3 Merge pull request #1410 from vhbit/master
Fixed a bug when changing selection in CPPopUpButton wasn't propagated back to bound object
2011-12-10 20:22:02 -08:00
Randy Luecke 5c8f201a92 Merge pull request #1406 from james-dessart-hb/master
Issue #1297 - fixing CPBrowser selection when using up/down arrow keys
2011-12-10 20:21:06 -08:00
Randy Luecke cf777d7f41 Merge pull request #1417 from BlairDuncan/master
Unnecessary globals
2011-12-10 20:20:22 -08:00
Blair Duncan bb7876759a unnecessary globals 2011-12-10 23:10:22 -05:00
Aparajita Fishman 800d6498d6 Added some missing semicolons 2011-12-10 10:48:54 -08:00
Aparajita Fishman 0648b4279f Added usage documentation for Framework.j 2011-12-10 09:48:08 -08:00
Antoine Mercadal 1a73abe7c3 Merge pull request #1267 from primalmotion/nib2cib-do-not-truncate-bold-labels
Do not truncate bold labels.

So this is a temp fix as @aparajita has a better way to handle this. As the patch is very straightforward, it will be easy to revert it when a more correct fix will come up. But while waiting, I think it's a good idea to have correct displaying of the bold labels.
2011-12-07 10:23:06 -08:00
Valerii Hiora cce4f7883c Merge branch 'master' of git://github.com/cappuccino/cappuccino 2011-12-07 09:58:36 +02:00
Alexander Ljungberg 3dff67e0b1 Faster CPNotificationCenter removeObserver.
Removing observers is now faster, significantly so when there are very many observers and one or more is removed while a notification is being posted.
2011-12-07 01:48:16 +00:00
Alexander Ljungberg 24326883ca More extensive Notification Center tests. 2011-12-07 01:38:41 +00:00
Alexander Ljungberg a5854f129d Fixes #1411. In IE, no table/outline view selection highlights would render for certain CIBs.
This fix also enables `setSelectionHighlightStyle: CPTableViewSelectionHighlightStyleSourceList` in Internet Explorer. Even that the gradient effect can't be rendered and the fallback regular rendering will be used, the proper field value might still be useful for subclasses or saving out to CIBs etc.
2011-12-06 23:29:57 +00:00
Alexander Ljungberg 052c07f3e3 Refs #1412, #1413. Manual test for the last two fixes. 2011-12-06 23:26:13 +00:00
Alexander Ljungberg 9367566e61 Fixes #1412. IE rendered clearColor shadows in black. 2011-12-06 23:01:26 +00:00
Alexander Ljungberg 107103bcbb Fixes #1413: Internet Explorer colorWithCSSString crash.
Syntax such as [[CPColor colorWithCSSString:@"rgba(0,0,0,0.5)"] cssString] lead to a CSS string incompatible with browsers without the CSS rgba feature.
2011-12-06 22:45:26 +00:00
Alexander Ljungberg 20ae47971c Missing semicolons. 2011-12-06 22:43:00 +00:00
Valerii Hiora d4ecb03d15 Fixed: On changing selection of CPPopUpButton value wasn't reverse
transformed to binded object
2011-12-06 22:41:30 +02:00
James Dessart f4eb47519d Issue #1297: Added tableViewSelectionDidChange: to the table view delegate in order to propagate keyboard-driven selection changes up to the browser 2011-12-02 15:46:07 -04:00
Alexander Ljungberg e37bfeeb09 Merge branch 'master' of github.com:cappuccino/cappuccino 2011-12-01 18:18:29 +00:00
Alexander Ljungberg bb0972ba49 Fixed: notifications were sent to removed observers.
If one observer of a notification centre notification removed another observer, that other observer would still be notified even that it was no longer observing.

Now the code agrees with its comments.
2011-12-01 18:18:15 +00:00
Antoine Mercadal ddc5994869 tooltips are now themable. 2011-11-28 12:05:43 +01:00
lowell 2169ba35ad [XcodeCapp] Silenced build warning: -[id<NSTableViewDelegate> tableView:heightOfRow:] expects an NSInteger for the second argument. 2011-11-24 13:59:39 -08:00
lowell 50b447b05d [XcodeCapp] App controller should conform to NSTableView data source and delegate protocols. Protocol methods don't need to be declared in the adopting class' interface because they will have already been declared in the protocol declaration. 2011-11-24 13:58:03 -08:00
Antoine Mercadal bc14ad6b9d small improvments in XcodeCapp, including handling quick remove/create existing files 2011-11-24 17:59:09 +01:00
Neer Friedman ffa33788c4 enquote ENVIRONMENTS environment variable 2011-11-24 18:04:26 +02:00
Neer Friedman 23c9c6bf44 concat command parts in Objective-j/Jakefile 2011-11-24 18:03:20 +02:00
Alexander Ljungberg 476c02976b Code formatting. 2011-11-23 00:28:27 +00:00
Aparajita Fishman 6ac28e1a77 A few text tweaks to make the prompts more friendly. 2011-11-18 01:02:32 -08:00
Antoine Mercadal 4ec7cea6c4 update doxygen displayed Cappuccini version to 0.9.5 2011-11-16 15:12:22 +01:00
Alexander Ljungberg 0036f329f5 Fixed: in recent builds, WithBindingsTest failed with a "CPScroller does not contain theme attribute 'scroller-width'" error. 2011-11-16 12:57:01 +00:00
Alexander Ljungberg 15af54efda Fixed with CPTokenField: quickly entered tokens would be ignored.
If the autocomplete state had not been set yet, tokens could not be finished using the token separator, return or tab. Instead the user typed text remained in its 'non token' state.
2011-11-16 12:52:27 +00:00
Alexander Ljungberg 07966bb7fe Fixed with CPTokenField: crash if added to a window in a unit test. 2011-11-16 12:50:05 +00:00
Alexander Ljungberg e7d9b0503b Fixes #1398. Fixed with CPTokenField: deleting tokens in front of selected tokens would shift the selection to the right. 2011-11-16 12:04:03 +00:00
Alexander Ljungberg 072b43d178 Fixes #1397. Fixed with CPTokenField: make sure selection is initialised when loading from cib. 2011-11-16 11:55:38 +00:00
Alexander Ljungberg 281d2295ae Code formatting. 2011-11-15 23:47:56 +00:00
Alexander Ljungberg 79cf4370b4 Update bootstrap to 0.9.5 as well. 2011-11-14 18:49:30 +00:00
Alexander Ljungberg 6217fc8459 Given the large number of changes, this will be Cappuccino 0.9.5 instead. 2011-11-14 18:37:00 +00:00
Alexander Ljungberg f1fd3d170a Merge branch '0.9.2b' of github.com:cappuccino/cappuccino into 0.9.2b 2011-11-14 18:27:08 +00:00
Antoine Mercadal 4e410f8a81 Merge remote-tracking branch 'upstream/0.9.2b' into 0.9.2b 2011-11-14 16:46:36 +01:00
Antoine Mercadal 7a1b273d8d simplify the ignored path matching 2011-11-13 23:34:49 +01:00
Antoine Mercadal 820531342d fix during tidying shadow files 2011-11-13 21:58:45 +01:00
Antoine Mercadal 353db3277a fix file level mode deactivated, fix auto ignore not working 2011-11-13 21:36:52 +01:00
Antoine Mercadal 82f37549ae reactivate 10.7 file level API 2011-11-13 20:28:11 +01:00
Alexander Ljungberg 09e1bd6bf1 The 0.9.2 GM will be tagged v0.9.2 simply. 2011-11-11 16:52:48 +00:00
Alexander Ljungberg 44f3abf262 Don't mention "steam" in TOOLS-README. 2011-11-11 16:45:43 +00:00
Antoine Mercadal 8c09af5013 Merge remote-tracking branch 'upstream/master' 2011-11-10 14:11:12 +01:00
Antoine Mercadal 0781e932c6 Merge branch 'xcc-improvments' 2011-11-10 14:10:45 +01:00
Alexander Ljungberg 3cee00323c Don't separate statements by commas. 2011-11-10 12:31:16 +00:00
Alexander Ljungberg b1f6f3ddfa Missing semicolons. 2011-11-10 12:30:05 +00:00
Alexander Ljungberg 7147266ddf objjc option to compile to plain JavaScript (suitable for linting). 2011-11-10 11:59:26 +00:00
Alexander Ljungberg 357212bff7 Missing semicolons. 2011-11-10 11:34:26 +00:00
Alexander Ljungberg ed4fc3b20f objjc compile to stdout, argument parsing, --help. 2011-11-10 10:37:46 +00:00
Alexander Ljungberg 7e8b71dd52 Semicolons. 2011-11-10 10:36:47 +00:00
Alexander Ljungberg 267f00bfe1 Put spaces around = in [name] = function... generated JS to reduce lint warnings. 2011-11-10 09:41:21 +00:00
Alexander Ljungberg 8f90dbce99 Allow almost anything as a key equivalent unless a text field is the first responder.
After testing in Cocoa, even unexpected keys such as tab can be used when a text field isn't selected. Some keys such as the arrow keys and escape act like key equivalents even with a text field active.
2011-11-10 00:52:38 +00:00
Alexander Ljungberg 00485dba89 Refs #1019. Clean up. 2011-11-10 00:12:48 +00:00
Alexander Ljungberg 8fd4f5e4b6 Merge branch 'master' of github.com:cappuccino/cappuccino 2011-11-09 23:36:47 +00:00
Scott RiceandAlexander Ljungberg e7e69b3fd4 Fixed issue #1019 in IE 2011-11-10 07:35:50 +08:00
Alexander Ljungberg 2463c1dc05 IE compatibility. 2011-11-09 23:02:31 +00:00
Alexander Ljungberg bc590286f2 Missing semicolons. 2011-11-09 22:55:11 +00:00
Aparajita Fishman 8c83816ec8 Made [CPMenu -removeAllItems] KVO compliant
Fixes https://github.com/cappuccino/cappuccino/issues/1395
2011-11-09 14:50:52 -08:00
Alexander Ljungberg 699069ce8f Typo fix. 2011-11-09 20:48:01 +00:00
Alexander Ljungberg ec0cd22c1d Merge pull request #1382 from kjamieson/cappuccino
---

Currently CPTextField only updates its internal string value from the actual HTML input element on a keyUp event. If the CPTextField loses focus before the keyUp event is received, the internal value does not get updated and any text entered since the last keyUp event is lost.

This is easily reproduced when editing a text field by quickly entering text and hitting the enter/return key to insert a new line (before the keyUp event has fired), or when holding down a key (to repeatedly enter the same character), and then tabbing out of the text field -- the value gets reset to whatever the value was before the key was held down.

This fix changes CPTextField#insertNewLine and CPTextField#resignFirstResponder to reload the string value from the input element if it has changed (in the same way as if a keyUp event had been triggered)
2011-11-09 20:43:13 +00:00
Antoine Mercadal 8da3a8866d remove white space 2011-11-08 23:07:41 +01:00
Antoine Mercadal 21f6fdff48 synchronize support folder if missing shadow files 2011-11-08 23:05:51 +01:00
Antoine Mercadal ed82a1fc87 remove useless argument 2011-11-08 22:45:00 +01:00
Antoine Mercadal 1fa143453d Merge branch 'xcc-improvments' of github.com:primalmotion/cappuccino into xcc-improvments 2011-11-08 22:37:32 +01:00
Antoine Mercadal 1240bab7ed typo in help (ref to xcodecapp-cocoa) 2011-11-08 22:35:11 +01:00
Aparajita Fishman 4af29d83d7 Merge branch 'xcc-improvments' of github.com:primalmotion/cappuccino into xcc-improvments 2011-11-08 13:32:23 -08:00
Aparajita Fishman 6aed29af91 Fixed ignore paths to be safe, new help file 2011-11-08 13:30:21 -08:00
Aparajita Fishman 37f1f50000 Fixed ignore paths to be safe, new help file 2011-11-08 13:25:48 -08:00
Aparajita Fishman a93654c66b Cleaned up event handling, fixed bug with shadow paths 2011-11-08 11:36:41 -08:00
Alexander Ljungberg 0d2dd94c81 Refs #1394. Don't attempt MacPorts autoreconf fix if the right autoconf isn't available. 2011-11-08 14:21:28 +00:00
Alexander Ljungberg c2f97e9aa3 Make 80 character line wrap more consistent throughout bootstrap. 2011-11-08 12:35:26 +00:00
Alexander Ljungberg e04bf6de95 Merge pull request #1394 from anddam/cappuccino
---

adding autoreconf to fix issues reported at [1]

[1] http://groups.google.com/group/objectivej/browse_thread/thread/b0cddeb1046bfcf4/3f0b0cbbe57ed64b

Conflicts:
	bootstrap.sh
2011-11-08 11:55:47 +00:00
Alexander Ljungberg 38499c006a Merge branch '0.9.2a' 2011-11-07 23:06:04 +00:00
Alexander Ljungberg 80cac38682 0.9.2 installation instructions. 2011-11-07 22:58:43 +00:00
Alexander Ljungberg 2b16d36aa2 Same as previous commit but for real. 2011-11-07 21:41:22 +00:00
Alexander Ljungberg dc9d49a12c GCC is not required to merely install Cappuccino. 2011-11-07 21:39:11 +00:00
Alexander Ljungberg 03c81dfa9c Merge branch 'master' of github.com:cappuccino/cappuccino 2011-11-07 21:18:00 +00:00
Alexander Ljungberg b096e5dd0a Talk even less about Narwhal. Give the logo some space. 2011-11-07 21:12:06 +00:00
Antoine Mercadal 7ae519145f some processing optimizations 2011-11-07 22:03:48 +01:00
Antoine Mercadal 592c3c1652 try to deactivated the kFSEventStreamCreateFlagNoDefer flag in FSEventStream 2011-11-07 21:36:43 +01:00
Antoine Mercadal e940f294a6 store the last eventID before processing anything to avoid mutliple events 2011-11-07 21:20:39 +01:00
Antoine Mercadal 759de8f45f remove debug print 2011-11-07 21:11:27 +01:00
Antoine Mercadal c92c6c37f7 if we were not able to know what event file it is, just consider it's a modification 2011-11-07 21:08:08 +01:00
Antoine Mercadal f425601043 fix bug with undescores in project path. Readd the project.pbx (not so useless) :) 2011-11-07 20:12:23 +01:00
Aparajita Fishman 68ba089a26 Cleanup Debug dialog, insert Debug… item below Help 2011-11-07 11:08:37 -08:00
Alexander Ljungberg 5ff7169546 Don't suggest changing NARWHAL_ENGINE to jsc if it's already jsc. 2011-11-07 19:00:20 +00:00
Alexander Ljungberg 7365a95b4d Friendly welcome screen.
Thanks to primalmotion.
2011-11-07 18:57:10 +00:00
Antoine Mercadal 788427ec09 Preference is now Debug, and is only active when XCC is launch while holding Option key 2011-11-07 19:52:02 +01:00
Alexander Ljungberg 01ed8ad583 Bootstrap without tusk. Reduce visibility of narwhal.
The tusk ecosystem is not maintained anymore within the Cappuccino community. The new installation system is not very elegant but it makes it very easy to release new versions of Cappuccino, while taking the first step on the road towards node.js.
2011-11-07 18:35:29 +00:00
Alexander Ljungberg f516ba7a7d This is Cappuccino 0.9.2. 2011-11-07 18:33:17 +00:00
Andrea D'Amore ab5603bd5a adding autoreconf to JSC's builtin libedit 2011-11-07 17:31:22 +01:00
Antoine Mercadal 5c560e82b3 ensure attached window is not nil when positioning or instanciate it 2011-11-07 15:05:34 +01:00
Antoine Mercadal 263a94af18 remove useless pbxproj that was provoking a warning at build 2011-11-06 10:58:43 +01:00
Antoine Mercadal 9d1cf360b6 rename folder to XcodeCapp and update Jakefiles 2011-11-06 10:54:19 +01:00
Antoine Mercadal 60f664a5c2 rename project to XcodeCapp 2011-11-06 10:48:32 +01:00
Antoine Mercadal a1c7aa7790 Merge remote-tracking branch 'upstream/master' 2011-11-05 16:55:22 +01:00
Antoine Mercadal a29096ca5c Some other improvments
- Add preferences window
- Allow user to choose to use the 10.6 mode on 10.7
- Allow user to choose if he wants to resume listening at startup
- Allow use to choose if XCC should react to inode modification (file level API)
- Support for clean mirrored path when origin files has some _ in their names
- Other various fixes
2011-11-05 16:46:34 +01:00
Antoine Mercadal 0ef64f4091 support for NSProgressIndicator. close #1385 2011-11-05 13:41:16 +01:00
Johannes FahrenkrugandAntoine Mercadal 945deeba60 added a missing @ for the divider-color theme attribute of _CPCornerView. It broke jake (sudo-)install 2011-11-05 07:41:01 +08:00
Antoine Mercadal aa775675b5 add manual test for zombie group rows (#1376) 2011-11-05 00:25:23 +01:00
Antoine Mercadal db76044880 fix zombie group rows style. closes #1376 2011-11-05 00:24:54 +01:00
Antoine Mercadal edc58e358b handle moving files when using file level API (10.7) 2011-11-04 23:23:16 +01:00
Aparajita Fishman 1133efb3f1 Merge branch 'refs/heads/cppopover-fix-transient-delegate-calls' into cappuccino 2011-11-04 12:50:30 -07:00
Aparajita Fishman d524accc98 Fix typo, unintended globals, use constants for CPCoding keys 2011-11-04 12:50:00 -07:00
Aparajita Fishman 543f91dd6e Fixed typos and error message 2011-11-04 12:09:07 -07:00
Randall LueckeandAparajita Fishman 9848dabfa8 Fix typo in popover error. 2011-11-04 12:03:00 -07:00
Antoine Mercadal bc59efc3ba cleanup plist and shadow files under 10.6 2011-11-04 19:48:48 +01:00
Aparajita Fishman 9af63ca32f Fixed compile warning 2011-11-04 10:53:23 -07:00
Aparajita Fishman eb8a566ae8 Fixed support for 10.6 2011-11-04 10:44:01 -07:00
Aparajita Fishman 38eb3e489e Merge branch 'xcc-improvments' of github.com:primalmotion/cappuccino into xcc-improvments
Conflicts:
	Tools/xcodecapp-cocoa/AppController.m
	Tools/xcodecapp-cocoa/TNXCodeCapp.m
	Tools/xcodecapp-cocoa/defines.h
2011-11-04 09:16:52 -07:00
Aparajita Fishman 97f7eaf499 UI overhaul, first attempt at 10.6 compatibility. 2011-11-04 09:15:07 -07:00
Aparajita Fishman d3356eea5c Merge branch 'master' of github.com:cappuccino/cappuccino into cappuccino
Conflicts:
	AppKit/CPPopover.j
2011-11-03 22:32:38 -07:00
Aparajita Fishman 7a57bd73c3 Fixed typos and error message 2011-11-03 22:30:54 -07:00
Randall Luecke b517c93190 Fix typo in popover error. 2011-11-04 01:28:43 -04:00
Antoine Mercadal 7a9fded2e4 fallback into date mode in 10.6 2011-11-04 01:13:16 +01:00
Antoine Mercadal 8ed2096de7 update weird delegate name 2011-11-03 23:14:44 +01:00
Antoine Mercadal 791a1eb130 reactive support for 10.6 EXPERIMENTAL, this support may be removed very soon 2011-11-03 22:10:46 +01:00
Antoine Mercadal 9dab10ce19 Fixes
- Fixes all logic error
- Add sanity checks
- Drop useless and buggy chunck of code
2011-11-03 22:02:48 +01:00
Antoine Mercadal fd95c2ced6 fix About window released when close 2011-11-03 20:19:53 +01:00
Antoine Mercadal c32fef0eb9 forget to add hg and Build folders 2011-11-03 17:54:15 +01:00
Antoine Mercadal c77b35c07b Major XCC improvments
This patch contains the following:

 - FSEvent is now at files level instead of folders level. This allows to drop the registry in plist and improve the performances
 - When you remove a J file, the mirrored H file is removed too
 - .xcodecapp-ignore has been added to the FSEvent stream. ignored token are updated in live
 - By default XCC ignores all .git, .svn, .hg .xCodeSupport, Frameworks and Build folders
 - When you quit XCC without stop listening of the project, at next launch it will resume on the same project
 - Help has been added
 - Help is displayed at first user launch
 - The Error & Warning table doesn't pop ups automatically, instead it displays Growl (you can then open the panel for more informations)
 - The code has been refactored into several classes, one for UI thing, another one for XCC worker
 - Several bugs has been fixed
 - The about window now displays the version number
 - The main window has been removed
 - Several other small enhancements.

This is XCC 2.0.
2011-11-03 17:47:33 +01:00
Antoine Mercadal 4303ea3584 cache delegates methods for _CPAttachedView 2011-11-02 16:59:34 +01:00
Antoine Mercadal ddb6f63ea7 use coherent delegate name 2011-11-02 15:55:58 +01:00
Antoine Mercadal 06985a5b6c fix test 2011-11-02 12:06:05 +01:00
Antoine Mercadal 4841f209b3 fix delegate methods not sent in transient mode when closing 2011-11-02 11:59:20 +01:00
Aparajita Fishman 7e6ed01dd2 Merge branch 'refs/heads/cpwindow-setmovable' into cappuccino 2011-10-31 12:41:32 -07:00
Aparajita Fishman b7e41894af fixed up the test app ui 2011-10-31 12:39:53 -07:00
Alexander Ljungberg 5dfcfc32e7 Fixes #1388. Fixes #1389. Make bootstrap.sh work again. 2011-10-29 11:59:18 +01:00
aparajita fb74541796 Merge pull request #1388 from Ch00rD/master
A few simple updates to the install script and docs.
2011-10-28 20:51:56 -07:00
Sjoerd van Geffen 2f7b29593e replaced "280north" by "cappuccino" for github install script and docs references.
Replaced "280north" by "cappuccino" for github username and all github
URL references in the install script and documentation.
2011-10-29 02:09:18 +02:00
Aparajita Fishman 7ce6b1cfda CPBundleName and CPBundleVersion have to get set in the Jakefile 2011-10-28 16:56:47 -07:00
Aparajita Fishman 7ad1d14d15 Added CPBundleName to Info.plist 2011-10-28 11:30:13 -07:00
Antoine Mercadal 444c30e389 add manual test case 2011-10-28 17:56:37 +02:00
aparajita 06fc31c33b Merge pull request #1322 from aparajita/framework-template
Framework capp template
2011-10-27 15:55:48 -07:00
aparajita 4c58077cee Merge pull request #1321 from aparajita/capp-postinstall
Support for capp postinstall scripts
2011-10-27 15:55:13 -07:00
Aparajita Fishman 25253942a6 replace tab with spaces 2011-10-27 15:53:32 -07:00
Aparajita Fishman 4d75b47713 Added default version 2011-10-27 15:51:22 -07:00
Alexander Ljungberg 63c500c444 Fixed: overlay scroll knobs never quite reached the edge.
The calculation of the number of pixels outside of the clip view assumed fixed, space consuming scrollbars even when overlay scrollbars were used, leading CPScrollView to always think a few more pixels could be revealed.
2011-10-27 15:57:29 +01:00
Alexander Ljungberg 208c3fea35 Fix scroller gap for hidden overlay scrollers.
If there is no vertical scroller, or there is no horizontal scroller, due to autohiding or scroll view settings, a single visible overlay scroller should extend all the way to the edge of its dimension.
2011-10-27 14:44:19 +01:00
Alexander Ljungberg 3201b5921c Fix unterminated var block. 2011-10-27 13:43:02 +01:00
Alexander Ljungberg e92a7825bf Optimise bottom corner view in overlay scrolling mode.
In particular, there is no need to update nor even draw the bottom corner view when in overlay mode.
2011-10-27 13:35:55 +01:00
Alexander Ljungberg 65b1fb2bae Use the scroll view test 1 background in test 2.
The background makes it easier to see the scrolling in action.
2011-10-27 12:52:12 +01:00
Alexander Ljungberg 98df7e1eb8 Refs #1373. Improve documentation. 2011-10-27 11:51:10 +01:00
Antoine Mercadal 86079af3b1 implement CPWindow setMovable: API. close #1358 2011-10-26 11:05:07 +02:00
Alexander Ljungberg eeab0cf1b2 Merge remote-tracking branch 'primalmotion/lionscrollview' 2011-10-25 17:05:03 +01:00
Antoine Mercadal ac16b7ad0b fix a wrong autoresizing mask in manual test of CPScrollView2 2011-10-25 17:18:08 +02:00
Antoine Mercadal e9b87d7acc update the CPScrollView2 manual test to use the new API 2011-10-25 17:14:32 +02:00
Antoine Mercadal b37893d9bb change names of class methods to [set]GlobalScrollerStyle 2011-10-25 17:14:14 +02:00
Alexander Ljungberg 6f4ecdfbd9 Merge remote-tracking branch 'primalmotion/lionscrollview'
Conflicts:
	AppKit/CPScrollView.j
2011-10-25 15:54:16 +01:00
Antoine Mercadal 697921b486 autodetect is user computer is using legacy or overlay mode 2011-10-25 14:35:46 +02:00
Antoine Mercadal 3c01d4aa8b do not put scroller mode here 2011-10-25 14:33:47 +02:00
Antoine Mercadal a1eafdfbd8 update manual test for CPScrollView2 2011-10-25 12:45:18 +02:00
Antoine Mercadal 2cfb171b38 support for system wide scroller style. Set default to legacy mode in info.plist 2011-10-25 12:39:51 +02:00
Antoine Mercadal 2742e3d77b fix flashScrollers doesn't work 2011-10-25 12:11:11 +02:00
Alexander Ljungberg 5488d8f633 Refs #1373. Use self in some class methods to make subclassing easier. 2011-10-24 23:54:50 +01:00
Alexander Ljungberg 35c7155983 Refs #1373. Use legacy style scrollbars by default.
The Lion style scrollbars are inconvenient for users without a touch scrolling device, and we do not have a way to detect whether the user has such a device yet.
2011-10-24 23:51:18 +01:00
Alexander Ljungberg b90a8a58fd Fix some comments. 2011-10-24 23:42:44 +01:00
Alexander Ljungberg 85fa2011b2 Merge pull request #1373 from primalmotion/cappuccino
---

This patch makes CPScrollView acts like Lions NSScrollView.

A online demo can be found here: http://nightlies.archipelproject.org/CPScrollView2/
2011-10-24 20:45:58 +01:00
Alexander Ljungberg 063b05d964 Fixes #1384. Avoid user defaults QUOTA_EXCEEDED_ERR crash.
Switch to cookie based user defaults if HTML 5 local storage exists but is disabled, as is the case when Safari is in 'private browsing' mode.

Don't crash if the local storage quota is reached. Instead log a warning and silently fail to store the new user default.
2011-10-24 01:12:02 +01:00
Alexander Ljungberg ac90a0c0fb Remember multiple split view pre-collapse positions. Autosave.
If more than one subview is collapsed, remember the pre-collapse divider position for each subview separately.

Autosave pre-collapse positions to restore positions when uncollapsing after a reload.
2011-10-23 13:30:37 +01:00
Alexander Ljungberg 3efe33d2fb Split view resize cursors for rightwards collapse.
If the right/lower subview is collapsible and the divider is at its uncollapsed maximum position, continue showing the two way resize cursor to indicate additional movement is actually possible. Also show the shrink cursor when the mouse is over the divider to the left/above of a collapsed subview.
2011-10-23 12:51:51 +01:00
Alexander Ljungberg 3e5ea97768 Eliminate excessive splitViewDidResizeSubviews: messages.
Merely clicking a divider without moving it should not result in a splitViewDidResizeSubviews: message. Fixed errors with setPosition:ofDividerAtIndex:'s no change detection.
2011-10-23 12:28:46 +01:00
Alexander Ljungberg a970657312 Fix split view splitViewDidResizeSubviews: delegate method.
Only call splitViewDidResizeSubviews: after the subviews have actually finished being resized. Make sure to call splitViewDidResizeSubviews: when views are collapsed, even if _adjustSubviewsWithCalculatedSize performed no work.
2011-10-23 11:25:25 +01:00
Alexander Ljungberg 240615c71b Fixed split view right collapse size restore.
When a collapsed split view subview was restored, e.g. by double clicking the divider, and the collapsed subview was on the right hand side of the divider, the pre-collapse split view position was not restored.
2011-10-23 00:09:47 +01:00
Alexander Ljungberg d3f4e205af Support split view collapse rightwards.
When a divider is dragged to the right past half of the minimum width of a collapsible subview, or the divider is double clicked and the delegate returns YES for shouldCollapseSubview:forDoubleClickOnDividerAtIndex:, the subview is collapsed. This is the mirror operation of collapsing towards the left.
2011-10-23 00:01:53 +01:00
Alexander Ljungberg cc63c239f6 Fix StaticResource.includeURLs caching.
The cache was being shadowed by a local variable, forcing the list of includeURLs to be recreated for every call to StaticResource.includeURLs.
2011-10-21 16:06:52 +01:00
Alexander Ljungberg 4b82cae638 Add missing semicolons. 2011-10-21 15:58:50 +01:00
Alexander Ljungberg 68c8d15ed4 Improve split view delegate error handling.
Fixed: if the split view delegate sent non numeric responses when asked to constrain divider positions, subviews would be resized with corrupt size information, which in turn could lead to infinite loops and redraw errors. These bad results are now handled more gracefully.
2011-10-21 15:55:34 +01:00
Alexander Ljungberg 021f5bb030 Fixed: disappearing or fuzzy table header dividing lines at certain table sizes. 2011-10-20 18:51:59 +01:00
Alexander Ljungberg fc5d9a413d Fixes #1380. Fixes #1383. Avoid "popen error (pipe): Too many open files" error when building Cappuccino. 2011-10-20 13:49:16 +01:00
Kevin Jamieson e09acb9208 Update internal string value of CPTextField when a newline is entered or the field loses focus. 2011-10-17 22:00:38 -07:00
Alexander Ljungberg 2f57404c9c Clarify and format bootstrap messages. 2011-10-17 21:51:43 +01:00
Alexander Ljungberg a29bdf0cf4 Merge pull request #1361 from hammerdr/cappuccino
---

Tusk seems to need OJTest to be alone in order to calculate and/or
download dependencies (which are the Objective-J and Cappuccino
pre-built packages).
2011-10-17 21:30:31 +01:00
Alexander Ljungberg c29597689c Tweak bootstrap instructions. 2011-10-17 19:41:41 +01:00
Alexander Ljungberg 797fbca6d4 Merge pull request #1381 from primalmotion/cappuccino
---

running tusk install browserjs jake shrinksafe AND extra packages (OJtest, objj and capp)
in a single instruction prevent the installation of the lasts.

This patch splits the procedure in two separate instructions and should fix all problems.
2011-10-17 19:25:11 +01:00
Antoine Mercadal 6ed4b289d8 Fix bootstrap errors
running tusk install browserjs jake shrinksafe AND extra packages (OJtest, objj and capp)
in a single instruction prevent the installation of the lasts.
This patch splits the procedure in two separate instructions
2011-10-17 20:04:54 +02:00
Alexander Ljungberg 7dd07b2f5b Refs #1378. Unit test for radio group actions. 2011-10-10 14:31:49 +01:00
Alexander Ljungberg b371fda0a5 Refs #1378. Position the continuous button test window so it's visible. 2011-10-10 14:21:08 +01:00
Alexander Ljungberg 3bdb11d804 Merge pull request #1378 from primalmotion/cappuccino
---

Cocoa compliance.

 * updated manual test: log a text only when user clicks a radio button butnot when using the CPButton that uses setState:
 * ignore .xCodeSupport folders.
2011-10-10 14:07:17 +01:00
Antoine Mercadal 199b777dcc update CPButtonTest to test setState: behavior 2011-10-10 14:52:08 +02:00
Antoine Mercadal 70ccec2e82 do not send action when using setState: programatically 2011-10-10 14:49:59 +02:00
Antoine Mercadal a195624549 ignore .xCodeSupport folders 2011-10-10 14:49:06 +02:00
Alexander Ljungberg e417eba6bd CPSplitView autosave support. 2011-10-09 19:11:38 +01:00
Antoine Mercadal 210bb3e5c9 prevent scrollers to show track on mouse enter when ratio is 1 2011-10-06 16:41:36 +02:00
Antoine Mercadal 140ae354a1 try to get 'NSScrollerKnobStyle'. for NSTableView in Xcode, this is not positioned and cause a crash 2011-10-06 15:10:19 +02:00
Antoine Mercadal 2451b08306 fix accidental global 2011-10-06 13:38:31 +02:00
Alexander Ljungberg 04d33e772f Allow binding a table column value to an array controller reached through a key path.
Cocoa might not support this but it is reasonable and consistent, and allows indirect bindings when using multiple CIB files.
2011-10-06 01:59:56 +01:00
Alexander Ljungberg 3592fd8dae Whitespace cleanup. 2011-10-06 01:59:48 +01:00
Alexander Ljungberg 889e8d3b6e Test automatic table bindings. 2011-10-06 00:36:13 +01:00
Alexander Ljungberg 908fc67f96 Whitespace cleanup. 2011-10-06 00:11:59 +01:00
Antoine Mercadal c9a645285a make labels selectable in test project to test accessibility of stuff under the overlay scrollers 2011-10-05 17:54:53 +02:00
Antoine Mercadal 3655724810 fix missing labels in test project 2011-10-05 17:51:49 +02:00
Antoine Mercadal 866047c116 fix sone visual glitches 2011-10-05 17:46:51 +02:00
Antoine Mercadal 8912d31bec do not fade in scrollers on overing 2011-10-05 17:32:44 +02:00
Antoine Mercadal 1e65342814 add manual test for CPScrollView specificities 2011-10-05 17:07:17 +02:00
Antoine Mercadal c7ca352205 remove debug print 2011-10-05 17:00:31 +02:00
Antoine Mercadal 4b1ce8bc0b better art for default knob style 2011-10-05 16:55:08 +02:00
Antoine Mercadal 422e940bc7 use default knob style as default. logic. 2011-10-05 16:24:37 +02:00
Antoine Mercadal 76e2a2b8ca support new properties in nib2cib 2011-10-05 16:24:12 +02:00
Antoine Mercadal e3565bdc7d fix visual glitch when scroller are hidden and overed 2011-10-05 15:57:18 +02:00
Antoine Mercadal 86f01cfaec add a timer before fading out the scroller when overed 2011-10-05 11:34:06 +02:00
Antoine Mercadal 6e4007adc0 add support for the different scroller knob styles 2011-10-05 11:27:32 +02:00
Antoine Mercadal 8c6913c399 small theming adjustment 2011-10-04 17:03:23 +02:00
Antoine Mercadal efdfd0db10 fix some bugs and update arts 2011-10-04 16:21:24 +02:00
Antoine Mercadal d6412eec58 tidy up the CPScrollView class file 2011-10-04 14:36:08 +02:00
Antoine Mercadal 53a6d2de83 support for changing scroller styles 2011-10-04 14:05:02 +02:00
Antoine Mercadal 7fe990e9f6 keep scroller visible if mouse is over, even if timer fire 2011-10-03 21:15:21 +02:00
Antoine Mercadal 7b7ad0715b add artwork 2011-10-03 21:08:06 +02:00
Antoine Mercadal 1a57d032b9 make CPScrollView acting like Mac OS X Lion ones 2011-10-03 21:07:46 +02:00
Alexander Ljungberg 77bb169680 Merge pull request #1371 from primalmotion/cappuccino
---

CPTokenField has the theme state ```CPTextFieldStatePlaceholder``` even if tokens are present, resulting with a wrong positioning of tokens.
2011-10-03 17:10:12 +01:00
Antoine Mercadal b424c19eee optimization 2011-10-03 17:28:32 +02:00
Antoine Mercadal 4d597069cf fix problem in CPTokenField with wrong theme state if containing tokens 2011-10-03 17:08:21 +02:00
Alexander Ljungberg 5afbdf7f20 Merge pull request #1370 from primalmotion/cappuccino
---

Store the conversion date before starting to actually convert. This should avoid to loop indefinitly in case of long conversion time.
Also convert tabs to space, and remove trailing spaces.
2011-10-03 15:10:12 +01:00
Antoine Mercadal 33f558b221 Fix conversion loop
Store the conversion date before starting to actually convert. This should avoids to loop indefinitly in case of long conversion time.
Also convert tabs to space, and remove trailing spaces.
2011-10-03 15:22:16 +02:00
Stephen Ierodiaconou b05d0dd1ec Fix for comparing decimal numbers < 1.0 with 0.0 2011-10-01 10:50:23 +01:00
Alexander Ljungberg b2b305cc4b Merge pull request #1274 from aparajita/cappuccino
---

- Enhanced -description method of CPImage and CPColor to show the exact content, especially for pattern colors.

- Added CPColorWithImages() convenience function, analogous to PatternColor() function used in theme descriptors.

- Added @cond/@endcond in CPColor to ignore local variables.

- Sample app included. See the console for samples of -description output for all color/image types.
2011-09-27 20:53:41 +01:00
Aparajita Fishman c5a9ee544c Comment cleanup, replace CPRect with _CGRect. 2011-09-25 17:06:02 -07:00
Aparajita Fishman 368d66f76e Copy the input frame, it should not be modified in place. 2011-09-25 16:59:44 -07:00
Nicolas GoyandAparajita Fishman 5aaae61b46 Modified CPStepper to support theming better by adding the ability to size buttons through theme 2011-09-25 15:19:14 -07:00
Alexander Ljungberg 29fe50c2d7 Merge pull request #1365 from primalmotion/cappuccino
---

My previous patches was preventing to change the CPPlatformWindowt title once it was opened using windows setTitle:

This patch fix it.
2011-09-21 13:04:24 +01:00
Antoine Mercadal d0c59ee253 fix bug preventing the CPPlatformWindow's title to change once opened 2011-09-21 14:00:35 +02:00
Aparajita Fishman d2e39238f4 Jakefile improvements...
- 'jake clean' now cleans instead of clobbers.
- Added task 'clean-sprites', cleans sprited images.
- Added task 'clobber-theme', clobbers all traces of Aristo.
- Added missing semicolons, followed JavaScript lint suggestions for using dot notation instead of [""].
2011-09-19 21:42:59 -07:00
Alexander Ljungberg 4aec3f7466 Refs #1355. Manual window title test.
In the PlatformWindows test, change the window title both when theWindow is a non platform window and when it is a platform window to verify that the browser window title changes only when it should.
2011-09-17 11:07:38 +01:00
Alexander Ljungberg c8991e07b9 Merge pull request #1355 from primalmotion/cappuccino
---

if setTitle: is called on a CPWindow with the primaryPlatformWindow as platformWindow,
the main pages title is changed. This patch prevent changing the primaryPlatformWindows title.
This is not optimal, but this is better than changing the title at each window setTitle: call
2011-09-17 10:55:43 +01:00
Alexander Ljungberg 48157db973 Refs #1360. Fixed: index was always 0 in CPTokenField tokenField:shouldAddObjects:atIndex: delegate method. 2011-09-16 21:52:09 +01:00
Alexander Ljungberg d070e5fce5 Merge branch 'master' of github.com:cappuccino/cappuccino 2011-09-16 21:47:20 +01:00
Alexander Ljungberg a8fae51ea8 Refs #1360. Cursor movement fixes, optimisations.
Don't move the cursor forward if no token was inserted. Only count new tokens once.
2011-09-16 21:46:20 +01:00
Alexander Ljungberg 2815d462be Refs #1360. Test for CPTokenField tokenField:shouldAddObjects:atIndex:. 2011-09-16 20:51:45 +01:00
Alexander Ljungberg 85f8ca9241 Refs #1360. Format code. 2011-09-16 19:29:53 +01:00
Alexander Ljungberg b5fb9e8c23 Merge pull request #1360 from jigzat/cappuccino
---

Enabled tokenField:shouldAddObjects:atIndex delegate method and used on _autocompleteWithDOMEvent method to have some control over tokens. Not sure why wasnt enabled, it needed very few code. Maybe no one needed it til now.

This is my first collaboration ever, so Im not sure if is of any use.
2011-09-16 19:10:23 +01:00
Klaas Pieter Annema 1addc002d3 Merge branch 'master' of github.com:cappuccino/cappuccino 2011-09-16 12:00:05 +02:00
Klaas Pieter Annema e99e2660e9 more fixes and tests for _CPKVCArray 2011-09-16 11:43:42 +02:00
Aparajita Fishman 03d1bb8bce Added missing statement separator, concatenated var block, fixed symlink deletion/creation sometimes failing. 2011-09-15 17:09:15 -07:00
Klaas Pieter Annema 5b00f7f2e8 improve _CPKVCArray
_CPKVCArray now consistently calls both single and multiple indexes accessors consistently
Tests that verify the behavior are included
2011-09-15 22:32:23 +02:00
Klaas Pieter Annema 97b7f0901e add tests for key view loop behavior 2011-09-15 17:50:37 +02:00
Klaas Pieter Annema 67b2671dad improve key view loops
- include the window's content view at the start of the key view loop
- set the initial first responder to the window's content view (and keep it that way unless it is explicitly changed)
- CPWindow should return NO from acceptsFirstResponder (Cocoa compliance).
- change the type of setInitialFirstResponder, this is compliant with Cocoa. The new key view loop code will break if initial first responder is anything but a view
- change the implementation of selectNextKeyView:, selectPreviousKeyView:, selectKeyViewFollowingView: and selectKeyViewPrecedingView: to follow to Cocoa's documentation
2011-09-15 16:39:24 +02:00
aparajita 7886d49e65 Merge pull request #1359 from primalmotion/fix-and-improve-doxygen-theme
Fix and improve doxygen theme
2011-09-09 21:48:17 -07:00
Samir Gartner e5284e9b43 Fixed some possible error of my part where selectedRange is moved beyond bounds 2011-09-09 22:31:17 -05:00
Samir Gartner c6403baa04 Fixed cursor position issue in a little escapade...guess that's all for now folks 2011-09-09 13:28:37 -05:00
Samir Gartner 662b1ec696 Submitted the right CPTokenField file, was missing the part to use the delegate approved tokens. Still lacks a way to put the cursor after the last token (if the delegate returns more than one token) 2011-09-09 12:48:18 -05:00
Derek Hammer 9570e541d9 Move OJTest install to after the tusk install of other packages.
Tusk seems to need OJTest to be alone in order to calculate and/or
download dependencies (which are the Objective-J and Cappuccino
pre-built packages).
2011-09-09 11:41:01 -05:00
Samir Gartner 043df71185 Enabled tokenField:shouldAddObjects:atIndex delegate method and used on _autocompleteWithDOMEvent method to have some control over tokens. Not sure why wasn't enabled, it was very few code. Maybe no one needed it 'til now 2011-09-08 22:56:52 -05:00
Antoine Mercadal 8dab47f4da mozilla compat 2011-09-08 18:12:32 +02:00
Alexander Ljungberg 90d069df2b Refs #1343. Remove now obsolete README.md.
Everything in the README has been fixed except 3 and 4. 4 is outside of the issue scope and 3 works as intended (nearly). The array controller does not have `setAvoidsEmptySelection:NO` so an empty selection should not be possible unless there are no items.
2011-09-08 17:02:15 +01:00
Antoine Mercadal dcbe3ee650 fix paremeters touching their description in bubbles 2011-09-08 17:15:12 +02:00
Antoine Mercadal e32489aba1 tiny padding improvment in generated html docs 2011-09-08 17:08:50 +02:00
Antoine Mercadal b619c0b793 some small graphical improvments 2011-09-08 16:55:12 +02:00
Antoine Mercadal fab61d14fa forget to restore the bg color of the tree view 2011-09-08 14:44:05 +02:00
Antoine Mercadal b4edc084f8 add Cappuccino logo 2011-09-08 14:00:20 +02:00
Antoine Mercadal c7518d0c49 merge Aparajita's previous improvments on the CSS 2011-09-08 12:44:10 +02:00
Antoine Mercadal a40345c14d fix the slider 2011-09-08 11:46:20 +02:00
Antoine Mercadal 909471a5d7 fix the documentation generation process 2011-09-08 01:30:58 +02:00
Antoine Mercadal 38f7ea00c2 update doxygen.css 2011-09-08 00:43:32 +02:00
Alexander Ljungberg 9f459f053e Fixed: several CPArrayController methods returned undefined instead of booleans. 2011-09-07 18:17:35 +01:00
Alexander Ljungberg 4195f3b8c6 Test that CPArrayController setSelectionIndexes: does not modify its input. 2011-09-07 18:02:53 +01:00
Alexander Ljungberg 4926824482 Fixed: CPArrayController setSelectionIndexes: sometimes modified its input.
Also very slightly improved performance as sometimes the input index set would be instantiated internally and then needlessly copied.
2011-09-07 17:53:48 +01:00
Alexander Ljungberg cb2f539cf7 Send didChange in reverse order of willChange in CPObjectController setContent:. 2011-09-07 17:32:19 +01:00
Alexander Ljungberg 7f31be7cb1 Fixed: array replaceObjectsInRange:withObjectsFromArray: always failed with a "'null' is not an object' error.
This was caused by the new range checks in f8404c7a97.
2011-09-07 16:18:08 +01:00
Alexander Ljungberg 78b9c5b576 Fixes #1343. Support nested willChange… didChange… calls.
When multiple calls are nested, only the first willChange… and the last didChange… will notify observers, avoiding duplicate notifications for the same change.
2011-09-07 16:14:01 +01:00
Alexander Ljungberg 01e35efdbb Refs #1343. Recreate manual bindings test as an automatic test. 2011-09-07 16:04:35 +01:00
Aparajita FishmanandAlexander Ljungberg bef1687b1f Test app for bindings fixes. 2011-09-07 12:51:36 +01:00
Antoine Mercadal afa691376e fix unable to change mainWindow's title 2011-09-02 14:00:49 +02:00
Antoine Mercadal be10bcf27a Fix CPPlatformWindow's title bug
if setTitle: is called on a CPWindow with the primaryPlatformWindow as platformWindow,
the main page's title is changed. This patch prevent changing the primaryPlatformWindow's title.
This is not optimal, but this is better than changing the title at each window setTitle: call
2011-09-02 12:42:09 +02:00
Alexander Ljungberg 608cb86a4a Whitespace cleanup. 2011-08-31 18:51:15 +01:00
Alexander Ljungberg 88780ff0a9 Merge pull request #1352 from primalmotion/cappuccino
---

In latest versions of webkit window.open(url) return undefined if url == ""
2011-08-31 18:47:43 +01:00
Antoine Mercadal a5e241afd7 update PlatformWindows test (use the slider to play with the titles) 2011-08-31 19:17:41 +02:00
Antoine Mercadal 28772d3254 use CPWindow's title for platform window 2011-08-31 19:17:10 +02:00
Antoine Mercadal d1f5c1eebc patch for enventual webkit bug with window.open() 2011-08-31 18:28:47 +02:00
Alexander Ljungberg c77a282aaf Raise CPRangeException if CPString substringToIndex: is out of bounds. 2011-08-27 23:50:18 +01:00
Alexander Ljungberg 7a1cd5c545 Fix CPString substringToIndex documentation. The index parameter is not inclusive. 2011-08-27 23:49:40 +01:00
Alexander Ljungberg 29ff54054e Fix a typo. 2011-08-22 23:03:34 +01:00
Alexander Ljungberg 8e1bbe0132 Merge pull request #1345 from primalmotion/cappuccino
---

This patch allow to send play message before
the sound is actually loaded (by remembering the play request
and playing the sound when loaded if needed)

this allows to do:

```objj
var sound = [[CPSound alloc] initWithContentsOfURL:aSoundURL byReference:NO];
[sound play];
```
2011-08-22 22:59:39 +01:00
Antoine Mercadal a2b6585c0d CPSound support play while loading
This patch allow to send 'play' message before
the sound is actually loaded (by remembering the play request
and playing the sound when loaded if needed)

this allow to do:

```objj
var sound = [[CPSound alloc] initWithContentsOfURL:aSoundURL byReference:NO];
[sound play];
```
2011-08-20 18:48:11 +02:00
Francisco Ryan Tolmasky I aa452952a8 Merge pull request #1344 from aparajita/valueForKeyPath-tweak
Much more efficient test for first character of string
2011-08-18 09:43:46 -07:00
Aparajita Fishman 6ea4aa0a66 Much more efficient test for first character of string 2011-08-18 00:52:59 -04:00
Randy Luecke 2462cd7b1d Merge pull request #1316 from primalmotion/cppopover
add CPPopover (Cocoa API compliant)
2011-08-17 11:17:02 -07:00
Randy Luecke 331e338c06 Merge pull request #1333 from eventualbuddha/CPAlert-subclass-builder-support
Allow CPAlert subclasses to use +alertWithMessageText:... et al.
2011-08-17 11:16:20 -07:00
Randy Luecke 2b68f40872 Merge pull request #1341 from cacaodev/CPTableView_drawBackgroundInClipRect
CPTableView: -drawBackroundInClipRect: bug
2011-08-17 11:15:33 -07:00
Randy Luecke 2f7b3c306d Merge pull request #1335 from alexmipego/master
CPBox autoresize settings
2011-08-17 11:13:46 -07:00
Randy Luecke eba5dbe654 Merge pull request #1334 from aparajita/array-range-checking
Added some missing range checking.
2011-08-17 11:11:49 -07:00
Randy Luecke 9ae1f548bf Merge pull request #1338 from purem/master
Added zsh to xcodecapp-cocoa
2011-08-17 11:05:18 -07:00
Alexander Ljungberg d191255a84 Merge branch 'master' of github.com:280north/cappuccino 2011-08-12 19:50:49 -04:00
Alexander Ljungberg 9bf8824109 nib2cib support for token fields. 2011-08-12 19:50:30 -04:00
Alexander Ljungberg f773bd217c Fixed with token field: remove false ivar '_tokenIndex' and fix tokenField:tokenField completionsForSubstring:indexOfToken:indexOfSelectedItem: ignoring its indexOfToken: parameter. 2011-08-12 19:46:39 -04:00
Alexander Ljungberg a5f0f0e3db CPTokenField archiving support. 2011-08-12 19:29:59 -04:00
Alexander Ljungberg 6f6bfc667b Inverted CPCharacterSet characterSetWithCharactersInString now archive properly. 2011-08-12 19:27:02 -04:00
Alexander Ljungberg 0789f49b94 CPCharacterSet isEqual support when the set is of the characterSetWithCharactersInString kind. 2011-08-12 19:12:47 -04:00
Alexander Ljungberg 92c94eab8f CPCharacterSet archiving support when the set is of the characterSetWithCharactersInString kind. 2011-08-12 18:50:06 -04:00
cacaodev 9f06ed725e CPTableView: -drawBackroundInClipRect:
Fixes a bug where we were drawing rows from 0 instead of the first exposed when usesAlternatingBackgroundColors:YES
2011-08-11 21:06:19 +02:00
Jonathan R H Evans c45039fd70 Added zsh to the list of shell configs that xcodecapp-cocoa checks. 2011-08-09 10:15:23 +01:00
Aparajita Fishman 8e203ec78e Fixed range checking for insertObject:atIndex: 2011-08-08 15:14:30 -07:00
alexmipego e32515e5cc Make boxEnclosingView: copy the auto resizing settings of the view 2011-08-07 20:22:14 +01:00
Klaas Pieter Annema 2b77da821c always build xcodecapp with 10.6 SDK 2011-08-06 16:43:11 +02:00
Aparajita Fishman f8404c7a97 Added some missing range checking. 2011-08-05 14:40:13 -07:00
Brian Donovan 156610ee07 Allow CPAlert subclasses to use +alertWithMessageText:... et al. 2011-08-05 08:32:44 -07:00
Alexander Ljungberg fcaf672bf8 Merge branch 'master' of github.com:280north/cappuccino 2011-07-29 02:43:52 -04:00
Alexander Ljungberg dd5d8fcdce Closes #1305. Fixed: don't constrain max toolbar item width to the width of the label. 2011-07-29 02:42:42 -04:00
Alexander Ljungberg e0c4f6455d Tweak some messages. 2011-07-29 02:02:11 -04:00
Alexander Ljungberg dd5d7e9979 Whitespace cleanup. 2011-07-29 02:01:31 -04:00
Alexander Ljungberg 408baac91e Fix Xcode capitalisation in xcodecapp-cocoa. 2011-07-29 02:00:14 -04:00
Klaas Pieter Annema f241142216 don't disallow setEnabled for auto enabled items 2011-07-21 14:41:47 +02:00
Klaas Pieter Annema f0561844d8 don't close a menu item with a submenu
A submenu item should only close the menu if it has a non default action.
This is compliant with how Cocoa behavior.
2011-07-21 12:23:11 +02:00
Randall Luecke bd6294b806 Updated Jakefile for xcodecapp-cocoa to use the proper variable name. This should also fix the buildbot. 2011-07-17 22:46:27 -07:00
Alexander Ljungberg 70f8e3a832 Merge pull request #1278 from aparajita/cappuccino
---

 I discovered the following behavior that is not in conformance with Cocoa:

- Backspace, tab, escape, and space are considered key equivalents.
- Function keys (F1 - FNN) are not considered key equivalents.
- CPTextField executes `performKeyEquivalent` twice if a field is first responder.

Build this Cocoa project and debug it: http://d.pr/Xc3h

Take a look at the debug log while typing some keys. You will see that backspace, tab, escape and space do not trigger `performKeyEquivalent`, and that `performKeyEquivalent` is only executed once for the first responder.

Then run the performKeyEquivalentsTest app in this commit and look at the console log while trying keys in the text fields. If you turn the old code on, you will see how `performKeyEquivalent` is executed twice for the first responder.

For reference on key handling code, I consulted this:

http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/EventOverview/EventArchitecture/EventArchitecture.html%23//apple_ref/doc/uid/10000060i-CH3-SW11
2011-07-17 22:55:18 -04:00
Alexander Ljungberg 59b302acde Merge pull request #1177 from cacaodev/cappuccino
---

Adds -scrollViewWillScroll: and -scrollviewDidScroll: delegate methods to CPScrollView.

These methods are not in AppKit but exist in UIKit. Useful for lazy loading data in a view, for example a CPTableview.
Tested in the CPScrollView example.

Conflicts:
	AppKit/CPScrollView.j
2011-07-17 22:05:55 -04:00
Alexander Ljungberg f54f8dfec9 Merge branch 'master' of github.com:280north/cappuccino 2011-07-17 21:48:53 -04:00
Alexander Ljungberg 93135e7e81 Header fixes. 2011-07-17 21:47:40 -04:00
Alexander Ljungberg b8026e19ba Merge pull request #1320 from MCF/cappuccino
---

If a CPTextFields target action changed the first responder then the target action was called twice if the textfield edit was completed by hitting the enter/return key.  This fixes the problem by setting the _isEditing flag to NO before the action is called in the insertNewline function.

See [this thread](https://groups.google.com/group/objectivej-dev/browse_thread/thread/ff64a4520102b3c5?hl=en) for more details.

Also included a new manual test for an editable CPTableView to make testing the fix easier.
2011-07-17 21:43:23 -04:00
Randy Luecke 147d9282fb Merge pull request #1323 from primalmotion/xcodecapp-cocoa-menu-for-error-panel
Small improvments in XcodeCapp-Cocoa
2011-07-17 15:49:21 -07:00
Antoine Mercadal 7c18b8bc5f Small improvments in XcodeCapp-Cocoa
- Do not release the Error & Warning window on close (or you can't open it again)
 - Small graphical updates
 - Remove the Growl notification in case of error (panel is sufficient)
 - Add a menu to open the error and warning panel when user wants to
2011-07-17 23:50:14 +02:00
Randall Luecke 2ccbf5d4e5 Errors in xcodecapp-cocoa now show up in their own panel. Should we keep growl? 2011-07-17 13:46:57 -07:00
Randall Luecke da6d8c86d1 Merge branch 'xcodecapp-cocoa-merge' of https://github.com/primalmotion/cappuccino into primalmotion-xcodecapp-cocoa-merge 2011-07-17 13:45:41 -07:00
Randall Luecke 78d997b404 Remove xcodecapp-cocoa in preparation for a proper merge 2011-07-17 13:44:09 -07:00
Aparajita Fishman 89b23ef0d7 Framework capp template 2011-07-17 09:17:08 +03:00
Aparajita Fishman b958911c63 Support for postinstall scripts 2011-07-17 09:15:26 +03:00
Randall Luecke c6e5219f2e Add Xcodecapp-cocoa build to Tools Jakefile 2011-07-16 23:11:13 -07:00
Randall Luecke 3bb450adbf Merge branch 'master' of git://github.com/280north/cappuccino 2011-07-16 22:57:56 -07:00
Randall Luecke a0f5257258 Errors in xcodecapp-cocoa now show up in their own panel. Should we keep growl? 2011-07-16 22:57:12 -07:00
Randall Luecke 6520615bb0 Merged xcodecapp-cocoa 2011-07-16 22:53:49 -07:00
Randy Luecke 4593212698 Merge pull request #1299 from farcaller/5d26066e02f6d1203981b27c8acf7f7991f4a419
Fixup for CPDictionary's dictionaryWithJSObject:recursively: and null objects in arrays
2011-07-16 19:45:45 -07:00
Randy Luecke 5363deb122 Merge pull request #1285 from aparajita/CPPredicate-fix
CPPredicate fix
2011-07-16 19:40:17 -07:00
Randy Luecke d5a651fc43 Merge pull request #1290 from hammerdr/include-ojtest
Adding OJTest installation to the bootstrap.sh file.
2011-07-16 19:39:52 -07:00
Randy Luecke 4740acbcc6 Merge pull request #1292 from aparajita/doxygen-font-fix
Use Menlo if Consolas is not available
2011-07-16 19:36:35 -07:00
Randy Luecke bfb2134329 Merge pull request #1293 from aparajita/CPKeyedArchiver-tweak
CPKeyedArchiver - Removed unused variable, fixed typo
2011-07-16 19:36:00 -07:00
Randy Luecke ec83977fe1 Merge pull request #1312 from aparajita/CPPlatformString-missing-methods
Make sure CPPlatformString +sizeOfString and +metricsOfFont work with CommonJS
2011-07-16 19:33:32 -07:00
Randy Luecke 98d08ff05d Merge pull request #1317 from aparajita/themeClass-fix
Have to set _themeClass when class changes
2011-07-16 19:32:54 -07:00
Randy Luecke 1eb6319b49 Merge pull request #1313 from cacaodev/CPViewAnimation
CPViewAnimation: current frame based on -currentValue.
2011-07-16 19:30:25 -07:00
Mike Fellows 8f7e06f9d6 Fix regression to CPTextField's insertNewline, duplicate target actions were being called when an edit on a textfield was ended with an enter/return keypress 2011-07-15 18:55:03 -07:00
Mike Fellows 81e3abe10c Add CPTableView test for editable table cells. 2011-07-15 18:54:53 -07:00
Klaas Pieter Annema edcee8934d fix empty contextual menus out of bounds error 2011-07-14 16:26:58 +02:00
Klaas Pieter Annema d115d2ef47 fix context menu only closes after two clicks
This is a regression from 73b4c33f05.
Because we were only tracking wether the left mouse button went up after a contextual menu (which is opened with the right mouse)
would only close after the second left mouse up.
2011-07-14 11:15:34 +02:00
Alexander Ljungberg d1dd725848 Merge pull request #1318 from aparajita/cappuccino
---

And several bugs fixed in the process.
2011-07-09 20:51:33 -04:00
Aparajita Fishman ebdba33082 Whitespace cleanup 2011-07-09 17:08:08 -07:00
Aparajita Fishman 918f6fbb8f CPFormatter support, bug fixes...
- Test application.

CPControl
---------
- Moved _formatter declaration up next to value, it was in the Target-Action Support section before.

- sendAction:to: should return a BOOL.

- Support for CPFormatter -editingStringForObjectValue.

- If a nil string is passed to -setStringValue in Cocoa, it raises an invalid parameter assertion and does nothing.

- Per Cocoa, if setting a string value fails, it tries again with an empty string.

- Removed a few extra blank lines.

- Changed NULL to nil.

CPTextField
-----------
- The string value is now cached in _stringValue to avoid constant calls to the formatter.

- There were several places where references to _inputElement were not wrapped with #if PLATFORM(DOM).

- When resigning first responder, if there is a formatter and formatting fails, reject the resignation and keep focus. Also, if the delegate responds to control:didFailToFormatString:errorDescription:, invoke it.

- _willBecomeFirstResponderByClick was not being set to NO when resigning. As a result, if you clicked in a field, tabbed to another field, and tabbed back to the original field, it would not select the text because it thought there was a mouse click.

- Don't send _sendStringValue: in keyUp: if the value has not changed. Previously it would do that for non-printing keys like navigation keys.

- insertNewLine: validates the string the same way resigning does.

- insertNewLine: would not send textDidEndEditing: if the field had no action, but it should.

- insertNewLine: should select all text (per Cocoa).

- insertNewLineIgnoringFieldEditor: and insertTabIgnoringFieldEditor: were not replacing the selection, Cocoa docs say they should.

- Per Cocoa, when setting an object value and there is a formatter, the value is first formatted as a string. If that fails, an object value for an empty string is attempted.

CPFormatter
-----------
- Fixed up the docs to match the method signatures.

- Indicated with "Ref" in argument types if the argument is pass by reference.

- isPartialStringValid:newEditingString:errorDescription: has a default implementation in Cocoa that nils the return values and returns YES.

- Fixed the name of isPartialStringValid:proposedSelectedRange:originalString:originalSelectedRange:errorDescription:

- isPartialStringValid:proposedSelectedRange:originalString:originalSelectedRange:errorDescription: has a default implementation in Cocoa that invokes isPartialStringValid:newEditingString:errorDescription:
2011-07-09 17:05:23 -07:00
Antoine Mercadal 28733ec592 label are white in CPPopoverTest if popover is HUD 2011-07-09 15:29:37 +02:00
Antoine Mercadal 916b9a399b make color matching Aristo 2.0 ones 2011-07-09 15:29:13 +02:00
Antoine Mercadal 3d62791477 fix animation lack in FF prevents Popover to close 2011-07-09 11:50:52 +02:00
Aparajita Fishman 64e6764015 Have to set _themeClass when class changes 2011-07-08 19:04:33 -07:00
Antoine Mercadal cbed5c9cb1 support for CPPopover 2011-07-08 17:51:08 +02:00
Antoine Mercadal 0246d501e2 full support for CPPopover and nib2cib + enchanced delegates 2011-07-08 17:49:53 +02:00
Antoine Mercadal 3d5b30ab9e add CPPopover (Cocoa API compliant) 2011-07-08 15:50:29 +02:00
Klaas Pieter Annema 4719578f10 fix 0 is a valid highlighted index 2011-07-07 20:40:22 +02:00
Klaas Pieter Annema fe370c7066 Merge branch 'master' of github.com:280north/cappuccino 2011-07-07 18:37:24 +02:00
Klaas Pieter Annema 63d208bf20 never return a separator as the highlighted item 2011-07-07 18:33:00 +02:00
Alexander LjungbergandKlaas Pieter Annema 5158540208 Fixed: initialise CPNumberFormatter maximumFractionalDigits to 3. 2011-07-07 16:04:12 +02:00
Alexander LjungbergandKlaas Pieter Annema a69f7dc81a Test CPTextField with a formatter. 2011-07-07 16:04:11 +02:00
Alexander LjungbergandKlaas Pieter Annema e848e161d4 CPNumberFormatter maximum fractional digits support. Optimise by only creating CPDecimalNumberHandler when needed and caching the result. 2011-07-07 16:04:11 +02:00
Alexander LjungbergandKlaas Pieter Annema 3db61216e1 CPFormatter support for CPControl which actually works. 2011-07-07 16:04:11 +02:00
Alexander LjungbergandKlaas Pieter Annema 63b00186f4 Fixed: level indicator warning and critical level ranges should be inclusive. 2011-07-07 16:04:11 +02:00
Alexander LjungbergandKlaas Pieter Annema 110d4c478d Fixed: pressing the up arrow key in a table view would cause a crash if the previous selection was non continuous. 2011-07-07 16:04:11 +02:00
Alexander LjungbergandKlaas Pieter Annema 49c29ded92 Nib2cib support for formatters. 2011-07-07 16:04:11 +02:00
Alexander LjungbergandKlaas Pieter Annema 06670f2214 CPFormatter support for CPControl. 2011-07-07 16:04:11 +02:00
Alexander LjungbergandKlaas Pieter Annema 134bfec615 Temporary numberFromString:. 2011-07-07 16:04:11 +02:00
Alexander LjungbergandKlaas Pieter Annema 279326ffe1 CPNumberFormatter rounding mode support. 2011-07-07 16:04:10 +02:00
Alexander LjungbergandKlaas Pieter Annema ecb04e983e Simple CPNumberFormatter stringFromNumber for CPNumberFormatterDecimalStyle. 2011-07-07 16:04:10 +02:00
Klaas Pieter Annema 73b4c33f05 track if the mouse was released after menu open
Make sure the menu isn't closed by the mouse up that is directly followed by the mouse down that opened the menu.
2011-07-07 16:04:10 +02:00
Klaas Pieter Annema ad30f4dcbb call delegate when submenu open and close 2011-07-07 16:04:10 +02:00
Klaas Pieter Annema 0318587f80 Set the title of a menu item's submenu
Correspond to Cocoa's behavior by automatically having CPMenuItem set the title of it's submenu
2011-07-07 16:04:10 +02:00
Klaas Pieter Annema 2b6fddf26c move menu delegate logic to generic methods 2011-07-07 16:04:04 +02:00
Alexander Ljungberg da61da392b Fixed: initialise CPNumberFormatter maximumFractionalDigits to 3. 2011-07-06 14:08:44 -04:00
Alexander Ljungberg 984b46ba07 Test CPTextField with a formatter. 2011-07-06 13:36:41 -04:00
Alexander Ljungberg 1abce77b3a Merge branch 'master' of github.com:280north/cappuccino 2011-07-06 13:32:46 -04:00
Francisco Ryan Tolmasky I 420606d8e8 Tests for forward invocation.
Reviewed by @tolmasky.
2011-07-02 13:33:53 -07:00
Francisco Ryan Tolmasky I 80c8fd9794 Fix bundletask to include .js files.
Reviewed by @tolmasky.
2011-07-02 08:38:10 -07:00
Antoine Mercadal 1f479c3f20 fix another problem with space in name that prevent launching XCode on the shadow project 2011-07-01 18:28:00 +02:00
Klaas Pieter Annema 0af89853d4 Merge pull request #1311 from aparajita/registerThemeValues-tweak
Added missing type in +registerThemeValues signature
2011-07-01 08:41:29 -07:00
Antoine Mercadal b5bb9c8ec3 fix a bug with NSURL and spaces 2011-07-01 17:29:12 +02:00
Randall Luecke ff13de9f75 Merge branch 'master' of git://github.com/280north/cappuccino 2011-07-01 00:05:19 -07:00
Randall Luecke 47f40eb04b Added left/right arrow key expand and collapse... just for you @tolmasky. 2011-07-01 00:04:09 -07:00
Aparajita Fishman 1ffc7ed6fb Make sure CPPlatformString +sizeOfString and +metricsOfFont work with CommonJS, so that OJUnitTest will work. 2011-06-29 10:52:22 -07:00
Aparajita Fishman 63710d5fae Added missing type in method signature 2011-06-29 09:08:12 -07:00
Klaas Pieter Annema a2ef701d18 Merge branch 'master' of github.com:280north/cappuccino 2011-06-29 16:05:26 +02:00
Klaas Pieter Annema 55e07536d9 don't start dragging if there are no rows 2011-06-29 16:04:46 +02:00
Randall Luecke fc81483371 Fix typeo in CPToolbar.j CPToolbarItems to not respect maxSize. Closes #1305. 2011-06-25 00:45:07 -07:00
Klaas Pieter Annema e552b022ba Merge branch 'pull-request-1302' 2011-06-24 12:21:02 +02:00
Antoine Mercadal af0a479f88 small style fix 2011-06-21 17:18:16 +02:00
Andrea D'Amore 86a28d8cc1 removed warning for Growl's framework path from relase target too 2011-06-21 17:05:00 +02:00
Andrea D'Amore 3dd178a69d fixes warnings while building: Growl bridging protocol, menu delegate, nonexistent framework search path, parser.j compiling 2011-06-21 16:09:21 +02:00
Antoine Mercadal 417334419a display the two last path components in title (usefull for localized bundles) + increase FSEvent latency 2011-06-20 15:37:13 +02:00
Antoine Mercadal 6c34bec51e do not return 0 if any conversion fail (return 2 instead) 2011-06-19 19:32:42 +02:00
Antoine Mercadal c03b3c2d34 use terminationStatus, not lenght of the nib2cib output 2011-06-19 19:24:45 +02:00
Antoine Mercadal e97d4a8e72 fix typo in FS checking 2011-06-19 18:55:06 +02:00
Antoine Mercadal 24d0af3104 warn if something goes wrong about sourcing bash profile path + add quote on paths in NSTasks' arguments 2011-06-18 21:07:15 +02:00
Antoine Mercadal 5790e99359 small style fix 2011-06-16 20:39:29 +02:00
Tobias Adamson 0d6c2c9890 Changed from using system call to NSTask, this enables the app to report on incorrect nib2cib and objj settings and usage.
Examples where a Growl message will now be send to indicate error
1. nib2cib or objj not found in path
2. Compilation errors with objj
3. XIB files with Cocoa components that are not supported yet
2011-06-16 18:57:34 +08:00
Ross Boucher cbabb544ab bootstrap should have a +x bit. 2011-06-15 12:54:11 -07:00
Alexander Ljungberg 42220e057b CPNumberFormatter maximum fractional digits support. Optimise by only creating CPDecimalNumberHandler when needed and caching the result. 2011-06-13 23:19:06 -07:00
Derek Hammer c5df9c973f Making the directions go before the prompt (doh!). Changing bootstrap to
+x.
2011-06-13 21:50:17 -07:00
Alexander Ljungberg 91509e7d36 CPFormatter support for CPControl which actually works. 2011-06-13 18:39:17 -07:00
Derek Hammer b89aa9af0d Merge branch 'master' of git://github.com/280north/cappuccino into include-ojtest 2011-06-12 10:07:15 -07:00
Alexander Ljungberg 4421b55613 Fixed: level indicator warning and critical level ranges should be inclusive. 2011-06-11 04:43:16 -07:00
Alexander Ljungberg 75d9929483 Fixed: pressing the up arrow key in a table view would cause a crash if the previous selection was non continuous. 2011-06-11 04:21:49 -07:00
Alexander Ljungberg 7c78c2ef5d Nib2cib support for formatters. 2011-06-11 03:59:52 -07:00
Alexander Ljungberg 3758c86d20 CPFormatter support for CPControl. 2011-06-11 03:59:33 -07:00
Alexander Ljungberg ada547a79d Temporary numberFromString:. 2011-06-11 03:36:44 -07:00
Alexander Ljungberg 445adcb47f CPNumberFormatter rounding mode support. 2011-06-10 11:41:23 -07:00
Alexander Ljungberg 4e9b975ca8 Simple CPNumberFormatter stringFromNumber for CPNumberFormatterDecimalStyle. 2011-06-10 11:23:36 -07:00
Vladimir Pouzanov 5d26066e02 Fixed dictionaryWithJSObject on arrays with null values 2011-06-08 14:10:10 +03:00
Antoine Mercadal de73d86684 Merge pull request #1 from gustaf-lindqvist/xcodecapp-cocoa-space-in-path-fix
xcodecapp-cocoa space in path fix

Reviewed.
2011-06-08 01:11:02 -07:00
Gustaf Lindqvist d6244f090e Fix white spaces in path for system() 2011-06-08 09:10:28 +02:00
Alexander Ljungberg aac09d8208 Clicking on a non-editable level indicator in a table row now selects that row. 2011-06-06 00:44:15 -04:00
Alexander Ljungberg a127fc9ec3 'Enabled' support for nib2cib of NSLevelIndicator. 2011-06-06 00:35:41 -04:00
Alexander Ljungberg 551aa300ea Merge branch 'master' of github.com:280north/cappuccino 2011-06-06 00:11:23 -04:00
Alexander Ljungberg 485e59b5eb More handlesContentAsCompoundValue, although fairly guess-work based. More research needed in the future. 2011-06-06 00:11:04 -04:00
Alexander Ljungberg fdfcbf1da2 CPArrayController handlesContentAsCompoundValue support for contentArray binding. 2011-06-05 19:39:28 -04:00
Alexander Ljungberg 0f5eee0258 nib2cib compatible CPNumberFormatter skeleton. 2011-06-05 19:27:21 -04:00
Alexander Ljungberg 870492eb96 Fix selection behaviour in previous commit. 2011-06-05 19:19:14 -04:00
Alexander Ljungberg b50005049e Fixed: array controller remove: would not only remove selected rows, but any other rows isEqual: to the selected rows. 2011-06-05 18:57:36 -04:00
Alexander Ljungberg 0e890e19ea Fixed: during CPUserDefault change notifications, objectForKey: could return the value from prior to the change. 2011-06-05 17:32:56 -04:00
Alexander Ljungberg 59aabc150c Crude but functional infinite recursion checker, optional at compile time. 2011-06-04 01:23:24 -04:00
Alexander Ljungberg b159815349 Suppress binding updates support. 2011-06-04 00:57:57 -04:00
Aparajita Fishman 1c44dc1052 Removed unused variable, fixed typo 2011-06-03 18:09:57 -07:00
Alexander Ljungberg bfe5afaddd Whitespace cleanup. 2011-06-03 00:05:30 -04:00
Alexander Ljungberg 64e907156c Minor array controller optimisation: don't send a filterPredicate change notification if clearsFilterPredicateOnInsertion is YES but filterPredicate is already nil when insertObject:atArrangedObjectIndex: is called. 2011-06-03 00:00:39 -04:00
Alexander Ljungberg 5d01ca428c Optimise CPArrayController insertObject:atArrangedObjectIndex: by not attempting to arrange the content array. The given index is only meant for the arrangedObjects. 2011-06-02 23:41:03 -04:00
Aparajita Fishman 4f7fbdc344 Use Menlo if Consolas is not available 2011-06-01 18:22:57 -07:00
Luc Vauvillier 6fe49fbf8d _CPThemeAttribute fix : encode missing _defaultTheme value 2011-06-01 17:02:01 +02:00
Derek Hammer c5f37e665b Adding OJTest installation to the bootstrap.sh file. Also added the
cappuccino/objective-j packages back to the file.
2011-05-31 03:05:24 -07:00
Aparajita Fishman 99180ba001 Enable escape as key equivalent. 2011-05-30 23:20:06 -07:00
Aparajita Fishman 9377cf9128 Test app and unit test to validate pinned ranges in beginsWith/endsWith predicate comparison. 2011-05-26 14:31:20 -07:00
Aparajita Fishman e17d8ca302 Pin ranges to valid values. 2011-05-26 14:31:13 -07:00
Aparajita Fishman acbaa1eec4 Restored space, backspace and escape as key equivalents, but only if the first responder is not a CPTextField. Updated test app to show clearly the effect of this change. 2011-05-23 16:31:52 -07:00
Aparajita Fishman 65b6ff6ecc Fixed set of keys that can be considered a key equivalent, removed redundant call to performKeyEquivalent, test app 2011-05-22 18:05:48 -07:00
Antoine Mercadal df7aa30267 include xcodecapp-cocoa in the Cappuccino build process. 2011-05-21 00:39:50 +02:00
Antoine Mercadal 0f4aab926e add Jakefile to build xcodecapp-cocoa 2011-05-21 00:24:10 +02:00
Antoine Mercadal 7f3512d22c update .gitignore 2011-05-21 00:23:47 +02:00
Antoine Mercadal a6b5ed22b0 make parse.j LGPLv3 2011-05-21 00:02:22 +02:00
Antoine Mercadal e843b31287 update license of xcodecapp-cocoa 2011-05-20 23:39:13 +02:00
Antoine Mercadal 06a5aa45ba Merge remote branch 'xcodecapp-cocoa/master' into xcodecapp-cocoa-merge 2011-05-20 23:34:07 +02:00
Antoine Mercadal 45a5eed62f Merge xcodecapp-cocoa 2011-05-20 23:32:17 +02:00
Antoine Mercadal 188e27e931 update status bar icon 2011-05-20 23:05:41 +02:00
Aparajita Fishman f7a7f06c67 Use CPLog instead of console.log 2011-05-20 08:12:37 -07:00
Antoine Mercadal ed560ed489 display ... when actually doing some jobs 2011-05-20 12:13:28 +02:00
Antoine Mercadal 186eb66f52 Make XCodeCapp-Cocoa a status bar application
+ fix bash_profile, thanks to @natemartinsf
 + add gitignore
2011-05-20 11:59:43 +02:00
Aparajita Fishman 860f0d5846 CPColor and CPImage enhancements
- Enhanced -description method of CPImage and CPColor to show the exact content, especially for pattern colors.

- Added CPColorWithImages() convenience function, analogous to PatternColor() function used in theme descriptors.

- Added @cond/@endcond in CPColor to ignore local variables.

- Sample app included.
2011-05-20 00:23:55 -07:00
Antoine Mercadal 4a7c2a96db compense the y placement 2011-05-17 01:24:54 +02:00
Antoine Mercadal 0b09ada144 Do not truncate bold labels
When label with default size are bold, letter like p, g, q etc,
are truncated like in http://gyazo.com/d6c25af20574a96f9af0f288a7bd802a.png

This commit fix this.
2011-05-17 01:02:53 +02:00
Antoine Mercadal 8b566f06f0 set default build as Universal Binary 2011-04-30 15:50:36 +02:00
Antoine Mercadal 28d174d9d8 handle when user click on cancle on open panel 2011-04-28 18:19:18 +02:00
Antoine Mercadal dd892f746d enable garbage collection + growl support 2011-04-28 18:08:27 +02:00
Antoine Mercadal 95b1b8b19d at first launch, parse all the project in a thread 2011-04-28 17:00:11 +02:00
Antoine Mercadal 298b73ddfc initial commit 2011-04-28 16:35:57 +02:00
cacaodev 4b9695ff50 cache respondsToSelector: ; Fire the timer only if both methods exists 2011-03-24 18:40:25 +01:00
cacaodev a02b721944 CPScrollView: add -scrollView(Will|Did)Change: delegate methods.
CPScroller: send action when dragging starts instead of immediately on mouse down.

Test: added delegate methods to the top-left scroll view in CPScrollView example and log.
2011-03-19 10:17:12 +01:00
cacaodev f60a92d2c4 CPViewAnimation: current frame based on -currentValue. CPAnimation: early return in -currentValue if linear 2011-01-24 20:24:19 +01:00
547 changed files with 47411 additions and 3505 deletions
+1
View File
@@ -9,3 +9,4 @@ WebSite
*.xcodeproj/*.perspectivev3
xcuserdata/
!*.xcodeproj/project.pbxproj
*.xCodeSupport/
+4
View File
@@ -42,6 +42,7 @@
@import "CPCollectionViewItem.j"
@import "CPColor.j"
@import "CPColorPanel.j"
@import "CPColorSpace.j"
@import "CPColorWell.j"
@import "CPCompatibility.j"
@import "CPControl.j"
@@ -55,6 +56,7 @@
@import "CPFont.j"
@import "CPFontManager.j"
@import "CPGeometry.j"
@import "CPGradient.j"
@import "CPGraphics.j"
@import "CPImage.j"
@import "CPImageView.j"
@@ -66,6 +68,7 @@
@import "CPOutlineView.j"
@import "CPPanel.j"
@import "CPPasteboard.j"
@import "CPPopover.j"
@import "CPPopUpButton.j"
@import "CPPredicateEditor.j"
@import "CPPredicateEditorRowTemplate.j"
@@ -98,5 +101,6 @@
@import "CPViewAnimation.j"
@import "CPViewController.j"
@import "CPWebView.j"
@import "CPWorkspace.j"
@import "CPWindow.j"
@import "CPWindowController.j"
+4 -4
View File
@@ -117,7 +117,7 @@ CPCriticalAlertStyle = 2;
*/
+ (CPAlert)alertWithMessageText:(CPString)aMessage defaultButton:(CPString)defaultButtonTitle alternateButton:(CPString)alternateButtonTitle otherButton:(CPString)otherButtonTitle informativeTextWithFormat:(CPString)informativeText
{
var alert = [[CPAlert alloc] init];
var alert = [[self alloc] init];
[alert setMessageText:aMessage];
[alert addButtonWithTitle:defaultButtonTitle];
@@ -142,7 +142,7 @@ CPCriticalAlertStyle = 2;
*/
+ (CPAlert)alertWithError:(CPString)anErrorMessage
{
var alert = [[CPAlert alloc] init];
var alert = [[self alloc] init];
[alert setMessageText:anErrorMessage];
[alert setAlertStyle:CPCriticalAlertStyle];
@@ -371,8 +371,8 @@ CPCriticalAlertStyle = 2;
[_informativeLabel setAlignment:[self currentValueForThemeAttribute:@"informative-text-alignment"]];
[_informativeLabel setLineBreakMode:CPLineBreakByWordWrapping];
informativeLabelWidth = CGRectGetWidth([[_window contentView] frame]) - inset.left - inset.right,
informativeLabelOriginY = [_messageLabel frameOrigin].y + [_messageLabel frameSize].height + defaultElementsMargin,
informativeLabelWidth = CGRectGetWidth([[_window contentView] frame]) - inset.left - inset.right;
informativeLabelOriginY = [_messageLabel frameOrigin].y + [_messageLabel frameSize].height + defaultElementsMargin;
informativeLabelTextSize = [[_informativeLabel stringValue] sizeWithFont:[_informativeLabel font] inWidth:informativeLabelWidth];
[_informativeLabel setFrame:CGRectMake(inset.left, informativeLabelOriginY, informativeLabelTextSize.width, informativeLabelTextSize.height + sizeWithFontCorrection)];
+3
View File
@@ -306,6 +306,9 @@ ACTUAL_FRAME_RATE = 0;
if ([_delegate respondsToSelector:@selector(animation:valueForProgress:)])
return [_delegate animation:self valueForProgress:t];
if (_animationCurve == CPAnimationLinear)
return t;
var c1 = [],
c2 = [];
+7 -7
View File
@@ -338,7 +338,7 @@ CPRunContinuesResponse = -1002;
Copyright - Human readable copyright information.
</pre>
If you choose not the include any of the above keys, they will default
If you choose not the include any of the above keys, they will default
to the following respective keys in your info.plist file.
<pre>
@@ -1003,7 +1003,7 @@ CPRunContinuesResponse = -1002;
}
/*!
Sets the arguments of your application.
Sets the arguments of your application.
That is, set the slash seperated values of an array as the window location hash.
For example if you pass an array:
@@ -1166,12 +1166,12 @@ CPRunContinuesResponse = -1002;
var _CPModalSessionMake = function(aWindow, aStopCode)
{
return { _window:aWindow, _state:CPRunContinuesResponse , _previous:nil };
}
};
var _CPEventListenerMake = function(anEventMask, aCallback)
{
return { _mask:anEventMask, _callback:aCallback };
}
};
// Make this a global for use in CPPlatformWindow+DOM.j.
_CPRunModalLoop = function(anEvent)
@@ -1183,7 +1183,7 @@ _CPRunModalLoop = function(anEvent)
if (theWindow == modalSession._window || [theWindow worksWhenModal])
[theWindow sendEvent:anEvent];
}
};
/*!
Starts the GUI and Cappuccino frameworks. This function should be
@@ -1340,8 +1340,8 @@ var _CPAppBootstrapperActions = nil;
[editMenu addItem:undoMenuItem];
[editMenu addItem:redoMenuItem];
[editMenu addItem:[[CPMenuItem alloc] initWithTitle:@"Cut" action:@selector(cut:) keyEquivalent:@"x"]],
[editMenu addItem:[[CPMenuItem alloc] initWithTitle:@"Copy" action:@selector(copy:) keyEquivalent:@"c"]],
[editMenu addItem:[[CPMenuItem alloc] initWithTitle:@"Cut" action:@selector(cut:) keyEquivalent:@"x"]];
[editMenu addItem:[[CPMenuItem alloc] initWithTitle:@"Copy" action:@selector(copy:) keyEquivalent:@"c"]];
[editMenu addItem:[[CPMenuItem alloc] initWithTitle:@"Paste" action:@selector(paste:) keyEquivalent:@"v"]];
[editMenuItem setSubmenu:editMenu];
+193 -38
View File
@@ -313,6 +313,8 @@
// Don't use [super setContent:] as that would fire the contentObject change.
// We need to be in control of when notifications fire.
// Note that if we have a contentArray binding, setting the content does /not/
// cause a reverse binding set.
_contentObject = value;
if (_clearsFilterPredicateOnInsertion && _filterPredicate != nil)
@@ -562,8 +564,9 @@
- (BOOL)setSelectionIndexes:(CPIndexSet)indexes
{
[self _selectionWillChange]
[self __setSelectionIndexes:indexes];
var r = [self __setSelectionIndexes:indexes avoidEmpty:NO];
[self _selectionDidChange];
return r;
}
/*
@@ -572,7 +575,7 @@
*/
- (BOOL)__setSelectionIndex:(int)theIndex
{
[self __setSelectionIndexes:[CPIndexSet indexSetWithIndex:theIndex]];
return [self __setSelectionIndexes:[CPIndexSet indexSetWithIndex:theIndex]];
}
/*
@@ -581,28 +584,43 @@
*/
- (BOOL)__setSelectionIndexes:(CPIndexSet)indexes
{
if (!indexes)
indexes = [CPIndexSet indexSet];
[self __setSelectionIndexes:indexes avoidEmpty:_avoidsEmptySelection];
}
if (![indexes count])
- (BOOL)__setSelectionIndexes:(CPIndexSet)indexes avoidEmpty:(BOOL)avoidEmpty
{
var newIndexes = indexes;
if (!newIndexes)
newIndexes = [CPIndexSet indexSet];
if (![newIndexes count])
{
if (_avoidsEmptySelection && [[self arrangedObjects] count])
indexes = [CPIndexSet indexSetWithIndex:0];
if (avoidEmpty && [[self arrangedObjects] count])
newIndexes = [CPIndexSet indexSetWithIndex:0];
}
else
{
var objectsCount = [[self arrangedObjects] count];
// Don't trash the input - the caller might depend on it or we might have been
// given _selectionIndexes as the input in which case the equality test below
// would always succeed despite our change below.
newIndexes = [newIndexes copy];
// Remove out of bounds indexes.
[indexes removeIndexesInRange:CPMakeRange(objectsCount, [indexes lastIndex] + 1)];
[newIndexes removeIndexesInRange:CPMakeRange(objectsCount, [newIndexes lastIndex] + 1)];
// When avoiding empty selection and the deleted selection was at the bottom, select the last item.
if (![indexes count] && _avoidsEmptySelection && objectsCount)
indexes = [CPIndexSet indexSetWithIndex:objectsCount - 1];
if (![newIndexes count] && avoidEmpty && objectsCount)
newIndexes = [CPIndexSet indexSetWithIndex:objectsCount - 1];
}
if ([_selectionIndexes isEqualToIndexSet:indexes])
if ([_selectionIndexes isEqualToIndexSet:newIndexes])
return NO;
_selectionIndexes = [indexes copy];
// If we haven't already created our own index instance, make sure to copy it here so that
// the copy the user sent in is decoupled from our internal copy.
_selectionIndexes = indexes === newIndexes ? [indexes copy] : newIndexes;
// Push back the new selection to the model for selectionIndexes if we have one.
// There won't be an infinite loop because of the equality check above.
@@ -634,10 +652,11 @@
[self willChangeValueForKey:@"selectionIndexes"];
[self _selectionWillChange];
[self __setSelectedObjects:objects];
var r = [self __setSelectedObjects:objects avoidEmpty:NO];
[self didChangeValueForKey:@"selectionIndexes"];
[self _selectionDidChange];
return r;
}
/*
@@ -645,6 +664,11 @@
@ignore
*/
- (BOOL)__setSelectedObjects:(CPArray)objects
{
[self __setSelectedObjects:objects avoidEmpty:_avoidsEmptySelection];
}
- (BOOL)__setSelectedObjects:(CPArray)objects avoidEmpty:(BOOL)avoidEmpty
{
var set = [CPIndexSet indexSet],
count = [objects count],
@@ -658,7 +682,7 @@
[set addIndex:index];
}
[self __setSelectionIndexes:set];
[self __setSelectionIndexes:set avoidEmpty:avoidEmpty];
return YES;
}
@@ -737,6 +761,10 @@
*/
_disableSetContent = YES;
[_contentObject addObject:object];
// Allow handlesContentAsCompoundValue reverse sets to trigger.
[[CPBinder getBinding:@"contentArray" forObject:self] _contentArrayDidChange];
_disableSetContent = NO;
if (willClearPredicate)
@@ -771,7 +799,8 @@
}
/*!
Adds an object at a given index to the receiver's collection.
Adds an object at a given index in the receiver's arrangedObjects. Also add the object
to the content collection (although at the end rather than the given index).
@param id anObject - The object to add to the collection.
@param int anIndex - The index to insert the object at.
@@ -781,8 +810,12 @@
if (![self canAdd])
return;
if (_clearsFilterPredicateOnInsertion)
var willClearPredicate = NO;
if (_clearsFilterPredicateOnInsertion && _filterPredicate)
{
[self willChangeValueForKey:@"filterPredicate"];
willClearPredicate = YES;
}
[self willChangeValueForKey:@"content"];
@@ -790,10 +823,17 @@
See _disableSetContent explanation in addObject:.
*/
_disableSetContent = YES;
[_contentObject insertObject:anObject atIndex:anIndex];
// The atArrangedObjectIndex: part of this method's name only refers to where the
// object goes in arrangedObjects, not in the content array. So use addObject:,
// not insertObject:atIndex: here for speed.
[_contentObject addObject:anObject];
// Allow handlesContentAsCompoundValue reverse sets to trigger.
[[CPBinder getBinding:@"contentArray" forObject:self] _contentArrayDidChange];
_disableSetContent = NO;
if (_clearsFilterPredicateOnInsertion)
if (willClearPredicate)
[self __setFilterPredicate:nil];
[[self arrangedObjects] insertObject:anObject atIndex:anIndex];
@@ -809,7 +849,7 @@
[self __setSelectionIndexes:[CPIndexSet indexSetWithIndex:0]];
[self didChangeValueForKey:@"content"];
if (_clearsFilterPredicateOnInsertion)
if (willClearPredicate)
[self didChangeValueForKey:@"filterPredicate"];
}
@@ -820,26 +860,28 @@
*/
- (void)removeObject:(id)object
{
[self willChangeValueForKey:@"content"];
[self willChangeValueForKey:@"content"];
/*
See _disableSetContent explanation in addObject:.
*/
_disableSetContent = YES;
[_contentObject removeObject:object];
_disableSetContent = NO;
// See _disableSetContent explanation in addObject:.
_disableSetContent = YES;
if (_filterPredicate === nil || [_filterPredicate evaluateWithObject:object])
{
[_contentObject removeObject:object];
// Allow handlesContentAsCompoundValue reverse sets to trigger.
[[CPBinder getBinding:@"contentArray" forObject:self] _contentArrayDidChange];
_disableSetContent = NO;
if (_filterPredicate === nil || [_filterPredicate evaluateWithObject:object])
{
// selectionIndexes change notification will be fired as a result of the
// content change. Don't fire manually.
var pos = [_arrangedObjects indexOfObject:object];
[_arrangedObjects removeObjectAtIndex:pos];
[_selectionIndexes shiftIndexesStartingAtIndex:pos by:-1];
}
}
[self didChangeValueForKey:@"content"];
[self didChangeValueForKey:@"content"];
}
/*!
@@ -875,16 +917,61 @@
*/
- (void)remove:(id)sender
{
[self removeObjects:[[self arrangedObjects] objectsAtIndexes:[self selectionIndexes]]];
[self removeObjectsAtArrangedObjectIndexes:_selectionIndexes];
}
/*!
Removes the objects at the specified indexes in the controller's arranged objects from the content array.
@param CPIndexSet indexes - indexes of the objects to remove.
*/
- (void)removeObjectsAtArrangedObjectIndexes:(CPIndexSet)indexes
- (void)removeObjectsAtArrangedObjectIndexes:(CPIndexSet)anIndexSet
{
[self _removeObjects:[[self arrangedObjects] objectsAtIndexes:indexes]];
[self willChangeValueForKey:@"content"];
/*
See _disableSetContent explanation in addObject:.
*/
_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
{
// 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];
// 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];
index = [anIndexSet indexLessThanIndex:index];
}
// Allow handlesContentAsCompoundValue reverse sets to trigger.
[[CPBinder getBinding:@"contentArray" forObject:self] _contentArrayDidChange];
_disableSetContent = NO;
// This will automatically handle the avoidsEmptySelection case.
[self __setSelectionIndexes:newSelectionIndexes];
[self didChangeValueForKey:@"content"];
}
/*!
@@ -904,6 +991,8 @@
[contentArray addObject:[objects objectAtIndex:i]];
[self setContent:contentArray];
// Allow handlesContentAsCompoundValue reverse sets to trigger.
[[CPBinder getBinding:@"contentArray" forObject:self] _contentArrayDidChange];
}
/*!
@@ -922,11 +1011,13 @@
{
[self willChangeValueForKey:@"content"];
/*
See _disableSetContent explanation in addObject:.
*/
// See _disableSetContent explanation in addObject:.
_disableSetContent = YES;
[_contentObject removeObjectsInArray:objects];
// Allow handlesContentAsCompoundValue reverse sets to trigger.
[[CPBinder getBinding:@"contentArray" forObject:self] _contentArrayDidChange];
_disableSetContent = NO;
var arrangedObjects = [self arrangedObjects],
@@ -985,12 +1076,76 @@
var destination = [_info objectForKey:CPObservedObjectKey],
keyPath = [_info objectForKey:CPObservedKeyPathKey],
options = [_info objectForKey:CPOptionsKey],
newValue = [destination mutableArrayValueForKeyPath:keyPath];
isCompound = [self handlesContentAsCompoundValue],
dotIndex = keyPath.lastIndexOf("."),
firstPart = dotIndex !== CPNotFound ? keyPath.substring(0, dotIndex) : nil,
isSelectionProxy = firstPart && [[destination valueForKeyPath:firstPart] isKindOfClass:CPControllerSelectionProxy];
if (!isCompound && !isSelectionProxy)
{
newValue = [destination mutableArrayValueForKeyPath:keyPath];
}
else
{
// 1. If handlesContentAsCompoundValue we cannot just set up a proxy.
// Every read and every write must go through transformValue and
// reverseTransformValue, and the resulting object cannot be described by
// a key path.
// 2. If isSelectionProxy, we don't want to proxy a proxy - that's bad
// for performance and won't work with markers.
newValue = [destination valueForKeyPath:keyPath];
}
var isPlaceholder = CPIsControllerMarker(newValue);
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];
// This seems to be what Cocoa does.
if (!newValue)
newValue = [CPMutableArray array];
}
else
newValue = [self transformValue:newValue withOptions:options];
if (isCompound)
{
// Make sure we can edit our copy of the content. TODO In Cocoa, this copy
// appears to be deferred until the array actually needs to be edited.
newValue = [newValue mutableCopy];
}
newValue = [self transformValue:newValue withOptions:options];
[_source setValue:newValue forKey:aBinding];
}
- (void)_contentArrayDidChange
{
// When handlesContentAsCompoundValue == YES, it is not sufficient to modify the content object
// in place because what we are holding is an array 'unwrapped' from a compound value by
// a value transformer. So when we modify it we need a reverse set and transform to create
// a new compound value.
//
// (The Cocoa documentation on the subject is not very clear but after substantial
// experimentation this seems both reasonable and compliant.)
if ([self handlesContentAsCompoundValue])
{
var destination = [_info objectForKey:CPObservedObjectKey],
keyPath = [_info objectForKey:CPObservedKeyPathKey];
[self suppressSpecificNotificationFromObject:destination keyPath:keyPath];
[self reverseSetValueFor:@"contentArray"];
[self unsuppressSpecificNotificationFromObject:destination keyPath:keyPath];
}
}
@end
var CPArrayControllerAvoidsEmptySelection = @"CPArrayControllerAvoidsEmptySelection",
+1 -2
View File
@@ -20,7 +20,6 @@
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
* Copyright 2009 280 North, Inc.
*/
@import <Foundation/CPObject.j>
@@ -276,7 +275,7 @@ var DefaultLineWidth = 1.0;
/*!
Append the contents of a CPBezierPath object.
*/
- (void)appendBezierPath:(NSBezierPath *)other
- (void)appendBezierPath:(CPBezierPath)other
{
CGPathAddPath(_path, nil, other._path);
}
+129 -6
View File
@@ -35,6 +35,16 @@ CPLineBorder = 1;
CPBezelBorder = 2;
CPGrooveBorder = 3;
// CPTitlePosition
CPNoTitle = 0;
CPAboveTop = 1;
CPAtTop = 2;
CPBelowTop = 3;
CPAboveBottom = 4;
CPAtBottom = 5;
CPBelowBottom = 6;
/*!
@ingroup appkit
@class CPBox
@@ -54,6 +64,10 @@ CPGrooveBorder = 3;
CPSize _contentMargin;
CPView _contentView;
CPString _title @accessors(getter=title);
int _titlePosition @accessors(getter=titlePosition);
CPTextField _titleView;
}
+ (id)boxEnclosingView:(CPView)aView
@@ -61,6 +75,7 @@ CPGrooveBorder = 3;
var box = [[self alloc] initWithFrame:CGRectMakeZero()],
enclosingView = [aView superview];
[box setAutoresizingMask:[aView autoresizingMask]];
[box setFrameFromContentFrame:[aView frame]];
[enclosingView replaceSubview:aView with:box];
@@ -83,6 +98,9 @@ CPGrooveBorder = 3;
_borderWidth = 1.0;
_contentMargin = CGSizeMake(0.0, 0.0);
_titlePosition = CPNoTitle;
_titleView = [CPTextField labelWithTitle:@""];
_contentView = [[CPView alloc] initWithFrame:[self bounds]];
[_contentView setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
@@ -277,18 +295,100 @@ CPGrooveBorder = 3;
- (void)setFrameFromContentFrame:(CPRect)aRect
{
[self setFrame:CGRectInset(aRect, -(_contentMargin.width + _borderWidth), -(_contentMargin.height + _borderWidth))];
var offset = [self _titleHeightOffset];
[self setFrame:CGRectInset(aRect, -(_contentMargin.width + _borderWidth), -(_contentMargin.height + offset[0] + _borderWidth))];
[self setNeedsDisplay:YES];
}
- (void)setTitle:(CPString)aTitle
{
if (aTitle == _title)
return;
_title = aTitle;
[self _manageTitlePositioning];
}
- (void)setTitlePosition:(int)aTitlePotisition
{
if (aTitlePotisition == _titlePosition)
return;
_titlePosition = aTitlePotisition;
[self _manageTitlePositioning];
}
- (void)_manageTitlePositioning
{
if (_titlePosition == CPNoTitle)
{
[_titleView removeFromSuperview];
[self setNeedsDisplay:YES];
return;
}
[_titleView setStringValue:_title];
[_titleView sizeToFit];
[self addSubview:_titleView];
switch (_titlePosition)
{
case CPAtTop:
case CPAboveTop:
case CPBelowTop:
[_titleView setFrameOrigin:CPPointMake(5.0, 0.0)];
[_titleView setAutoresizingMask:CPViewNotSizable];
break;
case CPAboveBottom:
case CPAtBottom:
case CPBelowBottom:
var h = [_titleView frameSize].height;
[_titleView setFrameOrigin:CPPointMake(5.0, [self frameSize].height - h)];
[_titleView setAutoresizingMask:CPViewMinYMargin];
break;
}
[self sizeToFit];
[self setNeedsDisplay:YES];
}
- (void)sizeToFit
{
var contentFrame = [_contentView frame];
var contentFrame = [_contentView frame],
offset = [self _titleHeightOffset];
if (!contentFrame)
return;
[_contentView setAutoresizingMask:CPViewNotSizable];
[self setFrameSize:CGSizeMake(contentFrame.size.width + _contentMargin.width * 2,
contentFrame.size.height + _contentMargin.height * 2)];
contentFrame.size.height + _contentMargin.height * 2 + offset[0])];
[_contentView setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
[_contentView setFrameOrigin:CGPointMake(_contentMargin.width, _contentMargin.height)];
[_contentView setFrameOrigin:CGPointMake(_contentMargin.width, _contentMargin.height + offset[1])];
}
- (float)_titleHeightOffset
{
if (_titlePosition == CPNoTitle)
return [0.0, 0.0];
switch (_titlePosition)
{
case CPAtTop:
return [[_titleView frameSize].height, [_titleView frameSize].height];
case CPAtBottom:
return [[_titleView frameSize].height, 0.0];
default:
return [0.0, 0.0];
}
}
- (void)drawRect:(CPRect)rect
@@ -296,7 +396,7 @@ CPGrooveBorder = 3;
if (_borderType === CPNoBorder)
return;
var bounds = [self bounds];
var bounds = CGRectMakeCopy([self bounds]);
switch (_boxType)
{
@@ -311,6 +411,16 @@ CPGrooveBorder = 3;
break;
}
if (_titlePosition == CPAtTop)
{
bounds.origin.y += [_titleView frameSize].height;
bounds.size.height -= [_titleView frameSize].height;
}
if (_titlePosition == CPAtBottom)
{
bounds.size.height -= [_titleView frameSize].height;
}
switch (_borderType)
{
case CPBezelBorder:
@@ -385,7 +495,10 @@ var CPBoxTypeKey = @"CPBoxTypeKey",
CPBoxFillColorKey = @"CPBoxFillColorKey",
CPBoxCornerRadiusKey = @"CPBoxCornerRadiusKey",
CPBoxBorderWidthKey = @"CPBoxBorderWidthKey",
CPBoxContentMarginKey = @"CPBoxContentMarginKey";
CPBoxContentMarginKey = @"CPBoxContentMarginKey",
CPBoxTitle = @"CPBoxTitle",
CPBoxTitlePosition = @"CPBoxTitlePosition",
CPBoxTitleView = @"CPBoxTitleView";
@implementation CPBox (CPCoding)
@@ -406,10 +519,16 @@ var CPBoxTypeKey = @"CPBoxTypeKey",
_contentMargin = [aCoder decodeSizeForKey:CPBoxContentMarginKey];
_title = [aCoder decodeObjectForKey:CPBoxTitle];
_titlePosition = [aCoder decodeIntForKey:CPBoxTitlePosition];
_titleView = [aCoder decodeObjectForKey:CPBoxTitleView] || [CPTextField labelWithTitle:_title];
_contentView = [self subviews][0];
[self setAutoresizesSubviews:YES];
[_contentView setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
[self _manageTitlePositioning];
}
return self;
@@ -428,6 +547,10 @@ var CPBoxTypeKey = @"CPBoxTypeKey",
[aCoder encodeFloat:_cornerRadius forKey:CPBoxCornerRadiusKey];
[aCoder encodeFloat:_borderWidth forKey:CPBoxBorderWidthKey];
[aCoder encodeObject:_title forKey:CPBoxTitle];
[aCoder encodeInt:_titlePosition forKey:CPBoxTitlePosition];
[aCoder encodeObject:_titleView forKey:CPBoxTitleView];
[aCoder encodeSize:_contentMargin forKey:CPBoxContentMarginKey];
}
+6
View File
@@ -901,6 +901,12 @@ var _CPBrowserResizeControlBackgroundImage = nil;
[_browser _column:_index clickedRow:[selectedIndexes count] === 1 ? [selectedIndexes firstIndex] : -1];
}
- (void)tableViewSelectionDidChange:(CPNotification)aNotification
{
var selectedIndexes = [[aNotification object] selectedRowIndexes];
[_browser selectRowIndexes:selectedIndexes inColumn:_index];
}
- (id)childAtIndex:(unsigned)index
{
return [_delegate browser:_browser child:index ofItem:_item];
+15 -15
View File
@@ -100,6 +100,16 @@ CPCheckBoxImageOffset = 4.0;
{
}
- (void)_updatePlaceholdersWithOptions:(CPDictionary)options
{
[super _updatePlaceholdersWithOptions:options];
[self _setPlaceholder:CPMixedState forMarker:CPMultipleValuesMarker isDefault:YES];
[self _setPlaceholder:CPOffState forMarker:CPNoSelectionMarker isDefault:YES];
[self _setPlaceholder:CPOffState forMarker:CPNotApplicableMarker isDefault:YES];
[self _setPlaceholder:CPOffState forMarker:CPNullMarker isDefault:YES];
}
- (void)setValueFor:(CPString)theBinding
{
var destination = [_info objectForKey:CPObservedObjectKey],
@@ -110,24 +120,14 @@ CPCheckBoxImageOffset = 4.0;
if (isPlaceholder)
{
switch (newValue)
if (newValue === CPNotApplicableMarker && [options objectForKey:CPRaisesForNotApplicableKeysBindingOption])
{
case CPMultipleValuesMarker:
newValue = CPMixedState;
break;
case CPNoSelectionMarker:
newValue = CPOffState;
break;
case CPNotApplicableMarker:
if ([options objectForKey:CPRaisesForNotApplicableKeysBindingOption])
[CPException raise:CPGenericException reason:@"can't transform non applicable key on: "+_source+" value: "+newValue];
newValue = CPOffState;
break;
[CPException raise:CPGenericException
reason:@"can't transform non applicable key on: " + _source + " value: " + newValue];
}
newValue = [self _placeholderForMarker:newValue];
if (newValue === CPMixedState)
{
[_source setAllowsMixedState:YES];
+16 -11
View File
@@ -40,23 +40,23 @@
@par Delegate Methods
@delegate -(void)collectionViewDidChangeSelection:(CPCollectionView)collectionView;
@delegate - (void)collectionViewDidChangeSelection:(CPCollectionView)collectionView;
Called when the selection in the collection view has changed.
@param collectionView the collection view who's selection changed
@delegate -(void)collectionView:(CPCollectionView)collectionView didDoubleClickOnItemAtIndex:(int)index;
@delegate - (void)collectionView:(CPCollectionView)collectionView didDoubleClickOnItemAtIndex:(int)index;
Called when the user double-clicks on an item in the collection view.
@param collectionView the collection view that received the double-click
@param index the index of the item that received the double-click
@delegate -(CPData)collectionView:(CPCollectionView)collectionView dataForItemsAtIndexes:(CPIndexSet)indices forType:(CPString)aType;
@delegate - (CPData)collectionView:(CPCollectionView)collectionView dataForItemsAtIndexes:(CPIndexSet)indices forType:(CPString)aType;
Invoked to obtain data for a set of indices.
@param collectionView the collection view to obtain data for
@param indices the indices to return data for
@param aType the data type
@return a data object containing the index items
@delegate -(CPArray)collectionView:(CPCollectionView)collectionView dragTypesForItemsAtIndexes:(CPIndexSet)indices;
@delegate - (CPArray)collectionView:(CPCollectionView)collectionView dragTypesForItemsAtIndexes:(CPIndexSet)indices;
Invoked to obtain the data types supported by the specified indices for placement on the pasteboard.
@param collectionView the collection view the items reside in
@param indices the indices to obtain drag types
@@ -340,19 +340,21 @@
*/
- (void)setSelectionIndexes:(CPIndexSet)anIndexSet
{
if ([_selectionIndexes isEqual:anIndexSet] || !_isSelectable)
if (!anIndexSet)
anIndexSet = [CPIndexSet indexSet];
if (!_isSelectable || [_selectionIndexes isEqual:anIndexSet])
return;
var index = CPNotFound;
while ((index = [_selectionIndexes indexGreaterThanIndex:index]) != CPNotFound)
while ((index = [_selectionIndexes indexGreaterThanIndex:index]) !== CPNotFound)
[_items[index] setSelected:NO];
_selectionIndexes = anIndexSet;
var index = CPNotFound;
while ((index = [_selectionIndexes indexGreaterThanIndex:index]) != CPNotFound)
while ((index = [_selectionIndexes indexGreaterThanIndex:index]) !== CPNotFound)
[_items[index] setSelected:YES];
var binderClass = [[self class] _binderClassForBinding:@"selectionIndexes"];
@@ -473,7 +475,7 @@
}
var superview = [self superview],
proposedHeight = y + itemSize.height + _verticalMargin;
proposedHeight = y + itemSize.height + _verticalMargin;
if ([superview isKindOfClass:[CPClipView class]])
{
@@ -559,6 +561,8 @@
*/
- (void)setMinItemSize:(CGSize)aSize
{
if (aSize === nil || aSize === undefined)
[CPException raise:CPInvalidArgumentException reason:"Invalid value provided for minimum size"];
if (CGSizeEqualToSize(_minItemSize, aSize))
return;
@@ -965,14 +969,15 @@ var CPCollectionViewMinItemSizeKey = @"CPCollectionViewMinItemSizeK
{
[super awakeFromCib];
if (CGSizeEqualToSize(_minItemSize, CGSizeMakeZero()) || CGSizeEqualToSize(_maxItemSize, CGSizeMakeZero()))
var prototypeView = [_itemPrototype view];
if (prototypeView && (CGSizeEqualToSize(_minItemSize, CGSizeMakeZero()) || CGSizeEqualToSize(_maxItemSize, CGSizeMakeZero())))
{
var item = _itemPrototype;
if (CGSizeEqualToSize(_minItemSize, CGSizeMakeZero()))
_minItemSize = [[item view] frameSize];
_minItemSize = [prototypeView frameSize];
else if (CGSizeEqualToSize(_maxItemSize, CGSizeMakeZero()))
_maxItemSize = [[item view] frameSize];
_maxItemSize = [prototypeView frameSize];
}
}
+134 -23
View File
@@ -27,6 +27,7 @@
@import "CPCompatibility.j"
@import "CPImage.j"
/// @cond IGNORE
var _redComponent = 0,
_greenComponent = 1,
@@ -54,6 +55,66 @@ var cachedBlackColor,
cachedShadowColor,
cachedClearColor;
/// @endcond
/*!
Orientation to use with \c CPColorPattern for vertical patterns.
*/
CPColorPatternIsVertical = YES;
/*!
Orientation to use with \c CPColorPattern for horizontal patterns.
*/
CPColorPatternIsHorizontal = NO;
/*!
To create a simple color with a pattern image:
<code>CPColorWithImages(name, width, height{, bundle})</code>
To create a color with a three part pattern image:
<code>CPColorWithImages(slices{, orientation})</code>
where slices is an array of three [name, width, height{, bundle}] arrays,
and orientation is \c CPColorPatternIsVertical or \ref CPColorPatternIsHorizontal.
If orientatation is not passed, it defaults to \ref CPColorPatternIsHorizontal.
To create a color with a nine part pattern image:
<code>CPColorWithImages(slices);</code>
where slices is an array of nine [name, width, height{, bundle}] arrays.
*/
function CPColorWithImages()
{
if (arguments.length < 3)
{
var slices = arguments[0],
imageSlices = [];
for (var i = 0; i < slices.length; ++i)
{
var slice = slices[i];
imageSlices.push(slice ? CPImageInBundle(slice[0], CGSizeMake(slice[1], slice[2]), slice[3]) : nil);
}
if (imageSlices.length === 3)
return [CPColor colorWithPatternImage:[[CPThreePartImage alloc] initWithImageSlices:imageSlices isVertical:arguments[1] || CPColorPatternIsHorizontal]];
else
return [CPColor colorWithPatternImage:[[CPNinePartImage alloc] initWithImageSlices:imageSlices]];
}
else if (arguments.length === 3 || arguments.length === 4)
{
return [CPColor colorWithPatternImage:CPImageInBundle(arguments[0], CGSizeMake(arguments[1], arguments[2]), arguments[3])];
}
else
{
return nil;
}
}
/*!
@ingroup appkit
@@ -72,7 +133,7 @@ var cachedBlackColor,
}
/*!
Creates a color in the RGB color space, with an alpha value.
Creates a color in the RGB colorspace, with an alpha value.
Each component should be between the range of 0.0 to 1.0. For
the alpha component, a value of 1.0 is opaque, and 0.0 means
completely transparent.
@@ -86,13 +147,13 @@ var cachedBlackColor,
*/
+ (CPColor)colorWithRed:(float)red green:(float)green blue:(float)blue alpha:(float)alpha
{
return [[CPColor alloc] _initWithRGBA:[red, green, blue, alpha]];
return [[CPColor alloc] _initWithRGBA:[MAX(0.0, MIN(1.0, red)), MAX(0.0, MIN(1.0, green)), MAX(0.0, MIN(1.0, blue)), MAX(0.0, MIN(1.0, alpha))]];
}
/*!
@deprecated in favor of colorWithRed:green:blue:alpha:
Creates a color in the RGB color space, with an alpha value.
Creates a color in the RGB colorspace, with an alpha value.
Each component should be between the range of 0.0 to 1.0. For
the alpha component, a value of 1.0 is opaque, and 0.0 means
completely transparent.
@@ -167,12 +228,12 @@ var cachedBlackColor,
switch (FLOOR(hue / 60))
{
case 0: return [CPColor colorWithCalibratedRed: b green: t blue: p alpha: alpha];
case 1: return [CPColor colorWithCalibratedRed: q green: b blue: p alpha: alpha];
case 2: return [CPColor colorWithCalibratedRed: p green: b blue: t alpha: alpha];
case 3: return [CPColor colorWithCalibratedRed: p green: q blue: b alpha: alpha];
case 4: return [CPColor colorWithCalibratedRed: t green: p blue: b alpha: alpha];
case 5: return [CPColor colorWithCalibratedRed: b green: p blue: q alpha: alpha];
case 0: return [CPColor colorWithCalibratedRed:b green:t blue:p alpha:alpha];
case 1: return [CPColor colorWithCalibratedRed:q green:b blue:p alpha:alpha];
case 2: return [CPColor colorWithCalibratedRed:p green:b blue:t alpha:alpha];
case 3: return [CPColor colorWithCalibratedRed:p green:q blue:b alpha:alpha];
case 4: return [CPColor colorWithCalibratedRed:t green:p blue:b alpha:alpha];
case 5: return [CPColor colorWithCalibratedRed:b green:p blue:q alpha:alpha];
}
}
@@ -192,6 +253,17 @@ var cachedBlackColor,
return rgba ? [[CPColor alloc] _initWithRGBA: rgba] : null;
}
/*!
Creates a color in the sRGB colorspace with the given components and alpha values.
Values below 0.0 are treated as 0.0 and values above 1.0 are treated as 1.0.
*/
+ (CPColor)colorWithSRGBRed:(float)red green:(float)green blue:(float)blue alpha:(float)alpha
{
// TODO If Cappuccino is ported to a colorspace aware platform, this color should be in
// sRGBColorSpace.
return [self colorWithRed:red green:green blue:blue alpha:alpha];
}
/*!
Returns a black color object. (RGBA=[0.0, 0.0, 0.0, 1.0])
*/
@@ -419,7 +491,9 @@ var cachedBlackColor,
parts[3] ? parseFloat(parts[3], 10) : 1.0
];
_cssString = aString;
// We can't reuse aString as _cssString because the browser might not support the `rgba` syntax, and aString might
// use it (issue #1413.)
[self _initCSSStringFromComponents];
return self;
}
@@ -433,18 +507,23 @@ var cachedBlackColor,
{
_components = components;
var hasAlpha = CPFeatureIsCompatible(CPCSSRGBAFeature) && _components[3] != 1.0;
_cssString = (hasAlpha ? "rgba(" : "rgb(") +
parseInt(_components[0] * 255.0) + ", " +
parseInt(_components[1] * 255.0) + ", " +
parseInt(_components[2] * 255.0) +
(hasAlpha ? (", " + _components[3]) : "") + ")";
[self _initCSSStringFromComponents];
}
return self;
}
- (void)_initCSSStringFromComponents
{
var hasAlpha = CPFeatureIsCompatible(CPCSSRGBAFeature) && _components[3] != 1.0;
_cssString = (hasAlpha ? "rgba(" : "rgb(") +
parseInt(_components[0] * 255.0) + ", " +
parseInt(_components[1] * 255.0) + ", " +
parseInt(_components[2] * 255.0) +
(hasAlpha ? (", " + _components[3]) : "") + ")";
}
/* @ignore */
- (id)_initWithPatternImage:(CPImage)anImage
{
@@ -633,7 +712,36 @@ url("data:image/png;base64,BASE64ENCODEDDATA") // if there is a pattern image
- (CPString)description
{
return [super description]+" "+[self cssString];
var description = [super description],
patternImage = [self patternImage];
if (!patternImage)
return description + " " + [self cssString];
description += " {\n";
if ([patternImage isThreePartImage] || [patternImage isNinePartImage])
{
var slices = [patternImage imageSlices];
if ([patternImage isThreePartImage])
description += " orientation: " + ([patternImage isVertical] ? "vertical" : "horizontal") + ",\n";
description += " patternImage (" + slices.length + " part): [\n";
for (var i = 0; i < slices.length; ++i)
{
var imgDescription = [slices[i] description];
description += imgDescription.replace(/^/mg, " ") + ",\n";
}
description = description.substr(0, description.length - 2) + "\n ]\n}";
}
else
description += [patternImage description].replace(/^/mg, " ") + "\n}";
return description;
}
@end
@@ -678,8 +786,10 @@ url("data:image/png;base64,BASE64ENCODEDDATA") // if there is a pattern image
@end
/// @cond IGNORE
var CPColorComponentsKey = @"CPColorComponentsKey",
CPColorPatternImageKey = @"CPColorPatternImageKey";
/// @endcond
@implementation CPColor (CPCoding)
@@ -710,13 +820,12 @@ var CPColorComponentsKey = @"CPColorComponentsKey",
@end
/// @cond IGNORE
var hexCharacters = "0123456789ABCDEF";
/*!
Used for the CPColor \c +colorWithHexString: implementation
@ignore
@class CPColor
@return an array of rgb components
/*
Used for the CPColor +colorWithHexString: implementation.
Returns an array of rgb components.
*/
var hexToRGB = function(hex)
{
@@ -754,3 +863,5 @@ var byteToHex = function(n)
return hexCharacters.charAt((n - n % 16) / 16) +
hexCharacters.charAt(n % 16);
};
/// @endcond
+1 -1
View File
@@ -51,7 +51,7 @@ CPWheelColorPickerMode = 1;
*/
CPSliderColorPickerMode = 2;
CPColorPickerViewWidth = 265,
CPColorPickerViewWidth = 265;
CPColorPickerViewHeight = 370;
/*!
+62
View File
@@ -0,0 +1,62 @@
/*
* CPColorSpace.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
*/
var sRGBColorSpace = nil;
/*!
Represent color spaces.
*/
@implementation CPColorSpace : CPObject
{
CGColorSpace _cgColorSpace;
}
/*!
Return an object representing the standard sRGB color space.
*/
+ (CPColorSpace)sRGBColorSpace
{
if (!sRGBColorSpace)
sRGBColorSpace = [[self alloc] initWithCGColorSpace:CGColorSpaceCreateDeviceRGB()];
return sRGBColorSpace;
}
- (id)initWithCGColorSpace:(CGColorSpace)cgColorSpace
{
if (self = [super init])
{
_cgColorSpace = cgColorSpace;
}
return self;
}
/*!
Return a Core Graphics color space representing the receiver.
*/
- (CGColorSpace)CGColorSpace
{
return _cgColorSpace;
}
@end
+58
View File
@@ -46,6 +46,22 @@ var _CPColorWellDidBecomeExclusiveNotification = @"_CPColorWellDidBecomeExclusiv
CPView _wellView;
}
+ (Class)_binderClassForBinding:(CPString)theBinding
{
if (theBinding == CPValueBinding)
return [CPColorWellValueBinder class];
return [super _binderClassForBinding:theBinding];
}
- (void)_reverseSetBinding
{
var binderClass = [[self class] _binderClassForBinding:CPValueBinding],
theBinding = [binderClass getBinding:CPValueBinding forObject:self];
[theBinding reverseSetValueFor:@"color"];
}
- (id)initWithFrame:(CGRect)aFrame
{
self = [super initWithFrame:aFrame];
@@ -262,6 +278,48 @@ var _CPColorWellDidBecomeExclusiveNotification = @"_CPColorWellDidBecomeExclusiv
@end
@implementation CPColorWellValueBinder : CPBinder
{
}
- (void)_updatePlaceholdersWithOptions:(CPDictionary)options
{
var placeholderColor = [CPColor blueColor];
[self _setPlaceholder:placeholderColor forMarker:CPMultipleValuesMarker isDefault:YES];
[self _setPlaceholder:placeholderColor forMarker:CPNoSelectionMarker isDefault:YES];
[self _setPlaceholder:placeholderColor forMarker:CPNotApplicableMarker isDefault:YES];
[self _setPlaceholder:placeholderColor forMarker:CPNullMarker isDefault:YES];
}
- (void)setValueFor:(CPString)theBinding
{
var destination = [_info objectForKey:CPObservedObjectKey],
keyPath = [_info objectForKey:CPObservedKeyPathKey],
options = [_info objectForKey:CPOptionsKey],
newValue = [destination valueForKeyPath:keyPath],
isPlaceholder = CPIsControllerMarker(newValue);
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];
}
else
{
newValue = [self transformValue:newValue withOptions:options];
}
[_source setColor:newValue];
}
@end
var CPColorWellColorKey = "CPColorWellColorKey",
CPColorWellBorderedKey = "CPColorWellBorderedKey";
+41 -8
View File
@@ -20,6 +20,9 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#import "../Foundation/Ref.h"
@import "../Foundation/CPFormatter.j"
@import "CPFont.j"
@import "CPShadow.j"
@import "CPView.j"
@@ -82,6 +85,7 @@ var CPControlBlackColor = [CPColor blackColor];
@implementation CPControl : CPView
{
id _value;
CPFormatter _formatter @accessors(property=formatter);
// Target-Action Support
id _target;
@@ -221,10 +225,11 @@ var CPControlBlackColor = [CPColor blackColor];
@param anAction the action to send
@param anObject the object to which the action will be sent
*/
- (void)sendAction:(SEL)anAction to:(id)anObject
- (BOOL)sendAction:(SEL)anAction to:(id)anObject
{
[self _reverseSetBinding];
[CPApp sendAction:anAction to:anObject from:self];
return [CPApp sendAction:anAction to:anObject from:self];
}
- (int)sendActionOn:(int)mask
@@ -502,15 +507,46 @@ var CPControlBlackColor = [CPColor blackColor];
*/
- (CPString)stringValue
{
if (_formatter && _value !== undefined && _value !== nil)
{
var formattedValue = [self hasThemeState:CPThemeStateEditing] ? [_formatter editingStringForObjectValue:_value] : [_formatter stringForObjectValue:_value];
if (formattedValue !== nil && formattedValue !== undefined)
return formattedValue;
}
return (_value === undefined || _value === nil) ? "" : String(_value);
}
/*!
Sets the receiver's string value.
*/
- (void)setStringValue:(CPString)anObject
- (void)setStringValue:(CPString)aString
{
[self setObjectValue:anObject];
// Cocoa raises an invalid parameter assertion and returns if you pass nil.
if (aString === nil || aString === undefined)
{
CPLog.warn("nil sent to CPControl -setStringValue");
return;
}
var value;
if (_formatter)
{
value = nil;
if ([_formatter getObjectValue:AT_REF(value) forString:aString errorDescription:nil] === NO)
{
// If the given string is non-empty and doesn't work, Cocoa tries an empty string.
if (!aString || [_formatter getObjectValue:AT_REF(value) forString:@"" errorDescription:nil] === NO)
value = undefined; // Means the value is invalid
}
}
else
value = aString;
[self setObjectValue:value];
}
- (void)takeDoubleValueFrom:(id)sender
@@ -526,21 +562,18 @@ var CPControlBlackColor = [CPColor blackColor];
[self setFloatValue:[sender floatValue]];
}
- (void)takeIntegerValueFrom:(id)sender
{
if ([sender respondsToSelector:@selector(integerValue)])
[self setIntegerValue:[sender integerValue]];
}
- (void)takeIntValueFrom:(id)sender
{
if ([sender respondsToSelector:@selector(intValue)])
[self setIntValue:[sender intValue]];
}
- (void)takeObjectValueFrom:(id)sender
{
if ([sender respondsToSelector:@selector(objectValue)])
@@ -882,7 +915,7 @@ var __Deprecated__CPImageViewImageKey = @"CPImageViewImageKey";
if (_target !== nil)
[aCoder encodeConditionalObject:_target forKey:CPControlTargetKey];
if (_action !== NULL)
if (_action !== nil)
[aCoder encodeObject:_action forKey:CPControlActionKey];
[aCoder encodeInt:_sendActionOn forKey:CPControlSendActionOnKey];
+2 -2
View File
@@ -922,9 +922,9 @@ var CPDocumentUntitledCount = 0;
var _CPReadSessionMake = function(aType, aDelegate, aDidReadSelector, aContextInfo)
{
return { fileType:aType, delegate:aDelegate, didReadSelector:aDidReadSelector, contextInfo:aContextInfo };
}
};
var _CPSaveSessionMake = function(anAbsoluteURL, aSaveOperation, aChangeCount, aDelegate, aDidSaveSelector, aContextInfo, aConnection)
{
return { absoluteURL:anAbsoluteURL, saveOperation:aSaveOperation, changeCount:aChangeCount, delegate:aDelegate, didSaveSelector:aDidSaveSelector, contextInfo:aContextInfo, connection:aConnection };
}
};
+16 -21
View File
@@ -571,31 +571,27 @@ var _CPEventPeriodicEventPeriod = 0,
if (_modifierFlags & (CPCommandKeyMask | CPControlKeyMask))
return YES;
// Cocoa allows almost any key as a key equivalent unless the first responder is a
// text field (presumably a subclass of NSText.)
var firstResponderIsText = [[_window firstResponder] isKindOfClass:[CPTextField class]];
// Some keys are accepted as key equivalents even if the first responder is a text
// field.
for (var i = 0; i < characterCount; i++)
{
switch (_characters.charAt(i))
var c = _characters.charAt(i);
if ((c >= CPUpArrowFunctionKey && c <= CPModeSwitchFunctionKey) ||
c === CPEnterCharacter ||
c === CPNewlineCharacter ||
c === CPCarriageReturnCharacter ||
c === CPEscapeFunctionKey)
{
case CPBackspaceCharacter:
case CPDeleteCharacter:
case CPDeleteFunctionKey:
case CPTabCharacter:
case CPCarriageReturnCharacter:
case CPNewlineCharacter:
case CPSpaceFunctionKey:
case CPEscapeFunctionKey:
case CPPageUpFunctionKey:
case CPPageDownFunctionKey:
case CPLeftArrowFunctionKey:
case CPUpArrowFunctionKey:
case CPRightArrowFunctionKey:
case CPDownArrowFunctionKey:
case CPEndFunctionKey:
case CPHomeFunctionKey:
return YES;
return YES;
}
}
// FIXME: More cases?
return NO;
return !firstResponderIsText;
}
/*!
@@ -651,4 +647,3 @@ function _CPEventFromNativeMouseEvent(aNativeEvent, anEventType, aPoint, modifie
return aNativeEvent;
}
+8 -8
View File
@@ -142,7 +142,7 @@ var _CPFonts = {},
*/
+ (CPFont)fontWithName:(CPString)aName size:(float)aSize
{
return _CPCachedFont(aName, aSize, NO, NO) || [[CPFont alloc] _initWithName:aName size:aSize bold:NO italic:NO];
return [CPFont fontWithName:aName size:aSize bold:NO italic:NO];
}
/*!
@@ -154,7 +154,7 @@ var _CPFonts = {},
*/
+ (CPFont)fontWithName:(CPString)aName size:(float)aSize italic:(BOOL)italic
{
return _CPCachedFont(aName, aSize, NO, NO) || [[CPFont alloc] _initWithName:aName size:aSize bold:NO italic:italic];
return [CPFont fontWithName:aName size:aSize bold:NO italic:italic];
}
/*!
@@ -165,7 +165,7 @@ var _CPFonts = {},
*/
+ (CPFont)boldFontWithName:(CPString)aName size:(float)aSize
{
return _CPCachedFont(aName, aSize, YES, NO) || [[CPFont alloc] _initWithName:aName size:aSize bold:YES italic:NO];
return [CPFont fontWithName:aName size:aSize bold:YES italic:NO];
}
/*!
@@ -177,7 +177,7 @@ var _CPFonts = {},
*/
+ (CPFont)boldFontWithName:(CPString)aName size:(float)aSize italic:(BOOL)italic
{
return _CPCachedFont(aName, aSize, NO, NO) || [[CPFont alloc] _initWithName:aName size:aSize bold:YES italic:italic];
return [CPFont fontWithName:aName size:aSize bold:YES italic:italic];
}
/*!
@@ -187,7 +187,7 @@ var _CPFonts = {},
*/
+ (CPFont)systemFontOfSize:(CPSize)aSize
{
return _CPCachedFont(_CPFontSystemFontFace, aSize, NO, NO) || [[CPFont alloc] _initWithName:_CPFontSystemFontFace size:aSize bold:NO italic:NO];
return [CPFont fontWithName:_CPFontSystemFontFace size:aSize bold:NO italic:NO];
}
/*!
@@ -197,15 +197,15 @@ var _CPFonts = {},
*/
+ (CPFont)boldSystemFontOfSize:(CPSize)aSize
{
return _CPCachedFont(_CPFontSystemFontFace, aSize, YES, NO) || [[CPFont alloc] _initWithName:_CPFontSystemFontFace size:aSize bold:YES italic:NO];
return [CPFont fontWithName:_CPFontSystemFontFace size:aSize bold:YES italic:NO];
}
/* FIXME Font Descriptor
@ignore
*/
- (id)_initWithName:(CPString)aName size:(float)aSize bold:(BOOL)isBold
+ (CPFont)fontWithName:(CPString)aName size:(float)aSize bold:(BOOL)bold italic:(BOOL)italic
{
return [self _initWithName:aName size:aSize bold:isBold italic:NO];
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
+3 -3
View File
@@ -143,7 +143,7 @@ var _CPFontDetectFontAvailable = function(font)
if (_CPFontDetectCompareFonts(_CPFontDetectReferenceFonts[i], font))
return true;
return false;
}
};
var _CPFontDetectCache = {};
@@ -165,7 +165,7 @@ var _CPFontDetectCompareFonts = function(fontA, fontB)
bHeight = _CPFontDetectSpan.offsetHeight;
return (a.w != bWidth || a.h != bHeight);
}
};
// Test the candidate fonts pairwise until we find two that are different. Otherwise return the first.
var _CPFontDetectPickTwoDifferentFonts = function(candidates)
@@ -175,6 +175,6 @@ var _CPFontDetectPickTwoDifferentFonts = function(candidates)
if (_CPFontDetectCompareFonts(candidates[i], candidates[j]))
return [candidates[i], candidates[j]];
return [candidates[0]];
}
};
[CPFontManager setFontManagerFactory:[CPFontManager class]];
+123
View File
@@ -0,0 +1,123 @@
/*
* CPGradient.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
*/
CPGradientDrawsBeforeStartingLocation = kCGGradientDrawsBeforeStartLocation;
CPGradientDrawsAfterEndingLocation = kCGGradientDrawsAfterEndLocation;
/*!
A class for drawing linear and radial gradients with a convenient API.
*/
@implementation CPGradient : CPObject
{
CGGradient _gradient;
}
- (id)initWithColors:(CPArray)someColors
{
var count = [someColors count];
if (count < 2)
[CPException raise:CPInvalidArgumentException reason:@"at least 2 colors required"];
var distance = 1.0 / (count - 1),
locations = [CPMutableArray array],
location = 0.0;
for (var i = 0; i < count; i++)
{
[locations addObject:location];
location += distance;
}
return [self initWithColors:someColors atLocations:locations colorSpace:nil];
}
- (id)initWithColors:(CPArray)someColors atLocations:(CPArray)someLocations colorSpace:(CPColorSpace)aColorSpace
{
if (self = [super init])
{
var cgColors = [],
count = [someColors count],
colorSpace = [aColorSpace CGColorSpace] || CGColorSpaceCreateDeviceRGB;
for (var i = 0; i < count; i++)
cgColors.push(CGColorCreate(colorSpace, [someColors[i] components]));
_gradient = CGGradientCreateWithColors(colorSpace, cgColors, someLocations);
}
return self;
}
- (void)drawInRect:(CGRect)rect angle:(float)angle
{
var ctx = [[CPGraphicsContext currentContext] graphicsPort];
CGContextSaveGState(ctx);
CGContextClipToRect(ctx, rect);
CGContextAddRect(ctx, rect);
var startPoint,
endPoint;
// Modulo of negative values doesn't work as expected in JS.
angle = ((angle % 360.0) + 360.0) % 360.0;
if (angle < 90.0)
startPoint = _CGPointMake(_CGRectGetMinX(rect), _CGRectGetMinY(rect));
else if (angle < 180.0)
startPoint = _CGPointMake(_CGRectGetMaxX(rect), _CGRectGetMinY(rect));
else if (angle < 270.0)
startPoint = _CGPointMake(_CGRectGetMaxX(rect), _CGRectGetMaxY(rect));
else
startPoint = _CGPointMake(_CGRectGetMinX(rect), _CGRectGetMaxY(rect));
// A line segment comes out of the starting point at the given angle, with the first colour
// at the starting point and the last at the end. To do what drawInRect: is supposed to do
// we want the opposite corner of the starting corner to just reach the final colour stop.
// So when the angle isn't a right angle, the segment has to extend beyond the edge of the
// rectangle just far enough. This is hard to describe without a picture but if we place
// another line through the opposite corner at -90 degrees, it'll help form some triangles
// from which we can derive this formula:
//
// length = cos(angle) * (rectWidth + rectHeight * tan(angle))
//
// This simplifies down to (in the first quadrant) rectWidth * cos(a) + rectHeight * sin(a).
var radians = PI * angle / 180.0,
length = ABS(_CGRectGetWidth(rect) * COS(radians)) + ABS(_CGRectGetHeight(rect) * SIN(radians));
endPoint = _CGPointMake(startPoint.x + length * COS(radians),
startPoint.y + length * SIN(radians));
[self drawFromPoint:startPoint toPoint:endPoint options:CPGradientDrawsBeforeStartingLocation | CPGradientDrawsAfterEndingLocation];
CGContextRestoreGState(ctx);
}
- (void)drawFromPoint:(NSPoint)startingPoint toPoint:(NSPoint)endingPoint options:(NSGradientDrawingOptions)options
{
var ctx = [[CPGraphicsContext currentContext] graphicsPort];
// TODO kCGGradientDrawsBeforeStartLocation and kCGGradientDrawsAfterEndLocation are not actually supported
// by CGContextDrawLinearGradient yet.
CGContextDrawLinearGradient(ctx, _gradient, startingPoint, endingPoint, options);
}
@end
+13
View File
@@ -86,4 +86,17 @@ var CPGraphicsContextCurrent = nil;
return _graphicsPort;
}
/*!
(Not implemented. Always returns Cappuccino's default, `YES`.)
Return `isFlipped` of the receiver's focused view, unless no view is focused in which case the receiver's
`flipped` flag, as set by `graphicsContextWithGraphicsPort:flipped:`, is returned.
Note: Cappuccino is flipped by default.
*/
- (BOOL)isFlipped
{
return YES;
}
@end
+23 -4
View File
@@ -44,7 +44,8 @@ CPImageNameColorPanel = @"CPImageNameColorPanel";
CPImageNameColorPanelHighlighted = @"CPImageNameColorPanelHighlighted";
var imagesForNames = { },
AppKitImageForNames = { };
AppKitImageForNames = { },
ImageDescriptionFormat = "%s {\n filename: \"%s\",\n size: { width:%f, height:%f }\n}";
AppKitImageForNames[CPImageNameColorPanel] = CGSizeMake(26.0, 29.0);
AppKitImageForNames[CPImageNameColorPanelHighlighted] = CGSizeMake(26.0, 29.0);
@@ -280,7 +281,7 @@ function CPAppKitImage(aFilename, aSize)
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
}
[self _derefFromImage];
}
};
_image.onerror = function ()
{
@@ -292,7 +293,7 @@ function CPAppKitImage(aFilename, aSize)
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
}
[self _derefFromImage];
}
};
_image.onabort = function ()
{
@@ -304,7 +305,7 @@ function CPAppKitImage(aFilename, aSize)
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
}
[self _derefFromImage];
}
};
_image.src = _filename;
@@ -324,6 +325,24 @@ function CPAppKitImage(aFilename, aSize)
return NO;
}
- (CPString)description
{
var filename = [self filename],
size = [self size];
if (filename.indexOf("data:") === 0)
{
var index = filename.indexOf(",");
if (index > 0)
filename = [CPString stringWithFormat:@"%s,%s...%s", filename.substr(0, index), filename.substr(index + 1, 10), filename.substr(filename.length - 10)];
else
filename = "data:<unknown type>";
}
return [CPString stringWithFormat:ImageDescriptionFormat, [super description], filename, size.width, size.height];
}
/* @ignore */
- (void)_derefFromImage
{
+4 -12
View File
@@ -41,15 +41,7 @@ CPImageAlignBottomLeft = 6;
CPImageAlignBottomRight = 7;
CPImageAlignRight = 8;
var CPImageViewShadowBackgroundColor = nil,
CPImageViewEmptyPlaceholderImage = nil;
var LEFT_SHADOW_INSET = 3.0,
RIGHT_SHADOW_INSET = 3.0,
TOP_SHADOW_INSET = 3.0,
BOTTOM_SHADOW_INSET = 5.0,
VERTICAL_SHADOW_INSET = TOP_SHADOW_INSET + BOTTOM_SHADOW_INSET,
HORIZONTAL_SHADOW_INSET = LEFT_SHADOW_INSET + RIGHT_SHADOW_INSET;
var CPImageViewEmptyPlaceholderImage = nil;
/*!
@ingroup appkit
@@ -297,8 +289,8 @@ var LEFT_SHADOW_INSET = 3.0,
imageScaling = [self currentValueForThemeAttribute:@"image-scaling"],
x = 0.0,
y = 0.0,
insetWidth = (_hasShadow ? HORIZONTAL_SHADOW_INSET : 0.0),
insetHeight = (_hasShadow ? VERTICAL_SHADOW_INSET : 0.0),
insetWidth = (_hasShadow ? [_shadowView horizontalInset] : 0.0),
insetHeight = (_hasShadow ? [_shadowView verticalInset] : 0.0),
boundsWidth = _CGRectGetWidth(bounds),
boundsHeight = _CGRectGetHeight(bounds),
width = boundsWidth - insetWidth,
@@ -406,7 +398,7 @@ var LEFT_SHADOW_INSET = 3.0,
_imageRect = _CGRectMake(x, y, width, height);
if (_hasShadow)
[_shadowView setFrame:_CGRectMake(x - LEFT_SHADOW_INSET, y - TOP_SHADOW_INSET, width + insetWidth, height + insetHeight)];
[_shadowView setFrame:_CGRectMake(x - [_shadowView leftInset], y - [_shadowView topInset], width + insetWidth, height + insetHeight)];
}
- (void)mouseDown:(CPEvent)anEvent
+95 -8
View File
@@ -39,6 +39,9 @@ var CPBindingOperationAnd = 0,
{
CPDictionary _info;
id _source;
JSObject _suppressedNotifications;
JSObject _placeholderForMarker;
}
+ (void)exposeBinding:(CPString)aBinding forClass:(Class)aClass
@@ -122,10 +125,14 @@ var CPBindingOperationAnd = 0,
{
_source = aSource;
_info = [CPDictionary dictionaryWithObjects:[aDestination, aKeyPath] forKeys:[CPObservedObjectKey, CPObservedKeyPathKey]];
_suppressedNotifications = {};
_placeholderForMarker = {};
if (options)
[_info setObject:options forKey:CPOptionsKey];
[self _updatePlaceholdersWithOptions:options];
[aDestination addObserver:self forKeyPath:aKeyPath options:CPKeyValueObservingOptionNew context:aBinding];
var bindings = [bindingsMap objectForKey:[_source UID]];
@@ -169,6 +176,10 @@ var CPBindingOperationAnd = 0,
if (!changes)
return;
var objectSuppressions = _suppressedNotifications[[anObject UID]];
if (objectSuppressions && objectSuppressions[aKeyPath])
return;
[self setValueFor:context];
}
@@ -197,14 +208,13 @@ var CPBindingOperationAnd = 0,
if (valueTransformer)
aValue = [valueTransformer transformedValue:aValue];
if (aValue === undefined || aValue === nil || aValue === [CPNull null])
aValue = [options objectForKey:CPNullPlaceholderBindingOption] || nil;
return aValue;
}
- (id)reverseTransformValue:(id)aValue withOptions: (CPDictionary)options
- (id)reverseTransformValue:(id)aValue withOptions:(CPDictionary)options
{
var valueTransformerName = [options objectForKey:CPValueTransformerNameBindingOption],
valueTransformer;
@@ -226,6 +236,80 @@ var CPBindingOperationAnd = 0,
return [[options objectForKey:CPContinuouslyUpdatesValueBindingOption] boolValue];
}
- (BOOL)handlesContentAsCompoundValue
{
var options = [_info objectForKey:CPOptionsKey];
return [[options objectForKey:CPHandlesContentAsCompoundValueBindingOption] boolValue];
}
/*!
Use this to avoid reacting to the notifications coming out of a reverseTransformedValue:.
*/
- (void)suppressSpecificNotificationFromObject:(id)anObject keyPath:(CPString)aKeyPath
{
if (!anObject)
return;
var uid = [anObject UID],
objectSuppressions = _suppressedNotifications[uid];
if (!objectSuppressions)
_suppressedNotifications[uid] = objectSuppressions = {};
objectSuppressions[aKeyPath] = YES;
}
/*!
Use this to cancel suppressSpecificNotificationFromObject:keyPath:.
*/
- (void)unsuppressSpecificNotificationFromObject:(id)anObject keyPath:(CPString)aKeyPath
{
if (!anObject)
return;
var uid = [anObject UID],
objectSuppressions = _suppressedNotifications[uid];
if (!objectSuppressions)
return;
delete objectSuppressions[aKeyPath];
}
- (void)_updatePlaceholdersWithOptions:(CPDictionary)options
{
var count = [CPBinderPlaceholderMarkers count];
while (count--)
{
var marker = CPBinderPlaceholderMarkers[count],
optionName = CPBinderPlaceholderOptions[count],
isExplicit = [options containsKey:optionName],
placeholder = isExplicit ? [options objectForKey:optionName] : nil;
[self _setPlaceholder:placeholder forMarker:marker isDefault:!isExplicit];
}
}
- (void)_placeholderForMarker:aMarker
{
var placeholder = _placeholderForMarker[aMarker];
if (placeholder)
return placeholder['value'];
return nil;
}
- (void)_setPlaceholder:(id)aPlaceholder forMarker:(id)aMarker isDefault:(BOOL)isDefault
{
if (isDefault)
{
var existingPlaceholder = _placeholderForMarker[aMarker];
// Don't overwrite an explicitly set placeholder with a default.
if (existingPlaceholder && !existingPlaceholder['isDefault'])
return;
}
_placeholderForMarker[aMarker] = { 'isDefault': isDefault, 'value': aPlaceholder };
}
@end
@implementation CPObject (KeyValueBindingCreation)
@@ -235,7 +319,6 @@ var CPBindingOperationAnd = 0,
[CPBinder exposeBinding:aBinding forClass:[self class]];
}
+ (Class)_binderClassForBinding:(CPString)theBinding
{
return [CPBinder class];
@@ -267,10 +350,10 @@ var CPBindingOperationAnd = 0,
- (void)bind:(CPString)aBinding toObject:(id)anObject withKeyPath:(CPString)aKeyPath options:(CPDictionary)options
{
if (!anObject || !aKeyPath)
return CPLog.error("Invalid object or path on "+self+" for "+aBinding);
return CPLog.error("Invalid object or path on " + self + " for " + aBinding);
//if (![[self exposedBindings] containsObject:aBinding])
// CPLog.warn("No binding exposed on "+self+" for "+aBinding);
// CPLog.warn("No binding exposed on " + self + " for " + aBinding);
var binderClass = [[self class] _binderClassForBinding:aBinding];
@@ -382,7 +465,7 @@ var resolveMultipleValues = function resolveMultipleValues(/*CPString*/key, /*CP
}
return !operation;
}
};
var invokeAction = function invokeAction(/*CPString*/targetKey, /*CPString*/argumentKey, /*CPDictionary*/bindings)
{
@@ -419,7 +502,7 @@ var invokeAction = function invokeAction(/*CPString*/targetKey, /*CPString*/argu
}
[invocation invoke];
}
};
// Keys in options dictionary
@@ -474,4 +557,8 @@ CPValueTransformerBindingOption = @"CPValueTransformer";
CPIsControllerMarker = function(/*id*/anObject)
{
return anObject === CPMultipleValuesMarker || anObject === CPNoSelectionMarker || anObject === CPNotApplicableMarker || anObject === CPNullMarker;
}
};
var CPBinderPlaceholderMarkers = [CPMultipleValuesMarker, CPNoSelectionMarker, CPNotApplicableMarker, CPNullMarker],
CPBinderPlaceholderOptions = [CPMultipleValuesPlaceholderBindingOption, CPNoSelectionPlaceholderBindingOption, CPNotApplicablePlaceholderBindingOption, CPNullPlaceholderBindingOption];
+11 -2
View File
@@ -149,9 +149,9 @@ var _CPLevelIndicatorBezelColor = nil,
var filledColor = _CPLevelIndicatorSegmentNormalColor,
value = [self doubleValue];
if (value < _criticalValue)
if (value <= _criticalValue)
filledColor = _CPLevelIndicatorSegmentCriticalColor;
else if (value < _warningValue)
else if (value <= _warningValue)
filledColor = _CPLevelIndicatorSegmentWarningColor;
for (var i = 0; i < segmentCount; i++)
@@ -223,6 +223,15 @@ var _CPLevelIndicatorBezelColor = nil,
return _isEditable;
}
- (CPView)hitTest:(CPPoint)aPoint
{
// Don't swallow clicks when displayed in a table.
if (![self isEditable])
return nil;
return [super hitTest:aPoint];
}
- (void)mouseDown:(CPEvent)anEvent
{
if (![self isEditable] || ![self isEnabled])
+35 -13
View File
@@ -352,8 +352,12 @@ var _CPMenuBarVisible = NO,
while (count--)
[_items[count] setMenu:nil];
_items = [CPMutableArray array];
_highlightedIndex = CPNotFound;
// Because we are changing _items directly, be sure to notify KVO
[self willChangeValueForKey:@"items"];
_items = [CPMutableArray array];
[self didChangeValueForKey:@"items"];
}
/*!
@@ -622,11 +626,11 @@ var _CPMenuBarVisible = NO,
var validator = [CPApp targetForAction:[item action] to:[item target] from:item];
if (!validator || ![validator respondsToSelector:[item action]])
[item _setEnabled:NO];
[item setEnabled:NO];
else if ([validator respondsToSelector:@selector(validateMenuItem:)])
[item _setEnabled:[validator validateMenuItem:item]];
[item setEnabled:[validator validateMenuItem:item]];
else if ([validator respondsToSelector:@selector(validateUserInterfaceItem:)])
[item _setEnabled:[validator validateUserInterfaceItem:item]];
[item setEnabled:[validator validateUserInterfaceItem:item]];
}
[[_menuWindow _menuView] tile];
@@ -711,10 +715,7 @@ var _CPMenuBarVisible = NO,
if (aView && !theWindow)
throw "In call to popUpMenuPositioningItem:atLocation:inView:callback:, view is not in any window.";
var delegate = [self delegate];
if ([delegate respondsToSelector:@selector(menuWillOpen:)])
[delegate menuWillOpen:self];
[self _menuWillOpen];
// Convert location to global coordinates if not already in them.
if (aView)
@@ -802,10 +803,7 @@ var _CPMenuBarVisible = NO,
+ (void)popUpContextMenu:(CPMenu)aMenu withEvent:(CPEvent)anEvent forView:(CPView)aView withFont:(CPFont)aFont
{
var delegate = [aMenu delegate];
if ([delegate respondsToSelector:@selector(menuWillOpen:)])
[delegate menuWillOpen:aMenu];
[aMenu _menuWillOpen];
if (!aFont)
aFont = [CPFont systemFontOfSize:12.0];
@@ -875,7 +873,15 @@ var _CPMenuBarVisible = NO,
*/
- (CPMenuItem)highlightedItem
{
return _highlightedIndex >= 0 ? _items[_highlightedIndex] : nil;
if (_highlightedIndex < 0)
return nil;
var highlightedItem = _items[_highlightedIndex];
if ([highlightedItem isSeparatorItem])
return nil;
return highlightedItem;
}
// Managing the Delegate
@@ -890,6 +896,22 @@ var _CPMenuBarVisible = NO,
return _delegate;
}
- (void)_menuWillOpen
{
var delegate = [self delegate];
if ([delegate respondsToSelector:@selector(menuWillOpen:)])
[delegate menuWillOpen:self];
}
- (void)_menuDidClose
{
var delegate = [self delegate];
if ([delegate respondsToSelector:@selector(menuDidClose:)])
[delegate menuDidClose:self];
}
// Handling Tracking
/*!
Cancels tracking.
+1 -1
View File
@@ -257,7 +257,7 @@ var _CPMenuBarWindowBackgroundColor = nil,
items = [_menu itemArray],
count = items.length;
for (index = 0; index < count; ++index)
for (var index = 0; index < count; ++index)
{
var item = items[index],
menuItemView = [item _menuItemView];
+28 -10
View File
@@ -1,8 +1,8 @@
@import <Foundation/CPObject.j>
_CPMenuManagerScrollingStateUp = -1,
_CPMenuManagerScrollingStateDown = 1,
_CPMenuManagerScrollingStateUp = -1;
_CPMenuManagerScrollingStateDown = 1;
_CPMenuManagerScrollingStateNone = 0;
var STICKY_TIME_INTERVAL = 500,
@@ -11,6 +11,7 @@ var STICKY_TIME_INTERVAL = 500,
@implementation _CPMenuManager: CPObject
{
CPTimeInterval _startTime;
BOOL _hasMouseGoneUpAfterStartedTracking;
int _scrollingState;
CGPoint _lastGlobalLocation;
@@ -60,6 +61,9 @@ var STICKY_TIME_INTERVAL = 500,
{
var menu = [aMenuContainer menu];
if ([menu numberOfItems] <= 0)
return;
CPApp._activeMenu = menu;
_startTime = [anEvent timestamp];//new Date();
@@ -87,6 +91,8 @@ var STICKY_TIME_INTERVAL = 500,
return [self trackMenuBarButtonEvent:anEvent];
}
_hasMouseGoneUpAfterStartedTracking = NO;
[self trackEvent:anEvent];
}
@@ -99,7 +105,7 @@ var STICKY_TIME_INTERVAL = 500,
if (type === CPAppKitDefined)
return [self completeTracking];
[CPApp setTarget:self selector:@selector(trackEvent:) forNextEventMatchingMask:CPKeyDownMask | CPPeriodicMask | CPMouseMovedMask | CPLeftMouseDraggedMask | CPLeftMouseUpMask | CPAppKitDefinedMask | CPScrollWheelMask untilDate:nil inMode:nil dequeue:YES];
[CPApp setTarget:self selector:@selector(trackEvent:) forNextEventMatchingMask:CPKeyDownMask | CPPeriodicMask | CPMouseMovedMask | CPLeftMouseDraggedMask | CPLeftMouseUpMask | CPRightMouseUpMask | CPAppKitDefinedMask | CPScrollWheelMask untilDate:nil inMode:nil dequeue:YES];
if (type === CPKeyDown)
{
@@ -221,8 +227,20 @@ var STICKY_TIME_INTERVAL = 500,
[CPEvent startPeriodicEventsAfterDelay:0.0 withPeriod:0.04];
}
}
else if (type === CPLeftMouseUp && ([anEvent timestamp] - _startTime > (STICKY_TIME_INTERVAL + [activeMenu numberOfItems] * 5)))
[trackingMenu cancelTracking];
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;
[trackingMenu cancelTracking];
}
else
_hasMouseGoneUpAfterStartedTracking = YES;
}
}
// Prevent previous selected menu items from opening by stopping the timer if a
@@ -306,11 +324,7 @@ var STICKY_TIME_INTERVAL = 500,
// Hide all submenus.
[self showMenu:nil fromMenu:trackingMenu atPoint:nil];
var delegate = [trackingMenu delegate];
if ([delegate respondsToSelector:@selector(menuDidClose:)])
[delegate menuDidClose:trackingMenu];
[trackingMenu _menuDidClose];
if (_trackingCallback)
_trackingCallback([self trackingMenuContainer], trackingMenu);
@@ -379,6 +393,8 @@ var STICKY_TIME_INTERVAL = 500,
var count = _menuContainerStack.length,
index = count;
[newMenu _menuWillOpen];
// Hide all menus up to the base menu...
while (index--)
{
@@ -398,6 +414,8 @@ var STICKY_TIME_INTERVAL = 500,
[_CPMenuWindow poolMenuWindow:menuContainer];
[_menuContainerStack removeObjectAtIndex:index];
[menu _menuDidClose];
}
if (!newMenu)
+1 -8
View File
@@ -148,14 +148,6 @@ var CPMenuItemStringRepresentationDictionary = [CPDictionary dictionary];
@param isEnabled \c YES enables the item. \c NO disables it.
*/
- (void)setEnabled:(BOOL)isEnabled
{
if ([_menu autoenablesItems])
return;
[self _setEnabled:isEnabled];
}
- (void)_setEnabled:(BOOL)isEnabled
{
if (_isEnabled === isEnabled)
return;
@@ -496,6 +488,7 @@ CPOffState
if (_submenu)
{
[_submenu setSupermenu:_menu];
[_submenu setTitle:[self title]]
[self setTarget:_menu];
[self setAction:@selector(submenuAction:)];
+18 -6
View File
@@ -131,8 +131,8 @@
_contentObject = aContent;
[self didChangeValueForKey:@"contentObject"];
[self _selectionDidChange];
[self didChangeValueForKey:@"contentObject"];
}
/*!
@@ -498,7 +498,7 @@ var CPObjectControllerContentKey = @"CPObjectControllerCo
- (CPString)description
{
return "<_CPObservableArray: "+[super description]+" >";
return "<_CPObservableArray: " + [super description] + " >";
}
- (id)initWithArray:(CPArray)anArray
@@ -663,7 +663,8 @@ var CPObjectControllerContentKey = @"CPObjectControllerCo
- (id)_controllerMarkerForValues:(CPArray)theValues
{
var count = [theValues count];
var count = [theValues count],
value;
if (!count)
value = CPNoSelectionMarker;
@@ -677,7 +678,7 @@ var CPObjectControllerContentKey = @"CPObjectControllerCo
{
value = [theValues objectAtIndex:0];
for (var i = 0, count= [theValues count]; i < count && value != CPMultipleValuesMarker; i++)
for (var i = 0, count = [theValues count]; i < count && value != CPMultipleValuesMarker; i++)
{
if (![value isEqual:[theValues objectAtIndex:i]])
value = CPMultipleValuesMarker;
@@ -693,8 +694,8 @@ var CPObjectControllerContentKey = @"CPObjectControllerCo
- (id)valueForKeyPath:(CPString)theKeyPath
{
var values = [[_controller selectedObjects] valueForKeyPath:theKeyPath];
value = [self _controllerMarkerForValues:values];
var values = [[_controller selectedObjects] valueForKeyPath:theKeyPath],
value = [self _controllerMarkerForValues:values];
[_cachedValues setObject:value forKey:theKeyPath];
@@ -710,6 +711,17 @@ var CPObjectControllerContentKey = @"CPObjectControllerCo
{
[[_controller selectedObjects] setValue:theValue forKeyPath:theKeyPath];
[_cachedValues removeObjectForKey:theKeyPath];
// Allow handlesContentAsCompoundValue to work, based on observation of Cocoa's
// NSArrayController - when handlesContentAsCompoundValue and setValue:forKey:@"selection.X"
// is called, the array controller causes the compound value to be rewritten if
// handlesContentAsCompoundValue == YES. Note that
// A) this doesn't use observation (observe: X is not visible in backtraces)
// B) it only happens through the selection proxy and not on arrangedObject.X, content.X
// or even selectedObjects.X.
// FIXME The main code for this should somehow be in CPArrayController and also work
// for table based row edits.
[[CPBinder getBinding:@"contentArray" forObject:_controller] _contentArrayDidChange];
}
- (void)setValue:(id)theValue forKey:(CPString)theKeyPath
+118 -39
View File
@@ -62,7 +62,7 @@ var CPOutlineViewDelegate_outlineView_dataViewForTableColumn_item_
CPOutlineViewDelegate_outlineView_shouldReorderColumn_toColumn_ = 1 << 12,
CPOutlineViewDelegate_outlineView_shouldSelectItem_ = 1 << 13,
CPOutlineViewDelegate_outlineView_shouldSelectTableColumn_ = 1 << 14,
CPOutlineViewDelegate_outlineView_shouldShowOutlineViewForItem_ = 1 << 15,
CPOutlineViewDelegate_outlineView_shouldShowOutlineDisclosureControlForItem_ = 1 << 15,
CPOutlineViewDelegate_outlineView_shouldShowViewExpansionForTableColumn_item_ = 1 << 16,
CPOutlineViewDelegate_outlineView_shouldTrackView_forTableColumn_item_ = 1 << 17,
CPOutlineViewDelegate_outlineView_shouldTypeSelectForEvent_withCurrentSearchString_ = 1 << 18,
@@ -80,6 +80,10 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
CPOutlineViewCoalesceSelectionNotificationStateOn = 1,
CPOutlineViewCoalesceSelectionNotificationStateDid = 2;
#define SELECTION_SHOULD_CHANGE(anOutlineView) (!((anOutlineView)._implementedOutlineViewDelegateMethods & CPOutlineViewDelegate_selectionShouldChangeInOutlineView_) || [(anOutlineView)._outlineViewDelegate selectionShouldChangeInOutlineView:(anOutlineView)])
#define SHOULD_SELECT_ITEM(anOutlineView, anItem) (!((anOutlineView)._implementedOutlineViewDelegateMethods & CPOutlineViewDelegate_outlineView_shouldSelectItem_) || [(anOutlineView)._outlineViewDelegate outlineView:(anOutlineView) shouldSelectItem:(anItem)])
/*!
@ingroup appkit
@class CPOutlineView
@@ -136,7 +140,7 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
_selectionHighlightStyle = CPTableViewSelectionHighlightStyleSourceList;
// The root item has weight "0", thus represents the weight solely of its descendants.
_rootItemInfo = { isExpanded:YES, isExpandable:NO, level:-1, row:-1, children:[], weight:0 };
_rootItemInfo = { isExpanded:YES, isExpandable:NO, shouldShowOutlineDisclosureControl:NO, level:-1, row:-1, children:[], weight:0 };
_itemsForRows = [];
_itemInfosForItems = { };
@@ -294,6 +298,19 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
return itemInfo.isExpandable;
}
- (BOOL)_shouldShowOutlineDisclosureControlForItem:(id)anItem
{
if (!anItem)
return YES;
var itemInfo = _itemInfosForItems[[anItem UID]];
if (!itemInfo)
return YES;
return itemInfo.shouldShowOutlineDisclosureControl;
}
/*!
Used to find if an item is already expanded.
@@ -690,7 +707,8 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
*/
- (CGRect)frameOfOutlineDisclosureControlAtRow:(CPInteger)aRow
{
if (![self isExpandable:[self itemAtRow:aRow]])
var theItem = [self itemAtRow:aRow];
if (![self isExpandable:theItem] || ![self _shouldShowOutlineDisclosureControlForItem:theItem])
return _CGRectMakeZero();
var dataViewFrame = [self _frameOfOutlineDataViewAtRow:aRow],
@@ -822,29 +840,24 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
name:CPOutlineViewSelectionIsChangingNotification
object:self];
if ([_outlineViewDelegate respondsToSelector:@selector(outlineViewItemWillExpand:)])
[defaultCenter
removeObserver:_outlineViewDelegate
name:CPOutlineViewItemWillExpandNotification
object:self];
if ([_outlineViewDelegate respondsToSelector:@selector(outlineViewItemDidExpand:)])
[defaultCenter
removeObserver:_outlineViewDelegate
name:CPOutlineViewItemDidExpandNotification
object:self];
if ([_outlineViewDelegate respondsToSelector:@selector(outlineViewItemWillCollapse:)])
[defaultCenter
removeObserver:_outlineViewDelegate
name:CPOutlineViewItemWillCollapseNotification
object:self];
if ([_outlineViewDelegate respondsToSelector:@selector(outlineViewItemDidCollapse:)])
[defaultCenter
removeObserver:_outlineViewDelegate
@@ -870,7 +883,7 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
CPOutlineViewDelegate_outlineView_shouldReorderColumn_toColumn_ , @selector(outlineView:shouldReorderColumn:toColumn:),
CPOutlineViewDelegate_outlineView_shouldSelectItem_ , @selector(outlineView:shouldSelectItem:),
CPOutlineViewDelegate_outlineView_shouldSelectTableColumn_ , @selector(outlineView:shouldSelectTableColumn:),
CPOutlineViewDelegate_outlineView_shouldShowOutlineViewForItem_ , @selector(outlineView:shouldShowOutlineViewForItem:),
CPOutlineViewDelegate_outlineView_shouldShowOutlineDisclosureControlForItem_ , @selector(outlineView:shouldShowOutlineDisclosureControlForItem:),
CPOutlineViewDelegate_outlineView_shouldShowViewExpansionForTableColumn_item_ , @selector(outlineView:shouldShowViewExpansionForTableColumn:item:),
CPOutlineViewDelegate_outlineView_shouldTrackView_forTableColumn_item_ , @selector(outlineView:shouldTrackView:forTableColumn:item:),
CPOutlineViewDelegate_outlineView_shouldTypeSelectForEvent_withCurrentSearchString_ , @selector(outlineView:shouldTypeSelectForEvent:withCurrentSearchString:),
@@ -921,7 +934,6 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
name:CPOutlineViewSelectionIsChangingNotification
object:self];
if ([_outlineViewDelegate respondsToSelector:@selector(outlineViewItemWillExpand:)])
[defaultCenter
addObserver:_outlineViewDelegate
@@ -984,7 +996,7 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
_disclosureControlData = nil;
_disclosureControlQueue = [];
// fIXME: really?
// FIXME: really?
[self reloadData];
}
@@ -1120,13 +1132,14 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
if (_dragHoverTimer)
[_dragHoverTimer invalidate];
var autoExpandCallBack = function(){
var autoExpandCallBack = function()
{
if (_dropItem)
{
[_dropOperationFeedbackView blink];
[CPTimer scheduledTimerWithTimeInterval:.3 callback:objj_msgSend(self, "expandItem:", _dropItem) repeats:NO];
}
}
};
_dragHoverTimer = [CPTimer scheduledTimerWithTimeInterval:.8 callback:autoExpandCallBack repeats:NO];
}
@@ -1284,7 +1297,12 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
item = _itemsForRows[row],
isExpandable = [self isExpandable:item];
if (!isExpandable)
if (!isExpandable)
continue;
var disclosureControlFrame = [self frameOfOutlineDisclosureControlAtRow:row];
if (_CGRectIsEmpty(disclosureControlFrame))
continue;
var control = [self _dequeueDisclosureControl];
@@ -1294,7 +1312,7 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
[control setState:[self isItemExpanded:item] ? CPOnState : CPOffState];
var selector = [self isRowSelected:row] ? @"setThemeState:" : @"unsetThemeState:";
[control performSelector:CPSelectorFromString(selector) withObject:CPThemeStateSelected];
[control setFrame:[self frameOfOutlineDisclosureControlAtRow:row]];
[control setFrame:disclosureControlFrame];
[self addSubview:control];
}
@@ -1458,6 +1476,62 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
userInfo:[CPDictionary dictionaryWithObject:item forKey:"CPObject"]];
}
- (void)keyDown:(CPEvent)anEvent
{
var character = [anEvent charactersIgnoringModifiers],
modifierFlags = [anEvent modifierFlags];
// Check for the key events manually, as opposed to waiting for CPWindow to sent the actual action message
// in _processKeyboardUIKey:, because we might not want to handle the arrow events.
if (character !== CPRightArrowFunctionKey && character !== CPLeftArrowFunctionKey)
return [super keyDown:anEvent];
var rows = [self selectedRowIndexes],
indexes = [],
items = [];
[rows getIndexes:indexes maxCount:-1 inIndexRange:nil];
var i = 0,
c = [indexes count];
for (; i < c; i++)
items.push([self itemAtRow:indexes[i]]);
if (character === CPRightArrowFunctionKey)
{
for (var i = 0; i < c; i++)
[self expandItem:items[i]];
}
else if (character === CPLeftArrowFunctionKey)
{
// When a single, collapsed item is selected and the left arrow key is pressed, the parent
// should be selected if possible.
if (c == 1)
{
var theItem = items[0];
if (![self isItemExpanded:theItem])
{
var parent = [self parentForItem:theItem],
shouldSelect = parent && SELECTION_SHOULD_CHANGE(self) && SHOULD_SELECT_ITEM(self, parent);
if (shouldSelect)
{
var rowIndex = [self rowForItem:parent];
[self selectRowIndexes:[CPIndexSet indexSetWithIndex:rowIndex] byExtendingSelection:NO];
[self scrollRowToVisible:rowIndex];
return;
}
}
}
for (var i = 0; i < c; i++)
[self collapseItem:items[i]];
}
[super keyDown:anEvent];
}
@end
// FIX ME: We're using with() here because Safari fails if we use anOutlineView._itemInfosForItems or whatever...
@@ -1496,8 +1570,9 @@ var _reloadItem = function(/*CPOutlineView*/ anOutlineView, /*id*/ anItem)
itemInfo.isExpandable = [dataSource outlineView:anOutlineView isItemExpandable:newItem];
itemInfo.isExpanded = itemInfo.isExpandable && itemInfo.isExpanded;
itemInfo.shouldShowOutlineDisclosureControl = !(_implementedOutlineViewDelegateMethods & CPOutlineViewDelegate_outlineView_shouldShowOutlineDisclosureControlForItem_) || [_outlineViewDelegate outlineView:self shouldShowOutlineDisclosureControlForItem:newItem];
}
}
};
// FIX ME: We're using with() here because Safari fails if we use anOutlineView._itemInfosForItems or whatever...
var _loadItemInfoForItem = function(/*CPOutlineView*/ anOutlineView, /*id*/ anItem, /*BOOL*/ isIntermediate)
@@ -1521,6 +1596,7 @@ var _loadItemInfoForItem = function(/*CPOutlineView*/ anOutlineView, /*id*/ anIt
return [];
itemInfo.isExpandable = [dataSource outlineView:anOutlineView isItemExpandable:anItem];
itemInfo.shouldShowOutlineDisclosureControl = !(_implementedOutlineViewDelegateMethods & CPOutlineViewDelegate_outlineView_shouldShowOutlineDisclosureControlForItem_) || [_outlineViewDelegate outlineView:self shouldShowOutlineDisclosureControlForItem:anItem];
// If we were previously expanded, but now no longer expandable, "de-expand".
// NOTE: we are *not* collapsing, thus no notification is posted.
@@ -1551,7 +1627,7 @@ var _loadItemInfoForItem = function(/*CPOutlineView*/ anOutlineView, /*id*/ anIt
if (!childItemInfo)
{
childItemInfo = { isExpanded:NO, isExpandable:NO, children:[], weight:1 };
childItemInfo = { isExpanded:NO, isExpandable:NO, shouldShowOutlineDisclosureControl:YES, children:[], weight:1 };
itemInfosForItems[[childItem UID]] = childItemInfo;
}
@@ -1602,7 +1678,7 @@ var _loadItemInfoForItem = function(/*CPOutlineView*/ anOutlineView, /*id*/ anIt
}
}//end of with
return descendants;
}
};
@implementation _CPOutlineViewTableViewDataSource : CPObject
{
@@ -1754,9 +1830,9 @@ var _loadItemInfoForItem = function(/*CPOutlineView*/ anOutlineView, /*id*/ anIt
var dataView = nil;
if ((_outlineView._implementedOutlineViewDelegateMethods & CPOutlineViewDelegate_outlineView_dataViewForTableColumn_item_))
dataView = [_outlineView._outlineViewDelegate outlineView:_outlineView
dataViewForTableColumn:theTableColumn
item:[_outlineView itemAtRow:theRow]];
dataView = [_outlineView._outlineViewDelegate outlineView:_outlineView
dataViewForTableColumn:theTableColumn
item:[_outlineView itemAtRow:theRow]];
if (!dataView)
dataView = [theTableColumn dataViewForRow:theRow];
@@ -1766,10 +1842,12 @@ var _loadItemInfoForItem = function(/*CPOutlineView*/ anOutlineView, /*id*/ anIt
- (BOOL)tableView:(CPTableView)theTableView shouldSelectRow:(int)theRow
{
if ((_outlineView._implementedOutlineViewDelegateMethods & CPOutlineViewDelegate_outlineView_shouldSelectItem_))
return [_outlineView._outlineViewDelegate outlineView:_outlineView shouldSelectItem:[_outlineView itemAtRow:theRow]];
return SHOULD_SELECT_ITEM(_outlineView, [_outlineView itemAtRow:theRow]);
}
return YES;
- (BOOL)selectionShouldChangeInTableView:(CPTableView)theTableView
{
return SELECTION_SHOULD_CHANGE(_outlineView);
}
- (BOOL)tableView:(CPTableView)aTableView shouldEditTableColumn:(CPTableColumn)aColumn row:(int)aRow
@@ -1847,16 +1925,22 @@ var _loadItemInfoForItem = function(/*CPOutlineView*/ anOutlineView, /*id*/ anIt
- (void)drawRect:(CGRect)aRect
{
var bounds = [self bounds],
context = [[CPGraphicsContext currentContext] graphicsPort];
context = [[CPGraphicsContext currentContext] graphicsPort],
width = _CGRectGetWidth(bounds),
height = _CGRectGetHeight(bounds);
CGContextBeginPath(context);
CGContextTranslateCTM(context, _CGRectGetWidth(bounds) / 2.0, _CGRectGetHeight(bounds) / 2.0);
CGContextRotateCTM(context, _angle);
CGContextTranslateCTM(context, -_CGRectGetWidth(bounds) / 2.0, -_CGRectGetHeight(bounds) / 2.0);
if (_angle)
{
var centre = _CGPointMake(FLOOR(width / 2.0), FLOOR(height / 2.0));
CGContextTranslateCTM(context, centre.x, centre.y);
CGContextRotateCTM(context, _angle);
CGContextTranslateCTM(context, -centre.x, -centre.y);
}
// Center, but crisp.
CGContextTranslateCTM(context, FLOOR((_CGRectGetWidth(bounds) - 9.0) / 2.0), FLOOR((_CGRectGetHeight(bounds) - 8.0) / 2.0));
CGContextTranslateCTM(context, FLOOR((width - 9.0) / 2.0), FLOOR((height - 8.0) / 2.0));
CGContextMoveToPoint(context, 0.0, 0.0);
CGContextAddLineToPoint(context, 9.0, 0.0);
@@ -1869,20 +1953,14 @@ var _loadItemInfoForItem = function(/*CPOutlineView*/ anOutlineView, /*id*/ anIt
[self hasThemeState:CPThemeStateHighlighted]));
CGContextFillPath(context);
CGContextBeginPath(context);
CGContextMoveToPoint(context, 0.0, 0.0);
CGContextAddLineToPoint(context, 4.5, 8.0);
if (_angle === 0.0)
{
CGContextAddLineToPoint(context, 4.5, 8.0);
CGContextAddLineToPoint(context, 9.0, 0.0);
}
else
CGContextAddLineToPoint(context, 4.5, 8.0);
CGContextSetStrokeColor(context, [CPColor colorWithCalibratedWhite:1.0 alpha: 0.8]);
CGContextSetStrokeColor(context, [CPColor colorWithCalibratedWhite:1.0 alpha: 0.7]);
CGContextStrokePath(context);
}
@@ -1946,7 +2024,8 @@ var CPOutlineViewIndentationPerLevelKey = @"CPOutlineViewIndentationPerLevelKey"
@end
var colorForDisclosureTriangle = function(isSelected, isHighlighted) {
var colorForDisclosureTriangle = function(isSelected, isHighlighted)
{
return isSelected
? (isHighlighted
? [CPColor colorWithCalibratedWhite:0.9 alpha: 1.0]
@@ -1954,4 +2033,4 @@ var colorForDisclosureTriangle = function(isSelected, isHighlighted) {
: (isHighlighted
? [CPColor colorWithCalibratedWhite:0.4 alpha: 1.0]
: [CPColor colorWithCalibratedWhite:0.5 alpha: 1.0]);
}
};
+13 -2
View File
@@ -86,7 +86,7 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
[self setPullsDown:shouldPullDown];
var options = CPKeyValueObservingOptionNew |CPKeyValueObservingOptionOld;/* |CPKeyValueObservingOptionInitial;*/
var options = CPKeyValueObservingOptionNew | CPKeyValueObservingOptionOld; // | CPKeyValueObservingOptionInitial;
[self addObserver:self forKeyPath:@"menu.items" options:options context:nil];
[self addObserver:self forKeyPath:@"_firstItem.changeCount" options:options context:nil];
[self addObserver:self forKeyPath:@"selectedItem.changeCount" options:options context:nil];
@@ -193,6 +193,7 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
- (void)removeAllItems
{
[[self menu] removeAllItems];
[self synchronizeTitleAndSelectedItem];
}
/*!
@@ -248,7 +249,7 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
/*!
@ignore
*/
- (int)selectedTag
- (int)_selectedTag
{
return [[self selectedItem] tag];
}
@@ -775,6 +776,16 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
[[self selectedItem] setState:CPOffState];
}
- (void)_reverseSetBinding
{
var binderClass = [[self class] _binderClassForBinding:CPSelectedIndexBinding],
theBinding = [binderClass getBinding:CPSelectedIndexBinding forObject:self];
[theBinding reverseSetValueFor:@"objectValue"];
[super _reverseSetBinding];
}
@end
var DEPRECATED_CPPopUpButtonMenuKey = @"CPPopUpButtonMenuKey",
+332
View File
@@ -0,0 +1,332 @@
/*
* CPPopover.j
* AppKit
*
* Created by Antoine Mercadal.
* Copyright 2011 Antoine Mercadal.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import <Foundation/CPObject.j>
@import "CPButton.j"
@import "CPColor.j"
@import "CPImage.j"
@import "CPImageView.j"
@import "CPResponder.j"
@import "CPView.j"
@import "_CPAttachedWindow.j"
CPPopoverBehaviorApplicationDefined = 0;
CPPopoverBehaviorTransient = 1;
CPPopoverBehaviorSemitransient = 2;
var CPPopoverDelegate_popover_willShow_ = 1 << 0,
CPPopoverDelegate_popover_didShow_ = 1 << 1,
CPPopoverDelegate_popover_shouldClose_ = 1 << 2,
CPPopoverDelegate_popover_willClose_ = 1 << 3,
CPPopoverDelegate_popover_didClose_ = 1 << 4;
/*! @ingroup appkit
@class CPPopover
This class represent a widget that displays a attached
view relative to another one.
Delegate can implement:
@code
popoverShouldClose:(CPPopover)aPopOver
popoverWillShow:(CPPopover)aPopOver
popoverDidShow:(CPPopover)aPopOver
popoverWillClose:(CPPopover)aPopOver
popoverDidClose:(CPPopover)aPopOver
@endcode
*/
@implementation CPPopover : CPResponder
{
@outlet CPViewController _contentViewController @accessors(property=contentViewController);
@outlet id _delegate @accessors(getter=delegate);
BOOL _animates @accessors(property=animates);
int _appearance @accessors(property=appearance);
int _behavior @accessors(getter=behavior);
_CPAttachedWindow _attachedWindow;
BOOL _needsNewAttachedWindow;
int _implementedDelegateMethods;
}
#pragma mark -
#pragma mark Initialization
/*!
Initialize the CPPopover witn default values
@returns anInitialized CPPopover
*/
- (CPPopover)init
{
if (self = [super init])
{
_animates = YES;
_appearance = CPPopoverAppearanceMinimal;
_behavior = CPPopoverBehaviorApplicationDefined;
_needsNewAttachedWindow = YES;
}
return self;
}
#pragma mark -
#pragma mark Getters / Setters
/*!
Returns the current rect of the popover
@return CGRect representing the frame of the popover
*/
- (CGRect)positioningRect
{
if (![_attachedWindow isVisible])
return nil;
return [_attachedWindow frame];
}
/*! Sets the frame of the popover
@param aRect the desired frame
*/
- (void)setPositioningRect:(CGRect)aRect
{
if (![_attachedWindow isVisible])
return;
[_attachedWindow setFrame:aRect];
}
/*!
Returns the size of the popover's view
@return CGSize representing the size of the popover's view
*/
- (CGSize)contentSize
{
if (![_attachedWindow isVisible])
return nil;
return [[_contentViewController view] frameSize];
}
/*!
Sets the size of of the popover's view
@param aSize the desired size
*/
- (void)setContentSize:(CPSize)aSize
{
[[_contentViewController view] setFrameSize:aSize];
}
/*!
Indicates if CPPopover is visible
@returns \c YES if visible
*/
- (BOOL)shown
{
return [_attachedWindow isVisible];
}
/*!
Set the behaviour 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
*/
- (void)setBehaviour:(int)aBehaviour
{
if (_behavior == aBehaviour)
return;
_behavior = aBehaviour;
_needsNewAttachedWindow = YES;
}
- (void)setDelegate:(id)aDelegate
{
if (_delegate === aDelegate)
return;
_delegate = aDelegate;
_implementedDelegateMethods = 0;
if ([_delegate respondsToSelector:@selector(popoverWillShow:)])
_implementedDelegateMethods |= CPPopoverDelegate_popover_willShow_;
if ([_delegate respondsToSelector:@selector(popoverDidShow:)])
_implementedDelegateMethods |= CPPopoverDelegate_popover_didShow_;
if ([_delegate respondsToSelector:@selector(popoverShouldClose:)])
_implementedDelegateMethods |= CPPopoverDelegate_popover_shouldClose_;
if ([_delegate respondsToSelector:@selector(popoverWillClose:)])
_implementedDelegateMethods |= CPPopoverDelegate_popover_willClose_;
if ([_delegate respondsToSelector:@selector(popoverDidClose:)])
_implementedDelegateMethods |= CPPopoverDelegate_popover_didClose_;
}
#pragma mark -
#pragma mark Positioning
/*!
Show the popover
@param positioningRect if set, the popover will be positionned to a random rect relative to the window
@param positioningView if set, the popover will be positioned relative to this view
@param preferredEdge: \c CPRectEdge representing the preferred positioning.
*/
- (void)showRelativeToRect:(CGRect)positioningRect ofView:(CPView)positioningView preferredEdge:(CPRectEdge)preferredEdge
{
if (!_contentViewController)
[CPException raise:CPInternalInconsistencyException reason:@"contentViewController must not be nil"];
if (_implementedDelegateMethods & CPPopoverDelegate_popover_willShow_)
[_delegate popoverWillShow:self];
if (!_attachedWindow || _needsNewAttachedWindow || [_attachedWindow isVisible])
{
var styleMask = (_behavior == CPPopoverBehaviorTransient) ? CPClosableOnBlurWindowMask : nil;
_attachedWindow = [[_CPAttachedWindow alloc] initWithContentRect:CGRectMakeZero() styleMask:styleMask];
_needsNewAttachedWindow = NO;
}
[_attachedWindow setAppearance:_appearance];
[_attachedWindow setAnimates:_animates];
[_attachedWindow setDelegate:self];
[_attachedWindow setMovableByWindowBackground:NO];
[_attachedWindow setFrame:[_attachedWindow frameRectForContentRect:[[_contentViewController view] frame]]];
[_attachedWindow setContentView:[_contentViewController view]];
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_)
[_delegate popoverDidShow:self];
}
/*!
Closes the popover
*/
- (void)close
{
if (_implementedDelegateMethods & CPPopoverDelegate_popover_shouldClose_)
if (![_delegate popoverShouldClose:self])
return;
if (_implementedDelegateMethods & CPPopoverDelegate_popover_willClose_)
[_delegate popoverWillClose:self];
[_attachedWindow close];
// popoverDidClose will be sent from attachedWindowDidClose, since
// the attached window will close asynchronously when animating.
}
#pragma mark -
#pragma mark Action
/*!
Close the popover
@param aSender the sender of the action
*/
- (IBAction)performClose:(id)aSender
{
[self close];
}
#pragma mark -
#pragma mark Delegates
/*! @ignore */
- (BOOL)attachedWindowShouldClose:(_CPAttachedWindow)anAttachedWindow
{
[self close];
// We return NO, because we want the CPPopover to determine
// if the attached window can be closed and to give us a chance
// to send delegate messages.
return NO;
}
/*! @ignore */
- (void)attachedWindowDidClose:(_CPAttachedWindow)anAttachedWindow
{
if (_implementedDelegateMethods & CPPopoverDelegate_popover_didClose_)
[_delegate popoverDidClose:self];
}
@end
var CPPopoverNeedsNewAttachedWindowKey = @"CPPopoverNeedsNewAttachedWindowKey",
CPPopoverAppearanceKey = @"CPPopoverAppearanceKey",
CPPopoverAnimatesKey = @"CPPopoverAnimatesKey",
CPPopoverContentViewControllerKey = @"CPPopoverContentViewControllerKey",
CPPopoverDelegateKey = @"CPPopoverDelegateKey",
CPPopoverBehaviorKey = @"CPPopoverBehaviorKey";
@implementation CPPopover (CPCoding)
- (id)initWithCoder:(CPCoder)aCoder
{
self = [super initWithCoder:aCoder];
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]];
}
return self;
}
- (void)encodeWithCoder:(CPCoder)aCoder
{
[super encodeWithCoder:aCoder];
[aCoder encodeBool:_needsNewAttachedWindow forKey:CPPopoverNeedsNewAttachedWindowKey];
[aCoder encodeInt:_appearance forKey:CPPopoverAppearanceKey];
[aCoder encodeBool:_animates forKey:CPPopoverAnimatesKey];
[aCoder encodeObject:_contentViewController forKey:CPPopoverContentViewControllerKey];
[aCoder encodeObject:_delegate forKey:CPPopoverDelegateKey];
[aCoder encodeInt:_behavior forKey:CPPopoverBehaviorKey];
}
@end
+2 -2
View File
@@ -477,7 +477,7 @@ var CPProgressIndicatorSpinningStyleColors = nil,
_doubleValue = [aCoder decodeObjectForKey:@"_doubleValue"];
_controlSize = [aCoder decodeObjectForKey:@"_controlSize"];
_isIndeterminate = [aCoder decodeObjectForKey:@"_isIndeterminate"];
_style = [aCoder decodeObjectForKey:@"_style"];
_style = [aCoder decodeIntForKey:@"_style"];
_isAnimating = [aCoder decodeObjectForKey:@"_isAnimating"];
_isDisplayedWhenStoppedSet = [aCoder decodeObjectForKey:@"_isDisplayedWhenStoppedSet"];
_isDisplayedWhenStopped = [aCoder decodeObjectForKey:@"_isDisplayedWhenStopped"];
@@ -495,7 +495,7 @@ var CPProgressIndicatorSpinningStyleColors = nil,
[aCoder encodeObject:_doubleValue forKey:@"_doubleValue"];
[aCoder encodeObject:_controlSize forKey:@"_controlSize"];
[aCoder encodeObject:_isIndeterminate forKey:@"_isIndeterminate"];
[aCoder encodeObject:_style forKey:@"_style"];
[aCoder encodeInt:_style forKey:@"_style"];
[aCoder encodeObject:_isAnimating forKey:@"_isAnimating"];
[aCoder encodeObject:_isDisplayedWhenStoppedSet forKey:@"_isDisplayedWhenStoppedSet"];
[aCoder encodeObject:_isDisplayedWhenStopped forKey:@"_isDisplayedWhenStopped"];
+8 -2
View File
@@ -150,6 +150,14 @@ CPRadioImageOffset = 4.0;
[_radioGroup _setSelectedRadio:self];
}
- (void)sendAction:(SEL)anAction to:(id)anObject
{
[super sendAction:anAction to:anObject];
if (_radioGroup)
[CPApp sendAction:[_radioGroup action] to:[_radioGroup target] from:_radioGroup];
}
@end
var CPRadioRadioGroupKey = @"CPRadioRadioGroupKey";
@@ -220,8 +228,6 @@ var CPRadioRadioGroupKey = @"CPRadioRadioGroupKey";
[_selectedRadio setState:CPOffState];
_selectedRadio = aRadio;
[CPApp sendAction:_action to:_target from:self];
}
- (CPRadio)selectedRadio
+2 -2
View File
@@ -200,7 +200,7 @@
if (isPopup)
{
itemArray = [[templateView itemArray] valueForKey:@"title"];
itemsCount = [itemArray count],
itemsCount = [itemArray count];
menuIndex = 0;
}
@@ -501,4 +501,4 @@ var CPPredicateTemplatesKey = @"CPPredicateTemplates";
@end
/*! @endcond */
/*! @endcond */
@@ -20,17 +20,17 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
CPUndefinedAttributeType = 0,
CPInteger16AttributeType = 100,
CPInteger32AttributeType = 200,
CPInteger64AttributeType = 300,
CPDecimalAttributeType = 400,
CPDoubleAttributeType = 500,
CPFloatAttributeType = 600,
CPStringAttributeType = 700,
CPBooleanAttributeType = 800,
CPDateAttributeType = 900,
CPBinaryDataAttributeType = 1000,
CPUndefinedAttributeType = 0;
CPInteger16AttributeType = 100;
CPInteger32AttributeType = 200;
CPInteger64AttributeType = 300;
CPDecimalAttributeType = 400;
CPDoubleAttributeType = 500;
CPFloatAttributeType = 600;
CPStringAttributeType = 700;
CPBooleanAttributeType = 800;
CPDateAttributeType = 900;
CPBinaryDataAttributeType = 1000;
CPTransformableAttributeType = 1800;
@implementation CPPredicateEditorRowTemplate : CPObject
@@ -785,4 +785,4 @@ var CPPredicateTemplateTypeKey = @"CPPredicateTemplateType",
}
@end
/*! @endcond */
/*! @endcond */
@@ -16,12 +16,12 @@ var GRADIENT_NORMAL,
{
if (CPBrowserIsEngine(CPWebKitBrowserEngine))
{
GRADIENT_NORMAL = "-webkit-gradient(linear, left top, left bottom, from(rgb(252, 252, 252)), to(rgb(223, 223, 223)))",
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_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))";
}
}
@@ -35,7 +35,7 @@ var GRADIENT_NORMAL,
style.border = "1px solid rgb(189, 189, 189)";
style.filter = IE_FILTER;
[self setTextColor:[CPColor colorWithWhite:101/255 alpha:1]];
[self setTextColor:[CPColor colorWithWhite:101 / 255 alpha:1]];
[self setBordered:NO];
}
+1011 -583
View File
File diff suppressed because it is too large Load Diff
+274 -73
View File
@@ -5,6 +5,9 @@
* Created by Francisco Tolmasky.
* Copyright 2008, 280 North, Inc.
*
* Modified to match Lion style by Antoine Mercadal 2011
* <antoine.mercadal@archipelproject.org>
*
* 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
@@ -20,8 +23,9 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "CPControl.j"
#include "../Foundation/Foundation.h"
@import "CPControl.j"
// CPScroller Constants
CPScrollerNoPart = 0;
@@ -54,6 +58,17 @@ NAMES_FOR_PARTS[CPScrollerKnobSlot] = @"knob-slot";
NAMES_FOR_PARTS[CPScrollerKnob] = @"knob";
CPScrollerStyleLegacy = 0;
CPScrollerStyleOverlay = 1;
CPScrollerKnobStyleDefault = 0;
CPScrollerKnobStyleDark = 1;
CPScrollerKnobStyleLight = 2;
CPThemeStateScrollViewLegacy = CPThemeState("scroller-style-legacy");
CPThemeStateScrollerKnobLight = CPThemeState("scroller-knob-light");
CPThemeStateScrollerKnobDark = CPThemeState("scroller-knob-dark");
@implementation CPScroller : CPControl
{
CPControlSize _controlSize;
@@ -68,8 +83,19 @@ NAMES_FOR_PARTS[CPScrollerKnob] = @"knob";
CPScrollerPart _trackingPart;
float _trackingFloatValue;
CGPoint _trackingStartPoint;
CPViewAnimation _animationScroller;
BOOL _allowFadingOut @accessors(getter=allowFadingOut);
int _style;
CPTimer _timerFadeOut;
BOOL _isMouseOver;
}
#pragma mark -
#pragma mark Class methods
+ (CPString)defaultThemeClass
{
return "scroller";
@@ -78,49 +104,43 @@ NAMES_FOR_PARTS[CPScrollerKnob] = @"knob";
+ (id)themeAttributes
{
return [CPDictionary dictionaryWithJSObject:{
@"scroller-width": 15.0,
@"knob-slot-color": [CPColor lightGrayColor],
@"scroller-width": 7.0,
@"knob-slot-color": [CPNull null],
@"decrement-line-color": [CPNull null],
@"increment-line-color": [CPNull null],
@"knob-color": [CPColor grayColor],
@"knob-color": [CPNull null],
@"decrement-line-size":_CGSizeMakeZero(),
@"increment-line-size":_CGSizeMakeZero(),
@"track-inset":_CGInsetMakeZero(),
@"knob-inset": _CGInsetMakeZero(),
@"minimum-knob-length":21.0
}]
@"minimum-knob-length":21.0,
@"track-border-overlay": 9.0
}];
}
// Calculating Layout
- (id)initWithFrame:(CGRect)aFrame
+ (float)scrollerWidth
{
self = [super initWithFrame:aFrame];
if (self)
{
_controlSize = CPRegularControlSize;
_partRects = [];
[self setFloatValue:0.0];
[self setKnobProportion:1.0];
_hitPart = CPScrollerNoPart;
[self _calculateIsVertical];
}
return self;
return [self scrollerWidthInStyle:CPScrollerStyleLegacy];
}
// Determining CPScroller Size
/*!
Returns the CPScroller's width for a CPRegularControlSize.
*/
+ (float)scrollerWidth
+ (float)scrollerWidthInStyle:(int)aStyle
{
return [[[CPScroller alloc] init] currentValueForThemeAttribute:@"scroller-width"];
var scroller = [[self alloc] init];
if (aStyle == CPScrollerStyleLegacy)
return [scroller valueForThemeAttribute:@"scroller-width" inState:CPThemeStateScrollViewLegacy];
return [scroller currentValueForThemeAttribute:@"scroller-width"];
}
/*!
Returns the CPScroller's overlay value.
*/
+ (float)scrollerOverlay
{
return [[[self alloc] init] currentValueForThemeAttribute:@"track-border-overlay"];
}
/*!
@@ -132,6 +152,87 @@ NAMES_FOR_PARTS[CPScrollerKnob] = @"knob";
return [self scrollerWidth];
}
#pragma mark -
#pragma mark Initialization
- (id)initWithFrame:(CGRect)aFrame
{
if (self = [super initWithFrame:aFrame])
{
_controlSize = CPRegularControlSize;
_partRects = [];
[self setFloatValue:0.0];
[self setKnobProportion:1.0];
_hitPart = CPScrollerNoPart;
_allowFadingOut = YES;
_isMouseOver = NO;
_style = CPScrollerStyleOverlay;
var paramAnimFadeOut = [CPDictionary dictionaryWithObjects:[self, CPViewAnimationFadeOutEffect]
forKeys:[CPViewAnimationTargetKey, CPViewAnimationEffectKey]];
_animationScroller = [[CPViewAnimation alloc] initWithDuration:0.2 animationCurve:CPAnimationEaseInOut];
[_animationScroller setViewAnimations:[paramAnimFadeOut]];
[_animationScroller setDelegate:self];
[self setAlphaValue:0.0];
[self _calculateIsVertical];
}
return self;
}
#pragma mark -
#pragma mark Getters / Setters
/*!
Returns the scroller's style
*/
- (void)style
{
return _style;
}
/*!
Set the scroller's control size
@param aStyle the scroller style: CPScrollerStyleLegacy or CPScrollerStyleOverlay
*/
- (void)setStyle:(id)aStyle
{
if (_style != nil && _style === aStyle)
return;
_style = aStyle;
if (_style === CPScrollerStyleLegacy)
{
[self fadeIn];
[self setThemeState:CPThemeStateScrollViewLegacy];
}
else
{
_allowFadingOut = YES;
[self unsetThemeState:CPThemeStateScrollViewLegacy];
}
[self _adjustScrollerSize];
}
- (void)setObjectValue:(id)aValue
{
[super setObjectValue:MIN(1.0, MAX(0.0, +aValue))];
}
/*!
Returns the scroller's control size
*/
- (CPControlSize)controlSize
{
return _controlSize;
}
/*!
Sets the scroller's size.
@param aControlSize the scroller's size
@@ -147,27 +248,6 @@ NAMES_FOR_PARTS[CPScrollerKnob] = @"knob";
[self setNeedsDisplay:YES];
}
/*!
Returns the scroller's control size
*/
- (CPControlSize)controlSize
{
return _controlSize;
}
- (void)setObjectValue:(id)aValue
{
[super setObjectValue:MIN(1.0, MAX(0.0, +aValue))];
}
- (void)setKnobProportion:(float)aProportion
{
_knobProportion = MIN(1.0, MAX(0.0001, aProportion));
[self setNeedsDisplay:YES];
[self setNeedsLayout];
}
/*!
Return's the knob's proportion
*/
@@ -176,17 +256,50 @@ NAMES_FOR_PARTS[CPScrollerKnob] = @"knob";
return _knobProportion;
}
- (id)currentValueForThemeAttribute:(CPString)anAttributeName
/*!
Set the knob's proportion
@param aProportion the desired proportion
*/
- (void)setKnobProportion:(float)aProportion
{
var themeState = _themeState;
if (!_IS_NUMERIC(aProportion))
[CPException raise:CPInvalidArgumentException reason:"aProportion must be numeric"];
if (NAMES_FOR_PARTS[_hitPart] + "-color" !== anAttributeName)
themeState &= ~CPThemeStateHighlighted;
_knobProportion = MIN(1.0, MAX(0.0001, aProportion));
return [self valueForThemeAttribute:anAttributeName inState:themeState];
[self setNeedsDisplay:YES];
[self setNeedsLayout];
}
// Calculating Layout
#pragma mark -
#pragma mark Privates
/*! @ignore */
- (void)_adjustScrollerSize
{
var frame = [self frame],
scrollerWidth = [self currentValueForThemeAttribute:@"scroller-width"];
if ([self isVertical] && CGRectGetWidth(frame) !== scrollerWidth)
frame.size.width = scrollerWidth;
if (![self isVertical] && CGRectGetHeight(frame) !== scrollerWidth)
frame.size.height = scrollerWidth;
[self setFrame:frame];
}
/*! @ignore */
- (void)_performFadeOut:(CPTimer)aTimer
{
[self fadeOut];
_timerFadeOut = nil;
}
#pragma mark -
#pragma mark Utilities
- (CGRect)rectForPart:(CPScrollerPart)aPart
{
@@ -208,6 +321,9 @@ NAMES_FOR_PARTS[CPScrollerKnob] = @"knob";
// The ordering of these tests is important. We check the knob and
// page rects first since they may overlap with the arrows.
if (![self hasThemeState:CPThemeStateSelected])
return CPScrollerNoPart;
if (CGRectContainsPoint([self rectForPart:CPScrollerKnob], aPoint))
return CPScrollerKnob;
@@ -330,7 +446,35 @@ NAMES_FOR_PARTS[CPScrollerKnob] = @"knob";
return _usableParts;
}
// Drawing the Parts
/*!
Display the scroller
*/
- (void)fadeIn
{
if (_isMouseOver && _knobProportion != 1.0)
[self setThemeState:CPThemeStateSelected];
if (_timerFadeOut)
[_timerFadeOut invalidate];
[self setAlphaValue:1.0];
}
/*!
Start the fade out anination
*/
- (void)fadeOut
{
if ([self hasThemeState:CPThemeStateScrollViewLegacy])
return;
[_animationScroller startAnimation];
}
#pragma mark -
#pragma mark Drawing
/*!
Draws the specified arrow and sets the highlight.
@param anArrow the arrow to draw
@@ -382,7 +526,8 @@ NAMES_FOR_PARTS[CPScrollerKnob] = @"knob";
[self checkSpaceForParts];
var index = 0,
count = PARTS_ARRANGEMENT.length;
count = PARTS_ARRANGEMENT.length,
view;
for (; index < count; ++index)
{
@@ -458,7 +603,8 @@ NAMES_FOR_PARTS[CPScrollerKnob] = @"knob";
[CPApp setTarget:self selector:@selector(trackKnob:) forNextEventMatchingMask:CPLeftMouseDraggedMask | CPLeftMouseUpMask untilDate:nil inMode:nil dequeue:YES];
[self sendAction:[self action] to:[self target]];
if (type === CPLeftMouseDragged)
[self sendAction:[self action] to:[self target]];
}
/*!
@@ -564,6 +710,20 @@ NAMES_FOR_PARTS[CPScrollerKnob] = @"knob";
[self setNeedsLayout];
}
#pragma mark -
#pragma mark Overrides
- (id)currentValueForThemeAttribute:(CPString)anAttributeName
{
var themeState = _themeState;
if (NAMES_FOR_PARTS[_hitPart] + "-color" !== anAttributeName)
themeState &= ~CPThemeStateHighlighted;
return [self valueForThemeAttribute:anAttributeName inState:themeState];
}
- (void)mouseDown:(CPEvent)anEvent
{
if (![self isEnabled])
@@ -582,10 +742,52 @@ NAMES_FOR_PARTS[CPScrollerKnob] = @"knob";
}
}
- (void)mouseEntered:(CPEvent)anEvent
{
[super mouseEntered:anEvent];
if (_timerFadeOut)
[_timerFadeOut invalidate];
if (![self isEnabled])
return;
_allowFadingOut = NO;
_isMouseOver = YES;
if ([self alphaValue] > 0 && _knobProportion != 1.0)
[self setThemeState:CPThemeStateSelected];
}
- (void)mouseExited:(CPEvent)anEvent
{
[super mouseExited:anEvent];
if ([self isHidden] || ![self isEnabled] || !_isMouseOver)
return;
_allowFadingOut = YES;
_isMouseOver = NO;
if (_timerFadeOut)
[_timerFadeOut invalidate];
_timerFadeOut = [CPTimer scheduledTimerWithTimeInterval:1.2 target:self selector:@selector(_performFadeOut:) userInfo:nil repeats:NO];
}
#pragma mark -
#pragma mark Delegates
- (void)animationDidEnd:(CPAnimation)animation
{
[self unsetThemeState:CPThemeStateSelected];
}
@end
var CPScrollerControlSizeKey = "CPScrollerControlSize",
CPScrollerKnobProportionKey = "CPScrollerKnobProportion";
var CPScrollerControlSizeKey = @"CPScrollerControlSize",
CPScrollerKnobProportionKey = @"CPScrollerKnobProportion",
CPScrollerStyleKey = @"CPScrollerStyleKey";
@implementation CPScroller (CPCoding)
@@ -605,20 +807,18 @@ var CPScrollerControlSizeKey = "CPScrollerControlSize",
_hitPart = CPScrollerNoPart;
_allowFadingOut = YES;
_isMouseOver = NO;
var paramAnimFadeOut = [CPDictionary dictionaryWithObjects:[self, CPViewAnimationFadeOutEffect]
forKeys:[CPViewAnimationTargetKey, CPViewAnimationEffectKey]];
_animationScroller = [[CPViewAnimation alloc] initWithDuration:0.2 animationCurve:CPAnimationEaseInOut];
[_animationScroller setViewAnimations:[paramAnimFadeOut]];
[_animationScroller setDelegate:self];
[self setAlphaValue:0.0];
[self _calculateIsVertical];
// Adjust the size of the scroller if the size from cib
// isn't equal to the scrollerWidth
var frame = [self frame],
scrollerWidth = [CPScroller scrollerWidth];
if ([self isVertical] && CGRectGetWidth(frame) !== scrollerWidth)
frame.size.width = scrollerWidth;
if (![self isVertical] && CGRectGetHeight(frame) !== scrollerWidth)
frame.size.height = scrollerWidth;
[self setFrame:frame];
[self setStyle:[aCoder decodeIntForKey:CPScrollerStyleKey]];
}
return self;
@@ -630,6 +830,7 @@ var CPScrollerControlSizeKey = "CPScrollerControlSize",
[aCoder encodeInt:_controlSize forKey:CPScrollerControlSizeKey];
[aCoder encodeFloat:_knobProportion forKey:CPScrollerKnobProportionKey];
[aCoder encodeInt:_style forKey:CPScrollerStyleKey];
}
@end
+38 -37
View File
@@ -47,7 +47,6 @@ var LIGHT_LEFT_INSET = 3.0,
/*!
@ingroup appkit
*/
@implementation CPShadowView : CPView
{
CPShadowWeight _weight;
@@ -60,35 +59,33 @@ var LIGHT_LEFT_INSET = 3.0,
var bundle = [CPBundle bundleForClass:[self class]];
CPShadowViewLightBackgroundColor = [CPColor colorWithPatternImage:[[CPNinePartImage alloc] initWithImageSlices:
[
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPShadowView/CPShadowViewLightTopLeft.png"] size:CGSizeMake(9.0, 9.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPShadowView/CPShadowViewLightTop.png"] size:CGSizeMake(1.0, 9.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPShadowView/CPShadowViewLightTopRight.png"] size:CGSizeMake(9.0, 9.0)],
CPShadowViewLightBackgroundColor = CPColorWithImages([
[@"CPShadowView/CPShadowViewLightTopLeft.png", 9.0, 9.0, bundle],
[@"CPShadowView/CPShadowViewLightTop.png", 1.0, 9.0, bundle],
[@"CPShadowView/CPShadowViewLightTopRight.png", 9.0, 9.0, bundle],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPShadowView/CPShadowViewLightLeft.png"] size:CGSizeMake(9.0, 1.0)],
nil,
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPShadowView/CPShadowViewLightRight.png"] size:CGSizeMake(9.0, 1.0)],
[@"CPShadowView/CPShadowViewLightLeft.png", 9.0, 1.0, bundle],
nil,
[@"CPShadowView/CPShadowViewLightRight.png", 9.0, 1.0, bundle],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPShadowView/CPShadowViewLightBottomLeft.png"] size:CGSizeMake(9.0, 9.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPShadowView/CPShadowViewLightBottom.png"] size:CGSizeMake(1.0, 9.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPShadowView/CPShadowViewLightBottomRight.png"] size:CGSizeMake(9.0, 9.0)]
]]];
[@"CPShadowView/CPShadowViewLightBottomLeft.png", 9.0, 9.0, bundle],
[@"CPShadowView/CPShadowViewLightBottom.png", 1.0, 9.0, bundle],
[@"CPShadowView/CPShadowViewLightBottomRight.png", 9.0, 9.0, bundle]
]);
CPShadowViewHeavyBackgroundColor = [CPColor colorWithPatternImage:[[CPNinePartImage alloc] initWithImageSlices:
[
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPShadowView/CPShadowViewHeavyTopLeft.png"] size:CGSizeMake(17.0, 17.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPShadowView/CPShadowViewHeavyTop.png"] size:CGSizeMake(1.0, 17.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPShadowView/CPShadowViewHeavyTopRight.png"] size:CGSizeMake(17.0, 17.0)],
CPShadowViewHeavyBackgroundColor = CPColorWithImages([
[@"CPShadowView/CPShadowViewHeavyTopLeft.png", 17.0, 17.0, bundle],
[@"CPShadowView/CPShadowViewHeavyTop.png", 1.0, 17.0, bundle],
[@"CPShadowView/CPShadowViewHeavyTopRight.png", 17.0, 17.0, bundle],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPShadowView/CPShadowViewHeavyLeft.png"] size:CGSizeMake(17.0, 1.0)],
nil,
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPShadowView/CPShadowViewHeavyRight.png"] size:CGSizeMake(17.0, 1.0)],
[@"CPShadowView/CPShadowViewHeavyLeft.png", 17.0, 1.0, bundle],
nil,
[@"CPShadowView/CPShadowViewHeavyRight.png", 17.0, 1.0, bundle],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPShadowView/CPShadowViewHeavyBottomLeft.png"] size:CGSizeMake(17.0, 17.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPShadowView/CPShadowViewHeavyBottom.png"] size:CGSizeMake(1.0, 17.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPShadowView/CPShadowViewHeavyBottomRight.png"] size:CGSizeMake(17.0, 17.0)]
]]];
[@"CPShadowView/CPShadowViewHeavyBottomLeft.png", 17.0, 17.0, bundle],
[@"CPShadowView/CPShadowViewHeavyBottom.png", 1.0, 17.0, bundle],
[@"CPShadowView/CPShadowViewHeavyBottomRight.png", 17.0, 17.0, bundle]
]);
}
+ (id)shadowViewEnclosingView:(CPView)aView
@@ -98,20 +95,24 @@ var LIGHT_LEFT_INSET = 3.0,
+ (id)shadowViewEnclosingView:(CPView)aView withWeight:(CPShadowWeight)aWeight
{
var shadowView = [[CPShadowView alloc] initWithFrame:[aView frame]];
[shadowView setWeight:aWeight];
var shadowView = [[self alloc] initWithFrame:[aView frame]];
var size = [shadowView frame].size,
width = size.width - [shadowView leftInset] - [shadowView rightInset],
height = size.height - [shadowView topInset] - [shadowView bottomInset],
enclosingView = [aView superview];
if (shadowView)
{
[shadowView setWeight:aWeight];
[shadowView setHitTests:[aView hitTests]];
[shadowView setAutoresizingMask:[aView autoresizingMask]];
[aView removeFromSuperview];
[shadowView addSubview:aView];
[aView setFrame:CGRectMake([shadowView leftInset], [shadowView topInset], width, height)]
[enclosingView addSubview:shadowView];
var size = [shadowView frame].size,
width = size.width - [shadowView leftInset] - [shadowView rightInset],
height = size.height - [shadowView topInset] - [shadowView bottomInset],
enclosingView = [aView superview];
[shadowView setHitTests:[aView hitTests]];
[shadowView setAutoresizingMask:[aView autoresizingMask]];
[aView removeFromSuperview];
[shadowView addSubview:aView];
[aView setFrame:CGRectMake([shadowView leftInset], [shadowView topInset], width, height)]
[enclosingView addSubview:shadowView];
}
return shadowView;
}
+14
View File
@@ -45,6 +45,7 @@ CPSoundPlayBackStatePause = 2;
CPString _name @accessors(property=name);
id _delegate @accessors(property=delegate);
BOOL _playRequestBeforeLoad;
HTMLAudioElement _audioTag;
int _loadStatus;
int _playBackStatus;
@@ -61,6 +62,7 @@ CPSoundPlayBackStatePause = 2;
_loops = NO;
_audioTag = document.createElement("audio");
_audioTag.preload = YES;
_playRequestBeforeLoad = NO;
_audioTag.addEventListener("canplay", function()
{
@@ -138,6 +140,12 @@ CPSoundPlayBackStatePause = 2;
- (void)_soundDidload
{
_loadStatus = CPSoundLoadStateCanBePlayed;
if (_playRequestBeforeLoad)
{
_playRequestBeforeLoad = NO;
[self play];
}
}
/*! @ignore
@@ -167,6 +175,12 @@ CPSoundPlayBackStatePause = 2;
*/
- (BOOL)play
{
if (_loadStatus === CPSoundLoadStateLoading)
{
_playRequestBeforeLoad = YES;
return YES;
}
if ((_loadStatus !== CPSoundLoadStateCanBePlayed)
|| (_playBackStatus === CPSoundPlayBackStatePlay))
return NO;
+322 -59
View File
@@ -20,16 +20,43 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "../Foundation/Foundation.h"
@import "CPButtonBar.j"
@import "CPImage.j"
@import "CPView.j"
#define SPLIT_VIEW_MAYBE_POST_WILL_RESIZE() \
if ((_suppressResizeNotificationsMask & DidPostWillResizeNotification) === 0) \
{ \
[self _postNotificationWillResize]; \
_suppressResizeNotificationsMask |= DidPostWillResizeNotification; \
}
#define SPLIT_VIEW_MAYBE_POST_DID_RESIZE() \
if ((_suppressResizeNotificationsMask & ShouldSuppressResizeNotifications) !== 0) \
_suppressResizeNotificationsMask |= DidSuppressResizeNotification; \
else \
[self _postNotificationDidResize];
#define SPLIT_VIEW_DID_SUPPRESS_RESIZE_NOTIFICATION() \
((_suppressResizeNotificationsMask & DidSuppressResizeNotification) !== 0)
#define SPLIT_VIEW_SUPPRESS_RESIZE_NOTIFICATIONS(shouldSuppress) \
if (shouldSuppress) \
_suppressResizeNotificationsMask |= ShouldSuppressResizeNotifications; \
else \
_suppressResizeNotificationsMask = 0;
CPSplitViewDidResizeSubviewsNotification = @"CPSplitViewDidResizeSubviewsNotification";
CPSplitViewWillResizeSubviewsNotification = @"CPSplitViewWillResizeSubviewsNotification";
var CPSplitViewHorizontalImage = nil,
CPSplitViewVerticalImage = nil;
CPSplitViewVerticalImage = nil,
ShouldSuppressResizeNotifications = 1,
DidPostWillResizeNotification = 1 << 1,
DidSuppressResizeNotification = 1 << 2;
/*!
@ingroup appkit
@@ -45,24 +72,29 @@ var CPSplitViewHorizontalImage = nil,
@implementation CPSplitView : CPView
{
id _delegate;
BOOL _isVertical;
BOOL _isPaneSplitter;
id _delegate;
BOOL _isVertical;
BOOL _isPaneSplitter;
int _currentDivider;
float _initialOffset;
float _preCollapsePosition;
int _currentDivider;
float _initialOffset;
CPDictionary _preCollapsePositions;
CPString _originComponent;
CPString _sizeComponent;
CPString _originComponent;
CPString _sizeComponent;
CPArray _DOMDividerElements;
CPString _dividerImagePath;
int _drawingDivider;
CPArray _DOMDividerElements;
CPString _dividerImagePath;
int _drawingDivider;
BOOL _needsResizeSubviews;
CPString _autosaveName;
BOOL _shouldAutosave;
BOOL _needsRestoreFromAutosave;
CPArray _buttonBars;
BOOL _needsResizeSubviews;
int _suppressResizeNotificationsMask;
CPArray _buttonBars;
}
+ (CPString)defaultThemeClass
@@ -93,11 +125,15 @@ var CPSplitViewHorizontalImage = nil,
{
if (self = [super initWithFrame:aFrame])
{
_suppressResizeNotificationsMask = 0;
_preCollapsePositions = [CPMutableDictionary new];
_currentDivider = CPNotFound;
_DOMDividerElements = [];
_buttonBars = [];
_shouldAutosave = YES;
[self _setVertical:YES];
}
@@ -412,7 +448,6 @@ var CPSplitViewHorizontalImage = nil,
{
_currentDivider = CPNotFound;
[self _updateResizeCursor:anEvent];
[self _postNotificationDidResize];
}
return;
@@ -436,7 +471,8 @@ var CPSplitViewHorizontalImage = nil,
[_delegate respondsToSelector:@selector(splitView:shouldCollapseSubview:forDoubleClickOnDividerAtIndex:)])
{
var minPosition = [self minPossiblePositionOfDividerAtIndex:i],
maxPosition = [self maxPossiblePositionOfDividerAtIndex:i];
maxPosition = [self maxPossiblePositionOfDividerAtIndex:i],
_preCollapsePosition = [_preCollapsePositions objectForKey:"" + i] || 0;
if ([_delegate splitView:self canCollapseSubview:_subviews[i]] && [_delegate splitView:self shouldCollapseSubview:_subviews[i] forDoubleClickOnDividerAtIndex:i])
{
@@ -526,20 +562,34 @@ var CPSplitViewHorizontalImage = nil,
// If we are currently tracking, keep the resize cursor active even outside of hit areas.
if (_currentDivider === i || (_currentDivider == CPNotFound && [self cursorAtPoint:point hitDividerAtIndex:i]))
{
var frame = [_subviews[i] frame],
size = frame.size[_sizeComponent],
startPosition = frame.origin[_originComponent] + size,
var frameA = [_subviews[i] frame],
sizeA = frameA.size[_sizeComponent],
startPosition = frameA.origin[_originComponent] + sizeA,
frameB = [_subviews[i + 1] frame],
sizeB = frameB.size[_sizeComponent],
canShrink = [self _realPositionForPosition:startPosition - 1 ofDividerAtIndex:i] < startPosition,
canGrow = [self _realPositionForPosition:startPosition + 1 ofDividerAtIndex:i] > startPosition,
cursor = [CPCursor arrowCursor];
if (size === 0)
if (sizeA === 0)
canGrow = YES; // Subview is collapsed.
else if (!canShrink &&
[_delegate respondsToSelector:@selector(splitView:canCollapseSubview:)] &&
[_delegate splitView:self canCollapseSubview:_subviews[i]])
canShrink = YES; // Subview is collapsible.
if (sizeB === 0)
{
// Right/lower subview is collapsed.
canGrow = NO;
// It's safe to assume it can always be uncollapsed.
canShrink = YES;
}
else if (!canGrow &&
[_delegate respondsToSelector:@selector(splitView:canCollapseSubview:)] &&
[_delegate splitView:self canCollapseSubview:_subviews[i + 1]])
canGrow = YES; // Right/lower subview is collapsible.
if (_isVertical && canShrink && canGrow)
cursor = [CPCursor resizeLeftRightCursor];
else if (_isVertical && canShrink)
@@ -597,7 +647,15 @@ var CPSplitViewHorizontalImage = nil,
{
// not sure where this should override other positions?
if ([_delegate respondsToSelector:@selector(splitView:constrainSplitPosition:ofSubviewAt:)])
position = [_delegate splitView:self constrainSplitPosition:position ofSubviewAt:dividerIndex];
{
var proposedPosition = [_delegate splitView:self constrainSplitPosition:position ofSubviewAt:dividerIndex];
// Silently ignore bad positions which could result from odd delegate responses. We don't want these
// bad results to go into the system and cause havoc with frame sizes as the split view tries to resize
// its subviews.
if (_IS_NUMERIC(proposedPosition))
position = proposedPosition;
}
var proposedMax = [self maxPossiblePositionOfDividerAtIndex:dividerIndex],
proposedMin = [self minPossiblePositionOfDividerAtIndex:dividerIndex],
@@ -605,18 +663,33 @@ var CPSplitViewHorizontalImage = nil,
actualMin = proposedMin;
if ([_delegate respondsToSelector:@selector(splitView:constrainMinCoordinate:ofSubviewAt:)])
actualMin = [_delegate splitView:self constrainMinCoordinate:proposedMin ofSubviewAt:dividerIndex];
{
var proposedActualMin = [_delegate splitView:self constrainMinCoordinate:proposedMin ofSubviewAt:dividerIndex];
if (_IS_NUMERIC(proposedActualMin))
actualMin = proposedActualMin;
}
if ([_delegate respondsToSelector:@selector(splitView:constrainMaxCoordinate:ofSubviewAt:)])
actualMax = [_delegate splitView:self constrainMaxCoordinate:proposedMax ofSubviewAt:dividerIndex];
{
var proposedActualMax = [_delegate splitView:self constrainMaxCoordinate:proposedMax ofSubviewAt:dividerIndex];
if (_IS_NUMERIC(proposedActualMax))
actualMax = proposedActualMax;
}
var viewA = _subviews[dividerIndex],
viewB = _subviews[dividerIndex + 1],
realPosition = MAX(MIN(position, actualMax), actualMin);
if (position < proposedMin + (actualMin - proposedMin) / 2)
// Is this position past the halfway point to collapse?
if (position < proposedMin + (actualMin - proposedMin) / 2)
if ([_delegate respondsToSelector:@selector(splitView:canCollapseSubview:)])
if ([_delegate splitView:self canCollapseSubview:viewA])
realPosition = proposedMin;
// We can also collapse to the right.
if (position > proposedMax - (proposedMax - actualMax) / 2)
if ([_delegate respondsToSelector:@selector(splitView:canCollapseSubview:)])
if ([_delegate splitView:self canCollapseSubview:viewB])
realPosition = proposedMax;
return realPosition;
}
@@ -628,6 +701,7 @@ var CPSplitViewHorizontalImage = nil,
*/
- (void)setPosition:(float)position ofDividerAtIndex:(int)dividerIndex
{
SPLIT_VIEW_SUPPRESS_RESIZE_NOTIFICATIONS(YES);
[self _adjustSubviewsWithCalculatedSize];
var realPosition = [self _realPositionForPosition:position ofDividerAtIndex:dividerIndex];
@@ -635,32 +709,59 @@ var CPSplitViewHorizontalImage = nil,
var viewA = _subviews[dividerIndex],
frameA = [viewA frame],
viewB = _subviews[dividerIndex + 1],
frameB = [viewB frame];
_preCollapsePosition = 0;
frameB = [viewB frame],
_preCollapsePosition = 0;
var preSize = frameA.size[_sizeComponent];
frameA.size[_sizeComponent] = realPosition - frameA.origin[_originComponent];
if (preSize !== 0 && frameA.size[_sizeComponent] === 0)
_preCollapsePosition = preSize;
[_subviews[dividerIndex] setFrame:frameA];
if (preSize !== frameA.size[_sizeComponent])
{
SPLIT_VIEW_MAYBE_POST_WILL_RESIZE();
[_subviews[dividerIndex] setFrame:frameA];
SPLIT_VIEW_MAYBE_POST_DID_RESIZE();
}
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 = preSize;
_preCollapsePosition = frameB.origin[_originComponent];
frameB.origin[_originComponent] = realPosition + [self dividerThickness];
[_subviews[dividerIndex + 1] setFrame:frameB];
if (preSize !== frameB.size[_sizeComponent] || preOrigin !== frameB.origin[_originComponent])
{
SPLIT_VIEW_MAYBE_POST_WILL_RESIZE();
[_subviews[dividerIndex + 1] setFrame:frameB];
SPLIT_VIEW_MAYBE_POST_DID_RESIZE();
}
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
{
[self _adjustSubviewsWithCalculatedSize];
if (_needsRestoreFromAutosave)
_shouldAutosave = NO;
else
[self _adjustSubviewsWithCalculatedSize];
[super setFrameSize:aSize];
if (_needsRestoreFromAutosave)
{
_needsRestoreFromAutosave = NO;
[self _restoreFromAutosave];
_shouldAutosave = YES;
}
[self setNeedsDisplay:YES];
}
@@ -672,67 +773,100 @@ var CPSplitViewHorizontalImage = nil,
return;
}
var count = [_subviews count];
if (!count)
return;
SPLIT_VIEW_MAYBE_POST_WILL_RESIZE();
[self _postNotificationWillResize];
var index = 0,
count = [_subviews count],
bounds = [self bounds],
boundsSize = bounds.size[_sizeComponent],
dividerThickness = [self dividerThickness],
totalDividers = count - 1,
totalSizableSpace = 0,
nonSizableSpace = 0,
lastSizableIndex = -1,
oldFlexibleSpace = 0,
totalSizablePanes = 0,
isVertical = [self isVertical];
isSizableMap = {},
viewSizes = [],
delegateRespondsToShouldAdjust = [_delegate respondsToSelector:@selector(splitView:shouldAdjustSizeOfSubview:)];
// What we want to do is to preserve non resizable sizes first, and then to preserve the ratio of size to available
// non fixed space for every other subview. E.g. assume fixed space was 20 pixels initially, view 1 was 20 and
// view 2 was 30 pixels, for a total of 70 pixels. Then the new total size becomes 140 pixels. Now we want the fixed
// space to still be 20 pixels, view 1 to be 48 pixels and view 2 to be 72 pixels. This way the relative size of
// view 1 to view 2 remains the same - view 1 was 66% of view 2 initially and after the resize view 1 is still
// 66% of view 2's size.
//
// For this calculation, we can consider the dividers themselves to also be fixed size areas - they should remain
// the same size before and after.
// How much flexible size do we have in pre-resize pixels?
for (index = 0; index < count; ++index)
{
var view = _subviews[index],
isSizable = isVertical ? [view autoresizingMask] & CPViewWidthSizable : [view autoresizingMask] & CPViewHeightSizable;
isSizable = !delegateRespondsToShouldAdjust || [_delegate splitView:self shouldAdjustSizeOfSubview:view],
size = [view frame].size[_sizeComponent];
isSizableMap[index] = isSizable;
viewSizes.push(size);
if (isSizable)
{
totalSizableSpace += [view frame].size[_sizeComponent];
lastSizableIndex = index;
oldFlexibleSpace += size;
totalSizablePanes++;
}
}
if (totalSizablePanes === count)
totalSizableSpace = 0;
// nonSizableSpace is the number of fixed pixels in pre-resize terms and the desired number post-resize.
var nonSizableSpace = oldSize[_sizeComponent] - oldFlexibleSpace,
newFlexibleSpace = boundsSize - nonSizableSpace,
remainingFixedPixelsToRemove = 0;
var nonSizableSpace = totalSizableSpace ? bounds.size[_sizeComponent] - totalSizableSpace : 0,
remainingFlexibleSpace = bounds.size[_sizeComponent] - oldSize[_sizeComponent],
oldDimension = (oldSize[_sizeComponent] - totalDividers * dividerThickness - nonSizableSpace),
ratio = oldDimension <= 0 ? 0 : (bounds.size[_sizeComponent] - totalDividers * dividerThickness - nonSizableSpace) / oldDimension;
if (newFlexibleSpace < 0)
{
remainingFixedPixelsToRemove = -newFlexibleSpace;
newFlexibleSpace = 0;
}
var remainingFixedPanes = count - totalSizablePanes;
for (index = 0; index < count; ++index)
{
var view = _subviews[index],
viewFrame = CGRectMakeCopy(bounds),
isSizable = isVertical ? [view autoresizingMask] & CPViewWidthSizable : [view autoresizingMask] & CPViewHeightSizable;
isSizable = isSizableMap[index],
targetSize = 0;
// The last area must take up exactly the remaining space, fixed or not.
if (index + 1 === count)
viewFrame.size[_sizeComponent] = bounds.size[_sizeComponent] - viewFrame.origin[_originComponent];
else if (totalSizableSpace && isSizable && lastSizableIndex === index)
viewFrame.size[_sizeComponent] = MAX(0, ROUND([view frame].size[_sizeComponent] + remainingFlexibleSpace))
else if (isSizable || !totalSizableSpace)
targetSize = boundsSize - viewFrame.origin[_originComponent];
// Try to keep fixed size areas the same size.
else if (!isSizable)
{
viewFrame.size[_sizeComponent] = MAX(0, ROUND(ratio * [view frame].size[_sizeComponent]));
remainingFlexibleSpace -= (viewFrame.size[_sizeComponent] - [view frame].size[_sizeComponent]);
var removedFixedPixels = MIN(remainingFixedPixelsToRemove / remainingFixedPanes, viewSizes[index]);
targetSize = viewSizes[index] - removedFixedPixels;
remainingFixedPixelsToRemove -= removedFixedPixels;
remainingFixedPanes--;
}
// (new size / flexible size available) == (old size / old flexible size available)
else if (oldFlexibleSpace > 0)
targetSize = newFlexibleSpace * viewSizes[index] / oldFlexibleSpace;
// oldFlexibleSpace <= 0 so all flexible areas were crushed. When we get space, allocate it evenly.
// totalSizablePanes cannot be 0 since isSizable.
else
targetSize = newFlexibleSpace / totalSizablePanes;
else if (totalSizableSpace && !isSizable)
viewFrame.size[_sizeComponent] = [view frame].size[_sizeComponent];
targetSize = MAX(0, ROUND(targetSize));
bounds.origin[_originComponent] += viewFrame.size[_sizeComponent] + dividerThickness;
viewFrame.size[_sizeComponent] = targetSize;
[view setFrame:viewFrame];
bounds.origin[_originComponent] += targetSize + dividerThickness;
}
[self _postNotificationDidResize];
SPLIT_VIEW_MAYBE_POST_DID_RESIZE();
}
/*!
@@ -749,6 +883,11 @@ Notifies the delegate when the subviews will be resized.
- (void)splitViewWillResizeSubviews:(CPNotification)aNotification;
@endcode
Allows the delegate to specify which of the CPSplitView's subviews should adjust if the window is resized.
@code
- (BOOL)splitView:(CPSplitView)aSplitView shouldAdjustSizeOfSubview:(CPView)aSubView
@endcode
Lets the delegate specify a different rect for which the user can drag the splitView divider.
@code
- (CGRect)splitView:(CPSplitView)aSplitView effectiveRect:(CGRect)aRect forDrawnRect:(CGRect)aDrawnRect ofDividerAtIndex:(int)aDividerIndex;
@@ -831,6 +970,7 @@ The sum of the views and the sum of the dividers should be equal to the size of
@param CPButtonBar - The supplied button bar.
@param unsigned int - The divider index the button bar will be assigned to.
*/
// FIXME Should be renamed to setButtonBar:ofDividerAtIndex:.
- (void)setButtonBar:(CPButtonBar)aButtonBar forDividerAtIndex:(unsigned)dividerIndex
{
if (!aButtonBar)
@@ -867,15 +1007,125 @@ The sum of the views and the sum of the dividers should be equal to the size of
- (void)_postNotificationDidResize
{
[self _autosave];
[[CPNotificationCenter defaultCenter] postNotificationName:CPSplitViewDidResizeSubviewsNotification object:self];
}
/*!
Set the name under which the split view divider positions is automatically saved to CPUserDefaults.
@param autosaveName the name to save under or nil to not save
*/
- (void)setAutosaveName:(CPString)autosaveName
{
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
*/
- (CPString)autosaveName
{
return _autosaveName;
}
/*!
@ignore
*/
- (void)_autosave
{
if (!_shouldAutosave || !autosaveName)
return;
var userDefaults = [CPUserDefaults standardUserDefaults],
autosaveName = [self _framesKeyForAutosaveName:[self autosaveName]],
autosavePrecollapseName = [self _precollapseKeyForAutosaveName:[self autosaveName]],
count = [_subviews count],
positions = [CPMutableArray new],
preCollapseArray = [CPMutableArray new];
for (var i = 0; i < count; i++)
{
var frame = [_subviews[i] frame];
[positions addObject:CPStringFromRect(frame)];
[preCollapseArray addObject:[_preCollapsePositions objectForKey:"" + i]];
}
[userDefaults setObject:positions forKey:autosaveName];
[userDefaults setObject:preCollapseArray forKey:autosavePrecollapseName];
}
/*!
@ignore
*/
- (void)_restoreFromAutosave
{
if (!_autosaveName)
return;
var autosaveName = [self _framesKeyForAutosaveName:[self autosaveName]],
autosavePrecollapseName = [self _precollapseKeyForAutosaveName:[self autosaveName]],
userDefaults = [CPUserDefaults standardUserDefaults],
frames = [userDefaults objectForKey:autosaveName],
preCollapseArray = [userDefaults objectForKey:autosavePrecollapseName];
if (frames)
{
var dividerThickness = [self dividerThickness],
position = 0;
_shouldAutosave = NO;
for (var i = 0, count = [frames count] - 1; i < count; i++)
{
var frame = CPRectFromString(frames[i]);
position += frame.size[_sizeComponent];
[self setPosition:position ofDividerAtIndex:i];
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 + ""];
}
}
/*!
@ignore
*/
- (CPString)_framesKeyForAutosaveName:(CPString)theAutosaveName
{
if (!theAutosaveName)
return nil;
return @"CPSplitView Subview Frames " + theAutosaveName;
}
/*!
@ignore
*/
- (CPString)_precollapseKeyForAutosaveName:(CPString)theAutosaveName
{
if (!theAutosaveName)
return nil;
return @"CPSplitView Subview Precollapse Positions " + theAutosaveName;
}
@end
var CPSplitViewDelegateKey = "CPSplitViewDelegateKey",
CPSplitViewIsVerticalKey = "CPSplitViewIsVerticalKey",
CPSplitViewIsPaneSplitterKey = "CPSplitViewIsPaneSplitterKey",
CPSplitViewButtonBarsKey = "CPSplitViewButtonBarsKey";
CPSplitViewButtonBarsKey = "CPSplitViewButtonBarsKey",
CPSplitViewAutosaveNameKey = "CPSplitViewAutosaveNameKey";
@implementation CPSplitView (CPCoding)
@@ -889,7 +1139,11 @@ var CPSplitViewDelegateKey = "CPSplitViewDelegateKey",
if (self)
{
_suppressResizeNotificationsMask = 0;
_preCollapsePositions = [CPMutableDictionary new];
_currentDivider = CPNotFound;
_shouldAutosave = YES;
_DOMDividerElements = [];
@@ -899,6 +1153,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;
}
return self;
@@ -919,6 +1180,8 @@ var CPSplitViewDelegateKey = "CPSplitViewDelegateKey",
[aCoder encodeBool:_isVertical forKey:CPSplitViewIsVerticalKey];
[aCoder encodeBool:_isPaneSplitter forKey:CPSplitViewIsPaneSplitterKey];
[aCoder encodeObject:_autosaveName forKey:CPSplitViewAutosaveNameKey];
}
@end
+99 -52
View File
@@ -25,15 +25,16 @@
@import <AppKit/CPTextField.j>
var CPStepperButtonsSize = CPSizeMake(19, 13);
/*! CPStepper is an implementation of Cocoa NSStepper.
/*!
CPStepper is an implementation of Cocoa NSStepper.
This control display a two part button that can be used to increase or decrease a value with a given interval.
This control displays a two part button that can be used to increase or decrease a value with a given interval.
*/
@implementation CPStepper: CPControl
{
BOOL _valueWraps @accessors(property=valueWraps);
BOOL _autorepeat @accessors(getter=autorepeat);
int _increment @accessors(property=increment);
int _maxValue @accessors(property=maxValue);
int _minValue @accessors(property=minValue);
@@ -45,7 +46,8 @@ var CPStepperButtonsSize = CPSizeMake(19, 13);
#pragma mark -
#pragma mark Initialization
/*! Initializes a CPStepper with given values
/*!
Initializes a CPStepper with given values.
@param aValue the initial value of the CPStepper
@param minValue the minimal acceptable value of the stepper
@param maxValue the maximal acceptable value of the stepper
@@ -53,7 +55,7 @@ var CPStepperButtonsSize = CPSizeMake(19, 13);
*/
+ (CPStepper)stepperWithInitialValue:(float)aValue minValue:(float)aMinValue maxValue:(float)aMaxValue
{
var stepper = [[CPStepper alloc] initWithFrame:CPRectMake(0, 0, 19, 25)];
var stepper = [[CPStepper alloc] initWithFrame:_CGRectMake(0, 0, 19, 25)];
[stepper setDoubleValue:aValue];
[stepper setMinValue:aMinValue];
[stepper setMaxValue:aMaxValue];
@@ -61,10 +63,12 @@ var CPStepperButtonsSize = CPSizeMake(19, 13);
return stepper;
}
/*! Initializes a CPStepper with default values:
/*!
Initializes a CPStepper with default values:
- minValue = 0.0
- maxValue = 59.0
- value = 0.0
@return Initialized CPStepper
*/
+ (CPStepper)stepper
@@ -72,7 +76,8 @@ var CPStepperButtonsSize = CPSizeMake(19, 13);
return [CPStepper stepperWithInitialValue:0.0 minValue:0.0 maxValue:59.0];
}
/*! Initializes the CPStepper
/*!
Initializes a CPStepper.
@param aFrame the frame of the control
@return initialized CPStepper
*/
@@ -84,33 +89,43 @@ var CPStepperButtonsSize = CPSizeMake(19, 13);
_minValue = 0.0;
_increment = 1.0;
_valueWraps = YES;
_autorepeat = YES;
[self setDoubleValue:0.0];
_buttonUp = [[CPButton alloc] initWithFrame:CPRectMake(aFrame.size.width - CPStepperButtonsSize.width, 0, CPStepperButtonsSize.width, CPStepperButtonsSize.height)];
[_buttonUp setContinuous:YES];
[_buttonUp setTarget:self];
[_buttonUp setAction:@selector(_buttonDidClick:)];
[_buttonUp setAutoresizingMask:CPViewNotSizable];
[self addSubview:_buttonUp];
_buttonDown = [[CPButton alloc] initWithFrame:CPRectMake(aFrame.size.width - CPStepperButtonsSize.width, CPStepperButtonsSize.height, CPStepperButtonsSize.width, CPStepperButtonsSize.height - 1)];
[_buttonDown setContinuous:YES];
[_buttonDown setTarget:self];
[_buttonDown setAction:@selector(_buttonDidClick:)];
[_buttonDown setAutoresizingMask:CPViewNotSizable];
[self addSubview:_buttonDown];
[self setNeedsLayout];
[self _init];
}
return self;
}
/*! @ignore */
- (void)_init
{
_buttonUp = [[CPButton alloc] initWithFrame:_CGRectMakeZero()];
[_buttonUp setContinuous:_autorepeat];
[_buttonUp setTarget:self];
[_buttonUp setAction:@selector(_buttonDidClick:)];
[_buttonUp setAutoresizingMask:CPViewNotSizable];
[self addSubview:_buttonUp];
_buttonDown = [[CPButton alloc] initWithFrame:_CGRectMakeZero()];
[_buttonDown setContinuous:_autorepeat];
[_buttonDown setTarget:self];
[_buttonDown setAction:@selector(_buttonDidClick:)];
[_buttonDown setAutoresizingMask:CPViewNotSizable];
[self setContinuous:_autorepeat];
[self addSubview:_buttonDown];
[self setNeedsLayout];
}
#pragma mark -
#pragma mark Superclass overrides
/*! set if the CPStepper is enabled or not
/*!
Set if the CPStepper is enabled or not.
@param shouldEnabled BOOL that define if stepper is enabled or not.
*/
- (void)setEnabled:(BOOL)shouldEnabled
@@ -121,19 +136,30 @@ var CPStepperButtonsSize = CPSizeMake(19, 13);
[_buttonDown setEnabled:shouldEnabled];
}
/*! set the frame of the CPStepper and check if width is not smaller than theme min-size
@param aFrame the frame
*/
- (void)setFrame:(CGRect)aFrame
{
if (aFrame.size.width >= CGRectGetWidth(aFrame))
[super setFrame:aFrame];
var upSize = [self valueForThemeAttribute:@"up-button-size"],
downSize = [self valueForThemeAttribute:@"down-button-size"],
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);
[super setFrame:frame];
}
/*! @ignore
*/
/*! @ignore */
- (void)layoutSubviews
{
var aFrame = [self frame],
upSize = [self valueForThemeAttribute:@"up-button-size"],
downSize = [self valueForThemeAttribute:@"down-button-size"],
upFrame = _CGRectMake(aFrame.size.width - upSize.width, 0, upSize.width, upSize.height),
downFrame = _CGRectMake(aFrame.size.width - downSize.width, upSize.height, downSize.width, downSize.height);
[_buttonUp setFrame:upFrame];
[_buttonDown setFrame:downFrame];
[_buttonUp setValue:[self valueForThemeAttribute:@"bezel-color-up-button" inState:CPThemeStateBordered] forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered];
[_buttonUp setValue:[self valueForThemeAttribute:@"bezel-color-up-button" inState:CPThemeStateBordered | CPThemeStateDisabled] forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered | CPThemeStateDisabled];
[_buttonUp setValue:[self valueForThemeAttribute:@"bezel-color-up-button" inState:CPThemeStateBordered | CPThemeStateHighlighted] forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered | CPThemeStateHighlighted];
@@ -142,16 +168,23 @@ var CPStepperButtonsSize = CPSizeMake(19, 13);
[_buttonDown setValue:[self valueForThemeAttribute:@"bezel-color-down-button" inState:CPThemeStateBordered | CPThemeStateHighlighted] forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered | CPThemeStateHighlighted];
}
/*! set if CPStepper should autorepeat
/*!
Set if CPStepper should autorepeat.
@param shouldAutoRepeat if YES, the first mouse down does one increment (decrement) and, after each delay of 0.5 seconds
*/
- (void)setAutorepeat:(BOOL)shouldAutoRepeat
{
[_buttonUp setContinuous:shouldAutoRepeat];
[_buttonDown setContinuous:shouldAutoRepeat];
if (shouldAutoRepeat !== _autorepeat)
{
[_buttonUp setContinuous:shouldAutoRepeat];
[_buttonDown setContinuous:shouldAutoRepeat];
}
[self setContinuous:shouldAutoRepeat];
}
/*! set the current value of the stepper
/*!
Set the current value of the stepper.
@param aValue a float containing the value
*/
- (void)setDoubleValue:(float)aValue
@@ -167,8 +200,7 @@ var CPStepperButtonsSize = CPSizeMake(19, 13);
#pragma mark -
#pragma mark Actions
/*! @ignore
*/
/*! @ignore */
- (IBAction)_buttonDidClick:(id)aSender
{
if (![self isEnabled])
@@ -183,7 +215,8 @@ var CPStepperButtonsSize = CPSizeMake(19, 13);
[self sendAction:_action to:_target];
}
/*! @perform a programatic click on up button
/*!
Perform a programatic click on up button.
@param aSender sender of the action
*/
- (IBAction)performClickUp:(id)aSender
@@ -191,7 +224,8 @@ var CPStepperButtonsSize = CPSizeMake(19, 13);
[_buttonUp performClick:aSender];
}
/*! @perform a programatic click on down button
/*!
Perform a programatic click on down button.
@param aSender sender of the action
*/
- (IBAction)performClickDown:(id)aSender
@@ -210,25 +244,33 @@ var CPStepperButtonsSize = CPSizeMake(19, 13);
+ (id)themeAttributes
{
return [CPDictionary dictionaryWithObjects:[[CPNull null], [CPNull null]]
forKeys:[@"bezel-color-up-button", @"bezel-color-down-button"]];
return [CPDictionary dictionaryWithObjects:[[CPNull null], [CPNull null], _CGSizeMakeZero(), _CGSizeMakeZero()]
forKeys:[@"bezel-color-up-button", @"bezel-color-down-button", @"up-button-size", @"down-button-size"]];
}
@end
var CPStepperMinValue = @"CPStepperMinValue",
CPStepperMaxValue = @"CPStepperMaxValue",
CPStepperValueWraps = @"CPStepperValueWraps",
CPStepperAutorepeat = @"CPStepperAutorepeat",
CPStepperIncrement = @"CPStepperIncrement";
@implementation CPStepper (CPCodingCompliance)
@implementation CPStepper (CPCoding)
- (id)initWithCoder:(CPCoder)aCoder
{
if (self = [super initWithCoder:aCoder])
{
_maxValue = [aCoder decodeObjectForKey:@"_maxValue"];
_minValue = [aCoder decodeObjectForKey:@"_minValue"];
_increment = [aCoder decodeObjectForKey:@"_increment"];
_buttonUp = [aCoder decodeObjectForKey:@"_buttonUp"];
_buttonDown = [aCoder decodeObjectForKey:@"_buttonDown"];
_increment = [aCoder decodeIntForKey:CPStepperIncrement];
_minValue = [aCoder decodeIntForKey:CPStepperMinValue] || 0;
_maxValue = [aCoder decodeIntForKey:CPStepperMaxValue] || 0;
_valueWraps = [aCoder decodeBoolForKey:CPStepperValueWraps] || NO;
_autorepeat = [aCoder decodeBoolForKey:CPStepperAutorepeat] || NO;
[self _init];
}
return self;
}
@@ -236,11 +278,16 @@ var CPStepperButtonsSize = CPSizeMake(19, 13);
{
[super encodeWithCoder:aCoder];
[aCoder encodeObject:_maxValue forKey:@"_maxValue"];
[aCoder encodeObject:_minValue forKey:@"_minValue"];
[aCoder encodeObject:_increment forKey:@"_increment"];
[aCoder encodeObject:_buttonUp forKey:@"_buttonUp"];
[aCoder encodeObject:_buttonDown forKey:@"_buttonDown"];
[aCoder encodeInt:_increment forKey:CPStepperIncrement];
if (_minValue)
[aCoder encodeInt:_minValue forKey:CPStepperMinValue];
if (_maxValue)
[aCoder encodeInt:_maxValue forKey:CPStepperMaxValue];
if (_valueWraps)
[aCoder encodeBool:_valueWraps forKey:CPStepperValueWraps];
if (_autorepeat)
[aCoder encodeBool:_autorepeat forKey:CPStepperAutorepeat];
}
@end
+40 -9
View File
@@ -1,3 +1,25 @@
/*
* CPTabView.j
* AppKit
*
* Created by Derek Hammer.
* Copyright 2010, Derek Hammer.
*
* 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 "CPBox.j"
@import "CPSegmentedControl.j"
@import "CPTabViewItem.j"
@@ -45,7 +67,6 @@ var CPTabViewDidSelectTabViewItemSelector = 1,
if (self = [super initWithFrame:aFrame])
{
_items = [CPArray array];
_selectedIndex = CPNotFound;
[self _init];
[self setTabViewType:CPTopTabsBezelBorder];
@@ -56,6 +77,8 @@ var CPTabViewDidSelectTabViewItemSelector = 1,
- (void)_init
{
_selectedIndex = CPNotFound;
_tabs = [[CPSegmentedControl alloc] initWithFrame:CGRectMake(0, 0, 0, 0)];
[_tabs setHitTests:NO];
@@ -252,8 +275,6 @@ var CPTabViewDidSelectTabViewItemSelector = 1,
*/
- (void)selectTabViewItemAtIndex:(unsigned)anIndex
{
var aTabViewItem = [_items objectAtIndex:anIndex];
if (anIndex === _selectedIndex)
return;
@@ -278,7 +299,10 @@ var CPTabViewDidSelectTabViewItemSelector = 1,
*/
- (CPTabViewItem)selectedTabViewItem
{
return [_items objectAtIndex:_selectedIndex];
if (_selectedIndex != CPNotFound)
return [_items objectAtIndex:_selectedIndex];
return nil;
}
// Modifying the font
@@ -428,8 +452,12 @@ var CPTabViewDidSelectTabViewItemSelector = 1,
- (void)_setSelectedIndex:(CPNumber)index
{
_selectedIndex = index;
[self _setContentViewForItem:[_items objectAtIndex:_selectedIndex]];
}
[_box setContentView:[[_items objectAtIndex:_selectedIndex] view]];
- (void)_setContentViewForItem:(CPTabViewItem)anItem
{
[_box setContentView:[anItem view]];
}
- (void)_updateItems
@@ -469,17 +497,17 @@ var CPTabViewItemsKey = "CPTabViewItemsKey",
[_tabs setFont:_font];
_items = [aCoder decodeObjectForKey:CPTabViewItemsKey];
[_items makeObjectsPerformSelector:@selector(_setTabView:) withObject:self];
[self _updateItems];
[self _repositionTabs];
var selected = [aCoder decodeObjectForKey:CPTabViewSelectedItemKey];
[self setDelegate:[aCoder decodeObjectForKey:CPTabViewDelegateKey]];
var selected = [aCoder decodeObjectForKey:CPTabViewSelectedItemKey];
if (selected)
[self selectTabViewItem:selected];
[self setDelegate:[aCoder decodeObjectForKey:CPTabViewDelegateKey]];
[self setTabViewType:[aCoder decodeIntForKey:CPTabViewTypeKey]];
}
@@ -491,7 +519,10 @@ var CPTabViewItemsKey = "CPTabViewItemsKey",
[super encodeWithCoder:aCoder];
[aCoder encodeObject:_items forKey:CPTabViewItemsKey];
[aCoder encodeObject:[self selectedTabViewItem] forKey:CPTabViewSelectedItemKey];
var selected = [self selectedTabViewItem];
if (selected)
[aCoder encodeObject:selected forKey:CPTabViewSelectedItemKey];
[aCoder encodeInt:_type forKey:CPTabViewTypeKey];
[aCoder encodeObject:_font forKey:CPTabViewFontKey];
+6
View File
@@ -132,7 +132,13 @@ CPPressedTab = 2;
*/
- (void)setView:(CPView)aView
{
if (_view == aView)
return;
_view = aView;
if ([_tabView selectedTabViewItem] == self)
[_tabView _setContentViewForItem:self];
}
/*!
+17 -3
View File
@@ -132,7 +132,7 @@ CPTableColumnUserResizingMask = 1 << 1;
{
var min = [self minWidth],
max = [self maxWidth],
newWidth = MIN(MAX(width, min), max);
newWidth = ROUND(MIN(MAX(width, min), max));
[self setWidth:newWidth];
@@ -594,7 +594,22 @@ CPTableColumnUserResizingMask = 1 << 1;
[super bind:aBinding toObject:anObject withKeyPath:aKeyPath options:options];
if (![aBinding isEqual:@"someListOfExceptedBindings(notAcceptedBindings)"])
[[self tableView] _establishBindingsIfUnbound:anObject];
{
// Bind the table to the array controller this column is bound to.
// Note that anObject might not be the array controller. E.g. the keypath could be something like
// somePathTo.anArrayController.arrangedObjects.aKey. Cocoa doesn't support this but it is consistent
// and it makes sense.
var acIndex = aKeyPath.lastIndexOf("arrangedObjects."),
arrayController = anObject;
if (acIndex > 1)
{
var firstPart = aKeyPath.substring(0, acIndex - 1);
arrayController = [anObject valueForKeyPath:firstPart];
}
[[self tableView] _establishBindingsIfUnbound:arrayController];
}
}
/*!
@@ -719,7 +734,6 @@ var CPTableColumnIdentifierKey = @"CPTableColumnIdentifierKey",
[self setIdentifier:[aCoder decodeObjectForKey:CPTableColumnIdentifierKey]];
[self setHeaderView:[aCoder decodeObjectForKey:CPTableColumnHeaderViewKey]];
[self setDataView:[aCoder decodeObjectForKey:CPTableColumnDataViewKey]];
[self setHeaderView:[aCoder decodeObjectForKey:CPTableColumnHeaderViewKey]];
_resizingMask = [aCoder decodeIntForKey:CPTableColumnResizingMaskKey];
_isHidden = [aCoder decodeBoolForKey:CPTableColumnIsHiddenKey];
+1 -1
View File
@@ -643,7 +643,7 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal
columnMaxX = _CGRectGetMaxX(columnToStroke);
CGContextMoveToPoint(context, FLOOR(columnMaxX) - 0.5, ROUND(_CGRectGetMinY(columnToStroke)));
CGContextAddLineToPoint(context, FLOOR(columnMaxX) - 0.5, ROUND(_CGRectGetMaxY(columnToStroke)));
CGContextAddLineToPoint(context, FLOOR(columnMaxX) - 0.5, ROUND(_CGRectGetMaxY(columnToStroke)) - 1.0);
}
CGContextClosePath(context);
CGContextStrokePath(context);
+52 -34
View File
@@ -87,9 +87,9 @@ CPTableViewSelectionHighlightStyleNone = -1;
CPTableViewSelectionHighlightStyleRegular = 0;
CPTableViewSelectionHighlightStyleSourceList = 1;
CPTableViewGridNone = 0;
CPTableViewSolidVerticalGridLineMask = 1 << 0;
CPTableViewSolidHorizontalGridLineMask = 1 << 1;
CPTableViewGridNone = 0;
CPTableViewSolidVerticalGridLineMask = 1 << 0;
CPTableViewSolidHorizontalGridLineMask = 1 << 1;
CPTableViewNoColumnAutoresizing = 0;
CPTableViewUniformColumnAutoresizingStyle = 1; // FIX ME: This is FUBAR
@@ -509,6 +509,11 @@ NOT YET IMPLEMENTED
_objectValues = { };
_cachedRowHeights = [];
// Otherwise, if we have a row marked as group with a
// index greater than the new number or rows
// it keeps the the graphical group style.
[_groupRows removeAllIndexes];
// This updates the size too.
[self noteNumberOfRowsChanged];
@@ -678,6 +683,7 @@ NOT YET IMPLEMENTED
*/
- (void)setRowHeight:(unsigned)aRowHeight
{
// Accept row heights such as "0".
aRowHeight = +aRowHeight;
if (_rowHeight === aRowHeight)
@@ -763,10 +769,6 @@ NOT YET IMPLEMENTED
*/
- (void)setSelectionHighlightStyle:(unsigned)aSelectionHighlightStyle
{
//early return for IE.
if (aSelectionHighlightStyle == CPTableViewSelectionHighlightStyleSourceList && !CPFeatureIsCompatible(CPHTMLCanvasFeature))
return;
_selectionHighlightStyle = aSelectionHighlightStyle;
[self setNeedsDisplay:YES];
@@ -953,6 +955,7 @@ NOT YET IMPLEMENTED
*/
- (void)_moveColumn:(unsigned)fromIndex toColumn:(unsigned)toIndex
{
// Convert parameters such as "0" to 0.
fromIndex = +fromIndex;
toIndex = +toIndex;
@@ -1510,6 +1513,8 @@ NOT YET IMPLEMENTED
if ([scrollView isKindOfClass:[CPScrollView class]] && [scrollView documentView] === self)
[scrollView _updateCornerAndHeaderView];
[self setNeedsLayout];
}
// Complexity:
@@ -1561,6 +1566,7 @@ NOT YET IMPLEMENTED
*/
- (CGRect)rectOfColumn:(CPInteger)aColumnIndex
{
// Convert e.g. "0" to 0.
aColumnIndex = +aColumnIndex;
if (aColumnIndex < 0 || aColumnIndex >= NUMBER_OF_COLUMNS())
@@ -1790,7 +1796,7 @@ NOT YET IMPLEMENTED
{
if (_implementedDelegateMethods & CPTableViewDelegate_tableView_heightOfRow_)
{
return idx = [_cachedRowHeights indexOfObject:aPoint
return [_cachedRowHeights indexOfObject:aPoint
inSortedRange:nil
options:0
usingComparator:function(aPoint, rowCache)
@@ -1984,7 +1990,7 @@ NOT YET IMPLEMENTED
// so we should size the last resized to fit
// find the last visisble column
while (count-- && [_tableColumns[count] isHidden]) ;
while (count-- && [_tableColumns[count] isHidden]);
// find the max x, but subtract a single pixel since the spacing isn't applicable here.
var delta = superviewWidth - _CGRectGetMaxX([self rectOfColumn:count]) - ([self intercellSpacing].width || 1),
@@ -2770,7 +2776,7 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
*/
- (BOOL)canDragRowsWithIndexes:(CPIndexSet)rowIndexes atPoint:(CGPoint)mouseDownPoint
{
return YES;
return [rowIndexes count] > 0 && [self numberOfRows] > 0;
}
/*!
@@ -3044,7 +3050,6 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
return _sortDescriptors;
}
/*!
@ignore
*/
@@ -3425,7 +3430,6 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
[aTableColumn setDataView:dataView];
}
return [aTableColumn _newDataViewForRow:aRow];
}
@@ -3497,8 +3501,20 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
{
[super setNeedsDisplay:aFlag];
[_tableDrawView setNeedsDisplay:aFlag];
[[self headerView] setNeedsDisplay:YES];
}
/*!
@ignore
*/
- (void)setNeedsLayout
{
[super setNeedsLayout];
[[self headerView] setNeedsLayout];
}
/*!
@ignore
*/
@@ -3544,16 +3560,16 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
}
var exposedRows = [self _unboundedRowsInRect:aRect],
firstRow = FLOOR(exposedRows.location / colorCount) * colorCount,
lastRow = CPMaxRange(exposedRows),
colorIndex = 0,
groupRowRects = [],
row = exposedRows.location;
groupRowRects = [];
//loop through each color so we only draw once for each color
while (colorIndex < colorCount)
{
CGContextBeginPath(context);
for (var row = colorIndex; row <= lastRow; row += colorCount)
for (var row = firstRow + colorIndex; row <= lastRow; row += colorCount)
{
// if it's not a group row draw it otherwise we draw it later
if (![_groupRows containsIndex:row])
@@ -3685,7 +3701,7 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
if (!count)
return;
var drawGradient = (_selectionHighlightStyle === CPTableViewSelectionHighlightStyleSourceList && [_selectedRowIndexes count] >= 1),
var drawGradient = (CPFeatureIsCompatible(CPHTMLCanvasFeature) && _selectionHighlightStyle === CPTableViewSelectionHighlightStyleSourceList && [_selectedRowIndexes count] >= 1),
deltaHeight = 0.5 * (_gridStyleMask & CPTableViewSolidHorizontalGridLineMask);
CGContextBeginPath(context);
@@ -3705,7 +3721,7 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
{
var topGroupLineColor = [CPColor colorWithCalibratedWhite:212.0 / 255.0 alpha:1.0],
bottomGroupLineColor = [CPColor colorWithCalibratedWhite:185.0 / 255.0 alpha:1.0],
gradientGroupColor = CGGradientCreateWithColorComponents(CGColorSpaceCreateDeviceRGB(), [212.0 / 255.0, 212.0 / 255.0, 212.0 / 255.0,1.0, 197.0 / 255.0, 197.0 / 255.0, 197.0 / 255.0,1.0], [0,1], 2);
gradientGroupColor = CGGradientCreateWithColorComponents(CGColorSpaceCreateDeviceRGB(), [212.0 / 255.0, 212.0 / 255.0, 212.0 / 255.0, 1.0, 197.0 / 255.0, 197.0 / 255.0, 197.0 / 255.0, 1.0], [0, 1], 2);
}
while (count--)
@@ -3812,7 +3828,7 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
*/
- (void)_drawGroupRowsForRects:(CPArray)rects
{
if (_selectionHighlightStyle === CPTableViewSelectionHighlightStyleSourceList || !rects.length)
if ((CPFeatureIsCompatible(CPHTMLCanvasFeature) && _selectionHighlightStyle === CPTableViewSelectionHighlightStyleSourceList) || !rects.length)
return;
var context = [[CPGraphicsContext currentContext] graphicsPort],
@@ -3823,8 +3839,8 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
var gradientCache = [self selectionGradientColors],
topLineColor = [CPColor colorWithHexString:"d3d3d3"],
bottomLineColor = [CPColor colorWithHexString:"bebebd"],
gradientColor = CGGradientCreateWithColorComponents(CGColorSpaceCreateDeviceRGB(), [220.0 / 255.0, 220.0 / 255.0, 220.0 / 255.0,1.0,
199.0 / 255.0, 199.0 / 255.0, 199.0 / 255.0,1.0], [0,1], 2),
gradientColor = CGGradientCreateWithColorComponents(CGColorSpaceCreateDeviceRGB(), [220.0 / 255.0, 220.0 / 255.0, 220.0 / 255.0, 1.0,
199.0 / 255.0, 199.0 / 255.0, 199.0 / 255.0, 1.0], [0, 1], 2),
drawGradient = YES;
while (i--)
@@ -3972,7 +3988,7 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
{
var row = [self rowAtPoint:aPoint];
//if the user clicks outside a row then deselect everything
// If the user clicks outside a row then deselect everything.
if (row < 0 && _allowsEmptySelection)
[self selectRowIndexes:[CPIndexSet indexSet] byExtendingSelection:NO];
@@ -4609,7 +4625,7 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
}
_wasSelectionBroken = true;
}
else if (_wasSelectionBroken && ((shouldGoUpward && i !== [selectedIndexes firstIndex]) || (!shouldGoUpward && i !== [selectedIndexes lastindex])))
else if (_wasSelectionBroken && ((shouldGoUpward && i !== [selectedIndexes firstIndex]) || (!shouldGoUpward && i !== [selectedIndexes lastIndex])))
{
shouldGoUpward ? i = [selectedIndexes firstIndex] - 1 : i = [selectedIndexes lastIndex];
_wasSelectionBroken = false;
@@ -4637,19 +4653,19 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
while (![_delegate tableView:self shouldSelectRow:i] && (i < [self numberOfRows] || i > 0))
shouldGoUpward ? i-- : i++; //check to see if the row can be selected if it can't be then see if the next row can be selected
//if the index still can be selected after the loop then just return
if (![_delegate tableView:self shouldSelectRow:i])
return;
// If the index still can be selected after the loop then just return.
if (![_delegate tableView:self shouldSelectRow:i])
return;
}
// if we go upward and see that this row is already selected we should deselect the row below
if ([selectedIndexes containsIndex:i] && extend)
// If we go upward and see that this row is already selected we should deselect the row below.
if (extend && [selectedIndexes containsIndex:i])
{
// the row we're on is the last to be selected
// The row we're on is the last to be selected.
var differedLastSelectedRow = i;
// no remove the one before/after it
shouldGoUpward ? i++ : i--;
shouldGoUpward ? i++ : i--;
[selectedIndexes removeIndex:i];
@@ -4661,7 +4677,7 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
if ([selectedIndexes containsIndex:i])
{
i = shouldGoUpward ? [selectedIndexes firstIndex] -1 : [selectedIndexes lastIndex] + 1;
i = MIN(MAX(i,0), [self numberOfRows] - 1);
i = MIN(MAX(i, 0), [self numberOfRows] - 1);
}
[selectedIndexes addIndex:i];
@@ -4938,15 +4954,17 @@ var CPTableViewDataSourceKey = @"CPTableViewDataSourceKey",
isBlinking = YES;
var showCallback = function() {
var showCallback = function()
{
objj_msgSend(self, "setHidden:", NO)
isBlinking = NO;
}
};
var hideCallback = function() {
var hideCallback = function()
{
objj_msgSend(self, "setHidden:", YES)
isBlinking = YES;
}
};
objj_msgSend(self, "setHidden:", YES);
[CPTimer scheduledTimerWithTimeInterval:0.1 callback:showCallback repeats:NO];
+207 -96
View File
@@ -1,4 +1,3 @@
/*
* CPTextField.j
* AppKit
@@ -21,13 +20,15 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#import "../Foundation/Ref.h"
@import "CPControl.j"
@import "CPStringDrawing.j"
@import "CPCompatibility.j"
@import "_CPImageAndTextView.j"
CPTextFieldSquareBezel = 0; /*! A textfield bezel with a squared corners. */
CPTextFieldSquareBezel = 0; /*! A textfield bezel with squared corners. */
CPTextFieldRoundedBezel = 1; /*! A textfield bezel with rounded corners. */
CPTextFieldDidFocusNotification = @"CPTextFieldDidFocusNotification";
@@ -83,12 +84,11 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
CPColor _textFieldBackgroundColor;
id _placeholderString;
CPString _placeholderString;
CPString _stringValue;
id _delegate;
CPString _textDidChangeValue;
// NS-style Display Properties
CPTextFieldBezelStyle _bezelStyle;
BOOL _isBordered;
@@ -202,14 +202,14 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
CPTextFieldInputDidBlur = YES;
return true;
}
};
CPTextFieldHandleBlur = function(anEvent)
{
CPTextFieldInputOwner = nil;
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
}
};
//FIXME make this not onblur
CPTextFieldDOMInputElement.onblur = CPTextFieldBlurFunction;
@@ -481,17 +481,17 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
[self setNeedsLayout];
_isEditing = NO;
_stringValue = [self stringValue];
#if PLATFORM(DOM)
var string = [self stringValue],
element = [self _inputElement],
var element = [self _inputElement],
font = [self currentValueForThemeAttribute:@"font"];
// generate the font metric
[font _getMetrics];
element.value = string;
element.value = _stringValue;
element.style.color = [[self currentValueForThemeAttribute:@"text-color"] cssString];
element.style.font = [font cssString];
element.style.zIndex = 1000;
@@ -548,8 +548,6 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
CPTextFieldInputOwner = self;
}, 0.0);
element.value = [self stringValue];
[[[self window] platformWindow] _propagateCurrentDOMEvent:YES];
CPTextFieldInputIsActive = YES;
@@ -572,17 +570,39 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
{
[self unsetThemeState:CPThemeStateEditing];
#if PLATFORM(DOM)
var element = [self _inputElement],
newValue = element.value,
error = @"";
if (newValue !== _stringValue)
{
[self _setStringValue:newValue];
}
// If there is a formatter, always give it a chance to reject the resignation,
// even if the value has not changed.
if ([self _valueIsValid:newValue] === NO)
{
[self setThemeState:CPThemeStateEditing];
element.focus();
return NO;
}
#endif
// Cache the formatted string
_stringValue = [self stringValue];
_willBecomeFirstResponderByClick = NO;
[self _updatePlaceholderState];
[self setNeedsLayout];
#if PLATFORM(DOM)
var element = [self _inputElement];
if ([self stringValue] !== element.value)
[self _setStringValue:element.value];
CPTextFieldInputResigning = YES;
if (CPTextFieldInputIsActive)
@@ -610,7 +630,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
#endif
//post CPControlTextDidEndEditingNotification
// post CPControlTextDidEndEditingNotification
if (_isEditing)
{
_isEditing = NO;
@@ -625,6 +645,28 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
return YES;
}
- (BOOL)_valueIsValid:(CPString)aValue
{
#if PLATFORM(DOM)
var error = @"";
if ([self _setStringValue:aValue isNewValue:NO errorDescription:AT_REF(error)] === NO)
{
var acceptInvalidValue = NO;
if ([_delegate respondsToSelector:@selector(control:didFailToFormatString:errorDescription:)])
acceptInvalidValue = [_delegate control:self didFailToFormatString:[self _inputElement] errorDescription:error];
if (acceptInvalidValue === NO)
return NO;
}
#endif
return YES;
}
/*!
Text fields require panels to become key window, so this returns \c YES.
*/
@@ -685,11 +727,14 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
- (void)keyUp:(CPEvent)anEvent
{
var oldValue = [self stringValue];
[self _setStringValue:[self _inputElement].value];
#if PLATFORM(DOM)
if (oldValue !== [self stringValue])
var newValue = [self _inputElement].value;
if (newValue !== _stringValue)
{
[self _setStringValue:newValue];
if (!_isEditing)
{
_isEditing = YES;
@@ -699,14 +744,13 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
[self textDidChange:[CPNotification notificationWithName:CPControlTextDidChangeNotification object:self userInfo:nil]];
}
#endif
[[[self window] platformWindow] _propagateCurrentDOMEvent:YES];
}
- (void)keyDown:(CPEvent)anEvent
{
if ([anEvent _couldBeKeyEquivalent] && [self performKeyEquivalent:anEvent])
return;
// CPTextField uses an HTML input element to take the input so we need to
// propagate the dom event so the element is updated. This has to be done
// before interpretKeyEvents: though so individual commands have a chance
@@ -735,45 +779,60 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
- (void)insertNewline:(id)sender
{
if (_isEditing)
var newValue = [self _inputElement].value;
if (newValue !== _stringValue)
{
_isEditing = NO;
[self textDidEndEditing:[CPNotification notificationWithName:CPControlTextDidEndEditingNotification object:self userInfo:nil]];
[self _setStringValue:newValue];
}
[self sendAction:[self action] to:[self target]];
[self selectText:nil];
if ([self _valueIsValid:_stringValue])
{
// If _isEditing == YES then the target action can also be called via
// resignFirstResponder, and it is possible that the target action
// itself will change this textfield's responder status, so start by
// setting the _isEditing flag to NO to prevent the target action being
// called twice (once below and once from resignFirstResponder).
if (_isEditing)
{
_isEditing = NO;
[self textDidEndEditing:[CPNotification notificationWithName:CPControlTextDidEndEditingNotification object:self userInfo:nil]];
}
// If there is no target action, or the sendAction call returns
// success.
if (![self action] || [self sendAction:[self action] to:[self target]])
{
[self selectAll:nil];
}
}
[[[self window] platformWindow] _propagateCurrentDOMEvent:NO];
}
- (void)insertNewlineIgnoringFieldEditor:(id)sender
{
var oldValue = [self stringValue];
[self _inputElement].value += CPNewlineCharacter;
[self _setStringValue:[self _inputElement].value];
if (oldValue !== [self stringValue])
{
if (!_isEditing)
{
_isEditing = YES;
[self textDidBeginEditing:[CPNotification notificationWithName:CPControlTextDidBeginEditingNotification object:self userInfo:nil]];
}
[self textDidChange:[CPNotification notificationWithName:CPControlTextDidChangeNotification object:self userInfo:nil]];
}
[self _insertCharacterIgnoringFieldEditor:CPNewlineCharacter];
}
- (void)insertTabIgnoringFieldEditor:(id)sender
{
var oldValue = [self stringValue];
[self _insertCharacterIgnoringFieldEditor:CPTabCharacter];
}
[self _inputElement].value += CPTabCharacter;
[self _setStringValue:[self _inputElement].value];
- (void)_insertCharacterIgnoringFieldEditor:(CPString)aCharacter
{
#if PLATFORM(DOM)
if (oldValue !== [self stringValue])
var oldValue = _stringValue,
range = [self selectedRange],
element = [self _inputElement];
element.value = [element.value stringByReplacingCharactersInRange:[self selectedRange] withString:aCharacter];
[self _setStringValue:element.value];
// NOTE: _stringValue is now the current input element value
if (oldValue !== _stringValue)
{
if (!_isEditing)
{
@@ -783,6 +842,8 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
[self textDidChange:[CPNotification notificationWithName:CPControlTextDidChangeNotification object:self userInfo:nil]];
}
#endif
}
- (void)textDidBlur:(CPNotification)note
@@ -813,15 +874,8 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
[super textDidChange:note];
}
- (void)sendAction:(SEL)anAction to:(id)anObject
{
[self _reverseSetBinding];
[CPApp sendAction:anAction to:anObject from:self];
}
/*!
Returns the string the text field.
Returns the string in the text field.
*/
- (id)objectValue
{
@@ -830,24 +884,84 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
/*
@ignore
Sets the internal string value without updating the value in the input element
Sets the internal string value without updating the value in the input element.
This should only be invoked when the underlying text element's value has changed.
*/
- (void)_setStringValue:(id)aValue
- (BOOL)_setStringValue:(CPString)aValue
{
[self willChangeValueForKey:@"objectValue"];
[super setObjectValue:String(aValue)];
[self _updatePlaceholderState];
[self didChangeValueForKey:@"objectValue"];
return [self _setStringValue:aValue isNewValue:YES errorDescription:nil];
}
/*
@ignore
Sets the internal string value without updating the value in the input element.
If there is a formatter and formatting fails, returns NO. Otherwise returns YES.
*/
- (BOOL)_setStringValue:(CPString)aValue isNewValue:(BOOL)isNewValue errorDescription:(CPStringRef)anError
{
_stringValue = aValue;
var objectValue = aValue,
formatter = [self formatter],
result = YES;
if (formatter)
{
var object = nil;
if ([formatter getObjectValue:AT_REF(object) forString:aValue errorDescription:anError])
objectValue = object;
else
{
objectValue = undefined; // Mark the value as invalid
result = NO;
}
isNewValue |= objectValue !== [super objectValue];
}
if (isNewValue)
{
[self willChangeValueForKey:@"objectValue"];
[super setObjectValue:objectValue];
[self _updatePlaceholderState];
[self didChangeValueForKey:@"objectValue"];
}
return result;
}
- (void)setObjectValue:(id)aValue
{
[super setObjectValue:aValue];
var formatter = [self formatter];
if (formatter)
{
// If there is a formatter, make sure the object value can be formatted successfully
var formattedString = [self hasThemeState:CPThemeStateEditing] ? [formatter editingStringForObjectValue:aValue] : [formatter stringForObjectValue:aValue];
if (formattedString === nil)
{
var value = nil;
// Formatting failed, get an "empty" object by formatting an empty string.
// If that fails, the value is undefined.
if ([formatter getObjectValue:AT_REF(value) forString:@"" errorDescription:nil] === NO)
value = undefined;
[super setObjectValue:value];
}
}
_stringValue = [self stringValue];
#if PLATFORM(DOM)
if (CPTextFieldInputOwner === self || [[self window] firstResponder] === self)
[self _inputElement].value = aValue;
[self _inputElement].value = _stringValue;
#endif
[self _updatePlaceholderState];
@@ -855,9 +969,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
- (void)_updatePlaceholderState
{
var string = [self stringValue];
if ((!string || string.length === 0) && ![self hasThemeState:CPThemeStateEditing])
if ((!_stringValue || _stringValue.length === 0) && ![self hasThemeState:CPThemeStateEditing])
[self setThemeState:CPTextFieldStatePlaceholder];
else
[self unsetThemeState:CPTextFieldStatePlaceholder];
@@ -910,7 +1022,6 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
However, since you don't know how tall it needs to be if you change the font, sizeToFit will still be
useful for making the textfield an appropriate height.
*/
- (void)sizeToFit
{
[self setFrameSize:[self _minimumFrameSize]];
@@ -923,7 +1034,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
minSize = [self currentValueForThemeAttribute:@"min-size"],
maxSize = [self currentValueForThemeAttribute:@"max-size"],
lineBreakMode = [self lineBreakMode],
text = ([self stringValue] || @" "),
text = (_stringValue || @" "),
textSize = _CGSizeMakeCopy(frameSize),
font = [self currentValueForThemeAttribute:@"font"];
@@ -994,8 +1105,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
return;
var pasteboard = [CPPasteboard generalPasteboard],
stringValue = [self stringValue],
stringForPasting = [stringValue substringWithRange:selectedRange];
stringForPasting = [_stringValue substringWithRange:selectedRange];
[pasteboard declareTypes:[CPStringPboardType] owner:nil];
[pasteboard setString:stringForPasting forType:CPStringPboardType];
@@ -1025,9 +1135,8 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
[self deleteBackward:sender];
var selectedRange = [self selectedRange],
stringValue = [self stringValue],
pasteString = [pasteboard stringForType:CPStringPboardType],
newValue = [stringValue stringByReplacingCharactersInRange:selectedRange withString:pasteString];
newValue = [_stringValue stringByReplacingCharactersInRange:selectedRange withString:pasteString];
[self setStringValue:newValue];
[self setSelectedRange:CPMakeRange(selectedRange.location + pasteString.length, 0)];
@@ -1041,6 +1150,8 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
if ([[self window] firstResponder] !== self)
return CPMakeRange(0, 0);
#if PLATFORM(DOM)
// we wrap this in try catch because firefox will throw an exception in certain instances
try
{
@@ -1067,6 +1178,8 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
// fall through to the return
}
#endif
return CPMakeRange(0, 0);
}
@@ -1075,6 +1188,8 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
if (![[self window] firstResponder] === self)
return;
#if PLATFORM(DOM)
var inputElement = [self _inputElement];
try
@@ -1103,6 +1218,8 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
catch (e)
{
}
#endif
}
- (void)selectAll:(id)sender
@@ -1120,8 +1237,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
selectedRange.location += 1;
selectedRange.length -= 1;
var stringValue = [self stringValue],
newValue = [stringValue stringByReplacingCharactersInRange:selectedRange withString:""];
var newValue = [_stringValue stringByReplacingCharactersInRange:selectedRange withString:""];
[self setStringValue:newValue];
[self setSelectedRange:CPMakeRange(selectedRange.location, 0)];
@@ -1274,7 +1390,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
string = [self placeholderString];
else
{
string = [self stringValue];
string = _stringValue;
if ([self isSecure])
string = secureStringForString(string);
@@ -1317,7 +1433,7 @@ var secureStringForString = function(aString)
return "";
return Array(aString.length + 1).join(CPSecureTextFieldCharacter);
}
};
var CPTextFieldIsEditableKey = "CPTextFieldIsEditableKey",
@@ -1387,6 +1503,16 @@ var CPTextFieldIsEditableKey = "CPTextFieldIsEditableKey",
{
}
- (void)_updatePlaceholdersWithOptions:(CPDictionary)options
{
[super _updatePlaceholdersWithOptions:options];
[self _setPlaceholder:@"Multiple Values" forMarker:CPMultipleValuesMarker isDefault:YES];
[self _setPlaceholder:@"No Selection" forMarker:CPNoSelectionMarker isDefault:YES];
[self _setPlaceholder:@"Not Applicable" forMarker:CPNotApplicableMarker isDefault:YES];
[self _setPlaceholder:@"" forMarker:CPNullMarker isDefault:YES];
}
- (void)setValueFor:(CPString)theBinding
{
var destination = [_info objectForKey:CPObservedObjectKey],
@@ -1397,29 +1523,14 @@ var CPTextFieldIsEditableKey = "CPTextFieldIsEditableKey",
if (isPlaceholder)
{
switch (newValue)
if (newValue === CPNotApplicableMarker && [options objectForKey:CPRaisesForNotApplicableKeysBindingOption])
{
case CPMultipleValuesMarker:
newValue = [options objectForKey:CPMultipleValuesPlaceholderBindingOption] || @"Multiple Values";
break;
case CPNoSelectionMarker:
newValue = [options objectForKey:CPNoSelectionPlaceholderBindingOption] || @"No Selection";
break;
case CPNotApplicableMarker:
if ([options objectForKey:CPRaisesForNotApplicableKeysBindingOption])
[CPException raise:CPGenericException
reason:@"can't transform non applicable key on: "+_source+" value: "+newValue];
newValue = [options objectForKey:CPNotApplicablePlaceholderBindingOption] || @"Not Applicable";
break;
case CPNullMarker:
newValue = [options objectForKey:CPNullPlaceholderBindingOption] || @"";
break;
[CPException raise:CPGenericException
reason:@"can't transform non applicable key on: " + _source + " value: " + newValue];
}
newValue = [self _placeholderForMarker:newValue];
[_source setPlaceholderString:newValue];
[_source setObjectValue:nil];
}
+3 -1
View File
@@ -579,6 +579,7 @@ CPThemeStateCircular = CPThemeState("circular");
_cache = {};
_name = [aCoder decodeObjectForKey:@"name"];
_defaultValue = [aCoder decodeObjectForKey:@"defaultValue"];
_values = [CPDictionary dictionary];
if ([aCoder containsValueForKey:@"value"])
@@ -611,6 +612,7 @@ CPThemeStateCircular = CPThemeState("circular");
- (void)encodeWithCoder:(CPCoder)aCoder
{
[aCoder encodeObject:_name forKey:@"name"];
[aCoder encodeObject:_defaultValue forKey:@"defaultValue"];
var keys = [_values allKeys],
count = keys.length;
@@ -666,7 +668,7 @@ var numberOfOnes = function(aNumber)
cachedNumberOfOnes[slot] = count;
return count;
}
};
numberOfOnes.displayName = "numberOfOnes";
+144 -63
View File
@@ -97,61 +97,66 @@ var CPThemeStateAutoCompleting = @"CPThemeStateAutoCompleting",
{
if (self = [super initWithFrame:frame])
{
_selectedRange = CPMakeRange(0, 0);
_tokenScrollView = [[CPScrollView alloc] initWithFrame:CGRectMakeZero()];
[_tokenScrollView setHasHorizontalScroller:NO];
[_tokenScrollView setHasVerticalScroller:NO];
[_tokenScrollView setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
var contentView = [[CPView alloc] initWithFrame:CGRectMakeZero()];
[contentView setAutoresizingMask:CPViewWidthSizable];
[_tokenScrollView setDocumentView:contentView];
[self addSubview:_tokenScrollView];
_tokenIndex = 0;
_cachedCompletions = [];
_completionDelay = [CPTokenField defaultCompletionDelay];
_tokenizingCharacterSet = [[self class] defaultTokenizingCharacterSet];
_autocompleteContainer = [[CPView alloc] initWithFrame:CPRectMake(0.0, 0.0, frame.size.width, 92.0)];
[_autocompleteContainer setBackgroundColor:[_CPMenuWindow backgroundColorForBackgroundStyle:_CPMenuWindowPopUpBackgroundStyle]];
_autocompleteScrollView = [[CPScrollView alloc] initWithFrame:CPRectMake(1.0, 1.0, frame.size.width - 2.0, 90.0)];
[_autocompleteScrollView setAutohidesScrollers:YES];
[_autocompleteScrollView setHasHorizontalScroller:NO];
[_autocompleteContainer addSubview:_autocompleteScrollView];
_autocompleteView = [[CPTableView alloc] initWithFrame:CPRectMakeZero()];
var tableColumn = [[CPTableColumn alloc] initWithIdentifier:CPTokenFieldTableColumnIdentifier];
[tableColumn setResizingMask:CPTableColumnAutoresizingMask];
[_autocompleteView addTableColumn:tableColumn];
[_autocompleteView setDataSource:self];
[_autocompleteView setDelegate:self];
[_autocompleteView setAllowsMultipleSelection:NO];
[_autocompleteView setHeaderView:nil];
[_autocompleteView setCornerView:nil];
[_autocompleteView setRowHeight:30.0];
[_autocompleteView setGridStyleMask:CPTableViewSolidHorizontalGridLineMask];
[_autocompleteView setBackgroundColor:[CPColor clearColor]];
[_autocompleteView setGridColor:[CPColor colorWithRed:242.0 / 255.0 green:243.0 / 255.0 blue:245.0 / 255.0 alpha:1.0]];
[_autocompleteScrollView setDocumentView:_autocompleteView];
[self setBezeled:YES];
[self _init];
[self setObjectValue:[]];
[self setNeedsLayout];
}
return self;
}
- (void)_init
{
_selectedRange = CPMakeRange(0, 0);
var frame = [self frame];
_tokenScrollView = [[CPScrollView alloc] initWithFrame:CGRectMakeZero()];
[_tokenScrollView setHasHorizontalScroller:NO];
[_tokenScrollView setHasVerticalScroller:NO];
[_tokenScrollView setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
var contentView = [[CPView alloc] initWithFrame:CGRectMakeZero()];
[contentView setAutoresizingMask:CPViewWidthSizable];
[_tokenScrollView setDocumentView:contentView];
[self addSubview:_tokenScrollView];
_cachedCompletions = [];
_autocompleteContainer = [[CPView alloc] initWithFrame:CPRectMake(0.0, 0.0, frame.size.width, 92.0)];
[_autocompleteContainer setBackgroundColor:[_CPMenuWindow backgroundColorForBackgroundStyle:_CPMenuWindowPopUpBackgroundStyle]];
_autocompleteScrollView = [[CPScrollView alloc] initWithFrame:CPRectMake(1.0, 1.0, frame.size.width - 2.0, 90.0)];
[_autocompleteScrollView setAutohidesScrollers:YES];
[_autocompleteScrollView setHasHorizontalScroller:NO];
[_autocompleteContainer addSubview:_autocompleteScrollView];
_autocompleteView = [[CPTableView alloc] initWithFrame:CPRectMakeZero()];
var tableColumn = [[CPTableColumn alloc] initWithIdentifier:CPTokenFieldTableColumnIdentifier];
[tableColumn setResizingMask:CPTableColumnAutoresizingMask];
[_autocompleteView addTableColumn:tableColumn];
[_autocompleteView setDataSource:self];
[_autocompleteView setDelegate:self];
[_autocompleteView setAllowsMultipleSelection:NO];
[_autocompleteView setHeaderView:nil];
[_autocompleteView setCornerView:nil];
[_autocompleteView setRowHeight:30.0];
[_autocompleteView setGridStyleMask:CPTableViewSolidHorizontalGridLineMask];
[_autocompleteView setBackgroundColor:[CPColor clearColor]];
[_autocompleteView setGridColor:[CPColor colorWithRed:242.0 / 255.0 green:243.0 / 255.0 blue:245.0 / 255.0 alpha:1.0]];
[_autocompleteScrollView setDocumentView:_autocompleteView];
}
// ===============
// = CONVENIENCE =
// ===============
@@ -159,7 +164,7 @@ var CPThemeStateAutoCompleting = @"CPThemeStateAutoCompleting",
{
var indexOfSelectedItem = 0;
_cachedCompletions = [self tokenField:self completionsForSubstring:[self _inputElement].value indexOfToken:_tokenIndex indexOfSelectedItem:indexOfSelectedItem];
_cachedCompletions = [self tokenField:self completionsForSubstring:[self _inputElement].value indexOfToken:0 indexOfSelectedItem:indexOfSelectedItem];
[_autocompleteView selectRowIndexes:[CPIndexSet indexSetWithIndex:indexOfSelectedItem] byExtendingSelection:NO];
[_autocompleteView reloadData];
@@ -167,19 +172,20 @@ var CPThemeStateAutoCompleting = @"CPThemeStateAutoCompleting",
- (void)_autocompleteWithDOMEvent:(JSObject)DOMEvent
{
if (!_cachedCompletions || ![self hasThemeState:CPThemeStateAutoCompleting])
if (![self _inputElement].value && (!_cachedCompletions || ![self hasThemeState:CPThemeStateAutoCompleting]))
return;
[self _hideCompletions];
var token = _cachedCompletions[[_autocompleteView selectedRow]],
var token = _cachedCompletions ? _cachedCompletions[[_autocompleteView selectedRow]] : nil,
shouldRemoveLastObject = token !== @"" && [self _inputElement].value !== @"";
if (!token)
token = [self _inputElement].value;
// Make sure the user typed an actual token to prevent the previous token from being emptied
// If the input area is empty, we want to fallback to the normal behavior, resigning first responder or select the next or previous key view
// If the input area is empty, we want to fall back to the normal behavior, resigning first
// responder or selecting the next or previous key view.
if (!token || token === @"")
{
if (DOMEvent && DOMEvent.keyCode === CPTabKeyCode)
@@ -194,7 +200,6 @@ var CPThemeStateAutoCompleting = @"CPThemeStateAutoCompleting",
return;
}
var objectValue = [self objectValue];
// Remove the uncompleted token and add the token string.
@@ -202,10 +207,25 @@ var CPThemeStateAutoCompleting = @"CPThemeStateAutoCompleting",
if (shouldRemoveLastObject)
[objectValue removeObjectAtIndex:_selectedRange.location];
[objectValue insertObject:token atIndex:_selectedRange.location];
// Give the delegate a chance to confirm, replace or add to the list of tokens being added.
var delegateApprovedObjects = [self tokenField:self shouldAddObjects:[CPArray arrayWithObject:token] atIndex:_selectedRange.location],
delegateApprovedObjectsCount = [delegateApprovedObjects count];
if (delegateApprovedObjects)
{
for (var i = 0; i < delegateApprovedObjectsCount; i++)
{
[objectValue insertObject:[delegateApprovedObjects objectAtIndex:i] atIndex:_selectedRange.location + i];
}
}
// Put the cursor after the last inserted token.
var location = _selectedRange.location;
[self setObjectValue:objectValue];
_selectedRange = CPMakeRange(location + 1, 0);
if (delegateApprovedObjectsCount)
location += delegateApprovedObjectsCount;
_selectedRange = CPMakeRange(location, 0);
[self _inputElement].value = @"";
[self setNeedsLayout];
@@ -250,8 +270,13 @@ var CPThemeStateAutoCompleting = @"CPThemeStateAutoCompleting",
var indexOfToken = [[self _tokens] indexOfObject:token],
objectValue = [self objectValue];
// If the token was selected, deselect it for selection preservation.
[self _deselectToken:token];
// If the selection was to the right of the deleted token, move it to the left. If the deleted token was
// selected, deselect it.
if (indexOfToken < _selectedRange.location)
_selectedRange.location--;
else
[self _deselectToken:token];
// Preserve selection.
var selection = CPCopyRange(_selectedRange);
[objectValue removeObjectAtIndex:indexOfToken];
@@ -291,6 +316,14 @@ var CPThemeStateAutoCompleting = @"CPThemeStateAutoCompleting",
[self _controlTextDidChange];
}
- (void)_updatePlaceholderState
{
if (([[self _tokens] count] === 0) && ![self hasThemeState:CPThemeStateEditing])
[self setThemeState:CPTextFieldStatePlaceholder];
else
[self unsetThemeState:CPTextFieldStatePlaceholder];
}
// =============
// = RESPONDER =
// =============
@@ -575,14 +608,16 @@ var CPThemeStateAutoCompleting = @"CPThemeStateAutoCompleting",
{
}
// ========
// = VIEW =
// ========
- (void)viewDidMoveToWindow
{
[[[self window] contentView] addSubview:_autocompleteContainer];
#if PLATFORM(DOM)
_autocompleteContainer._DOMElement.style.zIndex = 1000; // Anything else doesn't seem to work
#endif
}
- (void)removeFromSuperview
@@ -625,7 +660,7 @@ var CPThemeStateAutoCompleting = @"CPThemeStateAutoCompleting",
CPTokenFieldInputDidBlur = YES;
return true;
}
};
CPTokenFieldKeyDownFunction = function(aDOMEvent)
{
@@ -779,7 +814,7 @@ var CPThemeStateAutoCompleting = @"CPThemeStateAutoCompleting",
}
return true;
}
};
CPTokenFieldKeyPressFunction = function(aDOMEvent)
{
@@ -809,7 +844,7 @@ var CPThemeStateAutoCompleting = @"CPThemeStateAutoCompleting",
// Force immediate layout in case word wrapping is now necessary.
[owner setNeedsLayout];
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
}
};
CPTokenFieldKeyUpFunction = function()
{
@@ -822,14 +857,14 @@ var CPThemeStateAutoCompleting = @"CPThemeStateAutoCompleting",
[self setNeedsLayout];
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
}
};
CPTokenFieldHandleBlur = function(anEvent)
{
CPTokenFieldInputOwner = nil;
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
}
};
if (document.attachEvent)
{
@@ -991,7 +1026,7 @@ var CPThemeStateAutoCompleting = @"CPThemeStateAutoCompleting",
offset.x += width + spaceBetweenTokens.width;
return r;
}
};
var placeEditor = function(useRemainingWidth)
{
@@ -1018,7 +1053,7 @@ var CPThemeStateAutoCompleting = @"CPThemeStateAutoCompleting",
// When editing, always scroll to the cursor.
if (_selectedRange.length == 0)
[[_tokenScrollView documentView] scrollRectToVisible:inputFrame];
}
};
for (var i = 0, count = [tokens count]; i < count; i++)
{
@@ -1123,7 +1158,7 @@ var CPThemeStateAutoCompleting = @"CPThemeStateAutoCompleting",
{
if ([[self delegate] respondsToSelector:@selector(tokenField:completionsForSubstring:indexOfToken:indexOfSelectedItem:)])
{
return [[self delegate] tokenField:tokenField completionsForSubstring:substring indexOfToken:_tokenIndex indexOfSelectedItem:selectedIndex];
return [[self delegate] tokenField:tokenField completionsForSubstring:substring indexOfToken:tokenIndex indexOfSelectedItem:selectedIndex];
}
return [];
@@ -1149,7 +1184,19 @@ var CPThemeStateAutoCompleting = @"CPThemeStateAutoCompleting",
// // return an array of represented objects you want to add.
// // If you want to reject the add, return an empty array.
// // returning nil will cause an error.
// - (NSArray *)tokenField:(NSTokenField *)tokenField shouldAddObjects:(NSArray *)tokens atIndex:(NSUInteger)index;
- (CPArray)tokenField:(CPTokenField)tokenField shouldAddObjects:(CPArray)tokens atIndex:(int)index
{
var delegate = [self delegate];
if ([delegate respondsToSelector:@selector(tokenField:shouldAddObjects:atIndex:)])
{
var approvedObjects = [delegate tokenField:tokenField shouldAddObjects:tokens atIndex:index];
if (approvedObjects !== nil)
return approvedObjects;
}
return tokens;
}
//
// // If you return nil or don't implement these delegate methods, we will assume
// // editing string = display string = represented object
@@ -1292,3 +1339,37 @@ var CPThemeStateAutoCompleting = @"CPThemeStateAutoCompleting",
}
@end
var CPTokenFieldTokenizingCharacterSetKey = "CPTokenFieldTokenizingCharacterSetKey",
CPTokenFieldCompletionDelayKey = "CPTokenFieldCompletionDelay";
@implementation CPTokenField (CPCoding)
- (id)initWithCoder:(CPCoder)aCoder
{
self = [super initWithCoder:aCoder];
if (self)
{
_tokenizingCharacterSet = [aCoder decodeObjectForKey:CPTokenFieldTokenizingCharacterSetKey] || [[self class] defaultTokenizingCharacterSet];
_completionDelay = [aCoder decodeDoubleForKey:CPTokenFieldCompletionDelayKey] || [[self class] defaultCompletionDelay];
[self _init];
[self setNeedsLayout];
[self setNeedsDisplay:YES];
}
return self;
}
- (void)encodeWithCoder:(CPCoder)aCoder
{
[super encodeWithCoder:aCoder];
[aCoder encodeInt:_tokenizingCharacterSet forKey:CPTokenFieldTokenizingCharacterSetKey];
[aCoder encodeDouble:_completionDelay forKey:CPTokenFieldCompletionDelayKey];
}
@end
+34 -6
View File
@@ -50,9 +50,17 @@ CPToolbarDisplayModeIconOnly = 2;
*/
CPToolbarDisplayModeLabelOnly = 3;
CPToolbarSizeModeDefault = 0;
CPToolbarSizeModeRegular = 1;
CPToolbarSizeModeSmall = 2;
var CPToolbarsByIdentifier = nil,
CPToolbarConfigurationsByIdentifier = nil;
var TOOLBAR_REGULAR_HEIGHT = 59.0,
TOOLBAR_SMALL_HEIGHT = 46.0;
/*!
@ingroup appkit
@class CPToolbar
@@ -87,6 +95,7 @@ var CPToolbarsByIdentifier = nil,
BOOL _showsBaselineSeparator;
BOOL _allowsUserCustomization;
BOOL _isVisible;
int _sizeMode @accessors(property=sizeMode);
id _delegate;
@@ -148,6 +157,7 @@ var CPToolbarsByIdentifier = nil,
_identifier = anIdentifier;
_isVisible = YES;
_sizeMode = CPToolbarSizeModeDefault;
[CPToolbar _addToolbar:self forIdentifier:_identifier];
}
@@ -202,6 +212,16 @@ var CPToolbarsByIdentifier = nil,
[_window _noteToolbarChanged];
}
- (void)setSizeMode:(CPToolbarSizeMode)aSize
{
if (aSize === _sizeMode)
return;
_sizeMode = aSize;
[[self _toolbarView] setFrame:[self _toolbarViewFrame]];
[_window _noteToolbarChanged];
}
- (CPWindow)_window
{
return _window;
@@ -232,12 +252,17 @@ var CPToolbarsByIdentifier = nil,
}
- (CGRect)_toolbarViewFrame
{
return CPRectMake(0.0, 0.0, 1200.0, _sizeMode != CPToolbarSizeModeSmall ? TOOLBAR_REGULAR_HEIGHT : TOOLBAR_SMALL_HEIGHT);
}
/* @ignore */
- (CPView)_toolbarView
{
if (!_toolbarView)
{
_toolbarView = [[_CPToolbarView alloc] initWithFrame:CPRectMake(0.0, 0.0, 1200.0, 59.0)];
_toolbarView = [[_CPToolbarView alloc] initWithFrame:[self _toolbarViewFrame]];
[_toolbarView setToolbar:self];
[_toolbarView setAutoresizingMask:CPViewWidthSizable];
@@ -427,7 +452,8 @@ var CPToolbarIdentifierKey = @"CPToolbarIdentifierKey",
CPToolbarIdentifiedItemsKey = @"CPToolbarIdentifiedItemsKey",
CPToolbarDefaultItemsKey = @"CPToolbarDefaultItemsKey",
CPToolbarAllowedItemsKey = @"CPToolbarAllowedItemsKey",
CPToolbarSelectableItemsKey = @"CPToolbarSelectableItemsKey";
CPToolbarSelectableItemsKey = @"CPToolbarSelectableItemsKey",
CPToolbarSizeModeKey = @"CPToolbarSizeModeKey";
@implementation CPToolbar (CPCoding)
@@ -446,6 +472,7 @@ var CPToolbarIdentifierKey = @"CPToolbarIdentifierKey",
_showsBaselineSeparator = [aCoder decodeBoolForKey:CPToolbarShowsBaselineSeparatorKey];
_allowsUserCustomization = [aCoder decodeBoolForKey:CPToolbarAllowsUserCustomizationKey];
_isVisible = [aCoder decodeBoolForKey:CPToolbarIsVisibleKey];
_sizeMode = [aCoder decodeIntForKey:CPToolbarSizeModeKey];
_identifiedItems = [aCoder decodeObjectForKey:CPToolbarIdentifiedItemsKey];
_defaultItems = [aCoder decodeObjectForKey:CPToolbarDefaultItemsKey];
@@ -492,6 +519,7 @@ var CPToolbarIdentifierKey = @"CPToolbarIdentifierKey",
[aCoder encodeBool:_showsBaselineSeparator forKey:CPToolbarShowsBaselineSeparatorKey];
[aCoder encodeBool:_allowsUserCustomization forKey:CPToolbarAllowsUserCustomizationKey];
[aCoder encodeBool:_isVisible forKey:CPToolbarIsVisibleKey];
[aCoder encodeInt:_sizeMode forKey:CPToolbarSizeModeKey]
[aCoder encodeObject:_identifiedItems forKey:CPToolbarIdentifiedItemsKey];
[aCoder encodeObject:_defaultItems forKey:CPToolbarDefaultItemsKey];
@@ -515,7 +543,7 @@ var TOOLBAR_TOP_MARGIN = 5.0,
var _CPToolbarItemInfoMake = function(anIndex, aView, aLabel, aMinWidth)
{
return { index:anIndex, view:aView, label:aLabel, minWidth:aMinWidth };
}
};
/* @ignore */
@implementation _CPToolbarView : CPView
@@ -547,7 +575,7 @@ 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)];
}
@@ -876,7 +904,7 @@ var _CPToolbarItemVisibilityPriorityCompare = function(lhs, rhs)
return CPOrderedAscending;
return CPOrderedDescending;
}
};
var TOP_MARGIN = 5.0,
LABEL_MARGIN = 2.0;
@@ -1015,7 +1043,7 @@ 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, minSize.width), 100000000.0);
_maxSize = CGSizeMake(MAX(_labelSize.width, maxSize.width), 100000000.0);
[_toolbar tile];
}
+5 -5
View File
@@ -180,7 +180,7 @@ var CPUserDefaultsControllerSharedKey = "CPUserDefaultsControllerSharedKey";
var keys = [_cachedValues allKeys],
keysCount = [keys count];
while(keysCount--)
while (keysCount--)
{
var key = keys[keysCount];
[self willChangeValueForKey:key];
@@ -194,7 +194,7 @@ var CPUserDefaultsControllerSharedKey = "CPUserDefaultsControllerSharedKey";
var keys = [_cachedValues allKeys],
keysCount = [keys count];
while(keysCount--)
while (keysCount--)
{
var key = keys[keysCount];
[[_controller defaults] setObject:[_cachedValues objectForKey:key] forKey:key];
@@ -207,7 +207,7 @@ var CPUserDefaultsControllerSharedKey = "CPUserDefaultsControllerSharedKey";
keys = [_cachedValues allKeys],
keysCount = [keys count];
while(keysCount--)
while (keysCount--)
{
var key = keys[keysCount];
[self willChangeValueForKey:key];
@@ -229,7 +229,7 @@ var CPUserDefaultsControllerSharedKey = "CPUserDefaultsControllerSharedKey";
keys = [_cachedValues allKeys],
keysCount = [keys count];
while(keysCount--)
while (keysCount--)
{
var key = keys[keysCount],
value = [_cachedValues objectForKey:key],
@@ -250,7 +250,7 @@ var CPUserDefaultsControllerSharedKey = "CPUserDefaultsControllerSharedKey";
keys = [_cachedValues allKeys],
keysCount = [keys count];
while(keysCount--)
while (keysCount--)
{
var key = keys[keysCount],
value = [_cachedValues objectForKey:key],
+99 -2
View File
@@ -141,6 +141,7 @@ var CPViewFlags = { },
BOOL _postsFrameChangedNotifications;
BOOL _postsBoundsChangedNotifications;
BOOL _inhibitFrameAndBoundsChangedNotifications;
BOOL _inLiveResize;
#if PLATFORM(DOM)
DOMElement _DOMElement;
@@ -291,6 +292,9 @@ var CPViewFlags = { },
CPDOMDisplayServerSetStyleLeftTop(_DOMElement, NULL, _CGRectGetMinX(aFrame), _CGRectGetMinY(aFrame));
CPDOMDisplayServerSetStyleSize(_DOMElement, width, height);
if (typeof(appkit_tag_dom_elements) !== "undefined" && !!appkit_tag_dom_elements)
_DOMElement.setAttribute("data-cappuccino-view", [self className]);
_DOMImageParts = [];
_DOMImageSizes = [];
#endif
@@ -848,11 +852,17 @@ var CPViewFlags = { },
if (_backgroundType === BackgroundVerticalThreePartImage)
{
// 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);
}
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, size.height);
CPDOMDisplayServerSetStyleSize(_DOMImageParts[1], size.width - _DOMImageSizes[0].width - _DOMImageSizes[2].width, size.height);
CPDOMDisplayServerSetStyleSize(_DOMImageParts[2], _DOMImageSizes[2].width, size.height);
}
else if (_backgroundType === BackgroundNinePartImage)
{
@@ -1539,7 +1549,10 @@ var CPViewFlags = { },
}
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);
CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[0], NULL, 0.0, 0.0);
CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[1], NULL, 0.0, _DOMImageSizes[0].height);
@@ -1547,7 +1560,10 @@ var CPViewFlags = { },
}
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);
CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[0], NULL, 0.0, 0.0);
CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[1], NULL, _DOMImageSizes[0].width, 0.0);
@@ -2128,6 +2144,43 @@ setBoundsOrigin:
{
}
/*!
Return yes if the receiver is in a live-resize operation.
*/
- (BOOL)inLiveResize
{
return _inLiveResize;
}
/*!
Not implemented.
A view will be sent this message before a window begins a resize operation. The
receiver might choose to simplify its drawing operations during a live resize
for speed.
Subclasses should call super.
*/
- (void)viewWillStartLiveResize
{
_inLiveResize = YES;
}
/*!
Not implemented.
A view will be sent this message after a window finishes a resize operation. The
receiver which simplified its drawing operations in viewWillStartLiveResize might
stop doing so now. Note the view might no longer be in a window, so use
[self setNeedsDisplay:YES] if a final non-simplified redraw is required.
Subclasses should call super.
*/
- (void)viewDidEndLiveResize
{
_inLiveResize = NO;
}
@end
@implementation CPView (KeyView)
@@ -2543,6 +2596,50 @@ setBoundsOrigin:
return (_themeAttributes && _themeAttributes[aName] !== undefined);
}
/*!
Registers theme values encoded in an array at runtime. The format of the data in the array
is the same as that used by ThemeDescriptors.j, with the exception that you need to use
CPColorWithImages() in place of PatternColor(). For more information see the comments
at the top of ThemeDescriptors.j.
@param themeValues array of theme values
*/
- (void)registerThemeValues:(CPArray)themeValues
{
for (var i = 0; i < themeValues.length; ++i)
{
var attributeValueState = themeValues[i],
attribute = attributeValueState[0],
value = attributeValueState[1],
state = attributeValueState[2];
if (state)
[self setValue:value forThemeAttribute:attribute inState:state];
else
[self setValue:value forThemeAttribute:attribute];
}
}
/*!
Registers theme values encoded in an array at runtime. The format of the data in the array
is the same as that used by ThemeDescriptors.j, with the exception that you need to use
CPColorWithImages() in place of PatternColor(). The values in \c inheritedValues are
registered first, then those in \c themeValues override/augment the inherited values.
For more information see the comments at the top of ThemeDescriptors.j.
@param themeValues array of base theme values
@param inheritedValues array of overridden/additional theme values
*/
- (void)registerThemeValues:(CPArray)themeValues inherit:(CPArray)inheritedValues
{
// Register inherited values first, then override those with the subtheme values.
if (inheritedValues)
[self registerThemeValues:inheritedValues];
if (themeValues)
[self registerThemeValues:themeValues];
}
- (CPView)createEphemeralSubviewNamed:(CPString)aViewName
{
return nil;
@@ -2799,7 +2896,7 @@ var _CPViewFullScreenModeStateMake = function(aView)
var superview = aView._superview;
return { autoresizingMask:aView._autoresizingMask, frame:CGRectMakeCopy(aView._frame), index:(superview ? [superview._subviews indexOfObjectIdenticalTo:aView] : 0), superview:superview };
}
};
var _CPViewGetTransform = function(/*CPView*/ fromView, /*CPView */ toView)
{
@@ -2896,4 +2993,4 @@ var _CPViewGetTransform = function(/*CPView*/ fromView, /*CPView */ toView)
}*/
return transform;
}
};
+8 -7
View File
@@ -111,7 +111,8 @@ CPViewAnimationFadeOutEffect = @"CPViewAnimationFadeOutEffect";
view = [self _targetView:dictionary],
startFrame = [self _startFrame:dictionary],
endFrame = [self _endFrame:dictionary],
differenceFrame = _CGRectMakeZero();
differenceFrame = _CGRectMakeZero(),
value = [super currentValue];
differenceFrame.origin.x = endFrame.origin.x - startFrame.origin.x;
differenceFrame.origin.y = endFrame.origin.y - startFrame.origin.y;
@@ -119,19 +120,19 @@ CPViewAnimationFadeOutEffect = @"CPViewAnimationFadeOutEffect";
differenceFrame.size.height = endFrame.size.height - startFrame.size.height;
var intermediateFrame = _CGRectMakeZero();
intermediateFrame.origin.x = startFrame.origin.x + differenceFrame.origin.x * progress;
intermediateFrame.origin.y = startFrame.origin.y + differenceFrame.origin.y * progress;
intermediateFrame.size.width = startFrame.size.width + differenceFrame.size.width * progress;
intermediateFrame.size.height = startFrame.size.height + differenceFrame.size.height * progress;
intermediateFrame.origin.x = startFrame.origin.x + differenceFrame.origin.x * value;
intermediateFrame.origin.y = startFrame.origin.y + differenceFrame.origin.y * value;
intermediateFrame.size.width = startFrame.size.width + differenceFrame.size.width * value;
intermediateFrame.size.height = startFrame.size.height + differenceFrame.size.height * value;
[view setFrame:intermediateFrame];
// Update the view's alpha value
var effect = [self _effect:dictionary];
if (effect === CPViewAnimationFadeInEffect)
[view setAlphaValue:1.0 * progress];
[view setAlphaValue:1.0 * value];
else if (effect === CPViewAnimationFadeOutEffect)
[view setAlphaValue:1.0 + ( 0.0 - 1.0 ) * progress];
[view setAlphaValue:1.0 + ( 0.0 - 1.0 ) * value];
if (progress === 1.0)
[self _targetView:view setHidden:_CGRectIsNull(endFrame) || [view alphaValue] === 0.0];
+30 -23
View File
@@ -66,6 +66,7 @@ var CPViewControllerCachedCibs;
{
CPView _view @accessors(property=view);
BOOL _isLoading;
BOOL _isLazy;
id _representedObject @accessors(property=representedObject);
CPString _title @accessors(property=title);
@@ -124,6 +125,7 @@ var CPViewControllerCachedCibs;
_cibExternalNameTable = anExternalNameTable || [CPDictionary dictionaryWithObject:self forKey:CPCibOwner];
_isLoading = NO;
_isLazy = NO;
}
return self;
@@ -136,12 +138,12 @@ var CPViewControllerCachedCibs;
If you create your views manually, you must override this method and use
it to create your view and assign it to the view property. The default
implementation for programmatic views is to create a plain view. You can
invoke super to utilize this view.
implementation for programmatic views is to create a plain, zero width & height
view. You can invoke super to utilize this view.
If you use Interface Builder to create your views, you initialize the view
using the initWithCibName:bundle: method then you must not override this
method. The consequences risk shattering the space-time continuum.
If you use Interface Builder to create your views, and you initialize the
controller using the initWithCibName:bundle: methods, then you MUST NOT override
this method. The consequences risk shattering the space-time continuum.
Note: The cib loading system is currently synchronous.
*/
@@ -150,17 +152,22 @@ var CPViewControllerCachedCibs;
if (_view)
return;
// check if a cib is already cached for the current _cibName
var cib = [CPViewControllerCachedCibs objectForKey:_cibName];
if (!cib)
if (_cibName)
{
// if the cib isn't cached yet : fetch it and cache it
cib = [[CPCib alloc] initWithContentsOfURL:[_cibBundle pathForResource:_cibName + @".cib"]];
[CPViewControllerCachedCibs setObject:cib forKey:_cibName];
}
// check if a cib is already cached for the current _cibName
var cib = [CPViewControllerCachedCibs objectForKey:_cibName];
[cib instantiateCibWithExternalNameTable:_cibExternalNameTable];
if (!cib)
{
// if the cib isn't cached yet : fetch it and cache it
cib = [[CPCib alloc] initWithCibNamed:_cibName bundle:_cibBundle];
[CPViewControllerCachedCibs setObject:cib forKey:_cibName];
}
[cib instantiateCibWithExternalNameTable:_cibExternalNameTable];
}
else
_view = [CPView new];
}
/*!
@@ -199,6 +206,11 @@ var CPViewControllerCachedCibs;
_isLoading = NO;
[self viewDidLoad];
}
else if (_isLazy)
{
_isLazy = NO;
[self viewDidLoad];
}
return _view;
}
@@ -208,9 +220,9 @@ var CPViewControllerCachedCibs;
This method is called after the view controller has loaded its associated views into memory.
This method is called regardless of whether the views were stored in a nib
file or created programmatically in the loadView method. This method is
most commonly used to perform additional initialization steps on views
that are loaded from cib files.
file or created programmatically in the loadView method, but NOT when setView
is invoked. This method is most commonly used to perform additional initialization
steps on views that are loaded from cib files.
*/
- (void)viewDidLoad
{
@@ -228,13 +240,7 @@ var CPViewControllerCachedCibs;
*/
- (void)setView:(CPView)aView
{
var viewWasLoaded = !_view;
_view = aView;
// Make sure the viewDidLoad method is called if the view is set directly
if (!_isLoading && viewWasLoaded)
[self viewDidLoad];
}
@end
@@ -266,6 +272,7 @@ var CPViewControllerViewKey = @"CPViewControllerViewKey",
_cibBundle = bundlePath ? [CPBundle bundleWithPath:bundlePath] : [CPBundle mainBundle];
_cibExternalNameTable = [CPDictionary dictionaryWithObject:self forKey:CPCibOwner];
_isLazy = YES;
}
return self;
+2 -2
View File
@@ -199,7 +199,7 @@ CPWebViewAppKitScrollMaxPollCount = 3;
_ignoreLoadEnd = NO;
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
}
};
if (_iframe.addEventListener)
_iframe.addEventListener("load", _loadCallback, false);
@@ -830,7 +830,7 @@ CPWebViewAppKitScrollMaxPollCount = 3;
- (@action)reload:(id)sender
{
// If we're displaying pure HTML, redisplay it.
if(!_url && (_html !== nil))
if (!_url && (_html !== nil))
[self loadHTMLString:_html];
else
[self _loadMainFrameURL];
+92 -18
View File
@@ -271,6 +271,7 @@ var CPWindowActionMessageKeys = [
BOOL _isAnimating;
BOOL _hasShadow;
BOOL _isMovableByWindowBackground;
BOOL _isMovable;
unsigned _shadowStyle;
BOOL _showsResizeIndicator;
@@ -404,6 +405,7 @@ CPTexturedBackgroundWindowMask
_registeredDraggedTypesArray = [];
_isSheet = NO;
_acceptsMouseMovedEvents = YES;
_isMovable = YES;
// Set up our window number.
_windowNumber = [CPApp._windows count];
@@ -426,6 +428,7 @@ CPTexturedBackgroundWindowMask
// Create a generic content view.
[self setContentView:[[CPView alloc] initWithFrame:CGRectMakeZero()]];
[self setInitialFirstResponder:[self contentView]];
_firstResponder = self;
@@ -452,6 +455,7 @@ CPTexturedBackgroundWindowMask
if (aStyleMask & CPBorderlessBridgeWindowMask)
[self setFullPlatformWindow:YES];
_autorecalculatesKeyViewLoop = NO;
_defaultButtonEnabled = YES;
_keyViewLoopIsDirty = YES;
@@ -480,6 +484,7 @@ CPTexturedBackgroundWindowMask
[self close];
_platformWindow = aPlatformWindow;
[_platformWindow _setTitle:_title window:self];
if (wasVisible)
[self orderFront:self];
@@ -511,6 +516,10 @@ CPTexturedBackgroundWindowMask
- (void)awakeFromCib
{
_keyViewLoopIsDirty = ![self _hasKeyViewLoop];
// If no key view loop has been specified by hand, and we are not intending to auto recalculate,
// set up a default key view loop.
if (_keyViewLoopIsDirty && ![self autorecalculatesKeyViewLoop])
[self recalculateKeyViewLoop];
}
- (void)_setWindowView:(CPView)aWindowView
@@ -949,6 +958,12 @@ CPTexturedBackgroundWindowMask
var bounds = CGRectMake(0.0, 0.0, CGRectGetWidth(_frame), CGRectGetHeight(_frame));
// During init the initial first responder is set to the contentView
// if it hasn't changed in the mean time we need to update that reference
// to the new contentView
if ([self initialFirstResponder] === _contentView)
[self setInitialFirstResponder:aView];
_contentView = aView;
[_contentView setFrame:[self contentRectForFrameRect:bounds]];
@@ -1273,17 +1288,17 @@ CPTexturedBackgroundWindowMask
- (BOOL)acceptsFirstResponder
{
return YES;
return NO;
}
- (id)initialFirstResponder
- (CPView)initialFirstResponder
{
return _initialFirstResponder;
}
- (void)setInitialFirstResponder:(id)aResponder
- (void)setInitialFirstResponder:(CPView)aView
{
_initialFirstResponder = aResponder;
_initialFirstResponder = aView;
}
/*!
@@ -1359,6 +1374,7 @@ CPTexturedBackgroundWindowMask
_title = aTitle;
[_windowView setTitle:aTitle];
[_platformWindow _setTitle:_title window:self];
[self _synchronizeMenuBarTitleWithWindowTitle];
}
@@ -1429,6 +1445,23 @@ CPTexturedBackgroundWindowMask
return _isMovableByWindowBackground;
}
/*!
Sets whether the window can be moved.
@param shouldBeMovable \c YES makes the window movable.
*/
- (void)setMovable:(BOOL)shouldBeMovable
{
_isMovable = shouldBeMovable;
}
/*!
Returns \c YES if the window can be moved.
*/
- (void)isMovable
{
return _isMovable;
}
/*!
Sets the window location to be the center of the screen
*/
@@ -2472,9 +2505,7 @@ CPTexturedBackgroundWindowMask
_autorecalculatesKeyViewLoop = shouldRecalculate;
if (_keyViewLoopIsDirty)
[self recalculateKeyViewLoop];
else if (_autorecalculatesKeyViewLoop)
if (_autorecalculatesKeyViewLoop)
[self _dirtyKeyViewLoop];
}
@@ -2485,30 +2516,70 @@ CPTexturedBackgroundWindowMask
- (void)selectNextKeyView:(id)sender
{
if (_keyViewLoopIsDirty && [self autorecalculatesKeyViewLoop])
[self recalculateKeyViewLoop];
var nextValidKeyView = nil;
if ([_firstResponder isKindOfClass:[CPView class]])
[self selectKeyViewFollowingView:_firstResponder];
nextValidKeyView = [_firstResponder nextValidKeyView];
if (!nextValidKeyView)
{
var initialFirstResponder = [self initialFirstResponder];
if ([initialFirstResponder acceptsFirstResponder])
nextValidKeyView = initialFirstResponder;
else
nextValidKeyView = [initialFirstResponder nextValidKeyView];
}
[self makeFirstResponder:nextValidKeyView];
}
- (void)selectPreviousKeyView:(id)sender
{
if (_keyViewLoopIsDirty && [self autorecalculatesKeyViewLoop])
[self recalculateKeyViewLoop];
var previousValidKeyView = nil;
if ([_firstResponder isKindOfClass:[CPView class]])
[self selectKeyViewPrecedingView:_firstResponder];
previousValidKeyView = [_firstResponder previousValidKeyView];
if (!previousValidKeyView)
{
var initialFirstResponder = [self initialFirstResponder];
if ([initialFirstResponder acceptsFirstResponder])
previousValidKeyView = initialFirstResponder;
else
previousValidKeyView = [initialFirstResponder previousValidKeyView];
}
[self makeFirstResponder:previousValidKeyView];
}
- (void)selectKeyViewFollowingView:(CPView)aView
{
if (_keyViewLoopIsDirty)
if (_keyViewLoopIsDirty && [self autorecalculatesKeyViewLoop])
[self recalculateKeyViewLoop];
[self makeFirstResponder:[aView nextValidKeyView]];
var nextValidKeyView = [aView nextValidKeyView];
if ([nextValidKeyView isKindOfClass:[CPView class]])
[self makeFirstResponder:nextValidKeyView];
}
- (void)selectKeyViewPrecedingView:(CPView)aView
{
if (_keyViewLoopIsDirty)
if (_keyViewLoopIsDirty && [self autorecalculatesKeyViewLoop])
[self recalculateKeyViewLoop];
[self makeFirstResponder:[aView previousValidKeyView]];
var previousValidKeyView = [aView previousValidKeyView];
if ([previousValidKeyView isKindOfClass:[CPView class]])
[self makeFirstResponder:previousValidKeyView];
}
/*!
@@ -2596,14 +2667,16 @@ CPTexturedBackgroundWindowMask
var allViews = function(aWindow)
{
var views = [[aWindow contentView] subviews],
index = 0;
var views = [CPArray arrayWithObject:[aWindow contentView]];
[views addObjectsFromArray:[[aWindow contentView] subviews]];
var index = 0;
for (; index < views.length; ++index)
views = views.concat([views[index] subviews]);
return views;
}
};
var keyViewComparator = function(lhs, rhs, context)
{
@@ -2634,7 +2707,7 @@ var keyViewComparator = function(lhs, rhs, context)
return CPOrderedSame;
return CPOrderedDescending;
}
};
@implementation CPWindow (MenuBar)
@@ -2858,7 +2931,7 @@ var keyViewComparator = function(lhs, rhs, context)
var interpolate = function(fromValue, toValue, progress)
{
return fromValue + (toValue - fromValue) * progress;
}
};
/* @ignore */
@implementation _CPWindowFrameAnimation : CPAnimation
@@ -2928,5 +3001,6 @@ CPCustomWindowShadowStyle = 3;
@import "_CPHUDWindowView.j"
@import "_CPBorderlessWindowView.j"
@import "_CPBorderlessBridgeWindowView.j"
@import "_CPAttachedWindowView.j"
@import "CPDragServer.j"
@import "CPView.j"
+388
View File
@@ -0,0 +1,388 @@
/*
* _CPAttachedWindowView.j
* AppKit
*
* Created by Antoine Mercadal
* Copyright 2011 <primalmotion@archipelproject.org>
*
* 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"
#define ALIGN_STROKE(point) (FLOOR(point) === (point) ? (point) + halfStrokeWidth : (point))
#define ALIGN_COORD(point) (FLOOR(point))
var _CPAttachedWindowViewDefaultCursorSize = CGSizeMake(16, 10);
/*!
@ignore
A custom CPWindowView that manages a border and cursor
*/
@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);
CGSize _cursorSize;
}
/*!
Compute the contentView frame from a given window frame
@param aFrameRect the window frame
*/
- (CGRect)contentRectForFrameRect:(CGRect)aFrameRect
{
var contentRect = CGRectMakeCopy(aFrameRect);
// @todo change border art and remove this pixel perfect adaptation
// return CGRectInset(contentRect, 20, 20);
contentRect.origin.x += 18;
contentRect.origin.y += 17;
contentRect.size.width -= 35;
contentRect.size.height -= 37;
return contentRect;
}
/*!
Compute the window frame from a given contentView frame
@param aContentRect the contentView frame
*/
+ (CGRect)frameRectForContentRect:(CGRect)aContentRect
{
var frameRect = CGRectMakeCopy(aContentRect);
// @todo change border art and remove this pixel perfect adaptation
//return CGRectOffset(frameRect, 20, 20);
frameRect.origin.x -= 18;
frameRect.origin.y -= 17;
frameRect.size.width += 35;
frameRect.size.height += 37;
return frameRect;
}
/*!
Initialize the _CPWindowView
*/
- (id)initWithFrame:(CGRect)aFrame styleMask:(unsigned)aStyleMask
{
if (self = [super initWithFrame:aFrame styleMask:aStyleMask])
{
_arrowOffsetX = 0.0;
_arrowOffsetY = 0.0;
// @TODO: make this themable
_appearance = CPPopoverAppearanceMinimal;
_cursorSize = CGSizeMakeCopy(_CPAttachedWindowViewDefaultCursorSize);
}
return self;
}
/*!
Hide the cursor
*/
- (void)hideCursor
{
_cursorSize = CGSizeMakeZero();
[self setNeedsDisplay:YES];
}
/*!
Show the cursor
*/
- (void)showCursor
{
_cursorSize = CGSizeMakeCopy(_CPAttachedWindowViewDefaultCursorSize);
[self setNeedsDisplay:YES];
_mouseDownPressed = NO;
}
/*!
Draw the view
*/
- (void)drawRect:(CGRect)aRect
{
[super drawRect:aRect];
var context = [[CPGraphicsContext currentContext] graphicsPort],
radius = 5,
arrowWidth = _cursorSize.width,
arrowHeight = _cursorSize.height,
strokeWidth = 1,
halfStrokeWidth = strokeWidth / 2.0,
strokeColor,
shadowColor = [[CPColor blackColor] colorWithAlphaComponent:.2],
shadowSize = CGSizeMake(0, 6),
shadowBlur = 15,
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);
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);
strokeColor = [CPColor colorWithHexString:@"222222"];
}
// fix rect to take care of stroke and shadow
frame.origin.x += halfStrokeWidth + shadowBlur;
frame.origin.y += halfStrokeWidth + (shadowBlur + shadowSize.height / 2);
frame.size.width -= strokeWidth + (shadowBlur * 2);
frame.size.height -= strokeWidth + (shadowBlur * 2 + shadowSize.height);
CGContextSetStrokeColor(context, strokeColor);
CGContextSetLineWidth(context, strokeWidth);
CGContextBeginPath(context);
CGContextSetShadowWithColor(context, shadowSize, shadowBlur, shadowColor);
CGContextDrawLinearGradient(context, gradient, CGPointMake(CGRectGetMidX(frame), 0.0), CGPointMake(CGRectGetMidX(frame), frame.size.height), 0);
var xMin = _CGRectGetMinX(frame),
xMax = _CGRectGetMaxX(frame),
yMin = _CGRectGetMinY(frame),
yMax = _CGRectGetMaxY(frame),
arrowMinX = ALIGN_COORD(xMin + radius + strokeWidth),
arrowMaxX = ALIGN_COORD(xMax - radius - strokeWidth),
arrowMinY = ALIGN_COORD(yMin + radius + strokeWidth),
arrowMaxY = ALIGN_COORD(yMax - radius + strokeWidth),
arrowAnchor = CGPointMakeZero(),
arrowStart = CGPointMakeZero(),
pt = CGPointMakeZero();
// draw!
switch (_preferredEdge)
{
case CPMinXEdge:
case CPMaxXEdge:
// origin nw
pt.x = ALIGN_COORD(xMin + radius);
pt.y = yMin;
CGContextMoveToPoint(context, pt.x, pt.y);
// ne
pt.x = ALIGN_COORD(xMax - radius);
CGContextAddLineToPoint(context, pt.x, pt.y);
CGContextAddCurveToPoint(context, pt.x, pt.y, xMax, yMin, xMax, ALIGN_COORD(yMin + radius));
if (_preferredEdge === CPMinXEdge)
{
// arrow CPMinXEdge
arrowAnchor.x = ALIGN_STROKE(xMax);
arrowAnchor.y = ALIGN_COORD((frame.size.height / 2) + yMin + _arrowOffsetY);
// to top edge
pt.y = ALIGN_COORD(arrowAnchor.y - (arrowWidth / 2));
// adjust starting point to not go beyond the corner
if (pt.y <= arrowMinY)
pt.y = arrowMinY;
else if ((pt.y + arrowWidth) > arrowMaxY)
pt.y = arrowMaxY - arrowWidth;
pt.x = arrowAnchor.x;
arrowStart = CGPointMakeCopy(pt);
CGContextAddLineToPoint(context, pt.x, pt.y);
// top edge -> point
pt.x = ALIGN_STROKE(arrowAnchor.x + arrowHeight);
pt.y = arrowAnchor.y;
CGContextAddLineToPoint(context, pt.x, pt.y);
// point -> bottom edge
pt.x = arrowAnchor.x;
pt.y = ALIGN_COORD(arrowStart.y + arrowWidth);
CGContextAddLineToPoint(context, pt.x, pt.y);
}
// se
pt.x = xMax;
pt.y = ALIGN_COORD(yMax - radius);
CGContextAddLineToPoint(context, pt.x, pt.y);
CGContextAddCurveToPoint(context, pt.x, pt.y, pt.x, yMax, ALIGN_COORD(xMax - radius), yMax);
// sw
pt.x = ALIGN_COORD(xMin + radius);
pt.y = yMax;
CGContextAddLineToPoint(context, pt.x, pt.y);
CGContextAddCurveToPoint(context, pt.x, pt.y, xMin, pt.y, xMin, ALIGN_COORD(yMax - radius));
if (_preferredEdge === CPMaxXEdge)
{
// arrow CPMaxXEdge
arrowAnchor.x = ALIGN_STROKE(xMin);
arrowAnchor.y = ALIGN_COORD((frame.size.height / 2) + yMin + _arrowOffsetY);
// to bottom edge
pt.y = ALIGN_COORD(arrowAnchor.y + (arrowWidth / 2));
// adjust starting point to not go beyond the corner
if ((pt.y - arrowWidth) < arrowMinY)
pt.y = arrowMinY + arrowWidth;
else if (pt.y > arrowMaxY)
pt.y = arrowMaxY;
pt.x = arrowAnchor.x;
arrowStart = CGPointMakeCopy(pt);
CGContextAddLineToPoint(context, pt.x, pt.y);
// bottom edge -> point
pt.x = ALIGN_STROKE(arrowAnchor.x - arrowHeight);
pt.y = arrowAnchor.y;
CGContextAddLineToPoint(context, pt.x, pt.y);
// point -> top edge
pt.x = arrowAnchor.x;
pt.y = ALIGN_COORD(arrowStart.y - arrowWidth);
CGContextAddLineToPoint(context, pt.x, pt.y);
}
// nw
pt.x = xMin;
pt.y = ALIGN_COORD(yMin + radius);
CGContextAddLineToPoint(context, pt.x, pt.y);
CGContextAddCurveToPoint(context, pt.x, pt.y, pt.x, yMin, ALIGN_COORD(xMin + radius), yMin);
break;
case CPMaxYEdge:
case CPMinYEdge:
// origin sw
pt.x = xMin;
pt.y = ALIGN_COORD(yMax - radius);
CGContextMoveToPoint(context, pt.x, pt.y);
// nw
pt.y = ALIGN_COORD(yMin + radius);
CGContextAddLineToPoint(context, pt.x, pt.y);
CGContextAddCurveToPoint(context, pt.x, pt.y, pt.x, yMin, ALIGN_COORD(xMin + radius), yMin);
if (_preferredEdge === CPMaxYEdge)
{
// arrow CPMaxYEdge
arrowAnchor.x = ALIGN_COORD((frame.size.width / 2) + xMin + _arrowOffsetX);
arrowAnchor.y = ALIGN_STROKE(yMin + _arrowOffsetY);
// to left edge
pt.x = ALIGN_COORD(arrowAnchor.x - (arrowWidth / 2));
// adjust starting point to not go beyond the corner
if (pt.x < arrowMinX)
pt.x = arrowMinX;
else if ((pt.x + arrowWidth) > arrowMaxX)
pt.x = arrowMaxX - arrowWidth;
pt.y = arrowAnchor.y;
arrowStart = CGPointMakeCopy(pt);
CGContextAddLineToPoint(context, pt.x, pt.y);
// left edge -> point
pt.x = arrowAnchor.x;
pt.y = ALIGN_STROKE(arrowAnchor.y - arrowHeight);
CGContextAddLineToPoint(context, pt.x, pt.y);
// point -> right edge
pt.x = ALIGN_COORD(arrowStart.x + arrowWidth);
pt.y = arrowAnchor.y;
CGContextAddLineToPoint(context, pt.x, pt.y);
}
// ne
pt.x = ALIGN_COORD(xMax - radius);
pt.y = yMin;
CGContextAddLineToPoint(context, pt.x, pt.y);
CGContextAddCurveToPoint(context, pt.x, pt.y, xMax, pt.y, xMax, ALIGN_COORD(yMin + radius));
// se
pt.x = xMax;
pt.y = ALIGN_COORD(yMax - radius);
CGContextAddLineToPoint(context, pt.x, pt.y);
CGContextAddCurveToPoint(context, pt.x, pt.y, pt.x, yMax, ALIGN_COORD(xMax - radius), yMax);
if (_preferredEdge === CPMinYEdge)
{
// arrow CPMinYEdge
arrowAnchor.x = ALIGN_COORD((frame.size.width / 2) + xMin + _arrowOffsetX);
arrowAnchor.y = ALIGN_STROKE(yMax + _arrowOffsetY);
// to right edge
pt.x = ALIGN_COORD(arrowAnchor.x + (arrowWidth / 2));
// adjust starting point to not go beyond the corner
if ((pt.x - arrowWidth) < arrowMinX)
pt.x = arrowMinX + arrowWidth;
else if (pt.x > arrowMaxX)
pt.x = arrowMaxX;
pt.y = arrowAnchor.y;
arrowStart = CGPointMakeCopy(pt);
CGContextAddLineToPoint(context, pt.x, pt.y);
// right edge -> point
pt.x = arrowAnchor.x;
pt.y = ALIGN_STROKE(arrowAnchor.y + arrowHeight);
CGContextAddLineToPoint(context, pt.x, pt.y);
// point -> left edge
pt.x = ALIGN_COORD(arrowStart.x - arrowWidth);
pt.y = arrowAnchor.y;
CGContextAddLineToPoint(context, pt.x, pt.y);
}
// sw
pt.x = ALIGN_COORD(xMin + radius);
pt.y = yMax;
CGContextAddLineToPoint(context, pt.x, pt.y);
CGContextAddCurveToPoint(context, pt.x, pt.y, xMin, pt.y, xMin, ALIGN_COORD(yMax - radius));
break;
default:
// no computed edge means standard rounded rect
CGContextAddPath(context, CGPathWithRoundedRectangleInRect(frame, radius, radius, YES, YES, YES, YES));
}
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
@@ -33,7 +33,14 @@ var _CPToolbarViewBackgroundColor = nil;
+ (CPColor)toolbarBackgroundColor
{
if (!_CPToolbarViewBackgroundColor)
_CPToolbarViewBackgroundColor = [CPColor colorWithPatternImage:[[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:[_CPBorderlessBridgeWindowView class]] pathForResource:@"_CPToolbarView/_CPToolbarViewBackground.png"] size:CGSizeMake(1.0, 59.0)]];
{
var bundle = [CPBundle bundleForClass:[_CPBorderlessBridgeWindowView class]];
_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],
], CPColorPatternIsVertical);
}
return _CPToolbarViewBackgroundColor;
}
+1 -1
View File
@@ -90,7 +90,7 @@ var HUD_TITLEBAR_HEIGHT = 26.0;
if ([[[self window] toolbar] isVisible])
{
toolbarHeight = CGRectGetHeight([[self toolbarView] frame]);
var toolbarHeight = CGRectGetHeight([[self toolbarView] frame]);
contentRect.origin.y += toolbarHeight;
contentRect.size.height -= toolbarHeight;
+1 -1
View File
@@ -181,7 +181,7 @@ var STANDARD_GRADIENT_HEIGHT = 41.0,
if ([theToolbar isVisible])
{
toolbarHeight = CGRectGetHeight([[theToolbar _toolbarView] frame]);
var toolbarHeight = CGRectGetHeight([[theToolbar _toolbarView] frame]);
contentRect.origin.y += toolbarHeight;
contentRect.size.height -= toolbarHeight;
+25 -22
View File
@@ -27,15 +27,31 @@
{
BOOL _mouseDownPressed @accessors(getter=isMouseDownPressed, setter=setMouseDownPressed:);
unsigned _gravity @accessors(property=gravity);
CPColor _backgroundColor;
CPColor _strokeColor;
}
#pragma mark -
#pragma mark Class methods
+ (CPString)defaultThemeClass
{
return @"tooltip";
}
+ (id)themeAttributes
{
return [CPDictionary dictionaryWithObjects:[[CPColor colorWithHexString:@"E3E3E3"],
[CPColor colorWithHexString:@"FFFFCA"],
2.0,
1.0,
[CPColor blackColor]]
forKeys:[@"stroke-color",
@"background-color",
@"border-radius",
@"stroke-width",
@"color"]];
}
/*! compute the contentView frame from a given window frame
@param aFrameRect the window frame
*/
@@ -67,21 +83,6 @@
}
#pragma mark -
#pragma mark Initialization
- (id)initWithFrame:(CPRect)aFrame styleMask:(unsigned)aStyleMask
{
if (self = [super initWithFrame:aFrame styleMask:aStyleMask])
{
_strokeColor = [CPColor colorWithHexString:@"E3E3E3"];
_backgroundColor = [CPColor colorWithHexString:@"FFFFCA"];
}
return self;
}
#pragma mark -
#pragma mark drawing
@@ -90,11 +91,13 @@
[super drawRect:aRect];
var context = [[CPGraphicsContext currentContext] graphicsPort],
radius = 2,
strokeWidth = 1;
radius = [self currentValueForThemeAttribute:@"border-radius"],
strokeWidth = [self currentValueForThemeAttribute:@"stroke-width"],
strokeColor = [self currentValueForThemeAttribute:@"stroke-color"],
bgColor = [self currentValueForThemeAttribute:@"background-color"];
CGContextSetStrokeColor(context, _strokeColor);
CGContextSetFillColor(context, _backgroundColor);
CGContextSetStrokeColor(context, strokeColor);
CGContextSetFillColor(context, bgColor);
CGContextSetLineWidth(context, strokeWidth);
CGContextBeginPath(context);
+4 -1
View File
@@ -111,7 +111,7 @@ var _CPWindowViewResizeIndicatorImage = nil;
return [self trackResizeWithEvent:anEvent];
}
if ([theWindow isMovableByWindowBackground])
if ([theWindow isMovable] && [theWindow isMovableByWindowBackground])
[self trackMoveWithEvent:anEvent];
else
@@ -174,6 +174,9 @@ var _CPWindowViewResizeIndicatorImage = nil;
- (void)trackMoveWithEvent:(CPEvent)anEvent
{
if (![[self window] isMovable])
return;
var type = [anEvent type];
if (type === CPLeftMouseUp)
+56
View File
@@ -0,0 +1,56 @@
/*
* CPWorkspace.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 <Foundation/CPString.j>
var SharedWorkspace = nil;
@implementation CPWorkspace : CPObject
{
}
+ (CPWorkspace)sharedWorkspace
{
if (!SharedWorkspace)
SharedWorkspace = [CPWorkspace new];
return SharedWorkspace;
}
- (BOOL)openFile:(CPString)fullPath
{
var url = [CPURL URLWithString:fullPath];
return [self openURL:url];
}
- (BOOL)openURL:(CPURL)url
{
if (!url || ![url absoluteURL])
return NO;
window.open([url absoluteURL]);
return YES;
}
@end
+3 -3
View File
@@ -34,9 +34,9 @@
@import "_CPCibWindowTemplate.j"
CPCibOwner = @"CPCibOwner",
CPCibTopLevelObjects = @"CPCibTopLevelObjects",
CPCibReplacementClasses = @"CPCibReplacementClasses",
CPCibOwner = @"CPCibOwner";
CPCibTopLevelObjects = @"CPCibTopLevelObjects";
CPCibReplacementClasses = @"CPCibReplacementClasses";
CPCibExternalObjects = @"CPCibExternalObjects";
var CPCibObjectDataKey = @"CPCibObjectDataKey";
+2 -3
View File
@@ -125,14 +125,13 @@ var _CPCibWindowTemplateMinSizeKey = @"_CPCibWindowTemp
- (id)_cibInstantiate
{
var windowClass = CPClassFromString([self windowClass]);
var windowClass = CPClassFromString([self windowClass]),
theWindow = [[windowClass alloc] initWithContentRect:_windowRect styleMask:_windowStyleMask];
/* if (!windowClass)
[NSException raise:NSInvalidArgumentException format:@"Unable to locate NSWindow class %@, using NSWindow",_windowClass];
class=[NSWindow class];*/
var theWindow = [[windowClass alloc] initWithContentRect:_windowRect styleMask:_windowStyleMask];
if (_minSize)
[theWindow setMinSize:_minSize];
if (_maxSize)
+7 -6
View File
@@ -29,7 +29,7 @@
function CABackingStoreGetContext(aBackingStore)
{
return aBackingStore.context;
}
};
if (CPFeatureIsCompatible(CPHTMLCanvasFeature))
{
@@ -42,7 +42,7 @@ CABackingStoreCreate = function()
// FIXME: Consolidate drawImage to support this.
return { context:DOMElement.getContext("2d"), buffer:DOMElement, _image:DOMElement };
}
};
CABackingStoreSetSize = function(aBackingStore, aSize)
{
@@ -52,7 +52,8 @@ CABackingStoreSetSize = function(aBackingStore, aSize)
buffer.height = aSize.height;
buffer.style.width = PIXEL(aSize.width);
buffer.style.height = PIXEL(aSize.height);
}
};
}
else
{
@@ -64,10 +65,10 @@ CABackingStoreCreate = function()
context.buffer = "";
return { context:context };
}
};
CABackingStoreSetSize = function(aBackingStore, aSize)
{
}
};
}
}
+4 -3
View File
@@ -108,7 +108,7 @@ function CGColorCreateCopy(aColor)
*/
function CGColorCreateGenericGray(gray, alpha)
{
return CGColorCreate(CGColorSpaceCreateDeviceRGB(), [gray,gray,gray, alpha]);
return CGColorCreate(CGColorSpaceCreateDeviceRGB(), [gray, gray, gray, alpha]);
}
/*!
@@ -137,7 +137,7 @@ function CGColorCreateGenericRGB(red, green, blue, alpha)
*/
function CGColorCreateGenericCMYK(cyan, magenta, yellow, black, alpha)
{
return CGColorCreate(CGColorSpaceCreateDeviceCMYK(),
return CGColorCreate(CGColorSpaceCreateDeviceCMYK(),
[cyan, magenta, yellow, black, alpha]);
}
@@ -150,7 +150,8 @@ function CGColorCreateGenericCMYK(cyan, magenta, yellow, black, alpha)
*/
function CGColorCreateCopyWithAlpha(aColor, anAlpha)
{
if ( !aColor ) return aColor; // Avoid error null pointer in next line
if (!aColor)
return aColor; // Avoid error null pointer in next line
var components = aColor.components.slice();
+2 -2
View File
@@ -358,7 +358,7 @@ if (CPFeatureIsCompatible(CPJavaScriptCanvasTransformFeature))
CGContextConcatCTM = function(aContext, anAffineTransform)
{
aContext.transform(anAffineTransform.a, anAffineTransform.b, anAffineTransform.c, anAffineTransform.d, anAffineTransform.tx, anAffineTransform.ty);
}
};
}
else
@@ -428,7 +428,7 @@ CGContextConcatCTM = function(aContext, anAffineTransform)
CGContextScaleCTM(aContext, sx, sy);
if (a2 != 0.0)
CGContextRotateCTM(aContext, a2);
}
};
}
+4 -4
View File
@@ -29,16 +29,16 @@ kCGGradientDrawsAfterEndLocation = 1 << 1;
function CGGradientCreateWithColorComponents(aColorSpace, components, locations, count)
{
if ( locations === undefined || locations === NULL )
if (locations === undefined || locations === NULL)
{
var num_of_colors = components.length / 4,
locations = [];
for ( var idx = 0; idx < num_of_colors; idx++ )
for (var idx = 0; idx < num_of_colors; idx++)
locations.push( idx / (num_of_colors - 1) );
}
if ( count === undefined || count === NULL)
var count = locations.length;
if (count === undefined || count === NULL)
count = locations.length;
var colors = [];
+9
View File
@@ -42,7 +42,16 @@
#include "DOM/CPPlatformString.j"
#else
@implementation CPPlatformString : CPBasePlatformString
+ (CGSize)sizeOfString:(CPString)aString withFont:(CPFont)aFont forWidth:(float)aWidth
{
return _CGSizeMakeZero();
}
+ (CPDictionary)metricsOfFont:(CPFont)aFont
{
return [CPDictionary dictionaryWithObjectsAndKeys:0, @"ascender", 0, @"descender", 0, @"lineHeight"];
}
@end
#endif
+17
View File
@@ -32,6 +32,7 @@ var PrimaryPlatformWindow = NULL;
CPInteger _level;
BOOL _hasShadow;
unsigned _shadowStyle;
CPString _title;
#if PLATFORM(DOM)
DOMWindow _DOMWindow;
@@ -258,6 +259,22 @@ var PrimaryPlatformWindow = NULL;
return [CPPlatform isBrowser];
}
- (void)_setTitle:(CPString)aTitle window:(CPWindow)aWindow
{
_title = aTitle;
#if PLATFORM(DOM)
if (_DOMWindow && _DOMWindow.document
&& (aWindow === [CPApp mainWindow] || [aWindow platformWindow] !== [CPPlatformWindow primaryPlatformWindow]))
_DOMWindow.document.title = _title;
#endif
}
- (CPString)title
{
return _title;
}
@end
#if PLATFORM(BROWSER)
+1 -1
View File
@@ -49,7 +49,7 @@ var screenNeedsInitialization = NO,
window.onunload = function()
{
[CPApp terminate:nil];
}
};
}
+ (BOOL)isBrowser
+9 -6
View File
@@ -534,13 +534,15 @@ var ModifierKeyCodes = [
if (_DOMWindow)
return _DOMWindow.focus();
_DOMWindow = window.open("", "_blank", "menubar=no,location=no,resizable=yes,scrollbars=no,status=no,left=" + _CGRectGetMinX(_contentRect) + ",top=" + _CGRectGetMinY(_contentRect) + ",width=" + _CGRectGetWidth(_contentRect) + ",height=" + _CGRectGetHeight(_contentRect));
_DOMWindow = window.open("about:blank", "_blank", "menubar=no,location=no,resizable=yes,scrollbars=no,status=no,left=" + _CGRectGetMinX(_contentRect) + ",top=" + _CGRectGetMinY(_contentRect) + ",width=" + _CGRectGetWidth(_contentRect) + ",height=" + _CGRectGetHeight(_contentRect));
[PlatformWindows addObject:self];
// FIXME: cpSetFrame?
_DOMWindow.document.write("<!DOCTYPE html><html lang='en'><head></head><body style='background-color:transparent;'></body></html>");
_DOMWindow.document.close();
if (self != [CPPlatformWindow primaryPlatformWindow])
_DOMWindow.document.title = _title;
if (![CPPlatform isBrowser])
{
@@ -706,7 +708,8 @@ var ModifierKeyCodes = [
var characters;
// Handle key codes for which String.fromCharCode won't work.
if (aDOMEvent.which === 0 || aDOMEvent.charCode === 0)
// Refs #1036: In Internet Explorer, both 'which' and 'charCode' are undefined for special keys.
if (aDOMEvent.which === 0 || aDOMEvent.charCode === 0 || (aDOMEvent.which === undefined && aDOMEvent.charCode === undefined))
characters = KeyCodesToUnicodeMap[_keyCode];
if (!characters)
@@ -1565,7 +1568,7 @@ var _CPEventFromNativeMouseEvent = function(aNativeEvent, anEventType, aPoint, m
aNativeEvent._eventNumber = anEventNumber;
aNativeEvent._clickCount = aClickCount;
aNativeEvent._pressure = aPressure;
if((anEventType == CPLeftMouseDragged) || (anEventType == CPRightMouseDragged) || (anEventType == CPMouseMoved))
if ((anEventType == CPLeftMouseDragged) || (anEventType == CPRightMouseDragged) || (anEventType == CPMouseMoved))
{
aNativeEvent._deltaX = aPoint.x - aMouseDragStart.x;
aNativeEvent._deltaY = aPoint.y - aMouseDragStart.y;
@@ -1578,7 +1581,7 @@ var _CPEventFromNativeMouseEvent = function(aNativeEvent, anEventType, aPoint, m
return aNativeEvent;
}
};
var CLICK_SPACE_DELTA = 5.0,
CLICK_TIME_DELTA = (typeof document != "undefined" && document.addEventListener) ? 350.0 : 1000.0;
@@ -1593,7 +1596,7 @@ var CPDOMEventGetClickCount = function(aComparisonEvent, aTimestamp, aLocation)
return (aTimestamp - [aComparisonEvent timestamp] < CLICK_TIME_DELTA &&
ABS(comparisonLocation.x - aLocation.x) < CLICK_SPACE_DELTA &&
ABS(comparisonLocation.y - aLocation.y) < CLICK_SPACE_DELTA) ? [aComparisonEvent clickCount] + 1 : 1;
}
};
var CPDOMEventStop = function(aDOMEvent, aPlatformWindow)
{
@@ -1613,7 +1616,7 @@ var CPDOMEventStop = function(aDOMEvent, aPlatformWindow)
aPlatformWindow._DOMFocusElement.focus();
aPlatformWindow._DOMFocusElement.blur();
}
}
};
function CPWindowObjectList()
{
@@ -229,4 +229,4 @@ CPKeyCodes.isCharacterKey = function(keyCode)
default:
return false;
}
}
};
Binary file not shown.

Before

Width:  |  Height:  |  Size: 185 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 193 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 161 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 146 B

After

Width:  |  Height:  |  Size: 123 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 162 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 155 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 154 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 436 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 452 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 444 B

After

Width:  |  Height:  |  Size: 205 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 158 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 157 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 460 B

After

Width:  |  Height:  |  Size: 208 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 147 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 147 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 185 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 179 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 145 B

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