Compare commits

...
3937 Commits
Author SHA1 Message Date
Alexandre Wilhelm fb56955fff Fixed: deprecate FlashView, this old technology is now almost banned for all browser 2018-08-10 18:34:38 -07:00
Alexandre WilhelmandGitHub cbb7cc93e9 Merge pull request #2739 from Rosch/origin/bugfix-cpdateformatter-german
FIXED: CPDateFormatter not ready for german dates. Fixes #2736
2018-08-10 18:15:16 -07:00
Alexandre WilhelmandGitHub 8b608c5cce Merge pull request #2745 from daboe01/removed--dead-code-from-nativehost
Removed:  dead code from nativehost
2018-08-10 17:58:03 -07:00
Alexandre WilhelmandGitHub 163fb14d0e Merge pull request #2746 from didierkorthoudt/CPTableView-viewWillMoveToWindow-fix
FIXED: In CPTableView, viewWillMoveToWindow was incorrectly removing an observer on the wrong window
2018-08-10 17:57:43 -07:00
Didier Korthoudt e4f87bd805 CPTableView-viewWillMoveToWindow-fix 2018-08-08 22:06:42 +02:00
Didier Korthoudt 864c7d96f1 Revert "NEW: Added automatic Xcode syntax coloring"
This reverts commit 0a497d8c3f.
2018-08-08 22:05:57 +02:00
daboe01 e35e87fb05 fixed: obsolete code remnants from nativehost 2018-08-08 19:19:58 +02:00
Didier Korthoudt 3246bdbc8b Merge remote-tracking branch 'cappuccino/master' 2018-08-08 11:03:03 +02:00
daboe01 710bb5fe1c Merge remote-tracking branch 'cappuccino/master' 2018-08-08 09:32:07 +02:00
bedaltonandcacaodev 53a52da709 Fixed: _CPObjectAnimator initialize method did not match superclass return (#2743)
* Fixed: _CPObjectAnimator initialize method did not match superclass return

_CPObject animator labeled return type as BOOL, not only is this value not returned, but the super class CPProxy's initialize method returns void. Changed return type to void in _CPObject animator, to match superclass
2018-08-03 08:28:05 +02:00
Martin Carlberg 4afbfc6e57 Revert "Removed: dead code and dom clutter from nativehost (#2608)"
This reverts commit 5bfafaf241.
2018-07-11 09:20:49 +02:00
daboe01 f7aa9efe13 Merge remote-tracking branch 'cappuccino/master' 2018-07-09 22:24:30 +02:00
Rosch 1fce0ee551 fix CPDateformatter for german dates 2018-07-08 09:15:58 +02:00
daboe01andMartin Carlberg ee695f9000 Fixed: CPSearchPanel did not support PredicateBindings (#2699) 2018-07-05 15:44:36 +02:00
daboe01andMartin Carlberg 8f99ebb577 Fixed: optical clutter, link duplications in readme (#2729) 2018-07-05 13:01:41 +02:00
daboe01andMartin Carlberg 5bfafaf241 Removed: dead code and dom clutter from nativehost (#2608) 2018-07-05 11:40:10 +02:00
Kjell NilssonandMartin Carlberg 64e1a2ce4b Fixed: Protocol selector signature spell error (#2734) 2018-07-05 11:25:38 +02:00
Didier Korthoudtandcacaodev 27883c5beb FIXED: This fixes problems with default theme attributes values in CPTableView (#2732) 2018-06-21 16:47:21 +02:00
Didier Korthoudt 2772725fe3 Merge remote-tracking branch 'cappuccino/master' 2018-06-17 08:55:10 +02:00
Didier Korthoudtandcacaodev 3f58a64827 FIXED: Before this PR, images specified in IB could crash the app at Cib loading (#2731) 2018-06-16 19:14:58 +02:00
Didier Korthoudt cb37c7d218 Merge remote-tracking branch 'cappuccino/master' 2018-06-16 12:25:12 +02:00
daboe01 45d951071f Merge remote-tracking branch 'cappuccino/master' 2018-06-12 13:13:57 +02:00
daboe01andMartin Carlberg 2ac60684fa Fixed: CPDateFormatter was agnostic for the German language (#2724) 2018-06-08 14:00:25 +02:00
daboe01andMartin Carlberg af71742110 Fixed: Update README.markdown 2018-06-08 13:57:13 +02:00
daboe01andMartin Carlberg 1adf27427a Fixed: The word Site changed to Application in index.html (#2723) 2018-06-04 13:51:15 +02:00
daboe01 082f78eefa Merge remote-tracking branch 'cappuccino/master' 2018-06-03 19:44:23 +02:00
cacaodevandGitHub a8a9ec0023 Fix typo in CPPredicateEditorTest
Fixes #2714
2018-06-02 08:18:01 +02:00
Didier Korthoudt df4f945bc6 Merge remote-tracking branch 'cappuccino/master' 2018-05-29 12:04:40 +02:00
daboe01andcacaodev ad756a5b86 fixed: some mouse events were not propagated when sheets are open (#2603)
* fixed: mouse dragged was not propagated to parent window when sheet was opened

* better detection for attached sheet
2018-05-29 07:17:41 +02:00
Didier Korthoudtandcacaodev 2ca99ba669 FIXED: Before this PR, CPScroller theme attribute knob-inset was partially used (#2720) 2018-05-29 07:15:47 +02:00
daboe01andcacaodev 6443575114 fixed: nib2cib was susceptible to IB button issue with alternateImage (#2721) 2018-05-28 21:10:40 +02:00
Didier Korthoudtandcacaodev 52a51d81f1 FIXED: Before this PR, legacy scroller won't ever loose its selected theme state (#2718) 2018-05-28 20:56:00 +02:00
Didier Korthoudtandcacaodev 7d20b06e52 FIXED: Before this PR, CPSearchField was handling cursor updates by direct DOM manipulation. This PR uses tracking areas. (#2684) 2018-05-28 20:46:28 +02:00
Didier Korthoudtandcacaodev ad9d8a7200 FIXED: When attaching an externally owned tracking area to a view, view tracking areas were not correctly handled (#2681)
This PR also removes the -removeAllTrackingAreas method.
2018-05-28 20:44:31 +02:00
Didier Korthoudt 44da699343 Merge remote-tracking branch 'cappuccino/master' 2018-05-23 23:49:51 +02:00
cacaodev 0a542f9be9 Revert "FIXED: _CPTableColumnHeaderView was using hard coded values instead of theme values (#2703)"
This reverts commit e27bb4de50.
2018-05-17 05:48:59 +02:00
Didier Korthoudt 8f1601ca55 Merge remote-tracking branch 'cappuccino/master' 2018-05-15 22:03:16 +02:00
Didier Korthoudtandcacaodev ff0ce164da FIXED: CPTabView tabs were not reacting as in modern Cocoa (#2694)
Before this commit, the segments of a tab view were selected at mouse down. Now, they are selected at mouse up and there is a visible feedback when tracking tabs.
2018-05-14 07:10:43 +02:00
Didier Korthoudtandcacaodev 3650c38aa9 FIXED: In CPSearchField, the space between the magnifier and the textfield was hard coded (#2690) 2018-05-13 19:49:18 +02:00
Didier Korthoudtandcacaodev 61d97338e2 FIXED: _CPMenuItemStandardView was bypassing theme for disabled text color (#2695) 2018-05-13 19:48:33 +02:00
Didier Korthoudtandcacaodev e27bb4de50 FIXED: _CPTableColumnHeaderView was using hard coded values instead of theme values (#2703) 2018-05-13 19:47:53 +02:00
Didier Korthoudtandcacaodev 4462d8bf22 CHANGED: CPSegmentedControl code refactoring (#2704) 2018-05-13 19:40:33 +02:00
Didier Korthoudt f23a8ac928 Merge remote-tracking branch 'cappuccino/master' 2018-05-12 01:05:02 +02:00
daboe01 9e1750ee13 Merge remote-tracking branch 'cappuccino/master' 2018-05-08 22:46:19 +02:00
Didier Korthoudtandcacaodev 5cd284cb36 FIXED: CPSearchField menu diverged from modern Cocoa (#2697) 2018-05-07 21:52:06 +02:00
daboe01andcacaodev 5ea58430fe fixed: typo in theme attribute name (#2683) 2018-05-07 20:05:49 +02:00
Didier Korthoudtandcacaodev acfbda0d91 FIXED: CPSearchMenu _updateSearchMenu wasn't disabling autoenabling of menu items (#2693) 2018-05-07 19:57:35 +02:00
Didier Korthoudtandcacaodev 437e5a62f1 FIXED: CPSearchField -(void)resetSearchButton was using valueForThemeAttribute instead of currentValueForThemeAttribute (#2692) 2018-05-07 19:57:01 +02:00
Didier Korthoudtandcacaodev bbb5aea77d FIXED: CPTableView was using hard coded values instead of theme attributes (#2698) 2018-05-07 19:54:46 +02:00
Didier Korthoudt b5d04f84e7 Merge remote-tracking branch 'cappuccino/master' 2018-05-06 20:44:07 +02:00
cacaodevandGitHub 93b12eb14f Revert "FIXED: click to key window in the background did not bring it forward" (#2702)
Fixes #2700
2018-05-06 14:07:25 +02:00
Didier Korthoudt 0aa67c4cf2 Merge remote-tracking branch 'cappuccino/master' 2018-05-05 23:26:35 +02:00
Didier Korthoudtandcacaodev 1c1affac5c FIXED: CPTableHeaderView was faulty using inset.right instead of inset.left 2018-05-05 10:47:24 +02:00
Didier Korthoudt 0919797edc Merge remote-tracking branch 'cappuccino/master' 2018-05-04 23:22:49 +02:00
Didier Korthoudtandcacaodev 94ac8fd837 FIXED: Before this PR, CPButton setImage was also changing the alternate image 2018-05-04 16:16:01 +02:00
cacaodevandGitHub ecc82b5b51 Fixed: Typo CGSizZero() -> CGSizeMakeZero()
In BadgedOutlineView.j from SmartFoldersDemo test application.
2018-05-02 19:38:37 +02:00
daboe01 add021fd67 Merge remote-tracking branch 'cappuccino/master' 2018-04-28 16:35:05 +02:00
Didier Korthoudt 2daf309d7d Merge remote-tracking branch 'cappuccino/master' 2018-04-27 14:15:30 +02:00
Didier KorthoudtandMartin Carlberg 20be4a40ea NEW: Add CSS theming support (#2613) 2018-04-27 09:27:01 +02:00
bedaltonandcacaodev 7de91da87a Fix: rename _placeHolderView and add accessors in CPTabView.j (#2678)
In CPTabView.j on line 706 method is called `[_source
_setPlaceholderView:aValue]; ` this method does not exist, and this
call could possibly be expecting the property `_placeHolderView` to
have an accessor method. To add the correct accessor method the case of
either the method call selector or the variable must change —
`_placeHolderView` vs `_placeholderView`. For this fix I selected the
`_placeholderView` spelling, as opposed to the alternative with the
capitalized “holder” in “placeholder.”

Fixes #2674
2018-04-13 12:09:46 +02:00
cacaodevandMartin Carlberg b8b48b533b Previously, animating frame origin was not working on recent versions of Gecko (Firefox). The format for the matrix value of the transform property was matrix(a,b,c,d,tx,ty) and tx and ty had the "px" suffix. According to this page, tx and ty were accept (#2677)
ed (in my understanding not required) to have this suffix before FireFox
16.

All parameters are now numbers without suffix and this code will work
for all FireFox versions supporting css animations.
2018-04-12 11:25:43 +02:00
daboe01andMartin Carlberg 535f981739 Fixed: TextView bindings wrote data on blur even when not editable (#2582) 2018-04-12 09:25:12 +02:00
cacaodevandGitHub 0404ac0395 Merge pull request #2602 from daboe01/issue2545
FIXED: click to key window in the background did not bring it forward
2018-04-12 09:11:57 +02:00
daboe01 f961625f03 fixed: some events were not propagated to the bridge window 2018-04-11 18:30:47 +02:00
daboe01andMartin Carlberg 7909bae065 Fixed: touch-scrolling did not work (#2612) 2018-04-09 13:19:18 +02:00
bedaltonandMartin Carlberg 7e6e117b17 Formatting: add semi-colon to CPTextContainer.j (#2675) 2018-04-09 12:40:41 +02:00
bedaltonandMartin Carlberg 314e64d7b1 Formatting: add semi-colon to CPTextView.j (#2676) 2018-04-09 12:40:11 +02:00
Alexandre WilhelmandGitHub 77eb6b358f Merge pull request #2626 from daboe01/fix-cptextview-backspace-issue
fixed: backspace did not trigger scrolling properly 927d6d2
2018-04-08 11:37:19 -07:00
Alexandre WilhelmandGitHub 25f86e2542 Merge pull request #2616 from bedalton/add-idea-to-gitignore
New: Add *.idea to .gitignore
2018-04-08 11:36:25 -07:00
Alexandre WilhelmandGitHub 8bc0461463 Merge pull request #2627 from bedalton/formatting-add-semi-colon-cpcolorpicker
Formatting: add missing semi-colon to CPColorPicker.j
2018-04-08 11:35:34 -07:00
Alexandre WilhelmandGitHub c9dd1ea71d Merge pull request #2628 from bedalton/formatting-add-semi-colon-cpdatepicker
Formatting: add missing semi-colons to CPDatePicker.j
2018-04-08 11:35:26 -07:00
Alexandre WilhelmandGitHub 85d3529bc3 Merge pull request #2629 from bedalton/formatting-add-semi-colon-cpdatepickertextfield
Formatting: add semi-colon CPDatePickerTextField.j
2018-04-08 11:35:10 -07:00
Alexandre WilhelmandGitHub 3aac8bb072 Merge pull request #2630 from bedalton/formatting-add-semi-colon-cpevent
Formatting: add missing semi-colons to CPEvent.j
2018-04-08 11:34:59 -07:00
Alexandre WilhelmandGitHub e9a7e21aca Merge pull request #2638 from bedalton/formatting-add-semi-colon-cptableview
Formatting: add semi colon to CPTableView.j
2018-04-08 11:34:47 -07:00
Alexandre WilhelmandGitHub fc0e4da33c Merge pull request #2641 from bedalton/formatting-add-semi-colon-cpwindow
Formatting: add missing semi-colons to CPWindow.j
2018-04-08 11:33:54 -07:00
Alexandre WilhelmandGitHub ef3c1315dd Merge pull request #2642 from bedalton/formatting-add-semi-colon-cpwindowcontroller
Formatting: add semi-colon to CPWindowController.j
2018-04-08 11:33:45 -07:00
Alexandre WilhelmandGitHub 5c12890faf Merge pull request #2643 from bedalton/formatting-add-semi-colon-to-cpfontpanel
Formatting: add semi-colon to CPFrontPanel.j
2018-04-08 11:33:33 -07:00
Alexandre WilhelmandGitHub c4fd5e0999 Merge pull request #2645 from bedalton/formatting-add-semi-colons-cpdatepickercalendar
Formatting: add missing semi-colons to _CPDatePickerCalendar.j
2018-04-08 11:33:24 -07:00
Alexandre WilhelmandGitHub d3c56d635d Merge pull request #2669 from bedalton/formatting-add-semi-colons-cpplatformwindow
Formatting: minor formatting updates in CPPlatformWindow+DOM.j
2018-04-08 11:32:58 -07:00
Alexandre WilhelmandGitHub c53cb49034 Merge pull request #2640 from bedalton/formatting-add-semi-colon-cpview
Formatting: add semi-colon to CPView.j
2018-04-08 11:32:44 -07:00
Alexandre WilhelmandGitHub d38463c5d9 Merge pull request #2631 from bedalton/formatting-add-semi-colon-cpfont
Formatting: add semi-colon to CPFont.j
2018-04-08 11:32:33 -07:00
Alexandre WilhelmandGitHub bc4b424f0e Merge pull request #2632 from bedalton/formatting-add-semi-colon-cpimage
Formatting: add semi-colon to CPImage.j
2018-04-08 11:32:23 -07:00
Alexandre WilhelmandGitHub 6bd4f3b7b4 Merge pull request #2633 from bedalton/formatting-add-semi-colon-cpkeyvaluebinding
Formatting: add missing semi-colon to CPKeyValueBinding
2018-04-08 11:32:13 -07:00
Alexandre WilhelmandGitHub d91d83f115 Merge pull request #2634 from bedalton/formatting-add-semi-colon-cplayoutmanager
Formatting: add missing semi-colon to CPLayoutManager.j
2018-04-08 11:32:02 -07:00
Alexandre WilhelmandGitHub 584b6ab219 Merge pull request #2639 from bedalton/formatting-add-semi-colon-cptokenfield
Formatting: add semi colon to  CPTokenField.j
2018-04-08 11:31:47 -07:00
Alexandre WilhelmandGitHub 04b155dbfb Merge pull request #2635 from bedalton/formatting-add-semi-colon-cpoutlineview
Formatting: add semi-colons to CPOutlineView.j
2018-04-08 11:31:35 -07:00
Alexandre WilhelmandGitHub ddc5488db7 Merge pull request #2636 from bedalton/formatting-add-semi-colon-cpprogressindicator
Formatting: add semi-colons to CPProgressIndicator.j
2018-04-08 11:31:23 -07:00
Alexandre WilhelmandGitHub 5c6906d5fd Merge pull request #2637 from bedalton/formatting-add-semi-colon-cpscrollview
Formatting: add missing semi-colon to CPScrollView.j
2018-04-08 11:31:08 -07:00
Alexandre WilhelmandGitHub 56fee5d286 Merge pull request #2657 from bedalton/formatting-remove-redundant-variable-declaration
Formatting: remove redundant variable in _CPRuleEditorViewSlice.j
2018-04-08 11:29:35 -07:00
Alexandre WilhelmandGitHub c4dcab04b6 Merge pull request #2656 from bedalton/formatting-remove-semi-colon-cplevelindicator
Formatting: Remove semi-colon after method header in CPLevelIndicator
2018-04-08 11:29:17 -07:00
Alexandre WilhelmandGitHub 8dd9a96769 Merge pull request #2655 from bedalton/formatting-update-semi-colons-in-cpimageandtextview
Formatting: fix possible misuse of commas in _CPImageAndTextView.j
2018-04-08 11:28:59 -07:00
Alexandre WilhelmandGitHub 6864015af6 Merge pull request #2654 from bedalton/formatting-declare-variable-in-CPColor
Formatting: formally declared variable before use in CPColor.j
2018-04-08 11:28:46 -07:00
Alexandre WilhelmandGitHub ebaa60e929 Merge pull request #2653 from bedalton/formatting-cptextview
Formatting: add semi-colons and comma to CPTextView.j
2018-04-08 11:28:24 -07:00
Alexandre WilhelmandGitHub ac9962c624 Merge pull request #2644 from bedalton/formatting-add-semi-colon-to-cpmenuitem
Formatting: add missing semi-colons to CPMenuItem.j
2018-04-08 11:27:57 -07:00
Alexandre WilhelmandGitHub ccd1773643 Merge pull request #2646 from bedalton/formatting-add-semi-colons-cphudwindowview
Formatting: add missing semi-colon to _CPHudWindowView.j
2018-04-08 11:27:46 -07:00
Alexandre WilhelmandGitHub ac970ff768 Merge pull request #2647 from bedalton/formatting-add-semi-colons-cpplatformpasteboard
Formatting: add semi-colons to CPPlatformPasteboard.j
2018-04-08 11:27:38 -07:00
Alexandre WilhelmandGitHub 53ff45425d Merge pull request #2648 from bedalton/formatting-add-semi-colons-cptablecolumn
Formatting: add semi-colon to CPTableColumn.j
2018-04-08 11:27:25 -07:00
Alexandre WilhelmandGitHub de435c741f Merge pull request #2649 from bedalton/formatting-add-semi-colons-cptextfield
Formatting: add semi-colons to CPTextField.j
2018-04-08 11:27:12 -07:00
Alexandre WilhelmandGitHub 1dc9a44aec Merge pull request #2650 from bedalton/formatting-add-semi-colons-cptoolbar
Formatting: add semi-colon to CPToolBar.j
2018-04-08 11:26:37 -07:00
Alexandre WilhelmandGitHub 0206379315 Merge pull request #2651 from bedalton/formatting-add-semi-colons-cptypesetter
Formatting: add missing semi-colons to CPTypesetter.j
2018-04-08 11:26:29 -07:00
Alexandre WilhelmandGitHub c39adbbbc5 Merge pull request #2652 from bedalton/formatting-add-semi-colons-to-cprtfparser
Formatting: add semi-colons to _CPRTFParser.j
2018-04-08 11:26:16 -07:00
Alexandre WilhelmandGitHub 061a15d4f7 Merge pull request #2658 from bedalton/formatting-remove-redundant-variable-cpsearchfield
Formatting: removed redundant variable in CPSearchField.j
2018-04-08 11:25:25 -07:00
Alexandre WilhelmandGitHub 7c2518f027 Merge pull request #2659 from bedalton/formatting-add-semi-colons-cpusernotification
Formatting: add semi colons CPUserNotification.j
2018-04-08 11:25:04 -07:00
Alexandre WilhelmandGitHub a07459454b Merge pull request #2660 from bedalton/formatting-add-semi-colons-nib2cib-converter
Formatting: add semi-colons to nib2cib/Converter.j
2018-04-08 11:24:56 -07:00
Alexandre WilhelmandGitHub 752f9d2694 Merge pull request #2661 from bedalton/fix-cpproxy-respondstoselector
Fix: CPProxy respondsToSelector incorrect parameter name
2018-04-08 11:24:42 -07:00
Alexandre WilhelmandGitHub 0a180f9e20 Merge pull request #2662 from bedalton/format-add-semi-colon-cpdateformatter
Format: add semi-colons to CPDateFormatter.j
2018-04-08 11:24:21 -07:00
Alexandre WilhelmandGitHub 6fff2e1c2f Merge pull request #2663 from bedalton/formatting-add-semi-colon-cparray-kvo
Formatting: add semi-colon CPArray+KVO.j
2018-04-08 11:24:07 -07:00
Alexandre WilhelmandGitHub 4266900d2e Merge pull request #2664 from bedalton/formatting-add-semi-colon-cpdictionary
Formatting: add semi-colon to CPDictionary.j
2018-04-08 11:23:47 -07:00
Alexandre WilhelmandGitHub a2a1d84bc0 Merge pull request #2665 from bedalton/formatting-add-semi-colon-cpindexset
Formatting: add semi-colons to CPIndexSet
2018-04-08 11:23:39 -07:00
Alexandre WilhelmandGitHub 7648c562f1 Merge pull request #2666 from bedalton/formatting-add-semi-colon-cpnotificationqueue
Formatting: add semi-colons to CPNotificationQueue.j
2018-04-08 11:23:21 -07:00
Alexandre WilhelmandGitHub 403fd30926 Merge pull request #2667 from bedalton/formatting-add-semi-colon-cppredicate
Formatting: add semi-colon to CPPredicate.j
2018-04-08 11:23:07 -07:00
Alexandre WilhelmandGitHub 17ccddf541 Merge pull request #2668 from bedalton/formatting-add-semi-colon-cptheme
Formatting: add semi-colon to CPTheme.j
2018-04-08 11:22:59 -07:00
Alexandre WilhelmandGitHub c24366fcec Merge pull request #2670 from bedalton/formatting-add-semi-colons-nib2cib-nib2cib
Formatting: add semi-colon to nib2cib/Nib2Cib.j
2018-04-08 11:22:31 -07:00
Alexandre WilhelmandGitHub 9a258a6265 Merge pull request #2671 from bedalton/formatting-add-semi-colon-nscustomerresource
Formatting: add semi colon NSCustomResource.j
2018-04-08 11:22:24 -07:00
Alexandre WilhelmandGitHub 4542ccbdc2 Merge pull request #2672 from bedalton/formatting-add-semi-colon-capp-main
Formatting: add semi-colon capp/main.j
2018-04-08 11:22:01 -07:00
Daniel 41d8ad2b86 Formatting: add semi-colons to capp/main.j 2018-04-07 17:20:00 -07:00
Daniel a3a2ee118e Formatting: add semi-colon to NSCustomResource.j 2018-04-07 17:17:19 -07:00
Daniel f285efc277 Formatting: add semi-colon to Nib2Cib.j 2018-04-07 17:15:36 -07:00
Daniel fbaf87ec6c Formatting: add missing semi-colon in CPTheme.j 2018-04-07 17:03:33 -07:00
Daniel a005a468a7 Formatting: add semi-colons to nib2cib/Converter.j 2018-04-07 16:40:52 -07:00
Daniel c8d01549ba Formatting: add semi-colon to CPUserNotification.j 2018-04-07 16:13:20 -07:00
daniel 23af4505dd Fix: CPProxy uses incorrect variable name in method call
On line 51 of CPProxy, `class_getInstanceMethod` is called with the
variable  `aSelector`, but this variable does not exist in the
context, but a variable named `selector` does. This fix changes the
method parameter from `selector` to `aSelector` to match the parameter
used within the method.
2018-04-07 15:37:19 -07:00
daniel 53cb6a5b3e Formatting: add missing semi-colons to CPNotificationQueue.j 2018-04-07 15:29:27 -07:00
daniel 765384ace1 Formatting: add semi-colons to CPIndexSet.j
Variable assignments terminated in commas instead of semi-colons
2018-04-07 15:26:52 -07:00
daniel d39e3e2f69 Formatting: add semi-colon to CPDictionary.j 2018-04-07 15:22:36 -07:00
daniel d75124066e Formatting: add semi-colons to CPDateFormatter.j 2018-04-07 15:20:08 -07:00
daniel f4400876da Formatting: add semi-colon to CPArray+KVO.j 2018-04-07 14:10:03 -07:00
daniel c222c5127f Formatting: add semi-colon to _CPPredicate.j 2018-04-07 14:07:43 -07:00
daniel 90d04956e6 Merge remote-tracking branch 'cappuccino/master' 2018-04-07 11:34:21 -07:00
cacaodevandGitHub 5d3b918339 Merge pull request #2624 from bedalton/formatting-add-semi-colon-cparraycontroller
Formatting: add semi-colon CPArrayController
2018-04-07 06:53:38 +02:00
cacaodevandGitHub eba0091764 Merge pull request #2623 from bedalton/formatting-add-semi-colon-cpapplication
Formatting: add semi-colon CPApplication
2018-04-07 06:53:13 +02:00
cacaodevandGitHub 7999cbbea3 Merge pull request #2622 from bedalton/formatting-add-semi-colon-cppopoverwindow
Formatting: add semi-colon CPPopoverWindow.j
2018-04-07 06:52:57 +02:00
cacaodevandGitHub cee7987b35 Merge pull request #2621 from bedalton/formatting-add-semi-colon-cptooltip
Formatting: add semi-colon to CPToolTip.j
2018-04-07 06:52:40 +02:00
cacaodevandGitHub d475c08024 Merge pull request #2620 from bedalton/formatting-add-semi-colon-cpdatepickerclock
Formatting: add semi colon CPDatePickerClock.j
2018-04-07 06:52:26 +02:00
cacaodevandGitHub d78f83ae49 Merge pull request #2619 from bedalton/formatting-move-redeclared-variable-in-cgpath
Formatting: remove redeclared variables in CGPath.j
2018-04-07 06:52:12 +02:00
cacaodevandGitHub df694f01e7 Merge pull request #2618 from bedalton/add-semi-colons-to-cgcontextvml
Formatting: add semi-colon to CGContextVML.j
2018-04-07 06:51:55 +02:00
cacaodevandGitHub f5d9cbb11b Merge pull request #2615 from bedalton/add-missing-semi-colon-to-cpkeyvaluebinding
Formatting : add missing semi-colon to CPKeyValueBinding.j
2018-04-07 06:51:35 +02:00
cacaodevandGitHub d802588abe Merge pull request #2617 from bedalton/add-missing-semi-colons-cgcontextcanvas
Formatting: Add missing semi-colons to CGContextCanvas.j
2018-04-07 06:51:01 +02:00
daboe01 927d6d2fc6 fixed: backspace did not trigger scrolling properly 2018-04-05 21:36:32 +02:00
daboe01 bab7595078 Merge remote-tracking branch 'cappuccino/master' 2018-04-05 21:26:43 +02:00
daniel 1ea9a6c57f Formatting: add missing semi-colon to CPWindowController.j 2018-04-04 15:14:06 -07:00
daniel f479d415d8 Formatting: add missing semi-colon in CPView.j 2018-04-04 15:13:03 -07:00
daniel f41e7be726 Formatting: add semi-colons to CPToolbar.j 2018-04-04 15:11:52 -07:00
daniel c1fe28124f Formatting: add semi-colons to CPTokenField 2018-04-04 15:10:17 -07:00
daniel 01a1e506e4 Formatting: add missing semi-colons to CPTextField.j 2018-04-04 15:08:21 -07:00
daniel e61aebb55d Formatting: minor formatting changes for CPTableView.j
Added missing semi-colon on line 3763.
Removed the redundant `var` keyword on line 4910
Removed the second redundant variable `CPTableViewHeaderViewKey` which
was declared with the same name and value twice in the same variable
block.
2018-04-04 15:06:00 -07:00
daniel bae5bafc62 Formatting: add semi-colon to CPTableColumn.j 2018-04-04 14:55:01 -07:00
daniel be6cb266de Merge remote-tracking branch 'cappuccino/master' 2018-04-04 14:50:00 -07:00
daniel 6f72edc2d9 Formatting: removed redundant variable in CPSearchField.j
Variable `searches` is defined in the method selector, and then
redeclared with the `var` keyword two lines later. Removed the
redundant declaration, moving the variable assignment to its own line.
2018-04-04 14:45:13 -07:00
daniel 29f66bdfed Formatting: add missing semi-colon to CPScrollView.j 2018-04-04 14:41:53 -07:00
daniel c1c6f5682c Formatting: add semi-colons to CPProgressIndicator.j 2018-04-04 14:40:46 -07:00
daniel a8a74a0246 Formatting: add semi-colons to CPOutlineView.j 2018-04-04 14:37:34 -07:00
daniel f9b867c3eb Formatting: Remove semi-colon after method header in CPLevelIndicator
On lines 295 and 304, the selector for two method declarations are
followed by a semi-colon. Not sure if this causes problems or not, but
removed anyways.
2018-04-04 14:36:07 -07:00
daniel 6c07f9a048 Formatting: add missing semi-colon to CPKeyValueBinding 2018-04-04 14:33:24 -07:00
daniel 573e0acafa Formatting: add semi-colon to CPImage.j
Variable value assignment terminated in comma, despite not being a
variable list. Replaced comma with semi-colon.
2018-04-04 14:25:59 -07:00
daniel 530c664967 Formatting: add semi-colon to CPFont.j 2018-04-04 14:19:26 -07:00
daniel 12c29c8387 Formatting: add missing semi-colons to CPEvent.j 2018-04-04 14:17:42 -07:00
daniel 6c7f61d90f Formatting: add missing semi-colon to CPColorPicker.j 2018-04-04 14:11:59 -07:00
daniel eb6d8d0bb3 Formatting: formally declared variable before use in CPColor.j
Variable `isVertical` is used throughout the function
`patternColorsFromPattern` in CPColor.j despite never being declared.
In this pull request, the variable is declared formally in the variable
list before its use.
2018-04-04 14:09:28 -07:00
daniel ef462973c7 Formatting: add semi-colon to CPArrayController.j 2018-04-04 13:33:53 -07:00
daniel aa7e49cfde Formatting: add semi-colon to CPApplication.j 2018-04-04 13:32:37 -07:00
daniel 186048676a Formatting: add semi-colon to _CPTooltip.j 2018-04-04 13:31:19 -07:00
daniel 0f40721cff Formatting: add semi-colon to _CPPopoverWindow.j 2018-04-04 13:29:40 -07:00
daniel 3799dd92fd Formatting: fix possible misuse of commas in _CPImageAndTextView.j 2018-04-04 10:50:04 -07:00
daniel 9ea1a2b1de Formatting: minor formatting updates in CPPlatformWindow+DOM.j
Missing semi-colon on line 1425.
Removed redundant `var` modifier on already declared variable on line
947.
Added variable declaration to variable used without declaration on line
970.
Removed redundant `var` modifier on already declared variable
`CPDOMEventGetClickCount` removed var on latter declaration as original
declaration has note stating it is to be declared at top so “so
compressor knows about them.”
2018-04-04 10:46:02 -07:00
daniel d8b27d122e Formatting: add semi-colons to CPPlatformPasteboard.j 2018-04-04 09:41:10 -07:00
daniel 15c3a6eae4 Formatting: add missing semi-colons to CPWindow.j 2018-04-04 09:38:43 -07:00
daniel 4fcc90d53e Formatting: add missing semi-colon to _CPHudWindowView.j 2018-04-04 09:28:31 -07:00
daniel 2619a50976 Formatting: add missing semi-colons to CPTypesetter.j 2018-04-04 09:27:12 -07:00
daniel de116c95d4 Formatting: add missing semi-colon to CPLayoutManager.j 2018-04-04 09:23:38 -07:00
daniel 47594c9b07 Formatting: add missing coma and semi-colons to CPTextField 2018-04-04 09:10:52 -07:00
daniel 1b9098b564 Merge remote-tracking branch 'cappuccino/master' into formatting-cptextview 2018-04-04 09:10:14 -07:00
daniel b0306eac87 Formatting: add semi-colon to CPFrontPanel.j 2018-04-04 09:07:06 -07:00
daniel 125e813d25 Formatting: add semi-colons to _CPRTFParser.j 2018-04-04 09:00:36 -07:00
daniel 8e0d4a70f2 Formatting: remove redundant variable in _CPRuleEditorViewSlice.j 2018-04-03 15:04:55 -07:00
daniel 0556fc68b0 Formatting: add missing semi-colons to CPMenuItem.j 2018-04-03 14:59:14 -07:00
daniel e9e2313159 Formatting: add missing semi-colons to CPDatePicker.j 2018-04-03 14:27:07 -07:00
daniel dbb2f03a43 Formatting: add semi-colon CPDatePickerTextField.j 2018-04-03 14:18:36 -07:00
daniel ed0dc2d887 Formatting: add semi-colon to _CPDatePickerClock.j 2018-04-03 12:59:51 -07:00
daniel 0a93f2d0b0 Formatting: add missing semi-colons to _CPDatePickerCalendar.j 2018-04-03 12:54:39 -07:00
daniel fd581cd65c Formatting: removed variable redeclaration in CGPath.j
Variables `arcStartX` and `arcStartY` are declared on 125 and 126, but
are later redeclared in an `else` statement on lines 135 and 136 with
the same equation and presumably the same value used in the initial
declaration.
Also added missing semi-colon
2018-04-03 12:46:56 -07:00
daniel 36702bc971 Formatting: add missing semi-colon to CGContextVML 2018-04-03 12:15:04 -07:00
daniel 0fc3eb38f1 Formatting: Add semi-colons to CGContextCanvas.j 2018-04-03 12:11:57 -07:00
daniel 73c8e945e9 New: add .idea to .gitignore
Prevent Intellij Idea metadata from being committed to git.
2018-04-03 12:07:01 -07:00
daniel b8420303ba Formatting: add missing semi-colon to CPKeyValueBinding.j 2018-04-03 10:55:17 -07:00
daniel 532bfcf937 Merge remote-tracking branch 'cappuccino/master' 2018-04-03 10:20:07 -07:00
cacaodevandGitHub f6d892023e Merge pull request #2604 from bedalton/overshadowing-variable-in-_CPCibObjectData
Fixed: Variable in if statement overshadows variable in enclosing block
2018-04-03 07:54:11 +02:00
daboe01 7f2977f4af fixed: wording in manual test 2018-04-02 08:33:50 +02:00
cacaodevandGitHub e246a2753b Merge pull request #2610 from daboe01/issue2605
fixed: wrong method invocation to delegate of CALayer (displayLayer:)
2018-03-31 12:35:33 +02:00
daboe01 6d06a26c31 fixed: typo in method invocation 2018-03-26 17:53:38 +02:00
Daniel 7cda21b60f Merge remote-tracking branch 'cappuccino/master' 2018-03-20 13:46:13 -07:00
Daniel 1db740039b Fixed: Variable in if statement overshadows variable in enclosing block
If statement variable ‘instantiatedObject’ on line 229 of
_CPCibObjectData.j overshadows a variable with the same name declared
on line 233 in the enclosing block. Variable is added to array outside
the enclosing if statement.

Refs: #2601
2018-03-20 11:36:19 -07:00
daboe01 df462774aa refactured front detection logic to own method _isFrontmostWindow
fixes travis error
2018-03-20 14:25:42 +01:00
daboe01 f55fa789c4 new: manual test for issue 2545 2018-03-18 22:33:49 +01:00
daboe01 488541f26e fixed: click to key window in the background did not bring it forward 2018-03-18 21:45:25 +01:00
daboe01 b404b1cf50 Merge remote-tracking branch 'cappuccino/master' 2018-03-08 15:43:23 +01:00
Martin CarlbergandGitHub 69370aa806 Merge pull request #2596 from mrcarlberg/triple_click_noneditable_selectable_empty_textfield
Fixed: Crash when triple click an empty CPTextField that is not editable but selectable
2018-03-08 09:17:57 +01:00
daboe01andMartin Carlberg b3ddd85b09 Fixed: Editing text in tableviews throws DOM exceptions under certain conditions in Chrome (#2563)
Previosly, we unflagged ```CPTextFieldInputDidBlur``` and ```CPTextFieldInputResigning``` before
the call to removeChild. This resulted in DOM exceptions in Chrome under certain conditions.
See https://stackoverflow.com/questions/21926083/failed-to-execute-removechild-on-node for
why we need to unflag ```CPTextFieldInputDidBlur``` and ```CPTextFieldInputResigning``` only after removing the element.

This apply to token fields also but with the corresponding flags. Also token fields now have the same behavior as the text field when bluring etc.
2018-03-08 09:17:15 +01:00
Martin Carlberg 033221fd01 Fixed: When triple click in an empty CPTextField that is not editable but selectable this call will crash as _DOMTextElement is nil.
This check will make sure it is not called when no element is present. This is the same way as it is done in other parts of this class.
2018-03-07 11:24:21 +01:00
Didier Korthoudt 1201fa38a8 Merge remote-tracking branch 'cappuccino/master' 2018-03-07 00:05:40 +01:00
Martin CarlbergandGitHub 32059c376e Fixed: Nib2Cib will replace a CPTextFieldCell with a CPTextField as Cappuccino does not use cells. When a binding or connection is made to a CPTextFieldCell the binding / connection will get lost when read as the cell is never stored in the cib file. (#2572)
This fix make sure that the binding / connection is made to the CPTextField instead of the cell by replacing the cell with the text field when reading the xib file. The same mechanism is used in NSButton and NSMatrix.

This fix allows view based TableView bindings from a text field cell to the table cell view in the Interface Builder in Xcode.
2018-03-06 09:09:57 +01:00
Martin CarlbergandGitHub 511d393c78 Merge pull request #2576 from mrcarlberg/cptextview_delegate
New: CPTextView delegate methods added
2018-03-06 09:07:55 +01:00
Martin CarlbergandGitHub 237601cf29 Merge pull request #2579 from mrcarlberg/xml-parser-node
Fixed: The property list test cases can now run on the Node engine.
2018-03-06 09:00:41 +01:00
daboe01andMartin Carlberg 928f14872e Fixed: call to nonexistent method (#2588) 2018-03-06 08:59:36 +01:00
Martin CarlbergandGitHub c6a9adf96c Merge pull request #2556 from daboe01/plainsliderfix
Fixed: legacy scrollers used Aristo1 artwork in Aristo2
2018-03-05 11:06:59 +01:00
Martin CarlbergandGitHub cdd00e0bd4 Merge pull request #2595 from daboe01/cpnumber-unarchiving-fix
Fixed: initWithCoder: called unimplemented method on the coder
2018-03-05 11:04:41 +01:00
Martin CarlbergandGitHub 2503d13402 Merge pull request #2594 from daboe01/CPSavePanel-missing-class-method
Fixed: +proposedFileURLWithDocumentName: was missing
2018-03-05 11:01:18 +01:00
daboe01andMartin Carlberg 2d97970d24 Fixed: numberWithInteger: was erroneously used instead of numberWithInt: (#2587) 2018-03-05 10:50:30 +01:00
Martin CarlbergandGitHub d8945e53ba Merge pull request #2593 from daboe01/CPCoder--remove-bitrot
Fixed: unused and broken code removed from CPCoder
2018-03-05 10:43:41 +01:00
daboe01andMartin Carlberg f18012d07b Fixed: removed erroneous call to sizeValue (#2589) 2018-03-05 10:36:22 +01:00
daboe01 104f8603b9 fixed: initWithCoder: called unimplemented method on the coder 2018-03-04 21:27:08 +01:00
daboe01 19bb083030 fixed: +proposedFileURLWithDocumentName: was missing 2018-03-04 18:40:33 +01:00
daboe01 ae575a19a0 fixed: unused broken code removed from CPCoder 2018-03-04 11:55:34 +01:00
cacaodevandGitHub 5f94d0a5c2 Typo: remove extra semi-colon 2018-02-28 15:33:16 +01:00
Korthoudt Didier f2fe1a7c17 Merge remote-tracking branch 'cappuccino/master' 2018-02-27 23:41:34 +01:00
cacaodevandGitHub 618e6a1604 Merge pull request #2591 from daboe01/_CPFunctionExpression.j-missing-if
fixed: fromObject:(id)object index:(id)anIndex failed to raise if arg…
2018-02-27 15:59:19 +01:00
cacaodevandGitHub cef294513a Merge pull request #2590 from daboe01/CPKeyValueObserving-fix-CPKeyValueChangeReplacement
FIXED: Typo in call to replaceObjectsAtIndexes in CPKeyValueObserving
2018-02-27 15:58:13 +01:00
daboe01 8550abadef fixed: fromObject:(id)object index:(id)anIndex failed to raise if argument was not CPDictionary or CPArray 2018-02-24 15:41:17 +01:00
daboe01 25c8b2d631 fixed: typo in call to replaceObjectsAtIndexes 2018-02-24 14:59:27 +01:00
Martin Carlberg e7b690205e Fixed: The property list test cases can now run on the Node engine.
The xml parser in the Node.js engine is more modern and can handle more cases. Our property list parser does not handle this. This fix makes the test cases for the property lists run on the Node.js engine.
2018-01-15 09:28:39 +01:00
Martin Carlberg 2403f8833a Fixed: Added an application description at the top of the window 2018-01-09 13:43:09 +01:00
Martin Carlberg 9f25743b4d Fixed: Never send CPTextViewDidChangeTypingAttributes notification when selection the same selection again. This is how Cocoa works. 2018-01-09 13:41:34 +01:00
Martin Carlberg f1c76f65cf Fixed: Added some comments on some methods 2018-01-09 13:37:35 +01:00
Martin Carlberg 7b39533410 New: Added manual test application to monitor order and number of calls for CPTextView delegate methods and notifications. 2018-01-08 14:11:55 +01:00
Martin Carlberg 1fe9c39dd5 Fixed: Test cases for the new or changed delegate methods and notifications. 2018-01-08 13:57:53 +01:00
Martin Carlberg 2b7be2e3f1 Fixed: Make sure the delegate methods and notifications are handled in the same way as in the Cooca frameworks.
CPTextViewDidChangeSelectionNotification should not be send if the text view is empty.
CPTextDidBeginEditingNotification is send when an edit is started.
CPTextDidEndEditingNotification is send when an edit is ending.

textShouldBeginEditing: delegate method is called to allow control if edit should start.
textShouldEndEditing: delegate method is called to allow control if edit should end.
2018-01-08 13:56:24 +01:00
Martin Carlberg 1ee9a3f279 Fixed: Check if the correct delegate method is implemented before calling it 2018-01-08 13:47:45 +01:00
Martin Carlberg 679acfb239 Fixed: Register the delegate as an observer on any notification that the delegate implement.
Also make sure we remove the observers if for example the view does not have a superview. This will make sure that the Notification Center is not hanging on to the view and delegate if the view is not used any more. Can cause a memory leak.
2018-01-08 13:44:47 +01:00
Martin Carlberg 3c7ab4b49b Fixed: Make the view aware of some more delegate methods 2018-01-08 13:20:03 +01:00
Martin Carlberg 3f062e1c0a Fixed: Make all method in CPTextDelegate and CPTextViewDelegate protocol optional. 2018-01-08 13:15:31 +01:00
Didier Korthoudt 0a497d8c3f NEW: Added automatic Xcode syntax coloring
In Xcode, Objective-C source files are automatically recognised and the usual syntax coloring is applied. With this PR, Xcode will do so for Objective-J source files.
2017-12-17 20:49:56 +01:00
Korthoudt Didier 462351f485 Merge remote-tracking branch 'cappuccino/master' 2017-12-17 20:06:35 +01:00
Martin CarlbergandGitHub c4cbb631a9 Merge pull request #2561 from mrcarlberg/compile_with_sourcemap
Full support for source map when debugging
2017-12-11 10:52:05 +01:00
Martin Carlberg 76f2d15b1b Fixed: Added the option to only inline message send function without also compress the output javascript file.
This allows us to inline the message send function in DEBUG mode. This is great when stepping into a method in the debugger as the message send function is not a separate function. Also the stack traces in the debugger is much more compact as the message send function is not there.
2017-12-08 14:02:11 +01:00
cacaodevandGitHub 5d63865ae5 Merge pull request #2546 from cacaodev/CPSplitView
CPSplitView -trackDivider: performance
2017-11-08 18:53:22 +01:00
daboe01 ad7c88fb45 Merge remote-tracking branch 'cappuccino/master' 2017-09-27 11:46:45 +02:00
daboe01 1af3877758 FIXED: scroll-knob was slightly too bold 2017-09-27 11:05:59 +02:00
Martin CarlbergandGitHub 146ce3b12b Merge pull request #2544 from FrankReh/pullreq/cleanup/old/unused/ensurePackageUpToDate
Remove: ensurePackageUpToDate() from common.jake
2017-09-26 08:43:41 +02:00
Martin CarlbergandGitHub bf67721ac4 Merge pull request #2548 from cacaodev/CPWindow-live-resize-notifications
CPWindow live resize notifications
2017-09-25 14:04:01 +02:00
Martin CarlbergandGitHub 436f736a8e Merge pull request #2543 from FrankReh/pullreq/cleanup/remove/property/sub_classes
Remove objj_class.sub_classes property
2017-09-22 13:03:54 +02:00
Martin Carlberg 1446e90dd9 Fixed: Use correct naming on function parameter. Also changed som comments to reflect the correct meaning of the parameter 2017-09-18 13:39:28 +02:00
Martin Carlberg 54716c03d1 Fixed: Missed new line when increment tokPos. Now we use the correct skip space function that will take care of things in correct manners. 2017-09-18 13:36:51 +02:00
daboe01 fad5e97e0a Merge remote-tracking branch 'cappuccino/master' into plainsliderfix 2017-09-14 09:10:56 +02:00
Martin Carlberg 8cf79590c5 Fixed: When target was ’self’ in a message send expression the source map was showing the wrong variable. 2017-09-12 13:17:49 +02:00
Martin Carlberg c6aafac6c8 Fixed: Compile Foundation and AppKit frameworks with source maps for the debug version. 2017-09-11 12:50:49 +02:00
Martin Carlberg 94a5995197 New: We now support source maps when compiling both from command line and in browsers.
To add source maps add the ”-S” flag to the Jake file when compiling from command line. In the browser you need to add the compiler option into your index.html file. It should look something like this:
OBJJ_COMPILER_FLAGS = [... , "SourceMap"];

All browsers has support for source maps but currently Chrome works best.
2017-09-11 12:49:59 +02:00
Martin CarlbergandGitHub 74081dc981 Merge pull request #2551 from mrcarlberg/compile_without_gcc
Compile without gcc [+2]
2017-09-11 11:14:44 +02:00
daboe01 7a593b13a7 Merge remote-tracking branch 'cappuccino/master' into plainsliderfix 2017-09-09 10:56:37 +02:00
Martin CarlbergandGitHub 25dc38b2b1 Merge pull request #2558 from daboe01/smartcopypastefixes
Fixed: smart copy/paste did not work properly [+1]
2017-09-08 09:09:26 +02:00
Alexandre WilhelmandGitHub 403b12f7b7 Merge pull request #2550 from cacaodev/CPAnimationContext
FIXED: CPAnimationContext completionHandler was not called under certain circumstances.
2017-09-07 18:21:56 -07:00
Alexandre WilhelmandGitHub cd223be88a Merge pull request #2557 from daboe01/placeholderselectablefix
fixed: cursor blinks for placeholder
2017-09-07 18:21:12 -07:00
Alexandre WilhelmandGitHub a6a3fca1e7 Merge pull request #2559 from daboe01/onpaste-ff-fix
Fixed: CPTextView's onpaste handler used non-standard window.event
2017-09-07 18:20:32 -07:00
daboe01 63815eb5c2 fixed: onpaste handler used window.event (non-standard)
broke paste on FF/win
2017-09-07 19:19:19 +02:00
daboe01 4444264830 formatting 2017-09-04 23:02:50 +02:00
daboe01 255f91f7ca fixed: cornerview looked odd without scroller margins 2017-09-04 22:59:34 +02:00
cacaodevandGitHub 700207d29b Merge pull request #2554 from cacaodev/cptableview-issue#2549
CPTableView: fix invisible dragged rows
2017-08-30 08:35:40 +02:00
daboe01 72d96e9a3b fixed: smart pasting did not work properly 2017-08-29 15:11:29 +02:00
daboe01 a55b6de1b4 removed: unused artwork from aristo2 2017-08-28 23:32:47 +02:00
daboe01 9faac05666 fixed: cursor blinks for placeholder 2017-08-23 23:07:42 +02:00
daboe01 7bf408aba0 fixed: legacy scrollers used aristo1 artwork in aristo2 2017-08-22 22:02:42 +02:00
daboe01 70ee391b33 Merge remote-tracking branch 'origin/master' 2017-08-22 14:40:47 +02:00
cacaodev f5eb1158db Fix issue 2549: table rows where invisible when dragging. 2017-07-28 21:35:24 +02:00
cacaodev 81916d0f45 FIXED: A grouping context does not inherit the completion handler ...
… from the current context.
Also removed CPAnimationContext -copy method. CPAnimationContext is not
CPCopying compliant.

TEST: CPAnimationContextTest ->
testCompletionHandlerWithoutAnimatorWithGrouping2
2017-07-25 12:04:58 +02:00
Alexander Ljungberg 76d77cc244 This will be Cappuccino 0.9.10. 2017-07-11 14:26:57 +01:00
cacaodev 03dccbe613 Add a manual test for the previous fixes.
The tests must be run independently because animations are launched at
the end of the current run loop.
2017-06-30 12:26:15 +02:00
cacaodev 1ccec65619 Add debug information 2017-06-30 12:03:29 +02:00
cacaodev b78e9062a1 CompletionHandlerAgent fire() is a one shot. 2017-06-30 12:03:09 +02:00
cacaodev dc87354702 CPAnimationContext setCompletionHandler: add an equality check 2017-06-30 12:00:08 +02:00
Martin Carlberg 033e8583db Fixed: A more robust prettify message function 2017-06-26 17:59:08 +02:00
Martin Carlberg d46b51fa9a Fixed: In Rhino a function must be declared before it is used even if it is in the same scope. 2017-06-26 17:58:13 +02:00
Martin Carlberg dd1dfdcfeb Fixed: Added a comment on tricky code line 2017-06-26 16:25:44 +02:00
Martin Carlberg c0233c803d Fixed: Removed old print statements for debugging 2017-06-26 16:24:51 +02:00
Martin Carlberg 1fa8c88f6b Fixed: Speed up of objj_msgSend function. Don’t need to use complex check if class is initialized. 2017-06-26 16:23:59 +02:00
Martin Carlberg 195b109a36 New: Added ’#include’ to the preprocessor, compiler and Cappuccino load system. Also a lot of bug fixes in the preprocessor 2017-06-26 16:19:56 +02:00
Martin Carlberg 994ac3fc8e Fixed: Support for more options to the objj tool 2017-06-26 16:04:01 +02:00
Martin Carlberg a8ec5cf5e9 New: Support to create source maps for the frameworks and applications 2017-06-26 16:03:20 +02:00
Martin Carlberg b4263aa3ec New: Make sure we can use String function ’startsWith’ and ’endsWith’ even if an older browser or Javascript engine is used. 2017-06-26 15:50:08 +02:00
Martin Carlberg 6456809a72 Fixed: Use semicolon on last line in #included files. The new preprocessor might think that the statement will continue on the next line.
Due to Javascript don’t need to have semicolon at end of statement there are times when the parser thinks the line continues on the next line.

For example we have a file.js:
var f = function(x)
{
	return x + x;
}

Now in another file we do:
#include file.js
(function(exports) {
a = 42;
})(exports.b)

There will be two different behaviors if the ’file.js’ has a semicolon at the end of the last line. This commit make sure we have the right behavior.
2017-06-26 15:45:02 +02:00
Martin Carlberg 024c0a3186 Fixed: Handle source maps if source-map.js is included from the index.html file.
To create source maps the compiler flag ”SourceMap” has to be added in the OBJJ_COMPILER_FLAGS array in the index.html file.
2017-06-22 11:05:16 +02:00
Martin Carlberg 560b1d48bc Merge branch 'master' of https://github.com/cappuccino/cappuccino 2017-06-22 10:46:53 +02:00
cacaodev bb2d860807 CPViewAnimator: guard in the frame updater function
… in case the transform property value is ‘none’.
2017-06-12 12:46:05 +02:00
cacaodev 6f1c0fa4a8 FIXED: CPAnimationContext completionHandler was not called
Previously, if a context group was not generating any animation (no
calls to animator or non implemented method in the animator proxy), the
completionHandler was not called.
If the end value (frame, frameorigin, frameSize) was equal to the start
value, the completionHandler was not called neither.

This commit makes sure that the completionHandlerAgent counter is
incremented by the count of animations that actually start.
2017-06-12 12:46:05 +02:00
cacaodev 35808e7bde FIXED: uninitialized ivar 2017-06-02 11:15:23 +02:00
cacaodev 1b4eeb35b3 Add a manual test CPWindowLiveResizeTest 2017-06-02 09:44:42 +02:00
cacaodev cee032bbc9 FIXED: send live resize notifications when the window animates
Like in cocoa, these notifications are not sent when a sheet is
displayed.
2017-06-02 09:42:59 +02:00
cacaodevandGitHub 9547b70743 Merge pull request #2542 from FrankReh/pullreq/cleanup/fix/unused/cachedSearchResults
Removed an unused variable: cachedSearchResults.
2017-05-30 19:29:14 +02:00
cacaodevandGitHub 5df8939d84 Merge pull request #2541 from FrankReh/pullreq/cleanup/fix/syntax/protocol_list
Fix aClass.protocol_list syntax
2017-05-30 19:27:53 +02:00
cacaodevandGitHub 0b9c689273 Merge pull request #2540 from FrankReh/pullreq/cleanup/fix/syntax/global-var-key
Make variable local: key
2017-05-30 19:25:25 +02:00
cacaodev ac193cd97a Test: Add liveResize testing in CPWindowResizeStyle manual test
The window title changes during live resize.
2017-05-30 19:06:50 +02:00
cacaodev 7355a60f16 Call _setupDOMDivider when necessary only
Previoulsy, the backgroundColor and url css properties where set at
each drawing pass.
2017-05-30 18:33:08 +02:00
cacaodev fb6f6325b5 CPSplitView: refactor trackDivider: using _dividerAtPoint:
instead of a for loop.
2017-05-23 08:17:16 +02:00
cacaodev 0f767d9dfc CPWindow: add CPWindowWillStartLiveResizeNotification and CPWindowDidEndLiveResizeNotification
Also fixed CPView -(BOOL)inLiveResize
If a view is added during a live resize, it will not receive a
willStart notif.
If a view is removed during a live resize it will not receive a Didend
notif.
2017-05-20 13:52:50 +02:00
cacaodev d1addcab91 CPSplitView: do not track events outside of a divider.
Added private method -_dividerAtIndex:
2017-05-13 19:46:39 +02:00
cacaodev 7a02cd794b Properly catch single-click, double-click, dragging on a divider
Previously, a double-click was also catched as a single-click on mouse
up,
dragging was handled is mouse down before tracking actually begins.

Manual test: added collapse capabilities to all split views.
2017-05-12 11:09:08 +02:00
cacaodev 258cd9209f CPSplitView: exit a loop when the current divider is found 2017-05-12 10:28:47 +02:00
Frank Rehwinkel 700f6022d9 Remove: ensurePackageUpToDate() from common.jake
Some unused code in common.jake that had referred to tusk.  Has not
been used in years.
2017-05-06 13:10:49 -04:00
Frank Rehwinkel a0f6b815e8 Removed an unused variable: cachedSearchResults.
It is polluting the global namespace.

Seven years ago this line was added and even then the variable wasn't
being used but it was a local variable so would have been hard to spot
unless a linter should catch things like that.

Then some four years ago it was accidently converted to a global
variable because the line above it ended in a semicolon rather than
a comma.  'use strict' didn't exist at the time this file was created
and hasn't been added in general yet.
2017-05-04 16:03:11 -04:00
Frank Rehwinkel 54477b8b8f Make variable local: key
This line of code was introduced years ago with a variable that
javascript is happy to add to the global name space.  Clearly it
was meant as a local variable.  Probably a cut and paste error
because other places in the code use the same syntax but there the
value is a local because the var statement for it appeared elsewhere
in the function.

Once code like this is cleaned up to use the new 'let' construct,
as well as 'use strict', mistakes like this will be much less likely
to go uncaught.
2017-05-04 16:01:53 -04:00
Frank Rehwinkel 6183f8d4e9 Fix aClass.protocol_list syntax
A long standing bug that never mattered because each class is
initialized with a protocol_list set to an empty array.  This
is not the case for the protocol objects but there the syntax
was correct already.
2017-05-04 15:58:47 -04:00
Frank Rehwinkel d98e247665 Remove objj_class.sub_classes property
From the first day this class was added to the repo, the sub_classes
property, which is initialized with an empty array, has gone unused.

Removing it.  A little less code.  A little subsequent processing
and memory used.
2017-05-04 15:57:14 -04:00
Martin Carlberg d0cd976246 Fixed: Get class method instead of instance method
When asking a protocol for a specific class method we asked each super protocol for an instance method.

Thanks Frank for finding this!
2017-04-11 12:30:16 +02:00
daboe01 15f6f6a90a Merge remote-tracking branch 'cappuccino/master' 2017-03-18 11:02:38 +01:00
cacaodevandGitHub f18074bf49 Merge pull request #2532 from cacaodev/CPWindowAnimator
New: Optional declarative layout for use in CoreAnimation (css animations).
Code refactor.
2017-03-13 08:34:01 +01:00
cacaodevandGitHub 3f64b74453 Merge pull request #2533 from cacaodev/CPCompatibility-SetFeature
NEW: CPCompatibility: add a function to set a feature externally.
```CPSetPlatformFeature(aFeature, aBool)```
2017-03-13 08:28:51 +01:00
cacaodev 1c86256f83 Add CPCSSAnimationFeature to CPCompatibility constants 2017-03-02 11:21:57 +01:00
cacaodev 98105ad4dc Merge branch 'CPCompatibility-SetFeature' into CPWindowAnimator-copy 2017-03-02 10:57:23 +01:00
cacaodev 6bf2d6c1ab Move css animation creation & frame updaters to CPViewAnimator
Reason: • consistency : animations handled by animator.
• Views can now animate several DOM elements. For example
a view with a nine part image need to animate its sub divs.

• Do not create any css animation when the start and end values are
equal and there is no intermediate values.

+ This commit adds an optional method to CPView
- (CGRect)frameRectOfView:(CPView)aView inSuperviewSize:(CGSize)aSize
Returns the frame of a view given its superview frame. This will allow
views implementing -layoutSubviews to gain an optional declarative
layout. The animation system will use this method to compute the end
value of an animation.
2017-03-02 10:30:09 +01:00
cacaodev cebd51aac1 reduce the number of args in a private method 2017-03-02 10:30:08 +01:00
cacaodev 42b8b3aa75 Ask the animator if periodic frame updates are needed 2017-03-02 10:30:08 +01:00
cacaodev c0eaf79d25 Remove jshashtable.js in favor of Map() 2017-03-02 10:30:07 +01:00
cacaodev fb2fe3eb63 Enable forced frame updates in CPViewAnimator 2017-03-02 10:30:07 +01:00
cacaodev 184d63f7eb Move the FrameUpdater function to CPViewAnimator 2017-03-02 10:30:07 +01:00
cacaodev 14ebd58c96 Move CFRunLoopObserver to CPRunLoop.j as a global function 2017-03-02 10:30:05 +01:00
cacaodev 3edddb8e91 Add CSSAnimation.description() function 2017-03-02 10:30:05 +01:00
cacaodev d2340dff1a Style, whitespace 2017-03-02 10:30:04 +01:00
cacaodev d30c6aec7d Fix label in demo (AutoSize checkbox) 2017-03-02 09:56:47 +01:00
cacaodev 4854b3e08f Fix typo 2017-03-02 09:48:12 +01:00
cacaodev facc748090 NEW: CPCompatibility add a function to set a feature externally.
CPSetPlatformFeature(aFeature, aBool)
2017-03-01 19:10:00 +01:00
cacaodevandGitHub 5c71612e34 Typo 2017-02-10 20:01:57 +01:00
cacaodevandGitHub f00a5fbaf4 Merge pull request #2531 from cacaodev/cptableview-diddragcolumn
FIXED: tableView:didDragTableColumn: was never sent
With tests.
Fixes #2530
2017-02-03 08:13:46 +01:00
cacaodev 34769da9cc FIXED: tableview:didDragTableColumn: was never sent
With manual test.
2017-02-02 09:36:48 +01:00
cacaodev 458e6ed531 FiXED: CPTableColumn description 2017-02-02 09:34:17 +01:00
daboe01 05814e9351 Merge remote-tracking branch 'cappuccino/master' 2017-01-26 19:55:12 +01:00
daboe01 b6c0b1b396 Merge remote-tracking branch 'cappuccino/master' 2017-01-19 20:03:10 +01:00
Martin CarlbergandGitHub 1a299d85b6 Merge pull request #2503 from enquora/master
Fix CPBox drawing artifacts when used in CPSeparator mode
2017-01-19 09:46:33 +01:00
David Richardson 1816274ebe Revert "Fix CPBox drawing artifacts when used in CPSeparator mode"
This reverts commit 7596c66703.
2017-01-17 11:59:26 -07:00
David Richardson b02e4c5308 Handle case when CPBox is used as a separator line having no title
If _titlePosition is correctly set to CPNoTitle value, class already handles removing title view from display.
Previously, _titlePosition was not correctly set, title view was left in place.
With no supplied value for title, outline of title view was rendered with visible artifacts.
2017-01-16 11:23:32 -07:00
Martin CarlbergandGitHub 12ed42e163 Merge pull request #2505 from HTPC-Schrauber/fix-RegEx
Fixed: RegEx for gcc > 4.9
2017-01-16 12:36:57 +01:00
Martin CarlbergandGitHub 6c9c135062 Merge pull request #2525 from daboe01/new-textview-bindings
New: bindings support for CPTextView + dragging improvements
2017-01-16 12:24:56 +01:00
Martin CarlbergandGitHub 6aea0160df Merge pull request #2508 from daboe01/fix-sizing-issue
Fixed: text-sizing by canvas and via DOM sizing differed by 1px
2017-01-16 12:20:06 +01:00
daboe01 30edd9e8dd Merge remote-tracking branch 'cappuccino/master' 2017-01-06 13:05:18 +01:00
David Richardson 7734402e8e Merge branch 'master' of https://github.com/cappuccino/cappuccino into enquora-master 2017-01-05 16:00:51 -07:00
daboe01 ace1332ca5 fixed: semipredicate issue caused typingAttributes being overwritten by placeholder attibutes 2016-12-28 23:16:03 +01:00
daboe01 baa313e8f8 fixed: insertion point was wrong sometimes when dragging beyond last character 2016-12-26 23:30:23 +01:00
daboe01 3d9aa24f3c formatting 2016-12-26 23:18:24 +01:00
daboe01 c287d457d6 formatting 2016-12-26 22:14:12 +01:00
daboe01 7537b27a58 fixed: pboad types were wrong when unarchiving from cib 2016-12-26 22:11:11 +01:00
daboe01 1f560c92fc fixed: dragging pasteboard was not respecting rich vs. plain 2016-12-26 21:49:36 +01:00
daboe01 74cd11c763 minor cleanup 2016-12-26 14:50:33 +01:00
daboe01 ee7d89331b fixed: selection dragging was broken by changes to insertText 2016-12-26 12:50:16 +01:00
daboe01 5b51077823 fixed: changing the selection was possible despite isSelectable returning NO 2016-12-26 12:35:23 +01:00
daboe01 d2f94d1945 formatting 2016-12-26 11:53:49 +01:00
daboe01 0170a099bb formatting 2016-12-26 11:50:25 +01:00
daboe01 2b893d0ea1 fixed: placeholder string was not supported in textview bindings 2016-12-26 11:47:33 +01:00
daboe01 a08da57cbb fixed: reverse setting did not work 2016-12-26 10:56:43 +01:00
daboe01 a313fe5a86 add basic binder + manual test 2016-12-26 09:40:58 +01:00
daboe01 544de699f6 Merge remote-tracking branch 'cappuccino/master' into new-textview-bindings 2016-12-24 20:46:26 +01:00
daboe01 d9d35b7f50 add binder class router 2016-12-24 20:46:12 +01:00
daboe01 7dbec00f0e Merge remote-tracking branch 'cappuccino/master' into new-textview-bindings 2016-12-18 21:07:21 +01:00
Martin CarlbergandGitHub 51b9b40c7e Merge pull request #2515 from daboe01/chrome-rich-paste-fix
fixed: native paste on chrome was not working as robustly as it should [+1]
2016-12-13 09:40:18 +01:00
daboe01 b2383a084a fixed: wrong name in CPTextView manual test 2016-12-12 22:32:00 +01:00
daboe01 61848c5e24 fixed: selection was not properly restored upon undo/redo 2016-12-12 20:29:19 +01:00
Martin CarlbergandGitHub 60b2f7d243 Merge pull request #2513 from daboe01/fix-combobox-scroll-issue
Fixed: legacy scrollers were not clickable under some circumstances
2016-12-12 13:16:01 +01:00
daboe01 d2a5e126ae fixed: native rich text was parsed when pasted into plain textview
+ newline fix in rtf parser
2016-12-11 22:42:43 +01:00
daboe01 9d7d8ddde9 fixed: native rich pasting pasted rich text into plain textviews 2016-12-11 14:05:51 +01:00
Martin CarlbergandGitHub 249ebeb4aa Merge pull request #2517 from daboe01/fix-initial-blinking-on-sheet
Fixed: caret did not blink in empty textview, e.g. when on freshly opened popover
2016-12-10 11:11:13 +01:00
daboe01 378c14d790 formatting 2016-12-09 23:53:08 +01:00
daboe01 30c1093c2f fixed: rich native pasting caused FF to flicker 2016-12-09 23:45:16 +01:00
daboe01 b966c8cb0b formatting 2016-12-09 21:35:42 +01:00
daboe01 38cddf029b fixed: rich native pasting was not using the rtf pasteboard type on chrome 2016-12-09 21:32:21 +01:00
Martin CarlbergandGitHub 6652a27781 Merge pull request #2518 from cacaodev/CPControl-usesSingleLine
New: Allow a text based control to stay on a single line when text wraps.
2016-12-09 15:13:28 +01:00
daboe01andcacaodev 08b067cfc5 fixed: cared was blinking during typing (#2519) 2016-12-04 13:33:24 +01:00
daboe01 4959b84b4c fixed: implicit casting of NULL aWith argument to string in _sizeWithFont:inWidth: 2016-12-02 22:08:48 +01:00
cacaodev d42562fdcb New: Allow a text based control to stay on a single line when wrapping
A private flag have been added in _CPImageAndTextView. It must be set
to YES when it does not make sense for a control to hold multiline text.
This is now the case for all CPSegmentedControl.

Test: In CPSegmentedControlTest, hit « Add Segment with flexible
width » button. The new label should be vertically centered.
2016-12-02 09:10:39 +01:00
Alexandre WilhelmandGitHub 1e0aacd811 Merge pull request #2511 from cacaodev/CPObjet-instancesImplementSelector
New: CPObject -instancesImplementSelector:(SEL)aSelector
2016-11-22 22:44:30 -08:00
daboe01 329469fe84 fixed: _textContainerOrigin.y was not respected when predicting the cared position in empty textview 2016-11-20 22:36:24 +01:00
daboe01 93b0c5a7e5 fixed: font height was nil under certain circumstances 2016-11-20 21:44:08 +01:00
daboe01 9e456fd315 Merge remote-tracking branch 'cappuccino/master' 2016-11-20 15:31:25 +01:00
daboe01andcacaodev 8203c71b03 fixed: CPTextView's needsPanelToBecomeKey did not return YES (#2512)
This is confirmed to conform to cocoa.
2016-11-17 16:43:54 +01:00
daboe01 80d1e9a9a7 fixed: ceiling the sizing width caused subtle issues with CPTextView 2016-11-15 22:43:24 +01:00
daboe01 3c27e57b19 fixed: native rich pasting curly braces crashed chrome 2016-11-15 21:02:04 +01:00
daboe01 b46b2f048d fixed: native paste on chrome was not working as robustly as it should 2016-11-14 23:09:04 +01:00
cacaodev 8d403f579c FIxed: IB connections in CPTabViewNibTest 2016-11-14 22:03:51 +01:00
daboe01 12b274ab43 formatting 2016-11-13 22:55:29 +01:00
daboe01 986cccb800 fixed: legacy scroller was not clickable under some circumstances 2016-11-12 23:03:45 +01:00
cacaodev 5da8728d6c New: CPObject instancesImplementSelector:(SEL)aSelector
Tests if instances of given class implement a selector.

With test.

Note: The naming is from cocoa where this method is semi-public.
2016-11-12 18:30:02 +01:00
daboe01 66c9a1e90a ceil is a better solution than adding one 2016-11-11 23:02:57 +01:00
daboe01 a1925e1d0b fixed: the canvas sizing and DOM sizing differed by 1px 2016-11-08 19:52:45 +01:00
daboe01 da0910b1e5 Merge remote-tracking branch 'cappuccino/master' 2016-11-08 19:34:28 +01:00
Didier Korthoudt 8dbbe34dfc Merge remote-tracking branch 'cappuccino/master' 2016-11-08 15:21:17 +01:00
cacaodev 947d552509 Fix merging 2016-11-07 22:57:33 +01:00
cacaodev 037bc4ea2b Test: demonstrate the new wantsPeriodicFrameUpdates animator property
In Tests/Manual/CPAnimatablePropertyContainerTest/
2016-11-07 22:26:30 +01:00
cacaodev cfbef141d8 CPAnimationContext: Inhibit DOM updates during size animation
Previously, during frame updates, we were writing the css values we
just read before.
Canvas sizing is preserved as it is needed when the view has custom
drawing.
2016-11-07 22:26:30 +01:00
cacaodev 410ad0dc09 Style: print debug logs in debug mode only 2016-11-07 22:26:29 +01:00
cacaodev 3d9b42f0c2 Style: CSSAnimation.j linting
Using default eslint config for js
2016-11-07 22:26:29 +01:00
Didier Korthoudtandcacaodev eeea21c882 Fixed: CPViewAnimator was not giving correct frame information (#2502)
Fixed: When only animating frameSize, there’s no matrix defined. This is now
correctly handled.
New: The animator can explicitly request frames updates when the frameOrigin 
keyPath changes with the new method [animator setWantsPeriodicFramesUpdates:YES]
2016-11-07 22:20:55 +01:00
Maik Opitz d94e5480c9 Merge branch 'fix-RegEx' of https://github.com/HTPC-Schrauber/cappuccino into fix-RegEx 2016-11-03 12:42:05 +00:00
Maik Opitz a5c8e87e6d Removed mistaken triplequotes 2016-11-03 12:33:39 +00:00
Maik Opitz 08f74201b6 RegEx angepasst 2016-11-02 16:21:03 +00:00
Maik Opitz 3a25c683b6 Regex nochmals angepasst 2016-11-02 16:48:10 +01:00
Maik Opitz fb43f8bf1a Regex nochmals angepasst 2016-11-02 16:45:01 +01:00
Maik Opitz bf082600c3 fixed RegEx with newer gcc versions 2016-11-01 15:46:40 +01:00
David Richardson 7596c66703 Fix CPBox drawing artifacts when used in CPSeparator mode
Suppress title positioning when CPBox used as a line or separator - by definition the title is null.
2016-10-31 16:21:46 -06:00
Didier Korthoudt e1bcf6c47e Merge remote-tracking branch 'cappuccino/master' 2016-10-31 16:11:38 +01:00
Alexander Ljungberg ef1d6c78ac Merge branch 'master' of github.com:cappuccino/cappuccino 2016-10-30 21:06:25 +00:00
Alexander Ljungberg f36406af08 Text tweak. 2016-10-30 21:05:54 +00:00
Alexandre WilhelmandGitHub 4b7d215d9d Merge pull request #2498 from daboe01/fixed--font-can-be-nil
Fixed:  font can be nil sometimes
2016-10-30 13:52:03 -07:00
daboe01 e09f12dc0b fixed: accessors for _font were not used sometimes 2016-10-26 19:58:21 +02:00
daboe01 efa7406741 fixed: typing font was nil in sometimes cib-generated textviews 2016-10-26 19:53:59 +02:00
daboe01 5a2181c064 Merge remote-tracking branch 'cappuccino/master' 2016-10-26 19:51:22 +02:00
cacaodev dda81b12da Revert "nib2cib: discard warnings in the nib file."
This reverts commit 4e11152e76.
2016-10-22 08:40:38 +02:00
Martin CarlbergandGitHub c4bf67d133 Merge pull request #2496 from cacaodev/cptabview-initial-selection
Fixed: CPTabView should not allow empty selection
2016-10-21 18:16:31 +02:00
daboe01 f355c8679d Merge remote-tracking branch 'cappuccino/master' 2016-10-21 17:38:56 +02:00
cacaodev 095864de39 Fixed: CPTabView should not allow empty selection
Before this commit, a tab view could have an empty selection with the
following circumstances:
- The tab view was not created in IB
- the Tab View selection had not binding management

With test.
2016-10-21 10:13:47 +02:00
cacaodevandGitHub 0eb196e852 CPTabView: load tab view items asynchronously when possible (#2479)
When an item created with +tabViewItemWithViewController:, the view is loaded asynchronously

Manual test CPTabViewNib have been modified to show a tab view item
managed by a view controller. Any setup happens in
-viewDidAppear: because we cannot use any more the
tabView:didSelectTabViewItem: delegate method.
2016-10-20 17:24:18 +02:00
cacaodevandGitHub 62e5d8d841 Fixed: type declaration 2016-10-20 08:48:01 +02:00
cacaodevandGitHub 2f82fb842d Merge pull request #2495 from daboe01/fixed--typo-in-CPControl-comment
Fixed:  typo in CPControl comment
2016-10-19 08:37:27 +02:00
daboe01 f9fa6abbad fixed: small typo in comment 2016-10-18 21:46:21 +02:00
cacaodevandGitHub 4b55a69150 Merge pull request #2447 from cacaodev/CPAnimationContext-fixes
Fixed: The animation was reverting back to its initial position.
Fixed: custom layout and custom drawing was not animated in Chrome and Firefox.
2016-10-17 22:01:15 +02:00
Martin CarlbergandGitHub 42e12fae24 Merge pull request #2485 from cacaodev/ibtool-warnings
nib2cib: discard warnings in the nib file.
2016-10-17 18:07:59 +02:00
daboe01andcacaodev 2f55d5130a fixed: typo in accessor setHorizontallyResizable: (#2494) 2016-10-16 21:24:30 +02:00
daboe01 cd4b47b397 Merge remote-tracking branch 'cappuccino/master' 2016-10-16 13:20:13 +02:00
daboe01andcacaodev 126cba1e94 Fixed: textsizing was wrong in safari (#2486)
* fixed: color panel creation in font panel init did break text sizing in safari

* fixed: font sizing did not robustly work on safari

* removal of dead code

* fixed: browser sniffing was not using the mechanisms from CPCompatibility.j

* fixed: blink and webkit engines must not be mutually exclusive

* improved documentation
2016-10-16 10:11:10 +02:00
daboe01 e4e894fa54 Merge remote-tracking branch 'cappuccino/master' 2016-10-15 17:10:59 +02:00
Martin CarlbergandGitHub 65f701d459 Merge pull request #2487 from daboe01/fixed--CPTextView-did-not-support-dragging-the-selection
Fixed: CPTextView did not support dragging the selection
2016-10-13 17:22:51 +02:00
Martin CarlbergandGitHub c2b7cc7964 Merge pull request #2302 from ahankinson/fix-cpview-formatting
Formatting: CPView
2016-10-13 16:55:46 +02:00
Martin CarlbergandGitHub 969d1dff2a Merge pull request #2492 from didierkorthoudt/cpview-updateTA-recursive-bug
Fixed: CPView setFrameSize was calling _updateTrackingAreas too often + empty overlappingTA test
2016-10-13 16:07:10 +02:00
Didier Korthoudt e0fab808b9 fix-overlappingTA-could-be-empty 2016-10-08 17:33:21 +02:00
Didier Korthoudt 77031d7082 Fixed: setFrameSize was calling _updateTrackingAreas too often 2016-10-06 22:54:32 +02:00
Didier Korthoudt 5a0f7ea706 Merge remote-tracking branch 'cappuccino/master' 2016-10-06 20:25:25 +02:00
daboe01 9d041c4b62 fixed: unnecessary safety margin for dragview width 2016-10-02 21:28:38 +02:00
daboe01 ec4d29c327 fixed: transaction issue from the undo manager 2016-10-02 10:34:30 +02:00
daboe01 5f8d8988e3 revert: move drag indicator uncoditionally to the right side 2016-10-01 20:21:52 +02:00
daboe01 a31912f710 fixed: insertion marker was off by one 2016-10-01 20:11:25 +02:00
daboe01 e0d42962e7 fixed: wrapping issue when dragging last word 2016-10-01 19:56:35 +02:00
daboe01 47688bf016 formatting 2016-10-01 18:32:19 +02:00
daboe01 39a695959d formatting 2016-10-01 18:29:47 +02:00
daboe01 71d45a67b7 fixed: dragging placeholder did not always look like dragged text 2016-10-01 18:28:44 +02:00
daboe01 8dc1369ba3 fixed: direct DOM manipulation on drag placeholder instead of using capp methods + formatting 2016-09-30 16:03:36 +02:00
daboe01 1206654d98 fixed: drag placeholder was CPTextField instead of CPTextView 2016-09-29 15:41:46 +02:00
daboe01 1492763d0c fixed: par issue in rtf parser 2016-09-28 20:55:30 +02:00
daboe01 285fafc464 rtf parser fix + formatting 2016-09-28 20:34:46 +02:00
daboe01 b15cc59b95 prettify drag placeholder 2016-09-28 19:42:59 +02:00
daboe01 55cfe31dfe fixed: selection did not work directly after aborted drag 2016-09-28 17:36:28 +02:00
daboe01 dafa6e0310 fixed: space escape was missed for rich text pasting 2016-09-28 17:31:39 +02:00
daboe01 4befe17cab fixed: target index in selection dragging was sometimes wrong 2016-09-28 17:24:39 +02:00
daboe01 2217b560cb formatting 2016-09-28 16:21:55 +02:00
daboe01 39d01a1da8 sizing correction for dragging 2016-09-28 16:15:31 +02:00
daboe01 4e14ad7821 basic support of text selection dragging 2016-09-28 15:12:26 +02:00
daboe01 aee5a2cbe4 refactor point conversion to private method _characterIndexFromEvent 2016-09-28 11:55:56 +02:00
daboe01 de2d5aec1a Merge remote-tracking branch 'cappuccino/master' 2016-09-27 19:34:06 +02:00
Martin CarlbergandGitHub bea03de562 Merge pull request #2068 from daboe01/NEW--CPTextView
New: CPTextView, CPTextStorage, CPTextContainer, CPLayoutManager and CPSimpleTypesetter + CPFontPanel + RTF parser/producer [+2]
2016-09-26 09:53:29 +02:00
Martin CarlbergandGitHub 0aeccbb02c Merge pull request #2462 from daboe01/pasteboard-type-fix
fixed: cappuccino pasteboad is always clobbered by system pasteboard
2016-09-26 09:49:41 +02:00
cacaodev 4e11152e76 nib2cib: discard warnings in the nib file. 2016-09-26 09:44:23 +02:00
Alexandre WilhelmandGitHub 5059028e8a Merge pull request #2484 from daboe01/fixed--documentation-of-autoscroll--was-missing
Fixed:  documentation of autoscroll:  was missing
2016-09-25 13:00:21 -07:00
daboe01 070e6cf848 fixed: documentation of autoscroll: was missing 2016-09-24 17:04:12 +02:00
daboe01 4187fe7261 Merge remote-tracking branch 'cappuccino/master' 2016-09-17 17:07:44 +02:00
daboe01 bdec147874 formatting 2016-09-17 16:34:39 +02:00
daboe01 189fc76dad fixed: highspeed typing issue 2016-09-16 23:59:09 +02:00
daboe01 c0a68005d4 fixed: native rich pasting was not working robustly enough in chrome 2016-09-16 23:09:54 +02:00
daboe01 8187e4cdc2 formatting 2016-09-16 19:22:13 +02:00
daboe01 cc98fd4167 fixed: keystroke duplication when shift is pressed immediately after 2016-09-16 19:21:12 +02:00
daboe01 422e014eff fixed ^a and ^e semantics 2016-09-16 18:32:14 +02:00
daboe01 dd4e044608 fixed: various tab related line height issues 2016-09-15 22:26:20 +02:00
daboe01 13fad1ca47 fixed regression: line spacing was odd when small line followed large line 2016-09-15 20:25:28 +02:00
daboe01 70aaa29016 removal of dead code 2016-09-14 22:38:50 +02:00
daboe01 7dcec9afcf fixed: infinite loop due to undo edge case 2016-09-14 22:20:33 +02:00
daboe01 608642fc25 formatting 2016-09-14 22:18:52 +02:00
cacaodevandGitHub dd62c08b09 FIXED: Fix a build error in XcodeCapp (#2480) 2016-09-09 21:03:17 +02:00
daboe01 315fc21eca fixed: setFrameSize: was iterating every character 2016-09-09 21:00:22 +02:00
daboe01 8cfd3aeda9 fixed: sizing cache was not set up correctly 2016-09-09 20:31:53 +02:00
cacaodevandGitHub 6061323c36 Test CPSegmentedControl enabled state (#2481) 2016-09-07 20:56:49 +02:00
cacaodev 17da8b04bf Remove references to CPAnimationTriggerOrderIn 2016-09-05 21:43:54 +02:00
daboe01 3a948406d5 optimisation: _indexOfObject used a method call instead of js property 2016-09-03 10:00:24 +02:00
daboe01 91c52f8ec8 Merge remote-tracking branch 'cappuccino/master' into NEW--CPTextView 2016-09-03 09:40:49 +02:00
daboe01 6076bbb554 Fixed: CPRange was not copied before altering its content 2016-09-02 19:50:57 +02:00
daboe01 f70d3359c4 removed: temporary debugging code 2016-09-01 21:46:41 +02:00
daboe01 2dbfbe36c3 fixed: lineheight and base wrap issue 2016-09-01 21:45:12 +02:00
daboe01 a25bd03566 fixed: container switch semantics 2016-09-01 20:37:35 +02:00
daboe01 109da1c2cc fixed: typsetting the paragraph geometry was not as fast as it could be 2016-09-01 20:08:34 +02:00
daboe01 9a48e25bb1 fixed: container geometry was not cached appropriately 2016-09-01 14:48:51 +02:00
daboe01 a3ade200a9 fixed: textContainers were not cached appropriately 2016-09-01 14:43:10 +02:00
daboe01 eb1901f03d fixed: comparison was not using the characterCode 2016-09-01 13:50:46 +02:00
daboe01 f8c7cdfc28 typesetter optimization: use integer constants instead of strings 2016-09-01 13:31:40 +02:00
daboe01 ea58d84b55 fixed: text sizing was slower than it should be
thanks mrcarlberg for spotting this
2016-09-01 13:25:12 +02:00
Martin CarlbergandGitHub 1360caaa81 Merge pull request #2467 from daboe01/tableview-cell-editing-fix-2-take
Fixed: tableview corruption when clicking on a cell-based control during an editing session
2016-09-01 06:08:14 +02:00
Alexandre WilhelmandGitHub 315a7b9e6a Merge pull request #2476 from daboe01/New-CGContextText
fixed: CoreGraphics does not have basic text drawing support
2016-08-30 17:43:55 -06:00
daboe01 79311d107b fixed: line fragements were searched linearly instead of using binary search 2016-08-27 22:54:09 +02:00
daboe01 77435fcbd7 fixed: void scanning for fragments during typesetting 2016-08-27 14:25:44 +02:00
Alexander Ljungberg 4395c07648 Merge branch 'fix-mobile-text-entry' 2016-08-25 13:28:29 +01:00
Martin CarlbergandGitHub f9cc77382a Merge pull request #2475 from daboe01/daboe01-readme-fix
Fixed: missing requirements for developers...
2016-08-24 16:45:19 +02:00
Martin CarlbergandGitHub e4fce08eff Merge pull request #2477 from daboe01/setTimeout-scrolling-fix
fixed: scrolling events are missed on slower maschines in chrome 52
2016-08-24 16:23:56 +02:00
Alexander Ljungberg 47196cbc55 Typos. 2016-08-19 14:57:57 +01:00
Alexander Ljungberg c0bf301434 Test: full manual test for the iOS hit test bug. 2016-08-19 14:35:44 +01:00
Alexander Ljungberg f6671f8561 Fixed: iOS virtual keyboard broke hit tests.
Without this fix, tapping on the screen while the virtual keyboard of iOS was open, and it had forced scrolling (due to the input being low on the screen), would cause incorrect mouse event locations. So you might tap on a text field below your current field to edit it and something entirely different would get selected.
2016-08-19 14:35:19 +01:00
Alexander Ljungberg 26aab2961b New: iOS Safari virtual keyboard "Done" button support.
Without this change, clicking the done button in iOS Safari would dismiss the virtual keyboard but then it would immediately come back (as we forced a refocus).

The fix is to no longer force a refocus since it turns out we don't need to anymore given another previous fix.
2016-08-19 13:07:43 +01:00
Alexander Ljungberg c233abe3a4 New: -CPEvent subtype. 2016-08-19 12:45:41 +01:00
Alexander Ljungberg beb3646bef New: test which demonstrates a hit test bug in iOS Safari. 2016-08-19 01:15:12 +01:00
Alexander Ljungberg eb8330a420 New: test which demonstrates an iOS virtual keyboard bug. 2016-08-18 23:53:25 +01:00
Alexander Ljungberg 7f3c2176f8 Fix typos. 2016-08-18 23:52:10 +01:00
Alexander Ljungberg 1d0fdd68f4 Formatting. 2016-08-18 23:51:35 +01:00
daboe01 b26c78828e make manual test more explicit 2016-08-17 21:16:16 +02:00
daboe01 85648c7f11 fixed: manual test was missing 2016-08-17 20:10:02 +02:00
daboe01 8588f446aa formatting 2016-08-17 19:17:47 +02:00
daboe01 d723c5c1c7 formatting 2016-08-17 19:16:57 +02:00
daboe01 7897f2489c fixed: setString: altered selection 2016-08-17 19:15:41 +02:00
daboe01 86e2e0a2c3 minor rewording 2016-08-17 19:06:20 +02:00
daboe01 e2349019a3 minor rewording 2016-08-17 19:05:04 +02:00
daboe01 e485044cfb remove mentioning of gcc and clang dependencies 2016-08-17 19:02:34 +02:00
daboe01 72d80e2857 fixed: scrolling events were missed on slower maschines in chrome 52 2016-08-16 20:53:49 +02:00
daboe01 79a4733698 fixed: CoreGraphics does not have basic text drawing support 2016-08-16 20:30:42 +02:00
daboe01 c64e1daa99 minor rewording 2016-08-15 21:21:53 +02:00
daboe01 d6b4933b05 Merge remote-tracking branch 'origin/daboe01-readme-fix' into daboe01-readme-fix
# Conflicts:
#	README.markdown
2016-08-15 21:20:48 +02:00
daboe01 bcf9cee0f8 more details and compiler dependencies 2016-08-15 21:20:19 +02:00
Alexander Ljungberg a2960a7997 Merge pull request #2463 from daboe01/cppasteboad-cleanup
CPPasteboad.j removal of dead code
2016-08-15 14:50:04 +01:00
daboe01andGitHub dac9874895 minor rewording 2016-08-12 17:16:52 +02:00
daboe01andGitHub a4d374ecb6 Fixed: missing requirements for developers...
... in README.markdown
2016-08-12 16:43:42 +02:00
Alexander Ljungberg 3e56c8ed8b Fixed: XcodeCapp nib2cib incorrect vs jake release.
This bug is similar to the previous one in that the effect was the same. If XcodeCapp was used to `nib2cib`, the `NSClasses` setting would be ignored.

The reason for this, apart from the previous bug, was that `nib2cib` needs to be run from the project folder in order to find the main `Info.plist` file.

The fix is to change the CWD to the project folder before building.
2016-08-10 13:23:01 +01:00
Alexander Ljungberg f4c11d14e7 Fixed: nib2cib'ed files different with jake release and jake deploy.
Without this fix, if you ran `nib2cib` on its own on your UI files you could get a different result than what `jake release` or `jake deploy` would produce. In particular the `NSClasses` setting would be ignored unless `jake release` was used.

The reason for this bug was that the main bundle was never loaded and so the `Info.plist` was not read. But when using `jake release` (and deploy) the main bundle and the `Info.plist` gets baked in so it's always automatically loaded.

The fix is to load the main bundle before checking its settings.
2016-08-10 13:22:04 +01:00
Alexander Ljungberg dde805931d New: show successfully loaded NSClasses in nib2cib verbose.
It's helpful to see which ones are loaded when troubleshooting nib2cib.
2016-08-10 13:22:04 +01:00
Alexandre WilhelmandGitHub fedc721432 Merge pull request #2439 from cacaodev/CPView-viewDidAppear
NEW: CPViewController -viewWill/DidAppear & viewWill/didDisappear
2016-08-09 23:06:10 -07:00
Alexandre WilhelmandGitHub b09cb24804 Merge pull request #2473 from enquora/capp
Move XcodeCapp 'Preferences' menuItem to standard position
2016-08-09 22:54:39 -07:00
Alexandre WilhelmandGitHub 80bfeb1a29 Merge pull request #2470 from daboe01/remove-rakefile
Fixed: obsolete file in root directory
2016-08-09 22:54:00 -07:00
David Richardson 63ad51a637 Move XcodeCapp 'Preferences' menuItem to standard position 2016-08-09 11:33:45 -06:00
daboe01 5ee6232bfc fixed: unused file in the root directory 2016-08-05 12:47:49 +02:00
daboe01 b7d399faf7 fixed: bold and italic extraction from dom for native paste 2016-08-01 09:17:05 +02:00
daboe01 28691bb8a0 improved formatting extraction from the dom in native paste operations 2016-08-01 08:50:24 +02:00
daboe01 fd61f35f78 fixed: rtf-color table was not written 2016-07-29 18:49:38 +02:00
daboe01 0505b59781 formatting 2016-07-29 17:32:48 +02:00
daboe01 a3601e5167 preparations for native rich paste 2016-07-29 17:31:40 +02:00
daboe01 99f63ab64d fixed: are double typing issue in webkit browsers 2016-07-29 16:28:17 +02:00
daboe01 bb2a9fe180 formatting 2016-07-24 17:45:26 +02:00
daboe01 e9c7c7ee4c fixed: editing state was deleted after committing a non-text-control 2016-07-24 17:43:45 +02:00
daboe01 ff7d4f237a fixed: hitTest: had side effects 2016-07-24 17:03:00 +02:00
daboe01 8bf9f8057e Merge remote-tracking branch 'cappuccino/master' 2016-07-24 16:44:00 +02:00
daboe01 27b0f531d7 fixed: more support for RTF for Pages.app 2016-07-17 15:19:40 +02:00
daboe01 01e96d3086 fixed: Pages.app rtf did not parse correctly 2016-07-17 15:00:35 +02:00
daboe01 95e7a7c8eb fixed: wrong comparison (for proper null handling) 2016-07-17 07:53:53 +02:00
daboe01 bbc2f4766e fixed: one other reference to _stateUID 2016-07-17 07:33:21 +02:00
Alexandre WilhelmandGitHub 12dde5154f Merge pull request #2461 from cacaodev/CPView-viewDidHide
FIXED: CPView received multiple -viewDidHide/Unhide messages
2016-07-11 07:46:16 -07:00
Alexandre WilhelmandGitHub 5bc3609ad7 Merge pull request #2464 from daboe01/remove-nativehost
Remove nativehost
2016-07-09 19:14:29 -07:00
daboe01 5c1cdea3c6 Removed: Obsoleted Nativehost stuff 2016-07-08 21:34:14 +02:00
daboe01 3da5b3a278 fixed: entering return blocked the nativeinputmanager 2016-07-01 18:26:01 +02:00
daboe01 9f6460ddae prevent certain race conditions in deadkey handling in FF and safari 2016-06-30 19:45:09 +02:00
daboe01 f1dcf85d7b turned off logging in RTF parser 2016-06-26 21:33:17 +02:00
daboe01 7b78edf38f fixed: removed dead code from obsoleted native pasteboard approach 2016-06-26 18:35:25 +02:00
daboe01 4a726a0c75 Merge remote-tracking branch 'cappuccino/master' 2016-06-26 18:27:33 +02:00
daboe01 5afa7e9fc3 fixed: rtf parser did not propagate paragraph style sometimes 2016-06-26 17:05:19 +02:00
daboe01 75c102f304 fixed: rtf-producer colortable dead index issue 2016-06-25 21:23:35 +02:00
daboe01 68f3c10055 fixed: only one color was supported on the pasteboard 2016-06-25 20:49:56 +02:00
daboe01 e9aeda2a34 fixed: _RTFProducer was referencing wrong colortbl entries 2016-06-25 20:09:56 +02:00
daboe01 45c7a110b6 prevent blinking during cursor navigation more robustly 2016-06-22 22:04:10 +02:00
daboe01 e438e6aedb fixed: same pasteboardtype was used for plain and rich text 2016-06-22 20:39:41 +02:00
daboe01 8dd888bcbd fixed: native pasteboard unconditionally overwrites capp-pasteboard 2016-06-21 20:56:56 +02:00
cacaodev 5f12291ac4 Fixed: add missing import 2016-06-20 19:34:00 +02:00
daboe01 e206d78a52 removed unused range parameter from _characterRangeForIndex 2016-06-19 13:51:53 +02:00
daboe01 d94a82b0a7 paragraph selection dragging fix 2016-06-19 13:45:41 +02:00
daboe01 3bee3d1701 improved: paragraph selection via triple click 2016-06-18 22:51:41 +02:00
daboe01 631352e1ef improved FF deadkey detection 2016-06-18 20:36:22 +02:00
daboe01 f2d5dee49e backspace fix 2016-06-18 19:49:11 +02:00
daboe01 2d578c7cd9 Merge remote-tracking branch 'cappuccino/master' 2016-06-18 19:18:41 +02:00
daboe01 b07ff100d1 fixed: function is missing 2016-06-18 19:18:23 +02:00
daboe01 b0c10b2248 Merge remote-tracking branch 'cappuccino/master' into NEW--CPTextView 2016-06-18 19:17:53 +02:00
daboe01 7b8249442d selection fixes 2016-06-18 17:59:26 +02:00
cacaodev 8221339318 Style 2016-06-18 13:40:27 +02:00
cacaodev b773af96b8 FIXED : css display attribute was incorrectly set 2016-06-18 13:40:14 +02:00
daboe01 dbc7808c70 code simplification 2016-06-18 11:58:42 +02:00
daboe01 77c5000f16 selection fix 2016-06-18 11:47:47 +02:00
daboe01 56928b6ca0 formatting 2016-06-18 11:46:10 +02:00
daboe01 8178dfe7bd revert: fixed: word granularity selection was not always correct 2016-06-18 11:43:50 +02:00
daboe01 0db6c667c6 fixed: word granularity selection was not always correct 2016-06-18 11:40:12 +02:00
cacaodev 2b0a642827 FIXED: CPView received multiple -viewDidHide/Unhide messages
FIXED: when a view is hidden by a hidden superview and added to a non
hidden superview, the -viewDidUnhide message is sent.

With test : CPViewTest.j
2016-06-18 11:29:47 +02:00
daboe01 f71c0f8cb8 selection fixes 2016-06-18 11:25:02 +02:00
daboe01 3782372f65 optimisations for native input manager 2016-06-17 18:31:44 +02:00
daboe01 9e35e42030 nativeinputmanager optmisations for safari 2016-06-16 20:36:12 +02:00
daboe01 7a8195e54c fixed: cursor extended selections did not copy in safari 2016-06-15 22:55:48 +02:00
daboe01 b50ee28693 fixed: the native input manager did not get the focus after recent safari update 2016-06-15 20:52:55 +02:00
Martin CarlbergandGitHub e134f910aa Merge pull request #2436 from mrcarlberg/updated_compiler
Fixed: Merged in the parser and compiler that is used in the node objj-runtime
2016-06-14 21:32:28 +02:00
daboe01 17eb6e47eb improve wordBoundaryRegex to recognize numbers 2016-06-12 13:08:10 +02:00
cacaodev 82ce626d8a Underscore prefix on private methods 2016-06-12 10:52:19 +02:00
cacaodev e063ff5e54 Remove CPAnimationTriggerOrderIn partial support. Adds a warning if someone tries to use it. 2016-06-12 10:20:26 +02:00
cacaodev 5aa98966bc Cucapp test for CPView animation
Tests for commits #1, #2, #3 of this PR
2016-06-12 10:12:08 +02:00
cacaodev fca2746a82 Fixed: custom layout and custom drawing was not animated
The bug was appearing with the following conditions:
keypath : frame , frameSize
browsers : Google Chrome, Firefox
2016-06-12 10:12:08 +02:00
cacaodev 7faffc2de7 Use cancelAnimationFrame when available 2016-06-12 10:12:07 +02:00
cacaodev 86a8a9dc85 Fixed: The animation was reverting back to its initial position.
Although the fill-mode property was correctly set to forwards allowing
the final state to persist, the animation-name property was deleted too
early . It was causing the animation to be cancelled and the initial
state restored.
2016-06-12 10:12:07 +02:00
daboe01 c13a0c1c26 fixed: selection semantics differed from macos 2016-06-11 20:53:05 +02:00
daboe01 6ce3c070b8 fixed: selection semantics differed from macos 2016-06-11 20:42:39 +02:00
daboe01 e1cb11da22 fixed: double clicking right to a word selected too much in some cases 2016-06-11 17:16:06 +02:00
daboe01 c628ea34b7 formatting 2016-06-11 17:11:55 +02:00
daboe01 33b7c726f6 fixed: whitespace double-clicking resulted in cross-paragraph selection 2016-06-11 16:40:28 +02:00
daboe01 6f3fd424e1 fixed: umlaute were treated as word bounderies 2016-06-11 16:18:18 +02:00
daboe01 b048ce9c8e formatting 2016-06-09 22:46:59 +02:00
daboe01 6a1040d659 fixed: setTextColor: issue second take 2016-06-09 22:35:50 +02:00
daboe01 fc05c28231 fixed: change in model did not propagate resize 2016-06-09 20:54:09 +02:00
daboe01 5d165bc6df Merge remote-tracking branch 'cappuccino/master' 2016-06-09 19:22:25 +02:00
daboe01 c139b5eabb Merge remote-tracking branch 'cappuccino/master' into NEW--CPTextView 2016-06-09 19:20:38 +02:00
cacaodev d6dd0e551d Revert "FIXED: CPView received multiple -viewDidHide/Unhide messages"
This reverts commit e58420b031.
2016-06-09 10:13:21 +02:00
Alexandre Wilhelm a84a7bb7c3 Merge pull request #2460 from daboe01/fixed-colorpicker-brightness-bar
Fixed: brightness_bar.png was not displayed in CPColorPicker
2016-06-09 00:59:17 -07:00
daboe01 7195ae6e46 Merge remote-tracking branch 'cappuccino/master' into NEW--CPTextView 2016-06-08 20:05:31 +02:00
daboe01 3c70b2f033 fixed: brightness_bar.png was not displayed in CPColorPicker because the size was not initialized 2016-06-08 19:54:44 +02:00
daboe01 c46340a830 Merge remote-tracking branch 'cappuccino/master' into fixed-colorpicker-brightness-bar 2016-06-08 19:45:16 +02:00
daboe01 8d703b1459 fixed: updates to storage were not propageted to the view 2016-06-08 19:23:37 +02:00
Alexandre Wilhelm f1145ef169 Merge pull request #2457 from cacaodev/CPView-viewDidHide
FIXED: CPView received multiple -viewDidHide/Unhide messages
2016-06-07 20:21:52 -07:00
Alexandre Wilhelm a28f9ceeba Merge pull request #2456 from didierkorthoudt/Fixed--right-mouse-clic-during-a-drag-operation-problem
Fixed: right mouse clic during a drag operation cancels it
2016-06-07 20:17:31 -07:00
Alexandre Wilhelm 1927bb4798 Merge pull request #2452 from didierkorthoudt/CPTextField-tracking-area-optimization
Fixed: CPTextField doesn't optimize tracking areas management
2016-06-07 12:07:11 -07:00
daboe01 d4c77f9786 fixed: Setting textColor only changes first lines color 2016-06-07 20:54:11 +02:00
daboe01 021f8d0331 revert fixed: premature optimization 2016-06-05 22:23:26 +02:00
daboe01 e7d25550ee fixed: premature optimization 2016-06-05 22:21:01 +02:00
daboe01 8227276437 fixed: tabstops were accidentally cornercutting relayout 2016-06-05 21:20:50 +02:00
daboe01 38ef76bcdc fixed: fist tabstop was not working correctly 2016-06-02 20:19:00 +02:00
daboe01 7faa0f60b4 fixed: accidental duplication of variable definition 2016-05-28 13:40:30 +02:00
daboe01 faebbb2b8a fixed: font css properties were not considered when assessing visual identity 2016-05-27 23:13:54 +02:00
daboe01 bc9beb1e87 new: render to dom only the visible stuff 2016-05-27 21:24:30 +02:00
daboe01 f161f723d7 fixed: mimetype of rtf 2016-05-27 17:39:51 +02:00
daboe01 6c94550de3 fixed: accidental creation of a global variable 2016-05-27 17:25:19 +02:00
daboe01 b39a45781a fixed: accidental creation of a global variable 2016-05-27 17:23:30 +02:00
Alexandre Wilhelm 9273c9ee10 Merge pull request #2455 from didierkorthoudt/CPColorPanel-platform-window
Fixed: CPColorPanel always opens in main platform window.
2016-05-25 11:36:28 -07:00
daboe01 e6285914b0 Merge remote-tracking branch 'cappuccino/master' into NEW--CPTextView 2016-05-24 11:29:11 +02:00
daboe01 7d2eb83a1b fixed: undo support for fontpanel 2016-05-24 10:56:19 +02:00
daboe01 7e622f1153 undo color: fallback for textcolor 2016-05-24 10:44:09 +02:00
daboe01 9b30a634b1 formatting 2016-05-24 10:42:33 +02:00
daboe01 e897d2ef81 fixed: missing undo support for textcolor 2016-05-24 10:39:23 +02:00
daboe01 f5b177dda8 fixed: passing range directly instead of copy 2016-05-24 10:24:57 +02:00
daboe01 5f51b5d565 revert: no not make copy of range 2016-05-24 10:13:08 +02:00
daboe01 8d7753fb40 formatting 2016-05-24 09:07:41 +02:00
daboe01 4c6f5744d8 fixed: setFont semantics are wrong 2016-05-24 09:07:03 +02:00
daboe01 43eb2932ba fixed: textColor only changes first lines color 2016-05-23 21:42:25 +02:00
daboe01 59de0e7a4a fixed: text sizing did not work for javascript function names 2016-05-23 17:14:13 +02:00
cacaodev 7b204cf910 Documentation for CPViewController -view*Appear methods 2016-05-23 16:06:05 +02:00
cacaodev b587a19a0f NEW: CPViewController -viewWill/DidAppear & -viewWill/DidDisappear
When a view belonging to a CPViewController is hidden, unhidden, added
or removed, its viewController receives the appropriate message.

Added AppKit/CPViewControllerTest.
2016-05-23 16:06:04 +02:00
cacaodev e58420b031 FIXED: CPView received multiple -viewDidHide/Unhide messages
FIXED: when a view is hidden by a hidden superview and added to a non
hidden superview, the -viewDidUnhide message is sent.

With test : CPViewTest.j
2016-05-23 15:39:47 +02:00
Didier Korthoudt 24313d6709 Fixed: right mouse clic during a drag operation cancels it 2016-05-22 22:14:05 +02:00
daboe01 7acb30b981 fixed: text wrapping in textviews from nibs was wrong 2016-05-22 20:33:41 +02:00
Didier Korthoudt 7454620aa2 Fixed: color panel always open in main platform window 2016-05-18 19:43:19 +02:00
Alexandre Wilhelm abb0799817 Merge pull request #2453 from daboe01/tableview-autoscroll
enable autoscrolling for tableview columns
2016-05-18 10:13:36 -07:00
Didier Korthoudt aebd28dbef CPTextField and CPTrackingArea: optimization and cursor management. 2016-05-18 11:09:06 +02:00
daboe01 152db9fb8e fixed: autoscrolling message was commented out 2016-05-17 20:37:33 +02:00
daboe01 980cd520cd fix travis failure 2016-05-15 11:58:22 +02:00
daboe01 373ec8b5a1 Merge remote-tracking branch 'cappuccino/master' into NEW--CPTextView 2016-05-15 11:57:52 +02:00
daboe01 bacb78e9e8 move background color fallbacks to +themeAttributes 2016-05-15 11:51:44 +02:00
cacaodev 333e112e37 Fixed: CPPredicateEditor predicate when the template has a CPFloatAttributeType 2016-05-15 10:06:52 +02:00
Philippe Fuentesandcacaodev 818d5d782f Fixed: date comparisons in CPPredicateEditor (#2449)
CPPredicateEditorRowTemplate has been modified to allow a correct comparision of date objects when using the CPDateAttributeType
Before this correction, the predicate format was using a string representation of a date instead of a date object.
2016-05-14 23:16:10 +02:00
daboe01 8774090086 formatting 2016-05-14 16:27:01 +02:00
daboe01 0ca65c6d61 fix travis 2016-05-14 13:10:37 +02:00
cacaodev c38daac646 Test: test for pr #2449
In CPPredicateEditor, tests that the input predicate is equal to the
output when the right control is editable.
2016-05-14 10:00:44 +02:00
cacaodev c31f5b1d59 Fixed: CPPredicateEditor in OJTest
OJTest is reading theme attributes from the class default. In
CPPredicateEditor implementation, nil check an attribute and change the
default of another attribute to be non null.
2016-05-14 09:57:29 +02:00
daboe01 2320a56a63 revert travis test 2016-05-13 20:51:25 +02:00
daboe01 07bd91b456 travis test 2016-05-13 20:34:24 +02:00
daboe01 803f7c3a4b formatting 2016-05-13 19:39:30 +02:00
cacaodev a1926982c6 Fixed: make CPObject implementsSelector: work with proxies and KVO swizzled classes 2016-05-12 21:43:44 +02:00
daboe01 b3306d50eb move selection color to the themes 2016-05-12 20:17:14 +02:00
Alexandre Wilhelm 3e6e5f95ec Merge pull request #2448 from cacaodev/CPViewController-async
Fixed: CPViewController isViewLoaded property in async mode
2016-05-11 12:20:48 -07:00
daboe01 df71fb42ac remove duplicate code 2016-05-10 22:41:08 +02:00
daboe01 fe81a354a3 formatting 2016-05-10 22:28:35 +02:00
daboe01 67ba2e49c3 workaround for FF crash in very large documents 2016-05-10 22:27:21 +02:00
daboe01 8dec42f295 fix missing font panel in manual test of CPTextView 2016-05-10 20:35:16 +02:00
daboe01 5942553370 make selection handling more mac like 2016-05-10 19:40:27 +02:00
Martin Carlbergandcacaodev ae5d31746e Dependent key paths use a relationship (#2431)
Fixed: When dependent key paths use a relationship, only the first added observer will observe the attribute for the relationship object.

Also, an optimisation on when the willChange… chain is running, there is no need to replace the observers as no new values are set yet. That will be done when the didChange… chain is running.
2016-05-09 22:14:20 +02:00
cacaodev 1c1976abbf Simple cucapp test for the CPViewController isViewLoaded property in async mode 2016-05-09 09:45:18 +02:00
cacaodev b3465ddf89 Fixed: CPViewController -isViewLoaded property was always NO in async mode (loadViewWithCompletionHandler:).
The async mode calls the completionHandler whereas the sync mode calls the -viewDidLoad method.
Both are now run within the will/did change block of the isViewLoaded property.
2016-05-08 23:09:50 +02:00
Alexandre Wilhelm f67fafdb8e Merge pull request #2446 from cacaodev/CPCollectionView-fixes
CPCollectionView content binding & minor code refactor
2016-05-08 11:16:34 -07:00
cacaodev ffcac677e0 Fixed: Manual test SmartFoldersDemo
The sheet was not closing when asked.
2016-05-07 21:14:35 +02:00
cacaodev a9d643aa55 OJTest for CPCollectionView selectionIndexes, CPCollectionViewItem isSelected, CPSelectionIndexesBinding and CPContentBinding. 2016-05-03 21:51:10 +02:00
cacaodev fa3647e8e5 Refactor selection with modern code.
Handle out of range errors when reflecting selection.
2016-05-03 21:50:41 +02:00
cacaodev db839f6d6d Rename _lockResizing to _inLiveResize
_inLiveResize is a CPView flag.
2016-05-03 21:50:20 +02:00
cacaodev 3a85d5b89f CPCollectionView content binding support 2016-05-03 21:50:20 +02:00
cacaodev 1575c2bc10 CPTableView ViewBasedCib test app: a bug in CPBox decoding was crashing the app. Remove the box until this bug is fixed. 2016-05-03 19:09:32 +02:00
cacaodev 57189183d6 Merge pull request #2444 from cacaodev/fixed-deprecated-getPropertyCSSValue
FIXED: in CPAnimationContext, 'Unknown function getPropertyCSSValue' error in chrome
2016-04-24 13:24:12 +02:00
cacaodev 01c5cf98df FIXED: Unknown function getPropertyCSSValue in Chrome
getPropertyCSSValue have been deprecated in chrome. Replacing with
getPropertyValue supported by all browsers.
2016-04-23 10:54:22 +02:00
Martin Carlberg 9ad2995168 Fixed: Some Javascript minifiers will convert ”\u2028” to a string with the actual line separator inside. It is not valid Javascript to have the actual character inside a string literal.
Instead of fixing bugs in different minifiers it is easier to rewrite this small function. The same applies to \u2029
2016-04-07 10:32:47 +02:00
Martin Carlberg 51fc6518e1 Fixed: Removed some trailing white spaces 2016-04-07 10:32:46 +02:00
Martin Carlberg 530db4e904 Fixed: Merged in the same parser and compiler that is used in the objj-runtime that is running on node.
The life will be easier to have the same in both environments.
Warnings and errors now don’t use read only properties for line and column information. So the test cases in Toolstest.j now work in modern JS engines.
It is also easier to set options for the compiler.
2016-04-07 10:32:46 +02:00
Alexandre Wilhelm cd92ebd69c Merge pull request #2437 from mrcarlberg/cpobjectcontroller_set_entity_name_from_code
Fixed: Setting entity name from code does not work
2016-04-06 18:15:23 -07:00
Alexandre Wilhelm 5c58552d91 Merge pull request #2438 from mrcarlberg/cppopupbutton_binding_select_is_done_before_content
Fixed: First popup item is always selected if selected binding value is set before content binding value
2016-04-06 18:14:53 -07:00
Antoine Mercadal 584aebf76b FIXED: used the master of cappuccino-base 2016-04-06 09:55:38 -07:00
Antoine Mercadal 43a2480699 Merge pull request #2430 from herbatnik/master
FIXED: Cursor key binding methods do not fire in IE11 #2365
2016-04-06 08:35:14 -07:00
Martin Carlberg 699503042f Fixed: First item is always selected if selected binding value is set before content binding value.
Test case is provided.
2016-04-05 23:22:29 +02:00
Martin Carlberg 02e71c23de Merge branch 'master' of https://github.com/cappuccino/cappuccino 2016-04-05 23:12:07 +02:00
Martin Carlberg c24c3868bb Merge pull request #2434 from Dogild/TrackingAreaTableViewHeader
Fixed: crash when having a CPTableViewHeader without a CPTableView
2016-04-05 19:49:27 +02:00
Martin Carlberg 5c60819668 Merge pull request #2432 from Dogild/CacheURLRequest
Fixed: cache control was not set properly in CPURLRequest
2016-04-05 19:05:59 +02:00
Martin Carlberg 480a125a20 Fixed: When setting entity name from code the _managedProxy will be null and the name will not be stored 2016-04-05 18:43:32 +02:00
Antoine Mercadal 598a6ebaed Merge pull request #2278 from cacaodev/CPAnimationContext
Animations: CPAnimationContext & animator
2016-04-04 09:57:55 -07:00
Alexandre Wilhelm 185ad5e747 Fixed: crash when having a CPTableViewHeader without a CPTableView
Previously, when having a CPTableViewHeader without a CPTableView, cappuccino just crashed.
We now check if _tableView is set before iterating on the tableview's columns.
2016-04-04 06:48:26 -07:00
Alexander Ljungberg 42d7e4312b Formatting of CPCache. 2016-04-02 01:20:23 +01:00
Alexander Ljungberg 41a741724f New: Sweden / Swedish as a possible locale. 2016-04-01 23:47:13 +01:00
Alexander Ljungberg 087e811586 Bump XcodeCapp copyright year. 2016-04-01 22:44:23 +01:00
Alexander Ljungberg fa07bc143e Fixed: missed some version number bumps in the 0.9.9 release. 2016-04-01 22:25:21 +01:00
Alexander Ljungberg e13f5ed730 Fixed: CPNumber intValue did not return an integer.
We expect this method to return a whole number like in Objective-C. This also goes for the related methods, `shortValue`, `longValue` and `longLongValue`.

Also adds more tests (in addition to the existing, already failing test).
2016-04-01 22:22:03 +01:00
Alexander Ljungberg 48108cebc9 Merge branch '0.9.9' 2016-04-01 01:05:40 +02:00
Alexander Ljungberg ecac17a00a This will be Cappuccino 0.9.9. 2016-03-29 23:32:12 +01:00
Alexandre Wilhelm 3ba215887c Merge pull request #2426 from mrcarlberg/source_url_fix
Fixed: //@ sourceURL=... is deprecated since many years ago.
2016-03-28 23:43:45 -07:00
Alexandre Wilhelm edbc1baf32 Merge pull request #2427 from cacaodev/cpbutton-image-scaling
NEW: nib2cib support for CPButton -imageScaling.
2016-03-28 23:43:22 -07:00
Alexandre Wilhelm 500fa7f314 Fixed: cache control was not set properly in CPURLRequest 2016-03-28 23:32:48 -07:00
Alexandre Wilhelm a10dfa4ab4 Merge pull request #2429 from mrcarlberg/integer_value
Fixed: Added ’integerValue’ method for CPNumber and CPString.
2016-03-27 09:20:12 -07:00
Martin Carlberg b208571ed7 Fixed: Formatting 2016-03-23 10:17:15 +01:00
Martin Carlberg c1ec27045c Fixed: Rhino does not support numbers starting with ’0’ 2016-03-23 09:35:19 +01:00
Martin Carlberg 111b12161c Added: test cases for ’intValue’ and ’integerValue’ methods on CPString and CPNumber 2016-03-23 09:02:09 +01:00
daboe01 d23d18933c altgr fix for recent FF 2016-03-22 20:39:28 +01:00
Marek Kresnicki f0e736962d FIXED: Cursor key binding methods do not fire in IE11 #2365 2016-03-21 11:23:51 +00:00
Alexandre Wilhelm b12d1491d4 Merge pull request #2415 from cacaodev/CPViewController-loadviewAsynchronously
NEW: CPViewController -loadViewAsynchronously:(Function/*view, error*/)
2016-03-20 19:40:20 -07:00
Alexandre Wilhelm 6d1a094b15 Merge pull request #2428 from cacaodev/CPSearchField-indentationLevel
CPSearchField: use CPMenuItem -setIndentationLevel:
2016-03-20 19:35:48 -07:00
daboe01 88d14792a4 do not select all on setString 2016-03-20 20:29:16 +01:00
Martin Carlberg 7780a98abe Fixed: Added ’integerValue’ method for CPNumber and CPString.
This makes the classes more compliant to Cocoa
2016-03-15 22:25:10 +01:00
cacaodev a1248db3e7 CPSearchField: use CPMenuItem -setIndentationLevel: now that it's available. 2016-03-13 16:09:27 +01:00
cacaodev 6fd2d12d3f Merge remote-tracking branch 'cappuccino/master' into CPAnimationContext 2016-03-12 23:29:46 +01:00
cacaodev 9fab52c044 NEW: nib2cib support for CPButton -imageScaling. With manual test CPButtonTest. Fixes #2425. 2016-03-12 22:18:46 +01:00
daboe01 a32f55d64e add fontpanel to manual test 2016-03-09 19:55:50 +01:00
Aparajita Fishman 96d2b001ea Merge branch 'tableview-edit-fix' 2016-03-08 15:04:55 -08:00
Martin Carlberg e38d6c9f9e Fixed: //@ sourceURL=... is deprecated since many years ago.
We have not changed it for support of older browsers.
Chrome version 51 and above writes a warning about it
in the console so it is time now.
2016-03-07 13:44:29 +01:00
Alexandre Wilhelm be129d243b Fixed: refactoring of CPTextView 2016-03-06 21:48:42 -08:00
Alexandre Wilhelm c85355986b Fixed: manual merged with master 2016-03-06 18:47:58 -08:00
Alexandre Wilhelm 310c0e8379 Merge pull request #2423 from mrcarlberg/cpobject_controller_extension
Allow CPObjectController to get more attributes from the xib/cib file.
2016-03-06 18:20:51 -08:00
Martin Carlberg f0dbffe4f8 Fixed: Formatting 2016-03-06 11:14:22 +01:00
Alexandre Wilhelm 598a482538 New: added gitter badge in the README 2016-03-05 13:38:23 -08:00
Alexandre Wilhelm a995f3ab52 Merge pull request #2424 from mrcarlberg/invalid_plist_fix
Does not throw exception if plist is not valid. It will return nil instead
2016-03-05 13:32:15 -08:00
Martin Carlberg ec5454de44 Merge branch 'cpobject_controller_extension' 2016-03-03 15:09:10 +01:00
Martin Carlberg ec55bddbd4 Fixed: Does not throw exception if plist is not valid. It will return nil instead. 2016-03-01 21:45:08 +01:00
Martin Carlberg 808591df56 Fixed: Allow CPObjectController to get more attributes from the xib/cib file. 2016-03-01 21:40:00 +01:00
Alexandre Wilhelm 96ae3da1e0 Merge pull request #2412 from cacaodev/CPArray-arrayByApplyingBlock-replace
Replace loops with the new -arrayByApplyingBlock: method
2016-02-18 20:25:24 -08:00
Alexandre Wilhelm 4f13df69c7 Merge pull request #2419 from Dogild/cappuccino-test-launched
Test: some manual tests were broken
2016-02-18 20:24:36 -08:00
Alexandre Wilhelm 6d305e4a84 Test: some manual tests were broken
This PR fixes the manual tests. We can no launch every manual tests of Cappuccino...
2016-02-13 11:36:42 -08:00
cacaodev d3dab982a1 Remove ignored argument _ in CPColorPanel 2016-02-07 11:54:16 +01:00
cacaodev 2f6adbae3c Documentation for -loadViewWithCompletionHandler:
Also clarified a note in -loadView doc.
2016-02-07 11:19:26 +01:00
cacaodev ccdc1eed5a Rename to loadViewWithCompletionHandler: 2016-02-07 11:17:53 +01:00
cacaodev 65dee154f7 Remove ignored argument _ 2016-02-06 20:39:49 +01:00
Alexandre Wilhelm 662db009de Merge pull request #2418 from mrcarlberg/build_with_space_in_path
Fixed: Allow build in directory with space in path
2016-02-05 12:05:35 -06:00
cacaodev d07d8f6857 _CPBlockExpression: replace loops with arrayByApplyingBlock: method 2016-02-04 21:51:37 +01:00
cacaodev 0327f6b1ea Merge remote-tracking branch 'cappuccino/master' into CPArray-arrayByApplyingBlock-replace 2016-02-04 21:46:10 +01:00
Martin Carlberg 16dea2ee09 Fixed: Allow build in directory with space in path 2016-02-03 17:26:24 +01:00
Alexandre Wilhelm 5e3fe139fc Fixed: @cappuccino is now a link in the README... 2016-02-02 13:05:46 -08:00
Alexandre Wilhelm 55d41fca05 New: added twitter account in the READMA 2016-02-02 13:05:01 -08:00
daboe01 0b7bb29557 setString selection fix 2016-01-26 19:16:12 +01:00
cacaodev 6b683bd02d Merge pull request #2402 from cacaodev/CPExpression-constructors
NEW : CPExpression +expressionForBlock:arguments:
                                   +expressionForConditional:trueExpression:falseExpression:
2016-01-25 10:22:18 +01:00
daboe01 8f1a498953 added credits to andrew 2016-01-24 15:33:21 +01:00
daboe01 293ed9065d fix chrome duplicate key inserts cursor 2016-01-24 15:24:12 +01:00
Aparajita Fishman 8908fb7ee0 Merge pull request #2414 from didierkorthoudt/CPTrackingArea-fixes2
FIXED: CPTrackingArea incorrect handling of view hierarchy updates while processing events
2016-01-23 07:02:03 -08:00
Didier Korthoudt 2877178b34 Formatting: following Aparajita's recommandations 2016-01-21 20:46:37 +01:00
Antoine Mercadal d527139f48 Merge pull request #2416 from didierkorthoudt/CPBox-contentView-incorrect-initWithCoder
FIXED: CPBox contentView incorrect initWithCoder
2016-01-20 15:11:37 -08:00
Didier Korthoudt b3d8180541 FORMATTING: added comment to workaround 2016-01-21 00:10:38 +01:00
Didier Korthoudt 3411c340ab FIXED: incorrect view hierarchy update 2016-01-20 23:50:22 +01:00
Didier Korthoudt 4482089712 FIXED: corrected replaceSubview parameters order 2016-01-20 22:08:10 +01:00
Didier Korthoudt c8ce2343d7 Merge remote-tracking branch 'cappuccino/master' 2016-01-20 21:43:35 +01:00
cacaodev d547d04277 NEW: CPViewController -loadViewAsynchronously:(Function/*view, error*/)
with manual test CPViewControllerTest
2016-01-20 11:54:02 +01:00
Aparajita Fishman 8f1191733b Fixed race condition when editing table cells
Previously, when double-clicking on a table cell to edit it, there was a possibility of a race condition. A refresh of the display was requested, then the run loop was passed through once. But it was possible for the display refresh to not be queued when the run loop was passed through, in which case the refresh would cancel the editing. Or at least I think that's what was happening.  ;-)

This commit (hopefully) eliminates the race condition by synchronously refreshing the layout and display.

Made some miscellaneous formatting fixes as well.
2016-01-19 23:12:11 -08:00
Antoine Mercadal 00bdbcf857 FIXED: only set a content view of CPBox if it is not a separator 2016-01-19 16:10:31 -08:00
Antoine Mercadal bf8070c42d Revert "FIXED: Bug introduced by https://github.com/cappuccino/cappuccino/commit/9fba72cbab42145dc585c01efd82ce645373c04e#diff-227ef108401c2160357ae3fc65018c65R620"
This reverts commit ad48381744.
2016-01-19 16:08:59 -08:00
Antoine Mercadal 346a0b84ae Merge branch 'master' of https://github.com/cappuccino/cappuccino 2016-01-19 13:28:17 -08:00
Antoine Mercadal ad48381744 FIXED: Bug introduced by https://github.com/cappuccino/cappuccino/commit/9fba72cbab42145dc585c01efd82ce645373c04e#diff-227ef108401c2160357ae3fc65018c65R620
The changes in CPBox were messing with the subviews encoding. This patch restores the previous behavior of CPBox.
The original bug might be reintroduced, but this was definitly not the good solution
2016-01-19 13:26:10 -08:00
Didier Korthoudt 0f30d7744d FIXED: CPTrackingArea incorrect handling of view hierarchy updates while processing events 2016-01-19 07:07:45 +01:00
cacaodev 095a978120 Replace loops with arrayByApplyingBlock: 2016-01-17 20:54:43 +01:00
cacaodev 1b72646772 Style: remove tabs 2016-01-17 20:54:20 +01:00
Didier Korthoudt a7b129147f Merge remote-tracking branch 'cappuccino/master' 2016-01-17 12:32:31 +01:00
cacaodev 6496a6643f Merge remote-tracking branch 'upstream/master' 2016-01-16 22:06:42 +01:00
cacaodev e172217427 Merge pull request #2404 from cacaodev/CPArray-mapUsingBlock
New: CPArray -arrayByApplyingBlock:
2016-01-16 19:25:07 +01:00
cacaodev 8c67eee4c8 (CPArray)arrayByApplyingBlock: documentation 2016-01-16 18:28:04 +01:00
Didier Korthoudt ca9039b8d5 Merge remote-tracking branch 'cappuccino/master' 2016-01-16 18:22:20 +01:00
Antoine Mercadal e260632a45 Merge pull request #2408 from slevenbits/xcodecapp-settings-tweaks
Fix some typos/grammar in XcodeCapp settings, plus improve layout.
2016-01-14 16:03:52 -08:00
Antoine Mercadal 678f4fca8a Merge pull request #2409 from primalmotion/predicate-fix
FIXED: CPPredicate's predicateFormat with a CPNull value as right exp…
2016-01-14 15:54:56 -08:00
Antoine Mercadal 5d88d07edc FIXED: CPPredicate's predicateFormat with a CPNull value as right expression wasn't working
Previously a CPPredicate created with format `value == nil` was converted back to `value == <CPNull @ xxxx>`

This patch ensures `predicateFormat` returns `value == nil`

Test added in CPPredicateTest.j
2016-01-14 15:50:24 -08:00
cacaodev 08aa591c65 NEW CPArray -arrayByApplyingBlock:(Function/*element, index*/)aBlock
Test for CPArray -arrayByApplyingBlock:
2016-01-14 21:57:57 +01:00
Alexander Ljungberg f2a8edb29f Fixed: some uneven margins and spacing in XcodeCapp settings.
The horizontal margin was larger than the vertical margin, and larger than the margin guideline for Cocoa.

Also one of the hint text lines was much closer to its textbox than the other two, and not well aligned within its textfield (should be right aligned).
2016-01-14 11:40:09 +00:00
Alexander Ljungberg 50d7e8dc3d Fixed: some typos/grammar in XcodeCapp settings. 2016-01-14 11:40:09 +00:00
Alexander Ljungberg 8403e36d4d New: arrange the kitchen sink test windows a little.
It just looks better.
2016-01-14 11:28:58 +00:00
Alexander Ljungberg 2dda326cc4 Fixed: radio button cropped in Theme Kitchen Sink test.
Without this fix the radio group was too short for Aristo 2 and as a result the bottom radio button had its bottom pixels cut off.
2016-01-14 11:20:31 +00:00
Antoine Mercadal 9002a8db04 Merge pull request #2407 from t00f/fix_2406_splitview
Test: Added a test that verifies CPSplitView behavior
2016-01-12 09:31:40 -08:00
Christophe Serafin 5ec5198dda Test: Added a test that verifies CPSplitView divider behavior when having only 1 subview.
Issue#2406 reported a behavior different from Cocoa Framework. This test validates that Cappuccino CPSplitView is working well when adding
and removing a subview. A CPSplitView that has only one subview should resize it to take the whole space available.

This PR adds a new test to Tests/Manual
2016-01-12 16:29:24 +01:00
Antoine Mercadal 0326b7d7ac Merge pull request #2405 from Dogild/CPBoxNib2CibFixed
Fixed: nib2cib on a NSBox fails when having a CPTableView in it
2016-01-05 13:08:04 -08:00
Aparajita Fishman 2f5e7f3b2d Allow custom formatters in xibs
Previously, adding a "Custom Formatter" (direct subclass of NSFormatter) to a cell in Xcode would cause a failure in nib2cib, because it didn't know how to deal with it.

This commit adds support for custom formatters in nib2cib (and thus in xibs), and updates the CPFormatter test app to demonstrate that this works.
2016-01-03 15:26:06 -08:00
daboe01 0e17658269 use fraction again in cursorUp 2015-12-31 10:42:33 +01:00
daboe01 87edda5972 more cursor up fixes 2015-12-30 21:16:02 +01:00
daboe01 ab8c3c2b75 granular selection refac 2015-12-30 17:35:14 +01:00
daboe01 44cef002ed make selection upon doubleclick more mac like 2015-12-30 15:41:36 +01:00
daboe01 bc80fe693a formatting 2015-12-30 14:49:06 +01:00
daboe01 1898b51dc2 fix for cursor up issue in multiple newlines 2015-12-30 14:39:41 +01:00
daboe01 a5dcf5958e updated credits section 2015-12-30 11:28:07 +01:00
Alexandre Wilhelm 9fba72cbab Fixed: nib2cib on a NSBox fails when having a CPTableView in it
Previously, when having a CPTableView in a CPBox, nib2cib failed due to a superview not defined yet. This was raised because in nib2cib we used the method setFrame on the CPBox to modify the frame of the CPBox (we need to modify this frame because the sizing difference between cappuccino and cocoa). We now directly modify the attribute _frame from the object and update the bounds in the same time.

This PR fixed another bug as well. Previously the contentView of the CPBox was not encoded, we now encode it. This allows us to get a full CPView object for the contentView, previously we got a weird (I have no idea how this object was created though...) object CPView with some missing attributes. This raised a crash because _trackingAreas or _themeState were not defined in this object.

Fixed #2400
2015-12-28 17:58:10 -08:00
cacaodev 912fdeaf09 Merge pull request #2403 from cacaodev/cptabviewitem-test
TEST: CPTabViewBindings manual test
Adds a test for tab view item label change.
2015-12-28 16:37:52 +01:00
cacaodev 36c417458d STYLE: replaced expression methods with accessors
Also added methods and documentation for the new methods:
-trueExpression, -falseExpression and -expressionBlock.
Completed documentation for -predicate and -arguments.
2015-12-27 22:08:30 +01:00
cacaodev f1591e593a Coding style 2015-12-27 22:03:35 +01:00
cacaodev 117ac0f5d6 FIXED: replace js Array.map function with capp API
Also fixed BlockExpression description to match a little more with
cocoa impl.
2015-12-27 19:31:05 +01:00
cacaodev e72a42fd2d FIXED: block & conditional expressions: support for CPPredicate -predicateWithSubstitutionVariables: 2015-12-27 19:28:03 +01:00
cacaodev e6e2f4c22c TEST: CPTabViewBindings manual test
Add test for pr #1921 *Label size not calculated when they change*

closes #1921
2015-12-27 18:19:48 +01:00
cacaodev 07b6e2b9f1 CPExpression +expressionForConditional:trueExpression:falseExpression:
Conditional Expression : an expression using different expressions for
evaluation, depending of a predicate result.

Support for predicate parsing: ```TERNARY(predicate, trueExpression,
falseExpression)```

With init, equal, evaluation, parsing tests.
2015-12-27 15:45:03 +01:00
cacaodev 5ab10f4024 NEW: CPExpression +expressionForBlock:arguments:
An expression that returns the result of evaluating a block.

With tests.
2015-12-27 15:44:36 +01:00
cacaodev 0ac08456bc Merge pull request #2401 from cacaodev/CPSubqueryExpression
FIXED: Subquery expressions were ignoring evaluation context
2015-12-26 00:12:13 +01:00
cacaodev 80a3549ef5 FIXED: Subquery expressions were ignoring evaluation context
When the predicate part of a subquery expression was containing
variables, the substitution was ignored.
Now, the subpredicate can contain variables that will be substituted
when calling evaluateWithObject:substitutionVariables:.

Added expression test and predicate parsing test.
2015-12-23 18:49:07 +01:00
Alexandre Wilhelm 770d5eb257 Fixed: nib2cib is broken due to the new feature CPTrackingArea. The array _trackingAres is not initialize when creating NS* object 2015-12-22 11:10:31 -08:00
Didier Korthoudt b32499f6ec Merge remote-tracking branch 'cappuccino/master' 2015-12-22 18:07:02 +01:00
Didier Korthoudt d9819d8b3d Merge remote-tracking branch 'cappuccino/master' 2015-12-22 08:03:54 +01:00
Aparajita Fishman 932b825818 Merge pull request #2395 from didierkorthoudt/CPTrackingArea
Implementation of CPTrackingArea
2015-12-21 15:23:51 -08:00
daboe01 a0cbc5822e speedup for chrome 2015-12-21 20:17:51 +01:00
Didier Korthoudt 2ab50c6b61 code style fixed 2015-12-20 09:29:54 +01:00
Didier Korthoudt d7426f6d35 Several fixes 2015-12-19 21:56:27 +01:00
Didier Korthoudt 8f15266f0a delayed cursorUpdates modification 2015-12-17 21:48:27 +01:00
Didier Korthoudt 936c7190c7 manual test update 2015-12-16 22:16:31 +01:00
Didier Korthoudt 3452984b8e 2 cases added 2015-12-16 19:29:14 +01:00
Didier Korthoudt 3e17890528 cursor tests in CPViewTest 2015-12-15 23:33:10 +01:00
Didier Korthoudt 2a7c50d356 events-during-drag-fix 2015-12-15 15:09:19 +01:00
Didier Korthoudt 05bca368c2 several-fixes 2015-12-10 18:29:34 +01:00
Didier Korthoudt 89c78f6030 unit-test-additions 2015-12-09 21:38:50 +01:00
Alexandre Wilhelm b59b0259ca Fixed: CPDateFormatter did not work with symbols MM and LL with the month of december 2015-12-09 10:51:51 -08:00
Didier Korthoudt e46e1b20de unit-test-v2 2015-12-08 23:09:20 +01:00
Didier Korthoudt 7089abcef2 missing-fix 2015-12-08 22:41:18 +01:00
Didier Korthoudt e6148a97a3 _CPWindowView-fix 2015-12-08 18:33:27 +01:00
Didier Korthoudt 9e40033a92 skipped-fix 2015-12-07 15:13:31 +01:00
Didier Korthoudt 08d4e19851 various-fixes
Following @aparajita indications
2015-12-07 14:58:42 +01:00
Didier Korthoudt dcc0768411 Unit-test+fix 2015-12-05 20:14:24 +01:00
Didier Korthoudt f14062c721 Style-fixes 2015-12-03 20:44:34 +01:00
Alexandre Wilhelm 0508b70658 Refactored: refactoring of the file CFHTTPRequest.js 2015-12-02 11:32:04 -08:00
Alexandre Wilhelm 04f8545397 Merge pull request #2368 from Rosch/master
Fix startup on IE10
2015-12-02 11:25:59 -08:00
cacaodev 633f985360 CFHTTPRequest : removed unused variable. 2015-12-02 17:51:49 +01:00
Didier Korthoudt a649a6ebac CIB-fix
For some (yet unknown) reason, when declaring a view with tracking area
in a CIB, there’s some weird things happening that try to use the
_trackingAreas array when it’s not yet initialized… So, replacing
_trackingAreas.length by [_trackingAreas count] resolves the problem.
2015-12-02 00:03:59 +01:00
Didier Korthoudt 634a8b4532 cocoadev-fix 2015-12-01 21:16:02 +01:00
Didier Korthoudt f3709a41e3 removeAllTrackingAreas 2015-12-01 21:06:55 +01:00
Didier Korthoudt 2bfebfee3c Manual-test-fix 2015-12-01 05:58:36 +01:00
Didier Korthoudt 76ab5fbf78 CPControl-fix 2015-11-30 09:07:33 +01:00
Didier Korthoudt c0b0c74638 CPTableHeaderView-fix 2015-11-30 05:49:11 +01:00
Didier Korthoudt 6c0b771758 CPSplitView-fix 2015-11-29 21:54:36 +01:00
Didier Korthoudt 2f983fc305 optimization 2015-11-29 15:37:33 +01:00
Antoine Mercadal 3cf0d60f5d Merge pull request #2399 from mrcarlberg/default_include_method_types
Default include type signatures for all kind of builds
2015-11-23 13:38:14 -08:00
Alexandre Wilhelm 751e76b453 Merge pull request #2396 from mrcarlberg/objj_runtime_method_type_accessors
Objective-J runtime method type accessor functions
2015-11-23 10:40:44 -08:00
Martin Carlberg c2f95f7953 Fixed: Runtime method argument functions will now comply to how Objective-C runtime works. 2015-11-23 10:48:15 +01:00
Didier Korthoudt 924b994df2 First updateTrackingAreas implementation 2015-11-21 17:25:43 +01:00
Didier Korthoudt b10de5e82c Code-refactoring 2015-11-21 09:20:28 +01:00
daboe01 65ffce8db2 sheet fix part 2 2015-11-20 20:45:21 +01:00
Martin Carlberg 58aeb2e40f Fixed: Add test cases 2015-11-20 14:54:23 +01:00
Martin Carlberg 141d737ca5 Fixed: Removed old function instead of mark it deprecated 2015-11-20 14:54:11 +01:00
Martin Carlberg d0fd53a2ca Added: Function method_getNumberOfArguments 2015-11-20 14:53:46 +01:00
Martin Carlberg 3e0a6ea2cf Fixed: Return NULL when out of bounce 2015-11-20 14:52:53 +01:00
Martin Carlberg 758ad3eb06 Fixed: Method types was not copied into new KVO implementation of a class that is observed with KVO.
Some test cases are also added for this.
2015-11-20 12:43:53 +01:00
Martin Carlberg b132a66707 Fixed: Compiler option 'IncludeTypeSignatures' is default turn on for all type of builds. It can optionally be turned off. 2015-11-20 12:33:00 +01:00
daboe01 f241f12ddb fix for textview on sheets 2015-11-19 20:03:36 +01:00
Didier Korthoudt e1daf9467c Code-style-fixes 2015-11-19 06:13:18 +01:00
Alexandre Wilhelm 5457ddb44f Fixed: ignored compiled nib file of xcodecapp when having xcodecapp folder in a XcodeCapp project 2015-11-18 13:09:39 -08:00
Alexandre Wilhelm 6fee13b0a5 Fixed: XcodeCapp did not ignore folder when sourcing them 2015-11-18 11:29:09 -08:00
Alexandre Wilhelm 2b17e173f5 Fixed: only reload the operations and errors dataview when they are currently displayed in XcodeCapp 2015-11-18 11:01:09 -08:00
cacaodev 569d4a5d8b Merge branch 'master' of git://github.com/cappuccino/cappuccino 2015-11-15 19:34:39 +01:00
Alexandre Wilhelm 51a88a23ac Fixed: removed files Lumberjack 2015-11-13 10:48:48 -08:00
Alexandre Wilhelm f41504ca57 Fixed: remove library CocoaLumberjack in XcodeCapp. This lib added memory leaks when using it in an NSOperation. We now simply use NSLog 2015-11-13 10:48:02 -08:00
Alexandre Wilhelm bacb7018cb Fixed: thread of the spinning was always launched even if the spinner was not displayed in XcodeCapp 2015-11-12 16:29:46 -08:00
Alexandre Wilhelm 671ed3c2fe Fixed: memory leak in XcodeCapp due to NSAppleScript. We now use osascript 2015-11-12 11:59:00 -08:00
Alexandre Wilhelm 372e994617 Fixed: XcodeCapp ignored by defaul the ressources folder 2015-11-11 13:24:18 -08:00
Martin Carlberg e4560df62f Fixed: Use correct property in decorator 2015-11-10 11:31:04 +01:00
Martin Carlberg 920daf7fde Fixed: Marked function 'method_getTypes' as deprecated 2015-11-10 11:30:29 +01:00
Martin Carlberg ad1a15faaa New: Added runtime functions 'method_copyReturnType' and 'method_copyArgumentType'. 2015-11-10 11:29:52 +01:00
Didier Korthoudt 459cf2e380 Tests/Manual TrackingArea test app 2015-11-08 19:46:19 +01:00
Didier Korthoudt 8d058a53fd CursorUpdate management + various fixes 2015-11-08 12:06:13 +01:00
Didier Korthoudt d864ae9fef Code style 2015-11-07 07:07:14 +01:00
Didier Korthoudt f1eeb61264 Fix: log traces removal 2015-11-06 15:05:34 +01:00
Didier Korthoudt 1418dd8b29 First submit for CPTrackingArea 2015-11-06 14:09:23 +01:00
cacaodev 0297980ca3 Merge branch 'master' of git://github.com/cappuccino/cappuccino 2015-11-02 19:46:36 +01:00
cacaodev 5e94aaa2cb Merge pull request #2391 from zittix/fix_initial_cptabview_selection
Fixed: default selection of a CPTabView item
2015-11-02 09:25:04 +01:00
Martin Carlberg b929a8fe2e Merge pull request #2389 from mrcarlberg/faster_theme_attribute
Faster theme attribute handling
2015-11-01 20:42:13 +01:00
Martin Carlberg 8c2f0bacf1 Merge pull request #2384 from mrcarlberg/even_faster_objj_msg_send
Speedup of the Cappuccino framework by more efficient objj_msgSend
2015-11-01 20:39:18 +01:00
Alexandre Wilhelm 0bc02de012 Fixed: method loadCibNamed:(CPString)aName owner:(id)anOwner is broken
Previously, the method CPBundle loadCibNamed:(CPString)aName owner:(id)anOwner was broken, it loaded the cib asynchronous instead of synchronous. This was due to bad refactoring of a previous commit refs#c5b250236fa662e3da04e442f4414f95d64d9308

This PR refactor this piece of code and make works the method synchronous as it should.

More information here : https://github.com/cappuccino/cappuccino/commit/c5b250236fa662e3da04e442f4414f95d64d9308#commitcomment-14109453
2015-11-01 08:57:06 -08:00
Alexandre Wilhelm 411a282063 Test: fixed manual test SmartFoldersDemo 2015-11-01 08:56:49 -08:00
Alexandre Wilhelm 6c4d55622b Fixed: travis was broken because variable named char 2015-10-31 18:09:53 -07:00
Alexandre Wilhelm e214bf3581 Refactoring: refacroting of the method charPositionOfString:(CPString)aString withFont:(CPFont)aFont forPoint:(CGPoint)aPoint refs#78e29d2bbfe43f5a8bda2e65d974f7effb8fcbd4 2015-10-31 14:50:41 -07:00
Alexandre Wilhelm 78e29d2bbf Fixed: position of cursor in a CPTextField was wrong when becoming firstResponder
Previously, when a CPTextField became firstResponder, the cursor was always set at the first position. Now it position it at the expected location.
2015-10-31 12:31:49 -07:00
Mathieu Monneyandcacaodev a93c10b794 Fixed: default selection of a CPTabView
The selected tab item view is now loaded correctly after awakeFromCib, which wasn't the case before.
2015-10-30 15:27:34 +01:00
Martin Carlberg 3240d6f11a Fixed: Added TODO comments that deprecated use should be remove in future release 2015-10-30 11:20:51 +01:00
Antoine Mercadal d5f38fe2f2 Merge pull request #2392 from Dogild/RunLoopBlock
New: added the method performBlock in CPRunLoop
2015-10-27 17:36:22 -07:00
Alexandre Wilhelm d4b1680727 Fixed: new CPPLatformWindow did not have a platformPasteboard. copy and paste did not work for other platformWindow except the main one 2015-10-27 12:08:10 -07:00
Alexandre Wilhelm b04e5760fb Test: added unittest for method stringByReplacingCharactersInRange of CPString 2015-10-27 12:06:47 -07:00
Martin Carlberg 42c629ca45 Fixed: Use ’;’ instead of ’,’ 2015-10-27 09:03:55 +01:00
Martin Carlberg 68f45beb20 Fixed: Code formatting 2015-10-27 09:03:26 +01:00
Mathieu MonneyandMathieu Monney ea95897bbd Fixed: default selection of a CPTabView
The selected tab item view is now loaded correctly after awakeFromCib, which wasn't the case before.
2015-10-27 08:09:17 +01:00
Alexandre Wilhelm 4d1dc0c949 New: added the method performBlock in CPRunLoop
Previously, we could only give a selector and a target for perform in the runLoop. Now we can give a block.
This feature is used in the CPTextField class. Previously, when we wanted to call a function at the end of the stack we used window.setTimeout, however due to HTML5 specifications this wasn't called just at the end of the stack but at least 4ms (more information here https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setTimeout#Minimum_delay_and_timeout_nesting). Now we give a block to perform, and this block will be performed in the next runloop.

Unittest has been added in Tests/Foundation/CPRunLoopTest.j
2015-10-26 15:36:13 -07:00
Martin Carlberg 9fc892f723 Fixed: Check if ’OBJJ_COMPILER_FLAGS’ exists in a correct way 2015-10-26 14:47:51 +01:00
Martin Carlberg 5541381afe Fixed: Only have one ’release’ option for Jake.
Removed the ’release-inline’ option when building as it is not practical to have two different options. The release build now always has inlined msgSend functions. If a release build is needed without inlined msgSend functions an edit of the ”-O2” option to ”-O” in the Jakefile is needed.
2015-10-26 09:53:39 +01:00
Martin Carlberg ed12bae6aa Fixed: Removed unused global variable 2015-10-23 16:38:12 +02:00
Martin Carlberg 1520c1ebab Fixed: Linting 2015-10-23 15:40:45 +02:00
Martin Carlberg 790190e5c3 Fixed: Removed code collecting statistic of theme attribute creation and some logging 2015-10-23 10:39:52 +02:00
Martin Carlberg 24889f7dcd Fixed: Adjust test cases 2015-10-23 10:19:14 +02:00
Martin Carlberg 8397685430 Fixed: Joined caches for theme attributes for better performance
Conflicts:
	AppKit/CPTheme.j
2015-10-23 10:19:02 +02:00
Martin Carlberg fc411c5c1c Fixed: Cache ThemeAttribute
Conflicts:
	AppKit/CPTheme.j
2015-10-23 10:18:03 +02:00
Martin Carlberg 3a91f43bbb Fixed: Test cases are working correctly 2015-10-21 12:26:39 +02:00
Martin Carlberg 5e1f1675b8 Fixed: Method ’_themeAttributes’ never saved anything in the cache 2015-10-21 12:26:31 +02:00
Martin Carlberg 9946987f69 Fixed: Cache ThemeState for better performance 2015-10-21 12:26:12 +02:00
Aparajita Fishman 526181a76b Fixed: CPImage -size returned internal object ref
Previously, CPImage -size returned a reference to the internal _size object, which allowed the caller to directly change _size. In Cocoa a copy of the size is returned.

This commit returns a copy of _size to ensure no unwanted side effects.
2015-10-16 16:20:24 -04:00
Alexandre Wilhelm ce8f8c05e1 Merge pull request #2385 from Dogild/CPNotificationQueue
New: added the class CPNotificationQueue
2015-10-14 11:18:41 -07:00
Martin Carlberg 3844b88f7e Fixed: The browser can’t promise when a javascript block will execute so compiler flags can be set after the files are compiled. This implementation works all the time. 2015-10-09 16:06:53 +02:00
Alexandre Wilhelm db3c232173 Fixed: add CPNotificationQueue.j in Foundation.j 2015-10-08 16:07:50 -07:00
Alexandre Wilhelm 22b77af9d3 New: added the class CPNotificationQueue
This PR adds the feature of CPNotificationQueue.

Cappuccino provides a framework for sending messages between objects within
a process called notifications. CPNotificationQueue objects (or simply notification queues)
act as buffers for notification centers (instances of CPNotificationCenter).
Whereas a notification center distributes notifications when posted,
notifications placed into the queue can be delayed until the end of the current pass through the run loop
or until the run loop is idle. Duplicate notifications can also be coalesced so that only one notification
is sent although multiple notifications are posted. A notification queue maintains notifications
(instances of C¨Notification) generally in a first in first out (FIFO) order.
When a notification rises to the front of the queue, the queue posts it to the notification center,
which in turn dispatches the notification to all objects registered as observers.

More informations here :https://developer.apple.com/library/prerelease/ios/documentation/Cocoa/Reference/Foundation/Classes/NSNotificationQueue_Class/index.html#//apple_ref/occ/instm/NSNotificationQueue/enqueueNotification:postingStyle:coalesceMask:forModes:

Unit-Tests in Tests/Foundation/CPNotificationQueueTest.j
2015-10-08 16:06:16 -07:00
Alexandre Wilhelm 3e29732e46 Fixed: OperationQueue for the CPNotificationCenter is not ignored anymore
Previously, the operationQueue given to the notificationCenter was ignored.

Tests in CPNotificationCenterTest.j
2015-10-08 11:23:07 -07:00
Alexandre Wilhelm 54e1efd794 Test: refactoring of the manual test CPURLConnectionAsyncTest 2015-10-08 11:17:12 -07:00
Alexandre Wilhelm 8809c1634f Merge pull request #2286 from cacaodev/CPURLConnection
CPURLConnection +sendAsynchronousRequest:queue:completionHandler:
2015-10-08 10:25:12 -07:00
cacaodev 13e1be1f74 CPURLConnectionAsyncTest manual test. 2015-10-07 18:04:28 +02:00
Martin Carlberg 26a123f5a8 Fixed: Added code generation unit test cases with inlined objj_msgSend functions for all tests in OutputTest. 2015-10-07 15:58:28 +02:00
Alexandre Wilhelm f062fda2f7 Fixed: optimization with layoutSubviews and viewWillLayout 2015-10-06 14:41:01 -07:00
Martin Carlberg e45e31d223 Fixed: Introduce ’jake install-inline’ task to generate the cappuccino framework with objj_msgSend function inlined. Also introduced options in ’index-debug.html’ templates to allow inline of objj_msgSend function when compiling in browser. 2015-10-06 13:34:28 +02:00
Martin Carlberg 101261ca63 Fixed: Optionally inline objj_msgSend function. Generate faster code for Array and Dictionary Literals. 2015-10-06 13:30:09 +02:00
Martin Carlberg 4ba9a19b5c Fixed: Speed improvements in objj_msgSend and objj_msgSendSuper functions. More efficient implementation of objj_method. 2015-10-06 13:27:10 +02:00
Alexandre Wilhelm f8eab7d611 Merge branch 'master' of https://github.com/cappuccino/cappuccino 2015-10-02 16:03:04 -07:00
Alexandre Wilhelm 40a9f19352 Fixed: crash when opening a platformWindow with a popup blocker
Previously, when opening a CPPlatformWindow a crash happened when this new window was blocked by the browser (addblock, or browser feature).
Now when opening an external window, we check if the DOMWindow has been created.

This PR has modified the method isVisible of CPPlatformWindow. We now check if the _DOMWindow is not NULL and undefined.
2015-10-02 16:00:57 -07:00
Martin Carlberg 4b81e0d8af Merge pull request #2383 from mrcarlberg/use_more_fast_objj__msg_send
Use the faster objj_msgSend instead of the old slower objj_msgSend
2015-10-02 20:35:32 +02:00
Alexandre Wilhelm ea37bf8b45 Merge branch 'master' of https://github.com/cappuccino/cappuccino 2015-10-02 11:10:01 -07:00
Alexandre Wilhelm c30f8b09b0 Fixed: warning when compiling in CPWindow, CPPanel and _CPCibKeyedUnarchiver 2015-10-02 11:09:48 -07:00
Alexandre Wilhelm 686f931fb4 Merge pull request #2343 from Dogild/Localization
New: first work on localization
2015-10-02 11:04:35 -07:00
Alexandre Wilhelm 1fe1e6f265 Merge pull request #2374 from Dogild/ThemeForObject
New: possibility to create a theme for every object of the Appkit
2015-10-02 10:35:02 -07:00
Alexandre Wilhelm 860decdac5 Fixed: CPColor and CPView implemented the category CPTheme 2015-10-02 10:12:50 -07:00
cacaodev d5b90c91f5 Merge pull request #2339 from cacaodev/CPTabView
CPTabView improvements
2015-10-02 14:00:17 +02:00
Martin Carlberg 20d6e365a1 Fixed: Use the faster objj_msgSend in nib2cib too. 2015-10-01 22:19:04 +02:00
Martin Carlberg e5e50c2220 Fixed: Use the faster objj_msgSend instead of the old slower objj_msgSend
In some places the objj_msgSend function is called directly. Most of the times the old slower version is called. This commit will use the never faster version instead.
2015-10-01 22:17:13 +02:00
cacaodev e8da7baee2 Perform operation on network error (try/catch). 2015-10-01 13:19:40 +02:00
cacaodev 8ab9e6bac7 NEW +sendAsynchronousRequest:queue:completionHandler: If queue is nil, run handler immediately.
NEW: CPURLConnection -operation method, CPError CPURLErrorDomain constant.

    CPURLConnection -operation gives access to the operation generated by the new CPURLConnection creator.
    This allows to create dependencies between operations and setup priorities early.
    When the connection fails with a status code 404 or is cancelled, the
    operation is also cancelled and
    the next operation in the queue is started.
2015-10-01 12:36:57 +02:00
Alexandre Wilhelm 9129301c89 Merge pull request #2381 from mrcarlberg/cp_dictionary_duplicate_keys_in_init
CPDictionary handles duplicate keys in correct way on init
2015-09-30 14:54:24 -07:00
Alexandre Wilhelm 9545e0145f Fixed: conflict with auto-merge in CPTextView 2015-09-30 11:31:32 -07:00
Alexandre Wilhelm 15d3e4023b Merge remote-tracking branch 'origin' into NEW--CPTextView 2015-09-30 11:30:18 -07:00
Alexandre Wilhelm 205e4dedd1 Test: updated test CPTextViewCibTest 2015-09-30 11:30:12 -07:00
Alexandre Wilhelm 324d796aca Fixed: issue with typingAttributes and selectingAttributes when the CPTextView was created from a xib 2015-09-30 11:29:55 -07:00
daboe01 5b31e8e9d8 tighten atomicity in kvb 2015-09-30 19:49:04 +02:00
daboe01 0afb62ee88 formatting 2015-09-30 19:46:18 +02:00
Martin Carlberg 1b0d053ab9 Fixed: Check the abbreviation from the correct place in the test 2015-09-30 18:15:32 +02:00
Martin Carlberg 5871c4f092 Fixed: Fixed test cases where CPTimeZone does not handle daylight saving time.
For example the method ’initWithName:’ will return different abbreviation depending on the order CPDictionary returns keys from the method ’keyEnumerator’. As this is undefined the answer can vary. Test cases now handle all cases.
2015-09-30 17:03:36 +02:00
Martin Carlberg 5d415e6679 Fixed: Speed improvement 2015-09-30 16:59:16 +02:00
Martin Carlberg 3a7384ec26 Fixed: CPDictionary initWithObjectsAndKeys was not compliant with Cocoa or the init method ’initWithObjects:forKeys:’ when duplicated keys was passed to the method.
Test cases are also added
2015-09-30 16:59:04 +02:00
daboe01 1d3a8bcacd fix for moveRight: with non-zero length selection 2015-09-30 12:19:04 +02:00
daboe01 dd187aef08 refactor rich copy: to CPTextView 2015-09-30 12:11:39 +02:00
daboe01 78b2c4d094 kvb fix for editable and selectable 2015-09-30 12:00:12 +02:00
Alexandre Wilhelm 32b7a314b1 Fixed: warning when compiling Foundation adn CPException 2015-09-29 15:36:22 -07:00
Alexandre Wilhelm c8d768c59a New: added protocol CPTheme 2015-09-29 12:54:32 -07:00
cacaodev 3ef1c9167f Merge remote-tracking branch 'upstream/master' into CPTabView
Conflicts:
	AppKit/CPTabView.j
2015-09-29 11:04:51 +02:00
Alexandre Wilhelm 36cdcbc3c1 Fixed: setupViewFlags was not called when creating a view from a xib
Previously, the method setupViewFlags was not called when creating from a xib. This issue was introduced by the commit #448c2a2

Fixed #2380
2015-09-28 11:37:37 -07:00
daboe01 83876532d0 fix cursor position in empty textview 2015-09-26 22:56:17 +02:00
daboe01 edc824d05e fix moveLeft line issue 2015-09-26 21:09:06 +02:00
daboe01 9a7869dd40 fix select the text just after you have deleted something 2015-09-26 21:03:58 +02:00
daboe01 1aa247d4da no selection after undo 2015-09-26 20:57:25 +02:00
Martin Carlberg 5db9f28b33 Merge pull request #2379 from mrcarlberg/fix_cparray_initWithObjects_count
Fixed: The init method ’initWithObjects:count:’ for CPArray did not work
2015-09-25 22:24:49 +02:00
Martin Carlberg 8599ad4a3c Fixed: The init method ’initWithObjects:count:’ for CPArray did not work on native CPJavaScriptArray when ’count’ is not the same as the length on the provided array.
A test case for this is also added in the test class CPArrayTest
2015-09-25 17:07:15 +02:00
Antoine Mercadal 448c2a27d4 Merge pull request #2375 from Dogild/AppearanceCrash
Fixed: crash when using a viewBased CPTableView with appearance
2015-09-23 15:51:50 -07:00
Alexandre Wilhelm f2f4fa1b98 Fixed: readded _viewClassFlags. We only displayRect the view if drawRect: or viewWillDraw is implemented. layoutSubviews is still called even if the subclass does not implement it 2015-09-23 15:00:40 -07:00
Alexandre Wilhelm 6f43a189c0 Merge remote-tracking branch 'origin' into AppearanceCrash 2015-09-23 14:44:06 -07:00
Roland Schwingel dd4de9822f Adjustment for (a)sync request with timeout to work on IE and other browsers 2015-09-23 19:16:20 +02:00
Alexandre Wilhelm c9e83e0517 Merge pull request #2362 from cacaodev/cpview-skip_settransform
FIXED: In CPView, the transformation matrix was set at each drawing pass, even if the matrix was the identity matrix.
2015-09-22 17:02:30 -07:00
Alexandre Wilhelm 4ac63950ad Fixed: toolTip does not work on a external window
Previously, the toolTip created for an external window where shown on the primary platform window. We now display it on the desired platformWindow.
2015-09-22 15:58:53 -07:00
Alexandre Wilhelm 7a0b2c958b Fixed: crash with CPRuleEditor when dragging the first row
Previously, cappuccinos crashed when dragging to the top the first row of a CPRuleEditor.
2015-09-22 15:01:19 -07:00
Alexandre Wilhelm 3fcc37e086 Fixed: CPTabView did not accept first mouse event
Previously, the CPTabView did not react with the first mouse event (for instance when a CPTabView was in a not focused window). Now it does as in cocoa.

To do that, the CPTavView override the method acceptsFirstMouse. Previously, the tabView had a CPBox, it now has a _CPTabViewBox. This new box reacts differently than the CPBox for the method hitTests. It now returns nil when the click was performed on the segmentedControl of the CPTabView, previously this same click would be handle byt the CPBox.
2015-09-22 14:33:14 -07:00
Roland Schwingel 55181cec8c Set timeout in XHR requests AFTER they are opened to get them to work with IE 2015-09-17 14:45:35 +02:00
cacaodev 41d259006e Merge remote-tracking branch 'upstream/master' into CPTabView 2015-09-14 18:57:12 +02:00
daboe01 93e8ec7f06 formatting 2015-09-02 09:04:39 +02:00
daboe01 ba1d1c3bac fix for recent FF update 2015-09-02 09:02:04 +02:00
daboe01 fbaff2b75b fix for FF40+ 2015-09-02 09:00:29 +02:00
daboe01 9774e8807b fix disappearing cursor 2015-08-31 23:40:18 +02:00
Alexandre Wilhelm b30103c790 New: added methods viewWillLayout and viewDidLayout
Previously, when a view was about to layout, only layoutSubviews was called. Now the methods viewWillLayout and viewDidLayout are called as well. This is like in Cocoa.

This PR fixed the issue with the appearance and the view based tableView. We now handle everything related with appearance when making the layout of a view.

This PR removed a small optimization in CPView. Now when making setNeedsLayout and setNeedsDisplay, the methods drawRect: and layoutSubviews are always called even if there are not override. (As in cocoa)
2015-08-28 11:11:28 -07:00
Alexandre Wilhelm bb9408b5d0 Merge branch 'master' into Localization 2015-08-27 15:16:12 -07:00
Alexandre Wilhelm 42c3c7bc48 Fixed: crash when using a viewBased CPTableView with appearance
Previously, when using a viewBased CPTableView Cappuccino just crashed.
This was due to the new appearance feature. Indeed, at the end of the method initWithCoder: of CPView, we set the appearance of the current view and the themeStates of the view and its subviews. For an unknown reason some of these subviews were not completely initialized (see comment line 3742), this made crashed cappuccino because _themeState was null.

To fix this issue, we send the method setAppearance when the current stack was performed. (Magic setTimeout...).

This is for sure not the ultimate best fix, but it's prevent to have a broken master. We will need in the future to fix this issue in a better way.
2015-08-25 16:46:00 -07:00
Alexandre Wilhelm 464040895c Fixed: remove log... 2015-08-21 16:06:25 -07:00
Alexandre Wilhelm 525747dc53 New: possibility to create a theme for every object of the Appkit
The purpose of this feature is to create theme for every object of the AppKit. Previously, we could not theme object like CPColor, however CPColor could be very interesting to theme, value like alternateSelectedControlColor were hard coded in the framework. With this PR, we can now theme a CPColor and take some values from the current theme of the application. Then, this PR offers the possibility to refactor the themeDescriptors, some classes contains theme attributes for other class (CPTabView and  CPTabViewItem for instance).

How doe it work ? A new category _CPObject+Theme.j has been added to the AppKit. This category contains every theme methods needed to theme an object (previously this category was in CPView). We add utils method like _encodeThemeObjectsWithCoder: and _decodeThemeObjectsWithCoder: in this category to be able to code and decode easily a coder for every object (this is generic).

This PR did not refactor the themeDescriptors, it only add this new mechanism for the methods alternateSelectedControlColor and secondarySelectedControlColor of CPColor. We will need to refactor that gradually
2015-08-21 15:54:00 -07:00
Alexandre Wilhelm c61d992559 Merge pull request #2373 from Dogild/menu-context
New: default menu system is now disable for every right click except for the CPTextField
2015-08-20 19:47:20 -07:00
Alexandre Wilhelm 2f79b079fd New: default menu system is now disable for every right click except for the CPTextField
Previously, when making a right click and when a cappuccino menu was not displayed, the system menu was displayed. Now we don't display this menu anymore as in cocoa. We only display when making a right click on a CPTextField.
2015-08-20 16:14:14 -07:00
Alexandre Wilhelm 655bc39d85 Fixed: blinking popover animation on Chrome and Opera
Previously, when opening a popover, the animation was blinking on Chrome and Opera.
To resolve (temporary I hope) this issue, we launch the last part of the animation at the beginning of the next runloop. We do that by wrapping the desired code in window.setTimeout(function(){},0).

A google chrome issue has been opened here : https://code.google.com/p/chromium/issues/detail?id=523044&thanks=523044&ts=1440095724
2015-08-20 11:36:57 -07:00
Roland Schwingel 1eb12d4fa0 Damned... corrected formatting 2015-08-20 14:57:28 +02:00
Roland Schwingel 2ab9186259 Fix Chrome warning when using synchronous XHR requests 2015-08-20 14:52:19 +02:00
Alexandre Wilhelm ab61aef985 Merge pull request #2371 from primalmotion/CPVisualEffectView
CPVisualEffectView & CPAppearance
2015-08-18 15:15:03 -07:00
Roland Schwingel 65b3e9f8c1 Merge remote-tracking branch 'upstream/master' 2015-08-18 14:10:21 +02:00
Alexandre Wilhelm 1f57aa1ea5 Merge branch 'master' of https://github.com/cappuccino/cappuccino 2015-08-16 15:44:01 -07:00
Alexandre Wilhelm 340d827377 Fixed: command cmd+h did not work for the new XcodeCapp 2015-08-16 15:43:56 -07:00
Antoine Mercadal 5cd25e24e4 Merge pull request #2369 from tancred/preserve_boolean_type_when_parsing_predicate_constant_value_expressions
Fixed: preserve type of boolean values when parsing CPPredicate format
2015-08-14 13:55:18 -07:00
Antoine Mercadal 58afc92a26 Merge pull request #2370 from Dogild/new-cache-timeout-urlrequest
New: added timeout and cache feature in CPURLRequest
2015-08-14 13:51:20 -07:00
Alexandre Wilhelm acb9931fe6 Fixed: not possible to to synchrone request and set a timeout 2015-08-14 13:28:27 -07:00
Alexandre Wilhelm d4b035ac1a Fixed: style in CPURLConnection.j CPURLRequest.j CFHTTPRequest.js 2015-08-14 12:40:22 -07:00
Antoine Mercadal 403dd5c005 Updated CPVisualEffectViewTest
The test now show how to use the automatic theme state beased on
CPAppearance
2015-08-14 01:45:19 -07:00
Antoine Mercadal 7e4e1ec68f FIXED: lot's of error with CPAppearance 2015-08-14 01:44:22 -07:00
Antoine Mercadal 547764e3c1 FIXED: Always call [super awakeFromCib] in CPView subclasses 2015-08-14 01:43:55 -07:00
Antoine Mercadal 541a7974e0 NEW: effectiveAppearance and new CPThemeState
Each default (and only supported) CPAppearance now have an associated
theme state. As the appearance is correctly propagated in CPViews
hierarchy, it is now possible to have dark controls when the an
ancestor view has a dark appearance.

Added automated tests
2015-08-13 23:40:27 -07:00
Antoine Mercadal 6bf6f82cad Small refactoring 2015-08-13 21:29:33 -07:00
Antoine Mercadal 7be2325a95 Fix few mistakes 2015-08-13 21:12:04 -07:00
Antoine Mercadal fa1f739458 NEW: Support for basic CPVisualEffectView
This patch contains a very naive implementation of the
NSVisualEffectView. This will only work on very recent unreleased
version of Safari, but should be supported by all at some point. This
allow to use the Yosemite/iOS blurry effect.

Not all options are supported (especially the
`CPVisualEffectBlendingModeBehindWindow` mode…). But hey! it’s a start
:)

Tests in Manual/CPVisualEffectViewTest
2015-08-13 20:53:53 -07:00
Antoine Mercadal 20289ff81b fix two small bugs in CPApperance 2015-08-13 20:25:45 -07:00
Antoine Mercadal 6d67d30aee NEW: Initial support for CPAppearance
This patch adds the `CPAppearance` class and uses it where needed.
There is nearly no impact, but in `_CPPopoverWindowView` where the
`CPPopoverAppearance` needs to be converted to a `CPAppearance` object

nib2cib support has also been added.

*This patch brings no new functionality.*
2015-08-13 19:56:10 -07:00
Alexandre Wilhelm bd0bd2e087 New: added timeout and cache feature in CPURLRequest
This PR adds the possibility to set the timeout and the cache policy of a CPURLRequest.
For that, there are new things in the framework :

- CFHTTPRequest has now the functions setTimeout(), getTimeout() and isTimeoutRequest
- CPURLRequest has now the methods +requestWithURL:cachePolicy:timeoutInterval: and -initWithURL:cachePolicy:timeoutInterval:
- CPURLConnection does not call the delegate didReceiveData: when a request has timed out. I will call the delegate didFailWithError:
- Cache is now possible for a CPURLRequest, only CPURLRequestReturnCacheDataElseLoad, CPURLRequestReturnCacheDataDontLoad and CPURLRequestReloadIgnoringLocalCacheData are supported. By default CPURLRequestReloadIgnoringLocalCacheData.
- Default timeout has been set to 60sec as in cocoa.
- A request is considered as timeout when there isn't any response (text/xml/type) and when the status of the response is 0.
2015-08-13 17:08:59 -07:00
Antoine Mercadal 3d79799450 Do not fail Cappuccino installation if XcodeCapp build fails 2015-08-13 12:13:38 -07:00
Alexandre Wilhelm c99f9205b7 Merge pull request #2367 from primalmotion/xcodecapp4.0
Xcodecapp4.0
2015-08-12 11:26:55 -07:00
Malte Tancred 26bb54472f Fixed: preserve type of boolean values when parsing CPPredicate format
When parsing a predicate format that contains a constant boolean expression
(e.g., 'key = YES') the value of the returned constant value expression has
the wrong type. Instead of using native types as values, the parser uses
[CPNumber +numberWithBool:].

This commit changes the format parser (CPPredicateScanner) to use native
booleans for constant value expression.

There's a test case that checks the parse result and an additional test
that ensures boolean expressions evaluate as expected with different kinds
of objects. The latter test passed before the fix but was added to ensure
compliance with Cocoa.
2015-08-12 17:05:56 +02:00
Roland Schwingel 73e13fee37 Fix for startup on IE10. Reformatted patch 2015-08-11 09:03:21 +02:00
Roland Schwingel 205c1ac3b6 Fix startup on IE10 2015-08-10 17:08:28 +02:00
Antoine Mercadal d317744f05 Update pbxproj to auto deploy 2015-08-04 10:43:59 -07:00
Antoine Mercadal 47611b7615 NEW: XcodeCapp 4.0
XcodeCapp 4.0 is a major release of our beloved tool. In a nutshell it:

- allows to manage multiple projects simultaneously
- allows to follow operations and cancel them
- has a per project Error and Warning reporting
- supports capp_env as you can define additional paths and objj include path per project
- much more things
2015-08-04 10:35:23 -07:00
Antoine Mercadal 6420a51dd0 FIXED: crash when a cell based table view contains a dataview that contains an editable text field
Previously, CPTableView was listening to all end editing notifications in cell-based mode.
This caused a crash if the textfield is an actually subview of a dataview.

This patch ensures to listen only editing did end notification for direct subview of tableView.
2015-08-03 15:00:04 -07:00
Antoine Mercadal 7c17d5bac0 Merge branch 'master' of https://github.com/cappuccino/cappuccino 2015-08-03 14:57:15 -07:00
Antoine Mercadal 0efd7c93c5 FIXED: Fonts from IB not correctly interpreted in OSX El Capitain
This patch adds support for the new way of defining the default font from Xcode 7 beta. The patch also supports the old explicit 'Lucida Grande' of previous version.
2015-07-29 23:39:07 -07:00
Alexandre Wilhelm 806be9551c New: added protocol CPURLConnectionDelegate 2015-07-23 14:38:06 -07:00
daboe01 b4dd3a9889 typing at the end fix 2015-07-18 17:44:18 +02:00
Alexandre Wilhelm 6b4a1b6758 New: Added gitter link in the readme
New: Added gitter link in the readme
2015-07-15 15:42:07 -07:00
daboe01 4510b69798 refacturing 2015-07-14 19:29:46 +02:00
daboe01 84a3ee209a fix cursor up newline issues 2015-07-09 20:45:23 +02:00
Antoine Mercadal d6b0fccbda FIXED: Previous patch by @dogild was not correctly setting the CSS class
This patch adds a reference to the current CSS selectable field in and
reset the style when user clicks on a different one.
2015-07-08 15:35:20 -07:00
Alexandre Wilhelm d1e31da2e5 Fixed: selection did not work in Cappuccino when doing a right click or dragging
Previously, the selection of a textField did not work as expected when the user did a right click or a drag even if the label was set to none selectable.
Now, with the css style user-select, a textField can only be selected if it is selectable and enable.

Credit to @primalmotion
2015-07-08 13:34:57 -07:00
Alexandre Wilhelm 923d32ee6d Test: finally put the init of the CPApplication in the instance method setUp. See previous commit #6fe9dae3d62af995f2481bfebdd706aeb0b21365 2015-07-07 15:04:29 -07:00
Alexandre Wilhelm 4b0fe879cb Test: [[CPApplication alloc] init]; in instance setUp method 2015-07-07 14:46:38 -07:00
Alexandre Wilhelm b87aeffcd8 Test: updated unittest 2015-07-07 14:29:50 -07:00
Alexandre Wilhelm 88aafec6e3 Merge branch 'master' into NEW--CPTextView 2015-07-07 14:29:15 -07:00
Alexandre Wilhelm 6fe9dae3d6 Fixed: AppKit unit-tests are not standalone
Previously, every AppKit tests used the same sharedApplication. Due to this implementation, a could not pass because a previous test made failed the current test. For instance, a test could fail because the window of the previous test resigned (just imagine a new window is the key window in the current test), and this resign could raise an error. The error was displayed for the current test thought this test was perfect !

We now instead of using sharedApplication create a new CPApplication per unit-test file in the class method setUp.
2015-07-07 14:12:19 -07:00
Alexandre Wilhelm 2cb6ddf3ca Fixed: document was not wrap in a #if PLATFORM 2015-07-07 11:14:56 -07:00
daboe01 799622a932 Merge remote-tracking branch 'upstream/master' into NEW--CPTextView 2015-07-07 18:24:54 +02:00
Alexandre Wilhelm 4c1e22b0f6 Fixed: travis failed because the unittests tried to display a layer
Previously, the unittests for the CPDatePicker broke the tests suite of cappuccino. A CPDatePicker uses a CALayer, and the CALayer display methods wasn't wrap in a #if PLATFOrM(DOM). Now it does, so during the tests we do not try to access do the element document anymore.

This PR fixes also some warnings when compiling.
2015-07-06 14:14:39 -07:00
daboe01 2283652704 add missing ivar 2015-07-05 22:50:21 +02:00
daboe01 33fb2daabf fix shift selection 2015-07-05 14:19:11 +02:00
daboe01 c79f59ec05 fix manual test title 2015-07-05 14:02:30 +02:00
daboe01 845aaad891 fix keywindow observer mechanics 2015-07-05 08:57:25 +02:00
daboe01 3c0b061220 cursor fixes 2015-07-04 21:18:40 +02:00
daboe01 af7de73f5c fix dom protection 2015-07-04 19:24:52 +02:00
daboe01 1a8a9f0047 make dom protection more stringent 2015-07-04 19:17:22 +02:00
daboe01 a3b4e8db44 fix non-working unit test 2015-07-04 17:42:07 +02:00
daboe01 f9e8875803 merge current master in 2015-07-04 16:46:24 +02:00
daboe01 e4c11d9a88 various fixes 2015-07-03 23:13:57 +02:00
daboe01 6d1d8da101 recursion fix 2015-07-03 22:56:58 +02:00
daboe01 77303e668f fix missing reference 2015-07-03 21:03:28 +02:00
daboe01 72725b91c7 fix undefined constant 2015-07-03 20:56:14 +02:00
daboe01 46f50f55c2 various baseline fixes 2015-07-03 20:03:53 +02:00
daboe01 5e880f6bfa Revert "_textContainer refac preparation"
This reverts commit 80cf88dcc1.
2015-07-03 17:26:20 +02:00
Alexandre Wilhelm 058a73f8a0 New: added delegate methods applicationShouldTerminate and applicationShouldTerminateMessage
This PR adds the delegate methods applicationShouldTerminate and applicationShouldTerminateMessage in CPApplicationDelegateProtocol.

The delegate applicationShouldTerminate does not exactly work as in Cocoa. In Cocoa, this method is called in CPApp -terminate, but in cappuccino it is called in the method onbeforeunload of the window. In JS, this is the only time where we can prevent to reload the HTML page. If the developer cancel to reload the page, the browser will ask the user if he wants to reload or not the page thought (natural behavior of js).

The method applicationShouldTerminateMessage allows you to define what will be the text displayed in the confirmation alert.

Test app in Tests/Manual/CPPlatformWindow/
2015-07-02 16:35:35 -07:00
Alexandre Wilhelm 1ad8d34ecb Fixed: fixed travis with datePicker test 2015-07-02 15:12:18 -07:00
Alexandre Wilhelm 3f9f926c8e New: added method closeAllPlatformWindows in CPPlatform
Added the method closeAllPlatformWindows in CPPlatform. This platform close all platform windows of the application (except the main one). This method is now used when reloading or leaving a cappuccino application, the application will now close every external window openend by the application.
2015-07-02 13:41:37 -07:00
daboe01 80cf88dcc1 _textContainer refac preparation 2015-07-02 19:56:54 +02:00
daboe01 dddc7f348f fix lineheight issue during wrapping 2015-07-02 19:48:12 +02:00
daboe01 ce45f2e114 move to end of line fix 2015-07-02 06:03:05 +02:00
daboe01 d22a7c0a63 FF copy paste fix 2015-07-01 22:52:01 +02:00
daboe01 59162155de caret loc refac 2015-07-01 07:20:17 +02:00
daboe01 0f347cd0b4 revert to capp pasteboard 2015-07-01 05:58:12 +02:00
Alexandre Wilhelm 1f983db47c Fixed: refactoring of the class _CPDatePickerTextField.j. We now use the method called by interpreteKeyEvents instead of handling the key equivalent in performKeyEquivalent 2015-06-29 14:28:28 -07:00
daboe01 dc50793733 cosmetics 2015-06-29 20:58:33 +02:00
daboe01 b98329f91c end of doc fix 2015-06-29 20:54:43 +02:00
daboe01 587d8fbfa9 fix caret position 2015-06-29 20:19:47 +02:00
daboe01 26a2e9ef53 capture mode for copy/paste 2015-06-29 19:43:23 +02:00
daboe01 e5ca98a1d3 fix baseline cross multiple fragments issue 2015-06-28 21:19:33 +02:00
daboe01 5bd5e9000e fix baseline issue with native input 2015-06-28 21:07:51 +02:00
daboe01 d566642c98 improved baseline support 2015-06-28 17:16:24 +02:00
daboe01 f81ddc60ec simplify baseline code 2015-06-28 16:20:06 +02:00
daboe01 6e0b20c921 prepare baseline support 2015-06-28 16:03:23 +02:00
daboe01 0c308b38c5 move to right end simplification 2015-06-28 15:18:59 +02:00
daboe01 8e0fdf68e4 move left/right of line fix 2015-06-28 12:36:40 +02:00
daboe01 9c7a9b5674 cursor up down fix 2015-06-27 16:13:10 +02:00
daboe01 0a49e31b30 add lastmarker to linefrag 2015-06-27 16:01:42 +02:00
daboe01 9478206202 simplify insertText: 2015-06-27 15:43:10 +02:00
daboe01 c86e6f5b88 fix rare invisibility bug 2015-06-27 13:58:58 +02:00
daboe01 87868acecd formatitng 2015-06-27 13:46:31 +02:00
daboe01 6d877754da focusForClipboard fixes 2015-06-27 13:10:53 +02:00
daboe01 dd5521a07c various native deadkey fixes 2015-06-27 13:03:41 +02:00
Alexandre Wilhelm 3a6a84917b New: added CPUserNotification and CPUserNotificationCenter in Foundation
This PR adds the features CPUserNotification and CPUserNotificationCenter in Foundation.
The CPUserNotificationCenter allows you to send user notification to the system.
Right now, we only propose what the W3C proposes. We can set for a notification the title, informativeText and the icon.
We only support local notification yet.

The protocol CPUserNotificationCenterDelegate has been added as well.

Test app in Tests/Manual/CPUserNotificationTest
2015-06-26 16:36:11 -07:00
daboe01 cca142ce86 smart paste at end fix 2015-06-25 20:48:30 +02:00
daboe01 fa3567cb9f fix arrow down last line 2015-06-25 06:03:02 +02:00
daboe01 7d22230b13 keyboard-selection-extension fix 2015-06-25 05:54:34 +02:00
Alexandre Wilhelm 9694c796e3 Revert "fix disappearing buttons"
This reverts commit 7323a5e393.

Fixed #2361
2015-06-24 14:35:23 -07:00
daboe01 1b7f684ab2 make safari fix more robust 2015-06-24 21:14:24 +02:00
daboe01 fef8f4d29c safari backspace fix 2015-06-23 20:36:57 +02:00
daboe01 0d7e945623 fix native cut 2015-06-22 20:30:44 +02:00
daboe01 13ea8eae77 fix initial platform paste 2015-06-21 14:20:14 +02:00
daboe01 cdb2ef3ac7 prevent dom-flickering 2015-06-20 19:11:05 +02:00
daboe01 f216e0198f harmonize capp and system pasteboards 2015-06-20 13:23:33 +02:00
daboe01 c5c3698f43 make undo work again 2015-06-19 23:26:14 +02:00
daboe01 299d3b9f60 formatting 2015-06-19 22:41:12 +02:00
daboe01 eaaebeaebb refactoring paste 2015-06-19 22:39:41 +02:00
daboe01 2ef2d2b9c5 fix native pasteboard support 2015-06-19 22:31:57 +02:00
Antoine Mercadal da6698b216 Merge branch 'master' into capp_env 2015-06-19 10:12:02 -07:00
Antoine Mercadal c9f391dfc1 Update the installation process 2015-06-19 10:11:40 -07:00
Antoine Mercadal 0f62926623 rename cappenv_deactivate to capp_env_deactivate 2015-06-19 09:59:14 -07:00
daboe01 a856b4027b formatting 2015-06-18 20:30:05 +02:00
daboe01 e2f72ecffc prepare baseline support 2015-06-18 20:23:00 +02:00
daboe01 d888bcd473 deadkey backspace safari fix 2015-06-17 20:10:19 +02:00
daboe01 0bfd5fa9a3 fix missing parameters to _flushRange 2015-06-16 19:04:50 +02:00
daboe01 9c05ccef69 preparations for baseline alignment 2015-06-16 18:59:38 +02:00
cacaodev c7eb2ffe5c Merge remote-tracking branch 'upstream/master' into cpview-skip_settransform 2015-06-15 21:10:05 +02:00
daboe01 5281b6df77 increase timeout on FF 2015-06-15 20:49:10 +02:00
daboe01 cd5bb6a309 fix deadkey after deadkey on FF 2015-06-15 20:45:58 +02:00
daboe01 94a44d7af4 remove dead code 2015-06-15 19:50:09 +02:00
daboe01 662050b89f formatting 2015-06-14 21:34:19 +02:00
daboe01 3f7f3140eb rich copy fixes 2015-06-14 21:24:40 +02:00
Alexandre Wilhelm a419694f70 Test: updated unit test ToolsTest.j. Fixed travis... 2015-06-13 21:58:09 -06:00
cacaodev 0a20f77b08 FIXED: In CPView, the transformation matrix was set at each drawing pass, even if the matrix was the identity matrix.
Now we check if the highDPI ratio is == 1 and skip the setTransform call in this case.
2015-06-13 21:06:17 +02:00
daboe01 dc11d18161 formatting 2015-06-12 17:32:22 +02:00
daboe01 cde83e9d7d smart paste fix 2015-06-12 17:28:48 +02:00
daboe01 1476fda014 backspace fix 2015-06-12 17:22:55 +02:00
daboe01 7a875f2db4 filter out apple command keys 2015-06-11 23:03:44 +02:00
daboe01 b868f37da5 remove call to super cancelOperation:sender 2015-06-10 06:41:15 +02:00
daboe01 9bef5a62dd formatting 2015-06-09 22:46:47 +02:00
daboe01 d1aff30c9e fix invisible deadkey at beginning of newline 2015-06-09 22:43:31 +02:00
daboe01 a356dafde0 enter deadkey on exit 2015-06-09 21:14:38 +02:00
daboe01 09477384fe illegal deadkey sequence fix 2015-06-09 19:26:41 +02:00
daboe01 6b923542e8 invisibility fix 2015-06-08 21:36:30 +02:00
daboe01 9722cf718c mouse down fix 2015-06-08 20:30:24 +02:00
daboe01 702b973c87 fix Dead key input element leaves margin on right 2015-06-08 20:25:56 +02:00
Alexandre Wilhelm 472372c9ed Test: updated unittest for the tools 2015-06-08 10:35:13 -07:00
Alexandre Wilhelm d358f0d27b Fixed: xml format now has the key sourcePath instead of path for the command objj and objj2objcskeleton 2015-06-08 10:30:54 -07:00
daboe01 d66bbd95f0 add native support for deadkeys 2015-06-07 21:18:27 +02:00
daboe01 aae498509b typing attributes refactoring 2015-06-07 21:00:25 +02:00
daboe01 4987fb5f15 fontpanel color well fix 2015-06-06 19:03:37 +02:00
daboe01 b1ed299286 fix for paragraph style not being carried forward 2015-06-03 22:13:17 +02:00
daboe01 679ac3e5b1 fix caret height on last line 2015-06-02 23:25:55 +02:00
daboe01 181ef788a3 caret height fix 2015-06-02 22:47:53 +02:00
daboe01 d2caa0953f various caret fixes 2015-06-02 22:23:32 +02:00
Alexandre Wilhelm 3f88e02587 New: added the option -n to specify the name of the cocoa files generated by objj2objcskeleton 2015-06-01 15:22:56 -07:00
Antoine Mercadal 245da9b422 Add capp_env 2015-06-01 15:20:20 -07:00
Alexandre Wilhelm 8cc075aff3 Fixed: objj2objcskeleton does not work with categories on cappuccino class
Previously, when making objj2objcskeleton on a category of a cappuccino class, the cocoa category was not a cocoa class but still a cappuccino class. For instance, a CPView category was still a CPView category instead of being a NSView category.

Fixed #2344
2015-06-01 14:35:12 -07:00
Alexandre Wilhelm 128a243166 Merge branch 'master' of https://github.com/cappuccino/cappuccino 2015-06-01 13:53:56 -07:00
Alexandre Wilhelm 0e41365020 Fixed: some objj errors were not print in xml when necessary 2015-06-01 13:53:41 -07:00
daboe01 bd6d5ffbb9 formatting 2015-05-29 23:10:28 +02:00
Alexandre Wilhelm de7951f4db New: added build passing tag to the realm markdown 2015-05-27 18:38:10 -07:00
Alexandre Wilhelm bdbf1fbb43 Merge pull request #2348 from Dogild/BaseWritingDirection
New: added property baseWritingDirection in CPControl
2015-05-27 15:37:09 -07:00
Alexandre Wilhelm a7b6010ce2 Merge pull request #2358 from Dogild/CPScrollView-documentVisibleRect
Fixed: documentVisibleRect in CPScrollView does not return the expected result
2015-05-27 15:27:12 -07:00
Alexandre Wilhelm 5bba109873 Merge pull request #2346 from primalmotion/fix-popen
FIXED: Closes all streams after a OS.popen()
2015-05-27 15:25:36 -07:00
Alexandre Wilhelm d69ae60bcb Fixed: themeState of an editing CPTextField in a cell based CPTableView
Previously, when having a CPTableView cell based, the themeState of the textField were wrong. The text color was black as every textField was considered as editable. The CPTableView handled differently the textField, as long a textField is not editing, the textField is mark as non editable. Previously, the textFields were considered editable all the time.

More informations here : https://groups.google.com/forum/?fromgroups#!topic/objectivej/zImy4sj0Xz4
2015-05-27 14:57:28 -07:00
Alexandre Wilhelm a0277aba2e Merge pull request #2360 from Dogild/XMLOutputFormatObjj
New: added the option --xml-output-format for the command objj
2015-05-27 13:09:15 -07:00
Alexandre Wilhelm caba631db9 Test: updated ToolsTest.j 2015-05-27 12:38:56 -07:00
Alexandre Wilhelm 5095620005 Fixed: changed --xml-output-format to --xml in objj 2015-05-27 11:46:43 -07:00
Alexandre Wilhelm abcdc0875c Fixed: added option -x for objj and changed xml-output-format to --xml 2015-05-27 11:12:36 -07:00
daboe01 a4e41a57d7 make paragraph selection via triple click more mac like 2015-05-27 07:07:51 +02:00
daboe01 e8bb3864e3 smart delete 2015-05-26 07:37:13 +02:00
Alexandre Wilhelm 3e03d52fce Fixed: objj tests did only work on my system... 2015-05-25 15:22:30 -07:00
Alexandre Wilhelm 4f64d466fb Test: added unit test for option -xml-output-format of objj 2015-05-25 13:27:03 -07:00
Alexandre Wilhelm 3102c545ce Fixed: used url path (/Users/..) instead of absoluth path (file://Users/..) in the xml output format of objj 2015-05-25 13:26:37 -07:00
daboe01 3cd1066a8d backspace undo fix 2015-05-25 22:10:31 +02:00
daboe01 6494b7ea89 smart cut fix 2015-05-25 21:21:32 +02:00
Alexandre Wilhelm f232b327c0 Fixed: issue with options --objj-include-paths and --multifiles. Long options were not taken 2015-05-25 11:38:16 -07:00
Alexandre Wilhelm 204ed1f257 New: added the option --xml-output-format for the command objj
Previously, it was not possible to specify the desired output format of the command objj.
Now we can have either the default format or a xml format if --xml-output-format is added.
2015-05-25 11:20:55 -07:00
daboe01 2f5d13ac10 smart paste fix 2015-05-24 22:24:52 +02:00
Alexandre Wilhelm 65a379c8da Merge pull request #2359 from herbatnik/master
FIXED CPDatePicker AM/PM time format for GB locale
2015-05-21 17:24:01 -07:00
Marek Kresnicki 99df5fadbc Replaced confusing method _isEnglishFormat with _isAmericanFormat. Removed method was always true for US and GB locale while it shouldn't be. 2015-05-21 15:30:53 +01:00
daboe01 c8e6dca263 small refactoring of string sizing init 2015-05-20 19:42:03 +02:00
daboe01 9dec40eca7 init refactoring + cachekey fix 2015-05-20 05:58:32 +02:00
Alexandre Wilhelm 92cdb27e23 Fixed: documentVisibleRect in CPScrollView does not return the expected result
Previously, the method documentVisibleRect did not return the expected result. An issue happened when using this method on a scaled view. The converted rect was converted in the wrong context.

Unit test in Tests/AppKit/CPScrollViewTest.j

Fixed #2356
2015-05-19 14:30:09 -07:00
daboe01 4896043599 fix caching issue with numeric strings 2015-05-19 20:22:55 +02:00
daboe01 5f0ddeedd0 draw caret permantently during editing...
...or cursor navigation
2015-05-17 20:43:18 +02:00
daboe01 e679e760ee backspace fix 2015-05-17 20:23:41 +02:00
Alexandre Wilhelm a439688b3c Doc: move private variables to the top of files to not show them in the documentation 2015-05-15 09:55:17 -07:00
Antoine Mercadal 0d17757729 FIXED: CPPogressIndicator needs display when updateing it's state 2015-05-14 15:20:48 -07:00
Alexandre Wilhelm 899bbc2dbc Fixed: issue with determinate spinning progressBar annd value not between 0 and 100 2015-05-13 10:06:54 -07:00
Alexandre Wilhelm 57b68880db New: added indeterminate spinning progressBar
Previously, it wasn't possible to display an indeterminate spinning progressBar. Now we can as in cocoa.

Test app in Tests/Manual/CPProgressIndicator
2015-05-12 17:18:31 -07:00
Martin Carlberg 06c59763bc Merge pull request #2353 from Dogild/optionObjc
New: added option --objc to objj to generate objc files from a .j file
2015-05-12 09:19:08 +02:00
Alexandre Wilhelm 71c1d16c06 Test: fixed test ToolsTest.j 2015-05-11 21:52:04 -07:00
Alexandre Wilhelm 64c1b72481 Test: added unit test for objj2objcskeleton 2015-05-11 17:03:45 -07:00
Alexandre Wilhelm e5742e057d Fixed: issue with objj2objcskeleton and destination folder 2015-05-11 16:27:06 -07:00
Alexandre Wilhelm a9d6176fd2 New: added command objj2objskeleton. This feature is now not available from the command objj 2015-05-11 11:33:52 -07:00
cacaodev 1b0aa2a9b1 FIXED: test app merge issue with cib. Regenerated cib. 2015-05-11 10:37:00 +02:00
cacaodev a49c230bb2 FiXED: animatorClass when the receiver is a CPView custom subclass. 2015-05-11 10:34:12 +02:00
cacaodev b65749cf70 FIXED : setObject:nil in test app 2015-05-11 10:32:33 +02:00
cacaodev 0cf54a6a03 Fix a 'duplicate class' build error 2015-05-11 10:31:27 +02:00
cacaodev 4d77277f2d Merge branch 'master' of git://github.com/cappuccino/cappuccino into CPAnimationContext 2015-05-11 08:44:20 +02:00
daboe01 8b81506ed3 fix aWidth usecase 2015-05-11 05:56:52 +02:00
cacaodev 24c6509a61 FIXED: build error 'CPDictionary nil object'
CPViewAnimator : default mapping between css and capp props is now
lazily computed instead of a class var.
This was causing a build error because some values were not ready to be
read.
2015-05-10 19:23:41 +02:00
daboe01 3c32c4160d formatting 2015-05-10 18:03:42 +02:00
daboe01 1f912d86e1 small speed improvement
avoid the covering method send
2015-05-10 17:59:26 +02:00
daboe01 9c93ab0b6d fixed confusion between font an cssString 2015-05-10 15:30:40 +02:00
daboe01 6646a20a5d DOM protection 2015-05-10 15:22:56 +02:00
daboe01 92f471c476 move fontHeight to where it is needed 2015-05-10 15:19:26 +02:00
daboe01 4c7ce97650 measureText return type 2015-05-10 15:16:12 +02:00
daboe01 4d1fc994c0 refactor private sizing method to sizeWithFont: 2015-05-10 15:12:31 +02:00
daboe01 c4310c554e make DOM sizing faster 2015-05-10 13:37:36 +02:00
Antoine Mercadal c603326e58 Use try/finally to ensure popen streams are always closed 2015-05-09 10:22:13 -07:00
Alexandre Wilhelm a93e04a44e New: added option --objc to objj to generate objc files from a .j file
The command objj has now the option -c or --objc to generate objective-c files. The first arg is the file and the second the destination folder.

The objective-c class generated are basic and only contains IBOutlet and IBAction. To do that, the objective-c-parser is used. This parser is also used in xCodeCapp.
2015-05-08 23:05:58 -07:00
cacaodev db9e649f6e FIXED: missing return stmt in -indexOfTabViewItemWithIdenfier;
Refactored delegate notifications.
CPTabViewItem style.

Tests: All delegate methods are tested in CPTabViewNib manual test.
2015-05-07 22:35:02 +02:00
Alexandre Wilhelm c26aca4686 Fixed: memory leaks in CPSplitView with delegate 2015-05-04 16:43:37 -07:00
Alexandre Wilhelm f822268ae1 Test: updated manual test CPSplitViewTest 2015-05-04 16:43:13 -07:00
Alexandre Wilhelm 4ebcf40619 Fixed: make travis happy with DOM elements in CPTextView 2015-05-04 14:03:33 -07:00
Alexandre Wilhelm a884b94ac0 Test: fixe global var in CPTextViewTest.j 2015-05-04 14:02:46 -07:00
Alexandre Wilhelm 194e705982 Test: comment future test for CPTextView 2015-05-01 16:09:08 -07:00
Alexandre Wilhelm c77ec3bf20 Fixed: added coder for delegate of a CPTextView 2015-05-01 16:08:49 -07:00
Alexandre Wilhelm 0a1857249b Test: updated manual test CPTextViewCibTest 2015-05-01 16:08:30 -07:00
Alexandre Wilhelm 3be3a1f2e6 Merge pull request #2329 from daboe01/fix-issue-10
Added documentation for CPArray's hash method
2015-05-01 14:05:19 -07:00
Alexandre Wilhelm 62f9488829 New: added property baseWritingDirection in CPControl
This PR adds the support for baseWritingDirection in CPControl.
Support of nib2cib has been added as well.

Test app in Tests/Manual/CPTextFieldEditingStyleTest/
2015-05-01 12:11:03 -07:00
Antoine Mercadal 9bcaef192c Merge branch 'master' into fix-popen 2015-04-23 16:50:56 -07:00
Antoine Mercadal bcb1630f20 FIXED: Closes all streams after a OS.popen()
Previously, when popen was called, the 3 streams (stdin, stderr and stdourt) where never closed. This was the reason of the having an impossible number of open files.

This patch ensure all streams are closed after using them. This means that the ulimit trick is no more necessary
2015-04-23 16:46:01 -07:00
Alexandre Wilhelm 5f7922d7fd Fixed: crash in CPCib.j due to previous refactoring refs #c5b250236fa662e3da04e442f4414f95d64d9308 2015-04-22 16:21:24 -07:00
Alexandre Wilhelm 66b1d297ba Test: added unit test CPBundleTest 2015-04-22 15:11:47 -07:00
Alexandre Wilhelm eb4780a952 New: added protocol CPBundleDelegate 2015-04-22 15:11:19 -07:00
Alexandre Wilhelm 34f724a4a4 Fixed: capp_lint fixes 2015-04-22 11:22:44 -07:00
Alexandre Wilhelm c5b250236f New: support of base localization and nib localization 2015-04-21 18:26:28 -07:00
Alexandre Wilhelm e5b122ee61 New: added methods pathForResource:ofType, pathForResource:ofType:inDirectory: pathForResource:oftype:inDirectory:forLocalizations: 2015-04-21 18:25:58 -07:00
Alexandre Wilhelm 3b20021981 Test: updated test CPLocalizationTest 2015-04-21 18:24:50 -07:00
Alexandre Wilhelm a7d1f180a4 Test: updated manual test CPLocalizationTest to have base localization in the xib 2015-04-21 14:29:21 -07:00
Alexandre Wilhelm 68374e7c62 Fixed: fix minor issue with methods CPLocalizedStringFromTable and comment 2015-04-21 10:54:09 -07:00
Alexandre Wilhelm ba26a97ddc Test: updated test CPLocalizationTest 2015-04-21 10:53:36 -07:00
Alexandre Wilhelm 2db7ce8da1 New: added the methods CPLocalizedString CPLocalizedStringFromTable CPCopyLocalizedStringFromTableInBundle 2015-04-20 18:53:51 -07:00
Alexandre Wilhelm 6958da1adb Test: added manual test CPLocalizationTest 2015-04-20 18:53:17 -07:00
Alexandre Wilhelm cf48cd0ae5 Fixed: changed copyright of _CPLocalizableString.j 2015-04-20 10:15:05 -07:00
Alexandre Wilhelm b1b3966d41 Fixed compiling issue in CFBundle.js 2015-04-17 20:40:48 -07:00
Alexandre Wilhelm c171a37f24 New: first work on localization 2015-04-17 17:16:11 -07:00
Alexandre Wilhelm c13f1991c9 Fixed: removed stupid merging typo... 2015-04-13 16:18:46 -07:00
Alexandre Wilhelm da15cc4de7 Fixed: wrong nextValidKeyView in a CPScrollView
Previously, the nextValidKeyView was wrong when the views were in a scrollView. Cappuccino did not take in account the possibility of scrolling, the lowest views were considered as outside of the platformWindow.

Now, it works as cocoa! The nextValidKeyView is the good one in a scrollView.

This pull request fixes another issue as well. A CPTextField can now become firstResponder even if the textField is not visible (as in cocoa). Previously a jump of the (html)window occurred to the textField. Now, cappuccino will internally scroll if needed to the element, focus it and then go back to previous scrolling position.
2015-04-13 16:10:44 -07:00
Alexandre Wilhelm 44c686f494 Merge pull request #2323 from mrcarlberg/scroll_rect_to_visible_with_large_rect
Fixed: Method scrollRectToVisible:(CGRect)aRect in CPView didn’t work...
2015-04-13 13:12:27 -07:00
cacaodev 03bd5ad426 Fixed merge issue 2015-04-11 19:26:30 +02:00
cacaodev 914a3d71c2 Merge pull request #2342 from cacaodev/CPSegmentedControl-ni2cib
FIXED: segmented control height in nib2cib. Fixes #2341.
2015-04-11 10:03:50 +02:00
Alexandre Wilhelm 5c2e0935c6 Fixed: CPApplication does not send willBecomeActive and didBecomeActive when having the focus on the application again
Previously, when clicking somewhere else in the system, cappuccino did no raise the notifications willResignActive and didResignActive of the application. As well cappuccino did not raise the notifications willBecomeActive and didBecomeActive when the user was back on the application.

Now it does !

Test app in Test/Manual/CPPlatform
2015-04-10 12:59:05 -07:00
Alexandre Wilhelm e1ec604655 Test: updated manual test CPPlatformWindow 2015-04-10 11:11:22 -07:00
Alexandre Wilhelm 0dad10d6ab Fixed: notifications becomeActive and willActive were called even if the application was already active. The method run sends now an event CPAppKitDefined as in cocoa, this event will raise the notification becomeActive and willActive of the application when the application just finished to load 2015-04-10 10:57:34 -07:00
Alexandre Wilhelm 136138daab Fixed: CPTextField should not blur when resigning from a window which are not keyWindow 2015-04-10 10:55:48 -07:00
Alexandre Wilhelm 6efe563a69 Fixed: method _initOtherEventWithType: in CPEvent did not save the given windowNumber 2015-04-10 10:51:47 -07:00
Alexandre Wilhelm fd068443aa Fixed: keyWindow and mainWindow did not work when jumping from window to window when popover were open
Previously, when jumping from a platformWindow to another platformWindow where popover where opened, the wrong windows became key and main. This things occurred weird behavior of the platformWindows.

Now, it works as in cocoa, canBecomKeyWindow, becomeKeyWindow, becomeMainWindow, resignKeyWindow and resignMainWindow are called in the good order.
2015-04-09 15:14:33 -07:00
Alexandre Wilhelm 82d0f62d73 Added unittest for CPTextView 2015-04-08 13:53:10 -07:00
Alexandre Wilhelm 01ba6ddecd Fixed: floating windows did not become keyWindow and mainWindow of the application when jumping from platformWindow to another platformWindow
Previously, when having several platformWindows, jumping from another platform to another platform did not update the good key window of the application, specially when the expected windows was a panel.

Now it does. The CPPlatformWindow keeps a reference to the previous keyWindow when the window browser is about to blur. The we use this reference to update the keyWindow of the application.
2015-04-07 17:40:26 -07:00
Alexandre Wilhelm 769b379a8b Fixed: a CPPopover were closed when a click was made in another CPPlatformWindow 2015-04-07 17:39:35 -07:00
cacaodev 1b981e0695 FIXED: segmented control height in nib2cib
The -tile method now leaves the frame height unchanged instead of
sizingToFit the theme attribute « min-size ».
The « min-size » is still in use when we layout the ephemeral subviews.

This is how other controls with a min-size work.
Also added -minimumFrameSize. This CPControl subclass will return the
frame for sizeToFit, i.e. when you want to sync the frame attribute
with the minimum/visible height.

Tests : CPSegmentedControlTest & Nib2CibAlignment manual tests.

Fixes: #2341
2015-04-07 18:29:06 +02:00
Alexandre Wilhelm 9798b9fd50 Fixed: it was possible to scroll in a new platformWindow. The overflow style of the body of the plarformWindow was not set to hidden 2015-04-06 18:17:31 -07:00
Alexandre Wilhelm 10792c0bc6 New: Added listener onblur and onfocus on the CPPlatformWindow for updating keyWindow and firstResponder
Previously, when switching from a platformWindow to another platformWindow or to another application, Cappuccino did not behave as Cocoa, Cappuccino still considered that the window was key and main.

Now it works as in cocoa, the platform window lost its focus and is not the keyWindow and mainWindow of the cappuccino application.

Test app in Tests/Manual/CPPlatformWindow/
2015-04-06 17:37:08 -07:00
Alexandre Wilhelm 1c61afd3ee Test: updated CPPlatformWindow manual test 2015-04-06 17:36:53 -07:00
Alexandre Wilhelm 737ef583ee New: added delegate method windowDidMiniaturize: windowWillMiniaturize: and windowDidDeminiaturize: in CPWindow 2015-04-06 13:50:30 -07:00
Alexandre Wilhelm 7b4365bd8a New: added delegate method - (CPSize)windowWillResize:(CPWindow)sender toSize:(CPSize)aSize; in CPWindow 2015-04-06 13:34:36 -07:00
Alexandre Wilhelm 041fce743e New: added new options in nib2cib for CPTextView. It now supports the paragraphStyle, font and textColor 2015-03-31 18:17:57 -07:00
Alexandre Wilhelm ad4904a0ec Added nib2cib options _allowsUndo and _usesFontPanel for CPTextView 2015-03-31 16:38:47 -07:00
Alexandre Wilhelm 42a1bca64d Fixed: style in CPTextView 2015-03-31 16:08:16 -07:00
Alexandre Wilhelm 492a5bbb38 Fixed: memory leaks with delegate of CPTextStorage. Added protocol CPTextStorageDelegate 2015-03-31 15:48:15 -07:00
Alexandre Wilhelm c40ef22c20 New: create class _CPSelectionBox 2015-03-31 15:34:23 -07:00
Alexandre Wilhelm 783aac561a Fixed: capp_lint on AppKit/CPTextView 2015-03-31 15:14:15 -07:00
Alexandre Wilhelm 02245c150c Fixed: small issue due to refactoring 2015-03-31 15:10:59 -07:00
Alexandre Wilhelm 54a93775e4 Merge branch 'NEW--CPTextView' of https://github.com/daboe01/cappuccino into NEW--CPTextView 2015-03-31 15:05:53 -07:00
Alexandre Wilhelm ca778aac70 Merge remote-tracking branch 'origin' into NEW--CPTextView 2015-03-31 15:04:35 -07:00
Antoine Mercadal 007ca4c6b0 Merge pull request #2336 from cpasslack/cpasslack/corruptDecimalNumberAfterDecodingFix
Fixed: Encoding a [CPDecimalNumber zero] causes a corrupt CPDecimalNumbe...
2015-03-31 11:25:20 -07:00
Martin Carlberg b3dfce7b5a Fixed: Compared the rects minimum x value with it self instead of the visible minimum x value. Also fixed the test case to catch this. 2015-03-31 17:30:57 +02:00
cacaodev c75f1685c5 _CPObjectAnimator & CPViewAnimator
Make subclassing easier.
For a specific animator, can choose the implementation to invoke by
subclassing - (id) forwardingTargetForSelector:

The pattern for the animator class, if no -(id)animator is implemented,
is now <TargetClass>Animator by default and it searches for a
<TargetSuperClass>Animator if necessary.

NEW: Added support for CPAnimationTriggerOrderIn|Out animated key.
2015-03-31 00:33:28 +02:00
cacaodev db5b103ab3 Merge remote-tracking branch 'upstream/master' into CPAnimationContext 2015-03-30 22:20:46 +02:00
Alexander Ljungberg 1925b7b324 Merge branch 'refs/heads/0.9.8' 2015-03-29 13:39:28 +01:00
Alexander Ljungberg d39bcfb7bd Tests: new nil exception test for CPDictionary. 2015-03-29 13:16:51 +01:00
Alexander Ljungberg c7770c37d0 New: throw an exception on nil CPDictionary keys and values.
Previously only a deprecation warning was issued. This warning was scheduled to be removed in Cappuccino 0.9.8, this release.
2015-03-29 13:02:55 +01:00
Alexander Ljungberg ca2fb81247 This will be Cappuccino 0.9.8. 2015-03-29 12:45:10 +01:00
daboe01 b2f1c9e832 moved _CPCaret to the end 2015-03-28 21:06:28 +01:00
daboe01 cff4eebb74 caret refactoring + delegate notification fix 2015-03-28 20:59:17 +01:00
daboe01 a3aab5aeca prevent delegate related memory leaks 2015-03-28 19:59:33 +01:00
daboe01 63e5d8f7ea acceptsFirstResponder cleanup 2015-03-28 19:39:03 +01:00
daboe01 e4df7b10f6 _backgroundColor' is already declared for class CPText in superclass CPView 2015-03-28 15:27:37 +01:00
daboe01 f39a1e7d03 move inherited properties to CPText 2015-03-28 15:22:52 +01:00
daboe01 a473f6aa16 richTextPropery 2015-03-28 15:05:58 +01:00
daboe01 6907c24690 fix access to editable propery 2015-03-28 15:01:33 +01:00
daboe01 ef3d8a9277 fix access to selectable property 2015-03-28 14:59:13 +01:00
cacaodev 1a183b7f17 Merge remote-tracking branch 'upstream/master' into CPAnimationContext 2015-03-27 21:56:08 +01:00
cacaodev 88f7b30128 NEW: +tabViewItemWithViewController: 2015-03-27 14:38:59 +01:00
cacaodev 4b38389dc8 Update Manual test 2015-03-27 14:38:58 +01:00
cacaodev 865a45044f NEW: bindings support 2015-03-27 14:38:58 +01:00
cacaodev 7378d06bfd FIXED: CPTabView -insertTabViewItem:atIndex:
Before this commit, the tabViewItems and the segments were 2 different
collections. Any indexed change in the tabViewItems asked to re-sync
the segments making it difficult to maintain any persistent state. Now
the tabView items are the segments content.

Also fixed the selection update when items are removed.
See CPTabViewTest.j  and manual test Manual/CPTabViewNib/
2015-03-27 14:27:46 +01:00
Alexandre Wilhelm 55e19de8a1 Merge branch 'master' of https://github.com/cappuccino/cappuccino 2015-03-26 10:41:33 -07:00
Alexandre Wilhelm 4d7cb06481 Fixed: changed theme attributes image-search-left-margin image-cancel-right-margin by image-search-inset and image-cancel-inset in CPSearchField 2015-03-26 10:41:21 -07:00
cacaodev 7179a2995d CPTabViewItem image support 2015-03-24 23:42:44 +01:00
cacaodev 2b853df75b Merge pull request #2337 from cacaodev/CPSegmentedControl-setSelectedSegment
FIXED: CPSegmentedControl -setSelectedSegment:-1
2015-03-24 23:21:54 +01:00
daboe01 ae6bcc2987 improve critically low performance in safari
by means of caching cheap sizing data.
2015-03-24 09:59:58 +01:00
Alexandre Wilhelm ed61e5c7f7 Added test file CPTextViewTest.j 2015-03-23 20:56:40 -07:00
Alexandre Wilhelm 3581ac5ebd Fixed: nib2cib with CPTextView works. Editable, Selectable, RichText, StringValue, BackgroundColor, InsertionPointColor works 2015-03-23 14:50:43 -07:00
Alexandre Wilhelm 1f369b47d7 Added hierarchy for nib2cib of a CPTextView. NSTextViewSharedData is a object to retrieve attributes of the CPTextView 2015-03-23 13:06:22 -07:00
Christian Passlack bb9049bef4 Code-styling to match official style-guide. 2015-03-23 20:45:31 +01:00
Christian Passlack 94f15aba40 Updated Test-Cases of CPNumberFormater and CPTextfield because of the
changes for fix #2332. The test-cased failed, because now a
a CPDecimalNumber has a different UID compared to a CPNumber with the same
value. That means isEqual: will return false. In the test-cases the formatter now
generates CPNumbers to make the two Numbers compareable via isEqual.
2015-03-23 20:30:01 +01:00
Alexandre Wilhelm b16b8388ef Merge pull request #2335 from t00f/cpsearchfield_update_frame
Fixed: CPSearchField alignment from nib2cib
2015-03-23 11:39:04 -07:00
Alexandre Wilhelm b1e89e7904 New: added themeAttributes image-search-left-margin and image-cancel-right-margin in CPSearchField 2015-03-23 10:45:43 -07:00
Christophe Serafin f48e2f3b18 Fixed alignement content-inset and images for control size small and mini. 2015-03-20 15:44:37 -07:00
cacaodev bd673a3f26 FIXED: CPSegmentedControl -setSelectedSegment:-1
previously, -setSelectedSegment:-1 was not visualy deselecting the
segments and selectedSegment was not set to -1.
2015-03-20 21:19:36 +01:00
Alexandre Wilhelm 51ec699649 Removed tmp files... 2015-03-20 12:23:38 -07:00
Alexandre Wilhelm ed6be510fb Fixed: first work on nib2cib for the CPTextView. The example does not crash anymore 2015-03-20 12:22:23 -07:00
Alexandre Wilhelm 55f05ba839 Fixed: warnings when compiling 2015-03-20 10:03:42 -07:00
Alexandre Wilhelm 17c9382a21 Merge remote-tracking branch 'origin' into NEW--CPTextView 2015-03-20 09:52:51 -07:00
Christian Passlack 43c0eda2be Fixed: Encoding a [CPDecimalNumber zero] causes a corrupt CPDecimalNumber after decoding
Previously, CPNumber and CPDecimalNumber shared the same method UID and CPNumberUIDs-Dictionary.
This leads to some unexpected errors for example a [CPDecimalNumber zero] which refers to itself after
decoding. CPDecimalNumber now overwrites the method UID and has its own UID-Dictionary.

Fixes #2332
2015-03-20 11:21:07 +01:00
Antoine Mercadal f2c5515317 Merge pull request #2334 from Dogild/ReloadDataTableViewRunLoop
Fixed: reloadData in CPTableView run the runLoop
2015-03-19 18:22:24 -07:00
Christophe Serafin c1441eb758 Updated Aristo and Aristo2 alignments 2015-03-18 18:46:26 -07:00
Alexandre Wilhelm cf92fb921d Fixed: aligment for mini and small CPComboBox were wrong 2015-03-18 13:57:42 -07:00
Christophe Serafin 559ca3e97b Fixed: CPSearchField alignment from nib2cib
CPSearchField were not properly aligned in Aristo2 theme.
This fix uses the nib2cib-adjustment-frame information to align it.
It also improve the Nib2CibAlignement test.
2015-03-18 08:26:26 -07:00
cacaodev 7c095175ab Merge pull request #2324 from cacaodev/CPSegmentedControl-indexed-mutation
CPSegmentedControl
FIXED: widthForSegment: and frameForSegment: now return the correct values when the segments sizeToFit
Added indexed accessors for the segment object
Improved tile performance
With manual and ojtest
2015-03-16 12:13:03 +01:00
Alexandre Wilhelm 3b2635014c Fixed: the developer need to perform the run loop to get some informations in CPTableView. Now, the run loop is performed by the tableview 2015-03-15 19:38:06 -07:00
cacaodev 755040444a Fixed selection updating again.
This time it’s right. CPSegmentedControl does in fact allow empty
selection (-1) in cocoa.
Updated ojtets.
2015-03-15 20:42:17 +01:00
Alexandre Wilhelm 59afb012b6 Fixed: make sure to lay out the tableView when calling the method editColumn:row:withEvent:select: 2015-03-14 16:18:22 -07:00
Alexandre Wilhelm 7d9a52301c Fixed: reloadData in CPTableView run the runLoop
Previously, when reloading a CPTableView the run loop was explicitly call to layout the tableView. This is not the case in Cocoa.
You can call several times the method reloadData and this will only lay out the tableView one time.
2015-03-14 14:25:04 -07:00
cacaodev 50a53181dc Merge remote-tracking branch 'origin/CPAnimationContext' into CPAnimationContext
Conflicts:
	AppKit/CoreAnimation/CPViewAnimator.j
	Tests/Manual/CPAnimatablePropertyContainerTest/Resources/MainMenu.cib
	Tests/Manual/CPAnimatablePropertyContainerTest/Resources/MainMenu.xib
2015-03-14 21:31:12 +01:00
cacaodev 36f6fec99f Merge remote-tracking branch 'upstream/master' into CPAnimationContext
Conflicts:
	AppKit/CPView.j
2015-03-14 21:18:18 +01:00
cacaodev 83eeb488f9 Remove xcodeproj 2015-03-14 20:14:19 +01:00
cacaodev 5394a35e1a NEW: add -tile : layout all segments
Refactor -tileWithSegment: that still accepts a control with zero
segments.
2015-03-14 20:09:35 +01:00
cacaodev 0cd68ff8f8 FIXED: selection update when segmentCount changes n->0 or 0->n
If the segment count is set to 0, the [self selectedSegment] now
correctly return -1 (like cocoa).
If the segment count is set to n from 0, the first segment is selected.
See manual test.
2015-03-14 20:02:43 +01:00
cacaodev e9ae8063db Allow nil completionFunction and fix fallback == nil 2015-03-13 18:52:05 +01:00
Martin Carlberg 1c4e23512b Merge pull request #2326 from mrcarlberg/duplicate_ivar_superclass
Duplicate ivar on superclass
2015-03-13 10:36:40 +01:00
Alexandre Wilhelm 51bdfa44b1 New: added the protocol CPScrollViewDelegate 2015-03-12 14:39:42 -07:00
Alexandre Wilhelm 98d0a397a3 Fixed: _clickedRow and _clickedColumn not updated as in correclty
Previously, the var clickedRow and clickedColumn were only updated with a doubleClick.
Now clickedRow and clickedColumn are updated in the scope of a trackMouse as in cocoa. Once the method stopTracking:at:mouseIsUp is called, clickedRow and clickedColumn are set to -1 again. This var can't be used outside a user event.
2015-03-11 10:18:21 -07:00
Antoine Mercadal 1dc060123d NEW: Closing a platform window will correctly close its main CPWindow
Previously, when closing a platform window using the browser close
button, the represented `CPWindow` was not correctly closed.

This patch ensure `-(void)close` is called correctly by using the DOM
`unload` event. Also, delegate method `- (void)windowWillClose:` is
correctly called.
2015-03-10 16:35:03 -07:00
Antoine Mercadal 14349cb583 Merge pull request #2240 from Dogild/PlatformOrderOUt
New: added method initWithWindow in CPPlatformWindow
2015-03-10 13:24:00 -07:00
Aparajita Fishman eca959034c Merge pull request #2330 from daboe01/fix-issue-1686
Clarification for CPTableColumn's binding documentation
2015-03-10 11:25:58 +13:00
cacaodev 9844550d6c Use the translate(x,y) property for frameOrigin animated keyPath
Also adds a startValue arg to the function translating Capp values to
css values (needed for translate because you translate the offset).
CPViewAnimator: when ensuing animations, separate the fallback (the
function executed when animation are not supported) and the completion
function executed when the animation ends.
Cleanup xib in manual test: removed controls.
2015-03-09 21:15:17 +01:00
cacaodev 82fcf08d84 Rename 2015-03-08 21:52:42 +01:00
daboe01 845a35a9b8 rewording 2015-03-08 20:49:01 +01:00
daboe01 0e4751ebee wording 2015-03-08 20:46:56 +01:00
daboe01 56badd44f3 updated binding documentation 2015-03-08 19:20:57 +01:00
daboe01 399b3fd198 documentation for the hash method 2015-03-08 19:03:35 +01:00
cacaodev 43a7ca7fe8 Style & doc
Added @ignore directive for private methods.
Changed a parameter naming
Moved some layout code from indexed accessors to public method.
Accessors should only deal with the model, not the layout.
2015-03-07 23:04:32 +01:00
cacaodev b951624ed3 Merge remote-tracking branch 'origin/CPAnimationContext' into CPAnimationContext
Conflicts:
	AppKit/CoreAnimation/CPAnimationContext.j
	AppKit/CoreAnimation/CPViewAnimator.j
2015-03-07 20:03:05 +01:00
cacaodev 1b21f2d1c7 CPView (Animation) : simplified CSS_DESCRIPTORS.
Now easiest to subclass and not much more verbose.
CPVIEW_PROPERTIES_DESCRIPTOR is, for a given CPView subclass, the
mapping between animated keypaths and css properties and between
animated values and css values.
2015-03-07 19:51:13 +01:00
cacaodev 43ea0effa2 Replace objj FrameUpdater with a js function.
Also uses the native function window.requestAnimationFrame();
Expected improvement: the effective redraws should now happen only when
needed.
browser support = same as css animations.
2015-03-07 19:45:06 +01:00
cacaodev 6df9b95dea Code style. NEW CPView -DOMElementForKeyPath:keyPath:
-DOMElementForKeyPath:keyPath returns the DOMElement animated by the
css Animation. This allow for an element different from the view
_DOMElement to be animated.
2015-03-07 19:38:48 +01:00
Antoine Mercadal 630aa53d98 Merge pull request #2321 from william57m/master
New: added the CPCache class
2015-03-05 18:08:18 -08:00
Antoine Mercadal 40c81b88d4 Merge branch 'master' of https://github.com/cappuccino/cappuccino 2015-03-05 17:00:53 -08:00
Antoine Mercadal 027a317291 FIXED: Memory Leak with tooltips
Only populate the tooltips handler functions when necessary (when there is a tooltip and when the view is in a window) or clear them otherwise.

Tests in /Tests/AppKit/CPViewTest.j
2015-03-05 16:59:37 -08:00
Alexandre Wilhelm 81b538556d Fixed: removed unused var in CPScrollView.j 2015-03-04 13:01:32 -08:00
Alexandre Wilhelm 6aece1cf8c Fixed: changed default template for the generate ThemeDescriptor
Previously, the default template generated by capp gen for a new themeDescriptor project was not similar as the themeDescriptor of Aristo1 or 2.
This could confuse new developer who would like to create a new theme.
2015-03-03 22:50:39 -08:00
cacaodev cd7b9d31c9 Merge remote-tracking branch 'upstream/master' into CPAnimationContext 2015-03-03 23:03:10 +01:00
Martin Carlberg 03a6e6fc6a Fixed: Removed ivars that are already declared in superclass 2015-03-03 11:34:49 +01:00
Martin Carlberg 1d1aae03f3 Added: Test case for duplicate ivar in superclass 2015-03-03 11:33:50 +01:00
Martin Carlberg b47ad50d42 Fixed: Made the compiler manual test cases work again 2015-03-03 11:33:20 +01:00
Martin Carlberg a924fd0e7e Fixed: Generate compiler error when ivar is already declared in superclass 2015-03-03 11:32:18 +01:00
cacaodev 82ae908e6a Added Manual Test
Tests that widthForSegment: (the declared width) and frameForSegment:
(the effective frame) are disconnected.
Added a custom color for the divider.
2015-03-02 19:08:32 +01:00
Martin Carlberg 8e497e2a48 Fixed: Method scrollRectToVisible:(CGRect)aRect in CPView didn’t work correctly if aRect is larger then the visible rect.
If aRect is larger then the visible rect this method scrolled all they way to the opposite edge instead of the nearest.
2015-03-02 16:30:02 +01:00
daboe01 cbb4565a48 timer support for drag-scrolling 2015-03-01 21:16:49 +01:00
william57m 471fbee090 Formatting: code readability and tests improved 2015-03-01 13:05:22 -05:00
william57m d66de937d9 Formatting: to pass capp_lint and to respect Cappuccino's standards 2015-02-28 20:53:32 -05:00
cacaodev 3ea230fd17 Improved tests for segmented control
Added manual test showing fix for setLabel:forSegment for flexible
segments.
Added ojtest showing that the selection is preserved when a selected
segment is removed.
2015-02-27 13:33:11 +01:00
cacaodev 34bc571f80 FIXED: setSelected:forSegment:
Do not add to the themes array a reference to a deleted segment.
2015-02-27 11:47:42 +01:00
cacaodev db46804bfe NEW: -insertSegments:atIndexes: and -removeSegmentsAtIndexes:
These methods are not useful with the current public API but necessary
if we want to implement CPTabView insertion/deletion methods and the
CPContentBinding.
2015-02-27 11:47:22 +01:00
cacaodev 2bd0faac2e Update NSSegmentedControl.j (nib2cib) after the new titleWithChangedSegment: usage. 2015-02-27 11:47:21 +01:00
cacaodev a9a6e58d60 Simplified -tileWithChangedSegment:
Now tileWithChangedSegment: invalidates the frame of changed segments
and the following segments on the right. Then we just ask for the frame
of the last segment which will recompute all the invalidated frames and
give the total width of the container.
Added -intrinsicContentSize : the container size based on the sizes of
its segments.
2015-02-27 11:46:46 +01:00
william57m b40f980c62 New: added the CPCache class 2015-02-26 22:07:15 -05:00
cacaodev 12ac781ef8 FIXED: -widthForSegment: and - frameForSegment:
Previously, widthForSegment was returning the current width of a
segment.
Now we separate the 2 concepts: the segment width can only be set
explicitly with setWith:forSgment: or in IB. If the width is 0, it
means the actual frame sizeTofit. In this case, we compute lazily the
frame and frameForSegment: return the actual frame.
The frame is cached and can also be invalidate by setting it to a zero
frame, for example when the content of a segment changes and we need to
recompute it.
Use frameForSegment: in the code when we mean to get the real width as
opposed to the declared width.
2015-02-27 01:09:04 +01:00
cacaodev 8373ffbf10 Replace some direct ivar access with objj 2015-02-27 01:08:34 +01:00
cacaodev 0233dca884 FIXED: replace _segments[i] with [_segment objectAtIndex:i]
This will raise an out of bound exception if needed in the methods
whose  documentation says it should.
2015-02-26 15:28:16 +01:00
cacaodev c1a3162a54 FIXED: CPSegmentedControl uninitialized ivars 2015-02-26 15:28:15 +01:00
daboe01 fc2f5c3615 formatting 2015-02-26 05:55:04 +01:00
daboe01 3a5ac9df10 formatting 2015-02-26 05:53:37 +01:00
Alexandre Wilhelm 63f634af00 Merge pull request #2300 from ahankinson/fix-domserver-dead-code
Fixed: Remove unreachable code in CPDOMDisplayServer.h
2015-02-25 17:28:15 -08:00
Antoine Mercadal 9cb3eefdc4 Merge pull request #2319 from Dogild/TokenFieldkeyEquivalent
Fixed: CPApplication dispatch the event when having the auto complete menu of a CPTokenField opened
2015-02-25 11:34:44 -08:00
Antoine Mercadal 1c9e9da10f Merge pull request #2315 from Dogild/CPTableView-ViewAtColumn
New: Added method viewAtColumn:row:makeIfNecessary: in CPTableView
2015-02-25 11:31:36 -08:00
Antoine Mercadal 71c0ba63ca Merge pull request #2318 from cacaodev/CPTableView-columnbinding
FIXED: Exception when rows were removed in a table with binded columns.
2015-02-25 11:25:53 -08:00
Antoine Mercadal c04d3b2ace Merge pull request #2316 from Dogild/MethodSetNeedsLayout
New: added the method setNeedsLayout:
2015-02-25 11:23:45 -08:00
daboe01 e8497bb0cc typing attributes fix 2015-02-25 20:20:48 +01:00
Alexandre Wilhelm 3430349dd1 Fixed: CPApplication dispatch the event when having the auto complete menu of a CPTokenField opened
Previously, the CPApplication dispatched the current event when having the auto complete menu of a CPTokenField opened.
This occurs weird behavior. For instance when hitting enter on the menu and having a default button, the action of the button was triggered.
Now, the CPTokenField handles the key enter when the autocomplete menu is opened.
2015-02-25 10:16:56 -08:00
daboe01 fa6a5f75af fractional clicking support 2015-02-24 20:39:42 +01:00
daboe01 7b9eb4c87c color well font panel sync 2015-02-24 20:22:03 +01:00
cacaodev 808411bc0b FIXED: Exception when rows were removed in a table with binded columns.
Before this fix, the CPTableColumn binder was not correctly reloading
the table when the number of rows changed. Now we reload fully the
dataviews when the number of rows changes. If no rows are
inserted/deleted, there is an optimization: we just need to reload the
objectValues and leave the dataviews untouched.

With Test in Tests/AppKitCPTableViewTest.j
Fixes #2317
2015-02-24 16:15:20 +01:00
daboe01 c3ab510b57 fix copy paste of curly braces 2015-02-22 20:55:38 +01:00
Antoine Mercadal cbc653be37 Merge pull request #2313 from Dogild/UnionDistinct
New: added KVC operators unionOfObjects, distinctUnionOfObjects, unionOfArrays, distinctUnionOfArrays, distinctUnionOfSets
2015-02-21 11:38:26 -08:00
daboe01 e9efe5bbb7 fix cornercases 2015-02-21 20:01:53 +01:00
daboe01 a7c234b272 smart copy paste 2015-02-21 15:14:50 +01:00
Alexandre Wilhelm bb64d0dd54 New: added method needsLayout in CPView 2015-02-20 15:49:08 -08:00
Alexandre Wilhelm f82b478a77 New: added the method setNeedsLayout:
This PR adds the possibility to layout or not a CPView.
Previously, once setNeedsLayout was called on a CPView, it wasn't possible to cancel the layout of the view.
Now we can as in cocoa. The method setNeedsLayout will still work (it calls the method setNeedsLayout: with YES).

UnitTests in Tests/AppKit/CPViewTest.j
2015-02-20 14:36:27 -08:00
Alexandre Wilhelm 2028642efe Typo: removed console.error in CPTableView 2015-02-20 10:58:25 -08:00
Alexandre Wilhelm 9af9bd0c4c New: Added method viewAtColumn:row:makeIfNecessary: in CPTableView
This PR adds the method viewAtColumn:row:makeIfNecessary: in CPTableView.
This method first attempts to return an available view, which is generally in the visible area. If there is no available view, and makeIfNecessary is YES, a prepared temporary view is returned. If makeIfNecessary is NO, and the view is not available, nil will be returned.
An exception will be thrown if row is an invalid row index and if column is an invalid column index.
The returned result should generally not be held onto for longer than the current run loop cycle. Instead they should re-query the table view for the row view.

UnitTests in Tests/AppKit/CPTableViewTests.j
2015-02-20 10:54:45 -08:00
Alexandre Wilhelm 662bf83a88 Typo: type in _CPCollectionKVCOperators 2015-02-17 14:42:23 -08:00
Antoine Mercadal 2d474ccbda Merge pull request #2215 from Dogild/RetinaDisplayed
New: possibility to draw automatically in high DPI in canvas2D
2015-02-17 14:34:47 -08:00
Antoine Mercadal cec746d632 Merge pull request #2312 from cacaodev/CPTableView-issue2310
Fix for CPTableView issue #2310: wrong textcolor in unfocused table.
2015-02-17 14:32:45 -08:00
Alexandre Wilhelm 8371ac5b0d New: added KVC operators unionOfObjects, distinctUnionOfObjects, unionOfArrays, distinctUnionOfArrays, distinctUnionOfSets
This PR adds the KVC operators unionOfObjects, distinctUnionOfObjects, unionOfArrays, distinctUnionOfArrays, distinctUnionOfSets for array and set.

Unit-Tests Tests/Foundation/CPKVCArrayTest.j
Unit-Tests Tests/Foundation/CPSetTest.j
2015-02-17 00:14:48 -08:00
cacaodev f248788d14 Test for #2310 fix, CPTableView whitespace.
Note: It seems that CPThemeStateKeyWindow cannot be tested in the
console. A manual test with multiple windows and table views exists in
Manual/TableTest/OldTest/
2015-02-15 19:29:29 +01:00
cacaodev bf202f25dd Merge remote-tracking branch 'upstream/master' into CPTableView-issue2310 2015-02-15 18:44:32 +01:00
cacaodev 2d2472dbe9 FIXED: The firstResponder state of a table dataView was not correctly removed on dismiss. fixes #2310 2015-02-15 11:00:25 +01:00
Antoine Mercadal 3adfa3c2a8 Merge branch 'master' of https://github.com/cappuccino/cappuccino 2015-02-12 16:01:59 -08:00
Antoine Mercadal bf05155c5e [FIXED] Merge issues
During a previous merge the call to ..willDisplayView:.. and
…willRemoveView:.. for delegate methods were removed from CPTableView
and CPOutlineView
2015-02-12 16:01:38 -08:00
Antoine Mercadal d50df6a6fc Merge pull request #2306 from Dogild/WarningAppkit
Fixed: compilation warning for NSTableHeaderView.j
2015-02-12 15:58:42 -08:00
Antoine Mercadal a2b38c8d05 Merge pull request #2307 from cacaodev/patch-1
CPTableView & CPTableHeaderView : style, typos, tabs.
2015-02-12 15:57:05 -08:00
Alexandre Wilhelm d546da8b5f Fixed: issue with scaling a view. The associated canvas now upadtes its size when having a zoom 2015-02-12 12:49:18 -08:00
Antoine Mercadal 7c60ffa88d Merge pull request #2311 from Dogild/PopoverPosition
Fixed: CPPopover position does not update each time
2015-02-11 12:36:34 -08:00
Alexandre Wilhelm 6b235ab083 Fixed: CPPopover position does not update each time
Previously, when the frame of a superview of the targetedView would update, the popover did not update its position.
Now it does by observing each frame of each superviews of the targetedView.
2015-02-10 22:58:03 -08:00
Antoine Mercadal 7c4cdef66d Merge pull request #2309 from Dogild/SegmentedControlNice
Fixed: CPSegmentedControl divider wrong color
2015-02-10 11:42:07 -08:00
Antoine Mercadal c0a2da443a Merge pull request #2308 from Dogild/InvalidDateCPDatePicker
Fixed: The CPDatePicker can take invalid date
2015-02-10 11:41:56 -08:00
Alexandre Wilhelm e53658759b Merge remote-tracking branch 'origin' into RetinaDisplayed 2015-02-09 18:03:29 -08:00
Alexandre Wilhelm 6dc4c1c03a Fixed: CPSegmentedControl divider wrong color
Previously, when clicking on segment, the divider did not have the expected color. Now they does.
2015-02-09 17:56:23 -08:00
Alexandre Wilhelm 818c3b6092 Typo in CPDatePicker 2015-02-09 16:46:08 -08:00
Alexandre Wilhelm 6e5dee13e1 Fixed: The CPDatePicker can take invalid date
Previously, the CPDatePicker could get an invalid javascript date.
Now it will raise an exception when getting an invalidate date.
2015-02-09 16:44:59 -08:00
Alexandre Wilhelm cae78622f6 Fixed comiling warning for the class CPTableHeaderView 2015-02-08 22:36:25 -08:00
cacaodev c5db677663 Style, typos, tabs. 2015-02-08 21:07:27 +01:00
Alexandre Wilhelm c6942daf74 Fixed: compilation warning for NSTableHeaderView.j
Previously, there was a warning when compiling the file  NSTableHeaderView.j
2015-02-06 17:11:06 -08:00
Antoine Mercadal ea644a2293 Merge pull request #2301 from krodelin/fix-setValue_forKey
Fixed: Wrong value parameter in CPObjectController>>setValue:forKey:
2015-02-06 16:00:30 -08:00
Antoine Mercadal 01e69ce2b0 Merge pull request #2303 from cacaodev/check-box-theming
FIXED: The text color of a checkbox inside a selected table row was black
2015-02-06 16:00:11 -08:00
Antoine Mercadal 187a017c4d Merge pull request #2305 from Dogild/DuplicateTests
Fixed: Duplicate unit-tests
2015-02-06 15:58:27 -08:00
Antoine Mercadal f9ce1d17c8 Merge pull request #1892 from cacaodev/CPTableView-enumerateRows
CPTableView formatting and fixes [+1]
2015-02-06 15:52:36 -08:00
Antoine Mercadal ef4cd6a4a7 [NEW] --theme option for capp tool
This patch provides a new option to capp. You can do

```objj
capp gen [-f] [-l]  -T CustomTheme1 -T  CustomTheme2 MyProject
```
This will copy/symlink custom theme(s) from your CAPP_BUILD into the
current project’s `Resources` folder
2015-02-06 11:31:25 -08:00
Alexandre Wilhelm 6a1543cb82 Fixed: Duplicate unit-tests
Previously, some unit-tests had the same name in a test file. Now they have unique name.
2015-02-03 16:46:49 -08:00
cacaodev 80c8dcacb3 Code Style 2015-02-02 20:15:44 +01:00
cacaodev 0ad2dea722 Merge remote-tracking branch 'upstream/master' into CPAnimationContext 2015-01-30 22:35:01 +01:00
cacaodev dec3c45f6c Merge remote-tracking branch 'upstream/master' into CPAnimationContext 2015-01-29 15:09:08 +01:00
cacaodev 32a73ad4b9 FIXED: The text color of a checkbox inside a selected table row was black.\n Now it is white. the text-color values match the CPTextField values for the same theme states 2015-01-28 14:45:35 +01:00
cacaodev 452e03b894 FIXED: remove observation in -init. It was already handled in -viewWillMoveToWindow: 2015-01-27 22:01:32 +01:00
cacaodev 01bdddaee4 Merge 34c7ded (CPSelectionHighlightStyleNone and mouse click) 2015-01-27 13:09:33 +01:00
cacaodev f7c82b0920 FIXED : -startObservingFirstResponder: remaining renaming. 2015-01-27 13:04:45 +01:00
cacaodev 820eeb7752 _stopObservingFirstResponder -> _stopObservingFirstResponderForWindow: 2015-01-25 17:30:14 +01:00
cacaodev 2e25ef6f81 Merge remote-tracking branch 'upstream/master' into CPTableView-enumerateRows
Conflicts:
	AppKit/CPTableHeaderView.j
	AppKit/CPTableView.j
	Tests/AppKit/CPTableViewTest.j
2015-01-25 17:25:32 +01:00
Andrew Hankinson 5736d2c9cc Formatting: CPView
Previously CPView used "==" as an equality checker. This commit changes these to use "===" for consistency.
2015-01-22 13:31:04 -05:00
Udo Schneider 056a1f6a33 Fixed: Wrong value parameter in CPObjectController>>setValue:forKey: 2015-01-21 23:53:49 +01:00
Andrew Hankinson f96e211cd6 Tests: New tests for CPDOMDisplayServer 2015-01-20 16:19:24 -05:00
Andrew Hankinson 0d473cbe18 Formatting
Adjusting line lengths
2015-01-20 16:17:03 -05:00
Andrew Hankinson 95514b05ca Fixed: Remove unreachable code in CPDOMDisplayServer.h
The DOM_OPTIMIZATION flag was not used by any of the current compilers. This resulted in unreachable code in CPDOMDisplayServer.h. This commit removes this code.
2015-01-20 14:16:23 -05:00
Antoine Mercadal a2c0b47908 Merge pull request #2297 from daboe01/datepicker-date-constraint
Fixed: CPDatePicker does not grey out dates outside of minDate and maxDate
2015-01-15 13:44:23 -08:00
Antoine Mercadal f2528b5e9a Merge pull request #2296 from ahankinson/fixed-inconsistent-DOM-method
Fixed: Inconsistent naming of CPDOMDisplayServerSetStyleBackgroundSize
2015-01-15 11:38:32 -08:00
Antoine Mercadal 02f301dae0 Merge pull request #2294 from ahankinson/fix-issue-2293
Fixed: CPStepper class method returns `id` instead of CPStepper type
2015-01-15 11:37:38 -08:00
daboe01 6c47fc9023 disable forbidden dates 2015-01-15 20:28:46 +01:00
Andrew Hankinson f03adf727b Fixed: Inconsistent naming of CPDOMDisplayServerSetStyleBackgroundSize
Previously the method `CPDOMDisplayServerSetStyleBackgroundSize` was named `CPDomDisplayServerSetStyleBackgroundSize`, which was inconsistent with the names of all other similar methods in the CPDOMDisplayServer.h file. This commit fixes this and updates all instances of its use in CPView.j.
2015-01-15 13:59:19 -05:00
Andrew Hankinson 77684dfe31 Merge branch 'refs/heads/master' into fix-issue-2293 2015-01-15 12:00:09 -05:00
Antoine Mercadal ee688d9ae4 Merge pull request #2295 from Dogild/showCase-theme-collectionView
Fixed: showcase of themes are broken
2015-01-15 08:50:25 -08:00
Alexandre Wilhelm 9b16d3624e Fixed: showcase of themes are broken
Previously the showcase of the themes were broken. This was due to a change of the CPCollectionView, previously we used to use the delegate collectionViewDidChange. This delegate method has been removed. We now use an observer on the selectionIndexes.
2015-01-14 17:15:37 -08:00
Andrew Hankinson dc622a9bd5 Merge branch 'refs/heads/master' into NEW--CPTextView 2015-01-14 17:23:50 -05:00
Andrew Hankinson 2fc75be3dd Fixed: CPStepper class method returns id instead of CPStepper type
Previously the CPStepper class returned the `CPStepper` type instead of the `id` type. This caused warnings to be raised when initializing subclasses of CPStepper.

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

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

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

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

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

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

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

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

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

This commit adds this functionality.

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

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

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

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

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

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

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

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

Test App in Tests/Manual/CPDatePickerTest

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

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

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

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

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

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

Test /Tests/Foundation/CPNotificationCenterTest.j

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

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

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

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

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

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

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

For instance, this will throw a warning:

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

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

This will not:

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

@typedef NUSuppaType

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

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

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

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

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

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

This feature can be disabled on the preferences panel.

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

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

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

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

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

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

For instance `export IGNORE_ENV_COMMONJS=1`
2014-10-31 18:39:55 -07:00
Andrew Hankinson 49cb446f8b New: Initial commit of CFNetworkErrors file
This commit adds constants for CFURL Errors to enable cross-compatibility with the Cocoa CF and CPURL error reporting functions
2014-10-31 17:15:52 -04:00
Andrew Hankinson 82c32d7dee New: Implementation of the CoreFoundation CFError
This commit adds an implementation of the CoreFoundation CFError classes and functions.
2014-10-31 17:14:55 -04:00
Alexandre Wilhelm 9c87c36644 Fixed: refactoring of CPPlatformWindow 2014-10-30 18:08:03 -07:00
Alexandre Wilhelm be9f5ad951 Fixed: issue when initialize with contentRect in CPPlatformWindow 2014-10-30 18:04:20 -07:00
Alexandre Wilhelm d065a0cbc4 New: added method initWithWindow in CPPlatformWindow
The constructor initWithWindow: initializes a new CPPlatformWindow and set the given CPWindow as a fullPlatformWindow and bridgless window.
When using this constructor, you don't need to work with the platformWindow anymore, you can use the method orderFront: and orderOut: of the CPWindow to open or close the CPPlatformWindow.
You can also use the method setFrame: of the CPWindow to automatically change the contentRect of the CPPlatformWindow. In one word we assume that the given CPWindow and the CPPlatformWindow will have the same behavior. When not using the constructor initWithWindow:, the method setFrame: of the given CPWindow won't do anything to the CPPlateformWindow.

Test app in Tests/Manual/CPPlatformWindow/
2014-10-30 17:35:09 -07:00
Alexandre Wilhelm 02dfa638ca Fixed: orderOut on a fullPlatformWindow doesn't close the parent platformWindow
Previously, when calling the method orderOut: on the full platform window of a CPPlatformWindow, cappuccino didn't close the parent CPPlatformWindow. When he does, this only works if the parent platformWindow is not the primary platform.

Test app in Tests/Manual/CPPlatformWindow/
2014-10-30 15:59:15 -07:00
Andrew Hankinson bd71e779c3 Merge branch 'refs/heads/master' into NEW--CPTextView 2014-10-30 14:35:47 -04:00
Alexandre Wilhelm bfd0ceac53 Typo: becauwe instead of because 2014-10-29 21:50:46 -07:00
Alexandre Wilhelm ba20936c17 Fixed: unable to chain sheet in a window
Previously when chaining sheet on the same window, Cappuccino crashed.
Now chaining a sheet in the delegate method of the method endSheet: will open the next sheet.

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

Fixed #2159

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

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

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

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

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

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

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

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

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

Fixes #2211
2014-09-28 21:17:44 -07:00
Martin Carlberg 2f7681f881 Fixed: No line information was provided for compiler errors on the first line of a file 2014-09-26 13:28:44 +02:00
cacaodev e156badef6 FIXED: After a column removal, columns were not at the right place and non exposed views from the removed column were not removed 2014-09-25 23:14:54 +02:00
cacaodev ae6d379cce Improve TestTableColumn manual test to expose a bug when resizing after a column remove 2014-09-25 23:12:25 +02:00
kevin-xu a822ec729a Fixed: It cannot execute the "jake" commands correctly in the Cappuccino repository directory when it's not the Apple OS.
When running the "jake" commands in the repository directory, it would print:

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

Now, it will print:

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

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

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

Fixes #2198.
2014-09-24 13:45:49 +01:00
cacaodev 1a414ac69c view-based table: always use the proto UID as view identifier
-setDataView: was not working because the caching system was picking
views cached with the column identifier which is persistent.

Test: CPTableViewTest -testLayout
2014-09-23 13:56:52 +02:00
cacaodev f82099143f CPTableView: -_reloadDataViewsImmediately -> -reloadData
CPTableColumn: binder:-setValueFor:  is a simple data reload.
2014-09-23 12:17:52 +02:00
Alexandre Wilhelm 93743b11b2 Fixed: typo in documentation in CPView.j 2014-09-22 10:13:51 -07:00
Alexandre Wilhelm a94696e037 Fixed: refactoring of the retina drawing feature 2014-09-21 22:46:46 -07:00
Alexandre Wilhelm 0255e8980b Fixed: remove stupid debug mode 2014-09-21 22:38:11 -07:00
Alexandre Wilhelm eff9c69069 Fixed: transform matrix for retina displayed is reset when changing the frame of the view 2014-09-21 22:35:50 -07:00
Antoine Mercadal ca8a70a1ee Merge pull request #2217 from Dogild/SelectedThemeStateTableView
Fixed: CPThemeStateSelectedDataView still set when removing a view
2014-09-19 13:10:31 -07:00
Alexandre Wilhelm 903cc8ee83 Fixed: CPThemeStateSelectedDataView still set when removing a view
Previously, when removing a view from a CPTableView, the themeState CPThemeStateSelectedDataView wasn't unset. Now it does.
2014-09-19 09:59:56 -07:00
cacaodev 2dccd2f30b NEW: ojtest for method - (void)getColumn:(Function)columnRef row:(Function)rowRef forView:(CPView)aView
This internal method is used for editing and public methods rowForView: and columnForView
2014-09-18 19:23:16 +02:00
cacaodev b775cbb3bf Merge remote-tracking branch 'upstream/master' into CPTableView-enumerateRows 2014-09-18 18:36:53 +02:00
Alexandre Wilhelm 79ef6f2f75 Fixed: dpi drawing didn't work when changing the frame of a view 2014-09-17 13:35:07 -07:00
Alexandre Wilhelm 451ac297d4 Fixed: change accessors for CPViewHighDPIDrawingEnabled 2014-09-17 10:52:22 -07:00
Alexandre Wilhelm 0fd8a4507c New: possibility to draw automatically in high DPI in canvas2D
Previously, Cappuccino didn't handle retina device when drawing for canvas2D. Now it does.
To do that, Cappuccino will firstly calculate the pixel ratio of the current device, then it needs to change the css style of the canvas by multiply it by the current pixel ratio and finally scale the canvas by this pixel ratio.

More information about high DPI drawing here : http://www.html5rocks.com/en/tutorials/canvas/hidpi/

Added the method `setAllowsHighDPIDrawing:` and `allowsHighDPIDrawing` to deactivate or activate this feature.

Fixed #2175
2014-09-17 10:27:26 -07:00
Martin Carlberg 13fe318110 Fixed: When the compiler can't find a protocol in a class declaration it now gives an understandable error.
This fixes #2212
2014-09-16 20:13:42 +02:00
daboe01 49c7e7ce2d style 2014-09-15 20:10:24 +02:00
daboe01 1af7d01d96 fix of resizing regression 2014-09-15 18:20:53 +02:00
daboe01 66c6938df0 changed selection drawing from canvas to DOM
fixes height limitation, is faster and looks better
2014-09-14 21:24:23 +02:00
daboe01 bb9fb04788 make triple clicks behave more apple like 2014-09-13 20:24:27 +02:00
daboe01 f5cf2b2b55 fix selecting last character 2014-09-13 20:13:08 +02:00
Antoine Mercadal b9b396a279 FIXED: using setHidden: for a button in buttonbar was not working
Previously, CPButtonBar was not updating its layout after changing the visibility of its buttons.
This patch adds makes CPButtonBar observersing the buttons and relayout if the visibility of one button is updated.
2014-09-12 14:42:27 -07:00
cacaodev a2755221d0 The cocoa behavior is:
Exclusive bindings are impossible in IB
Possible in code (tested with segmented control and selectedIndex & selectedTag) but then you get unexpected behavior. A segment can be selected after a click and then
changes to another segment.
After this commit, extra exclusive bindings are just ignored and we warn about it.
2014-09-12 22:33:50 +02:00
cacaodev 3e8afaeae4 Fixed: -removeTableColumn: now works without error. OJTest in AppKit/CPTableColumnTest.j, manual test in TableTest/TestTanleColumn/
Fixed: Added an out of bounds check to _unloadDataViews:...
Revert: revert -reloadData to the previous behavior where views & data were reloaded, not only data. That's what cocoa does for view based tables.
2014-09-11 23:14:21 +02:00
daboe01 43169ced69 fix of the fix 2014-09-11 10:45:27 +02:00
daboe01 708844857d make canvas sizing detection more robust 2014-09-11 10:22:50 +02:00
Alexandre Wilhelm 83ec89fa20 Fixed: CPDatePicker send an action with the methods setObjectValue: and setDateValue:
Previously, the CPDatePicker sent an action to the target when the method setObjectValue: and setDateValue were called.
Now it sends the action only when the user makes an action.

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

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

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

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

All credits for @apajarita

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

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

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

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

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

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

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

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

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

Refs #1880
Refs #2024

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

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

Added unit-test in Tests/AppKit/CPViewTest.j
2014-08-19 14:26:26 -07:00
Christophe Serafin d1985bad3b update Nib2CibAlignment test 2014-08-18 13:09:51 -07:00
Christophe Serafin c83a4dc8e4 fix _adjustNib2CibSize calls 2014-08-18 13:09:15 -07:00
Christophe Serafin 5484bbf8bf fix Aristo and Aristo2 alignments 2014-08-18 13:08:47 -07:00
Christophe Serafin 62e8d70d74 fix _adjustNib2CibSize calls 2014-08-18 13:08:09 -07:00
Alexandre Wilhelm b2f1477b45 Fixed: wrong condition in CPApplication 2014-08-15 16:37:03 -07:00
Christophe Serafin 7323a5e393 fix disappearing buttons 2014-08-15 09:04:26 -07:00
Christophe Serafin f8205cc376 realign Aristo2 buttons for fix 6f9210 2014-08-15 08:20:46 -07:00
Antoine Mercadal 1b639ab978 Improve test XIB 2014-08-15 01:01:47 -07:00
Antoine Mercadal 4828f7478e Merge branch 'master' into themeable-rule-editor 2014-08-14 21:05:58 -07:00
Antoine Mercadal 9646f7039a Update XIB 2014-08-14 21:05:16 -07:00
Antoine Mercadal 6f921028de do not call again _adjustNib2CibSize 2014-08-14 21:04:57 -07:00
Antoine Mercadal 2508db0550 Remove usless computation 2014-08-14 21:04:32 -07:00
Antoine Mercadal 775141b7f7 Merge branch 'themeable-rule-editor' of https://github.com/t00f/cappuccino into themeable-rule-editor 2014-08-14 21:03:45 -07:00
Antoine Mercadal a2d9c1aa72 Merge pull request #2174 from Dogild/PopoverDelegate
Fixed: delegate popover did show not called with a none animate CPPopover
2014-08-14 20:59:29 -07:00
Christophe Serafin 4b639843ec fixed buttons positions and extended Nib2CibAlignment test 2014-08-14 18:18:08 -07:00
Christophe Serafin 464389a862 update nib2cib-adjustment-frame to match Nib2CibAlignment Test. Except for button in small and mini sizes 2014-08-14 14:17:57 -07:00
Alexandre Wilhelm 48b3eb259d Fixed: delegate popover did show not called with a none animate CPPopover
Previously, the delegate popoverDidShow wasn't called with an none animated CPPopover.
2014-08-14 14:10:37 -07:00
daboe01 4cebfbcd13 removed collectionViewDidChangeSelection 2014-08-14 22:57:05 +02:00
daboe01 1767cf8ad4 formatting+nil equality 2014-08-14 22:41:59 +02:00
daboe01 b1981bb70c fix activateIgnoringOtherApps:shouldIgnoreOthe... 2014-08-14 22:27:46 +02:00
Christophe Serafin 3dc581efbb introduce nib2cib-adjustment-frame as theme attribute to enbable proper control alignment 2014-08-14 10:54:38 -07:00
Christophe Serafin 655cc3256c remove arbitrary CONTROL_HEIGHT 2014-08-14 10:45:12 -07:00
daboe01 ce69410f49 revert of breaking change wrt backspace 2014-08-14 18:21:53 +02:00
daboe01 5f0be0cc7f make storage length zero more tolerant 2014-08-14 14:14:49 +02:00
Andrew Hankinson dca6347ea9 Fixed: Remove lingering references to i
Refs 75e347e8e3
2014-08-14 07:19:53 -04:00
daboe01 94c4db9072 fixed equality operator 2014-08-14 07:17:00 +02:00
Andrew Hankinson 7f63be2cd2 Formatting: Make if statement more readable
The if statement had a lot of sub-clauses. These were factored out into variable assignments.
2014-08-13 19:56:50 -04:00
Andrew Hankinson 1236dea4c5 Fixed: equality operators 2014-08-13 19:47:06 -04:00
Andrew Hankinson c5c46df613 Fixed: typo 2014-08-13 19:44:23 -04:00
Andrew Hankinson a96269150a Fixed: AppKit.j is alphabetized
CPTextView.j was out of alphabetical order. This commit fixes that.
2014-08-13 19:34:56 -04:00
Andrew Hankinson 75e347e8e3 Fixed: obscure use of variables
Previously, the counting variable "i" was used as a variable throughout this method, leading to the value of 'i' becoming unclear as the method progressed.

Additionally, a later loop in this method redeclared 'i', providing more confusion.

This commit renames 'i' to the more descriptive 'targetLine' and uses that in its place. The redeclared value of 'i' was also renamed to "newTargetLine".
2014-08-13 18:15:58 -04:00
daboe01 d641cc5057 fix fussy optimization 2014-08-14 00:12:02 +02:00
Christophe Serafin bf5b660cb5 fix background size with 1-part image 2014-08-12 17:26:43 -07:00
Christophe Serafin 712dc493ca remove CPDateFormater dependancy and CPString convertion 2014-08-12 15:42:03 -07:00
Christophe Serafin f4fba64ffb remove test on sendAction 2014-08-12 14:06:37 -07:00
Christophe Serafin 02430916cb add CPDatePicker without CPStepper in CPControlSize test demo 2014-08-12 13:58:05 -07:00
Christophe Serafin e3ad115698 correction based on primalmotion comments 2014-08-12 13:56:25 -07:00
Christophe Serafin c078bb04b2 Correction and optimizations based on Alex comments. Fix for CPDatePickerTest 2014-08-12 13:31:22 -07:00
Antoine Mercadal d95e133792 Merge pull request #2171 from Dogild/CPTextField-Platform
Fixed: Checking if a CPTextField is usable in a CPPlatformWindow
2014-08-12 12:11:50 -07:00
Alexandre Wilhelm a04f1045bc Fixed: Checking if a CPTextField is usable in a CPPlatformWindow
Previously, when a CPTextField was in a CPPlatformWindow, the checking of if the CPTextField was usable or not (depending on its position) in a CPPlatformWindow didn't take in account the content-inset of the CPTextField. Now it does.
2014-08-12 11:27:25 -07:00
daboe01 cf64145ff3 formatting 2014-08-12 16:06:49 +02:00
daboe01 195eca6b09 typesetter early exit in flushing fix 2014-08-12 15:48:31 +02:00
daboe01 b0ef077e48 fix typesetter nil bug 2014-08-12 15:12:19 +02:00
daboe01 e40a698d1a fixed accessor 2014-08-12 10:37:05 +02:00
daboe01 69c34b1b27 formatting 2014-08-12 08:33:28 +02:00
daboe01 4700c2583d fix acessor names 2014-08-12 08:29:28 +02:00
Christophe Serafin db6975e07a force size only for bordered buttons and bezeled textfields 2014-08-11 18:08:15 -07:00
Christophe Serafin 93127489e7 stop forcing font on CPButton and CPTextField. If the developper wants to set a bigger font it is possible in Cocoa 2014-08-11 17:25:31 -07:00
Christophe Serafin 83064294ac remove useless images and declaration 2014-08-11 15:04:35 -07:00
Christophe Serafin 0b64758360 adjust CPPopUpButton alignment 2014-08-11 15:04:06 -07:00
Christophe Serafin 4e1a2c04a5 create a CPControlSize Manual test to verify control sizes with a certain theme 2014-08-11 14:27:01 -07:00
Christophe Serafin 8412c1db21 enable autoresize theme images instead of creating small and mini images. Remove all existing small and mini images 2014-08-11 14:25:02 -07:00
Antoine Mercadal 18a7a9fdce Merge pull request #2168 from Dogild/CPOutlineView-fixed
Fixed: Memory leaks in CPOutlineView + corrupted itemInfos dictionary
2014-08-11 14:15:59 -07:00
Antoine Mercadal fc90d00354 Merge branch 'master' of https://github.com/cappuccino/cappuccino 2014-08-11 12:47:12 -07:00
Antoine Mercadal 55861a8f44 FIXED: transient popovers were not close with right click
This patch ensure that is a popover is transient and the user right clicks outside, it closes properly.
2014-08-11 12:46:09 -07:00
Alexandre Wilhelm 4fbd307163 Fixed: refactoring of the class CPOutlineView 2014-08-09 15:10:25 -07:00
Alexandre Wilhelm 3e4c03852d Fixed: Memory leaks in CPOutlineView + corrupted itemInfos dictionary
Previously, when reloading a CPOutlineView with different datas than before, the CPOutlineView kept a reference of the previous datas.
Now, when reloading, the CPOutlineView will delete these references when we don't need it anymore. For that, the CPOutlineView will only try to delete the previous reference when we have reloaded the children of a node, otherwise it will keep the other references.

This PR fix some issue with the following methods :

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Fixes #2013.
2014-07-23 15:04:07 +01:00
Alexander Ljungberg 7470f4ffcf New: CPEvent scrollingDeltaX, scrollingDeltaY and hasPreciseScrollingDeltas.
Refs #2013.
2014-07-23 15:00:30 +01:00
Alexander Ljungberg 81f9748313 Merge pull request #2013 from daboe01/fix-scrollwheel-speed-on-firefox
Fixed: scroll wheel speed is way to low in firefox [+1]
2014-07-23 13:49:19 +01:00
Alexander Ljungberg 58928a5000 Formatting: CPDateFormatter changes and tests.
Refs #2155.
2014-07-22 12:49:35 +01:00
Alexander Ljungberg 4c44ede945 Merge pull request #2155 from krodelin/CPDateFormatter-emptyLanguages
Fixed: CPDateFormatter now works for non-"en" locales [+1]
2014-07-22 12:41:03 +01:00
Alexander Ljungberg d3c4105429 Formatting recent changes. 2014-07-22 12:09:06 +01:00
daboe01 9cf8ec5dd7 formatting 2014-07-20 19:55:49 +02:00
daboe01 f5187b1533 _characterRangeForUn...: ternary operator 2014-07-20 11:44:03 +02:00
daboe01 6230a65a79 removed useless unit test 2014-07-20 11:24:22 +02:00
Alexandre Wilhelm f13c96839e Fixed synthax in CPTextView 2014-07-19 19:07:08 -07:00
Alexandre Wilhelm 776f68c9dd Fixed style in CPTextView 2014-07-19 18:46:25 -07:00
Alexandre Wilhelm 714ed89a4c Merged 2014-07-19 16:58:59 -07:00
Antoine Mercadal ed307adb22 Merge pull request #2135 from Dogild/TokenFieldDelegate
Fixed: unsigned delegate methods of CPTokenField erased by CPTextField
2014-07-18 18:42:49 -07:00
Antoine Mercadal 8001688daf Merge pull request #2076 from cacaodev/issue2039
FIXED: Error when binding several objects to the same objectController [+1]
2014-07-18 18:42:18 -07:00
Antoine Mercadal 4c0687b9a5 Merge branch 'fix-menu-enabled-bindings' of https://github.com/daboe01/cappuccino into daboe01-fix-menu-enabled-bindings 2014-07-15 10:22:46 -07:00
Alexandre Wilhelm 33043dd8af Fixed: removed unsued code in CPTokenFieldTest 2014-07-13 21:25:35 -07:00
daboe01 0b2b29b7cf removed unit test 2014-07-12 14:09:59 +02:00
Alexandre Wilhelmanddaboe01 a41c0a0519 Fixed: Update test CPTextViewCibTest 2014-07-12 14:03:32 +02:00
Alexandre Wilhelmanddaboe01 026e28114e Added : added default NSTextView for nib2cib 2014-07-12 14:03:32 +02:00
Alexandre Wilhelmanddaboe01 0840719289 Added: added CPTextViewCibTest 2014-07-12 14:03:32 +02:00
daboe01 aad875e113 make the plain look as white as in cocoa 2014-07-12 14:03:32 +02:00
Alexandre Wilhelmanddaboe01 6b059d94ba Fixed: reduce size of the test of CPTextView 2014-07-12 14:03:32 +02:00
Alexandre Wilhelmanddaboe01 39eeaea7e7 Fixed: circular import with CPText
Previously CPText was in CPTextView.j, now it is in CPText.j.
It fixes some other circular import as well, fixes some global var to import.
Fixed some code style.
2014-07-12 14:03:32 +02:00
daboe01 81a8e91180 fix cut with empty selection 2014-07-12 13:58:39 +02:00
Alexandre Wilhelmanddaboe01 4fc6f6f59b Fixed: refactoring delegate methods 2014-07-12 13:58:39 +02:00
Alexandre Wilhelmanddaboe01 dd2f573f27 Fixed: changed a bit the readability of the file 2014-07-12 13:58:39 +02:00
Alexandre Wilhelmanddaboe01 ff8ddc431b New: Added protocol CPTextViewDelegate 2014-07-12 13:58:38 +02:00
daboe01 d703945aa3 corrected inheritance 2014-07-12 13:58:38 +02:00
Alexandre Wilhelmanddaboe01 f4aba5f9ea New: Added protocol CPTextDelegate 2014-07-12 13:58:38 +02:00
Alexandre Wilhelmanddaboe01 393113c3e3 Fixed: capp_lint 2014-07-12 13:58:38 +02:00
Alexandre Wilhelmanddaboe01 f2db18820a Fixed: CPLog.error is used instead of abstract exception 2014-07-12 13:58:38 +02:00
daboe01 e04d300e18 next try 2014-07-12 13:58:38 +02:00
daboe01 685f836f41 another try 2014-07-12 13:58:38 +02:00
daboe01 d4f5ad641a more dom protection 2014-07-12 13:58:38 +02:00
daboe01 007d437ee8 dom projection 2014-07-12 13:58:38 +02:00
daboe01 00e380e8d8 more dom protection 2014-07-12 13:58:38 +02:00
daboe01 56749d9494 protecting document access with PLATFORM(DOM) 2014-07-12 13:58:38 +02:00
daboe01 cf10d37c90 automated tests and cleanup 2014-07-12 13:58:38 +02:00
daboe01 f9de34e36d font panel fix 2014-07-12 13:58:38 +02:00
daboe01 aa889be140 formatting 2014-07-12 13:58:38 +02:00
daboe01 6da6838bde beginning/end of line navigation + cleanup 2014-07-12 13:58:37 +02:00
daboe01 07a0be303f smart cutting+cleanup 2014-07-12 13:58:37 +02:00
daboe01 ddbe0af290 fix <cr> issue 2014-07-12 13:58:37 +02:00
daboe01 e71f0f44a4 fix relayouting optimization bug 2014-07-12 13:58:37 +02:00
daboe01 39f3bc7100 better workaorund for chrome bug 2014-07-12 13:58:37 +02:00
daboe01 211a145e58 stability improvement 2014-07-12 13:58:37 +02:00
daboe01 d2339b915f spooky chrome fix 2014-07-12 13:58:37 +02:00
daboe01 24c2651745 reverting erroneous patch 2014-07-12 13:58:37 +02:00
daboe01 36e95b93b4 typesetter fix 2014-07-12 13:58:37 +02:00
daboe01 e7a44e0b15 removed debugging code 2014-07-12 13:58:37 +02:00
daboe01 fbdb21ac72 style 2014-07-12 13:58:37 +02:00
daboe01 c9522cf6ae more style 2014-07-12 13:58:37 +02:00
daboe01 7bf9d334ad style 2014-07-12 13:58:37 +02:00
daboe01 422ff93dcd added support for setWidthTracksTextView: 2014-07-12 13:58:37 +02:00
daboe01 eee1ea7a09 fontmanager fix 2014-07-12 13:58:36 +02:00
daboe01 b90e482add typo 2014-07-12 13:58:36 +02:00
daboe01 875b51720b more missing prototypes 2014-07-12 13:58:36 +02:00
daboe01 5272d4f9e3 style 2014-07-12 13:58:36 +02:00
daboe01 c980f4f6e3 prototypes+style 2014-07-12 13:58:36 +02:00
daboe01 89525330c4 formatting+prototypes 2014-07-12 13:58:36 +02:00
daboe01 806db24c0e formatting+ fix prototypes 2014-07-12 13:58:36 +02:00
daboe01 ba7d6df5a4 formatting 2014-07-12 13:58:36 +02:00
daboe01 112301e0e0 formatting 2014-07-12 13:58:36 +02:00
daboe01 c07065e457 more formatting 2014-07-12 13:58:36 +02:00
daboe01 b9e1afae17 formatting 2014-07-12 13:58:36 +02:00
daboe01 549b4a9ebf formatting 2014-07-12 13:58:36 +02:00
daboe01 fa9a3fb7c4 formatting 2014-07-12 13:58:36 +02:00
daboe01 ccb15f278a formatting 2014-07-12 13:58:36 +02:00
daboe01 f0fb4b8842 formatting 2014-07-12 13:58:35 +02:00
daboe01 dacaf293b2 fix of circular imports 2014-07-12 13:58:35 +02:00
daboe01 627d0e4e6f fix circular imports 2014-07-12 13:58:35 +02:00
daboe01 f32b9e26e0 eliminate warnings + style 2014-07-12 13:58:35 +02:00
daboe01 db2b1a0a35 typos 2014-07-12 13:58:35 +02:00
daboe01 f734a60c62 manual test 2014-07-12 13:58:35 +02:00
daboe01 9aa815c1ed CPTextView commit 2014-07-12 13:58:35 +02:00
Antoine Mercadal 1848f96efa FIXED: style 2014-07-10 11:39:43 -07:00
Antoine Mercadal 51440cc7f7 Merge branch 'FIXED--insertAttributedString-did-not-coalsece' of https://github.com/daboe01/cappuccino into daboe01-FIXED--insertAttributedString-did-not-coalsece 2014-07-10 11:38:37 -07:00
Antoine Mercadal 09f100c0c2 Merge branch 'fix-cfhttp-cpurl-2141-2138' of https://github.com/ahankinson/cappuccino into ahankinson-fix-cfhttp-cpurl-2141-2138 2014-07-09 15:45:28 -07:00
Antoine Mercadal a8b66abe15 Merge pull request #2151 from Dogild/EscapePanelRefac
Fixed: escape on a panel or popover breaks the key chain event
2014-07-09 14:12:50 -07:00
Antoine Mercadal 03c45a78a9 Merge branch 'popoverOpen' of https://github.com/Dogild/cappuccino into Dogild-popoverOpen 2014-07-09 14:06:12 -07:00
Alexandre Wilhelm 6574d4450f Fixed: style in _CPPopoverWindow 2014-07-07 20:55:48 -07:00
Alexandre Wilhelm d7f0ff84d6 Fixed: code style in CPPopover 2014-07-07 19:21:00 -07:00
Andrew Hankinson 5ef4c8e83e Fix: Remove _backgroundColor
This parameter exists on CPView, so it has been removed here. A note was added on the setter to identify that the parameter was defined in the superclass.
2014-07-02 08:34:40 +01:00
Andrew Hankinson 5ab48c6015 Fixed: Updated backgroundColor internal variable handling
Previously, _textFieldBackgroundColor was used as the internal variable, and getter/setter methods were explicitly declared to handle getting/setting this value.

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

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

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

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

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

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

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

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

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

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

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

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

This commit adds the withCredentials property to CFHTTPRequest.

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

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

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

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

Test app in Tests/Manual/CPTextFieldEditingStyleTest/

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

Fixed #2133
2014-06-04 11:19:32 -07:00
daboe01 f1adf24f3b make the plain look as white as in cocoa 2014-06-04 18:34:46 +02:00
Alexandre Wilhelm 856765a775 Fixed: reduce size of the test of CPTextView 2014-06-03 21:15:21 -07:00
Alexandre Wilhelm 075da34cdb Fixed: circular import with CPText
Previously CPText was in CPTextView.j, now it is in CPText.j.
It fixes some other circular import as well, fixes some global var to import.
Fixed some code style.
2014-06-03 21:05:04 -07:00
Alexander Ljungberg 7c6ef51cb2 New: CPDate dateByAddingTimeInterval:.
Refs #2126.
2014-06-03 17:41:35 +01:00
Alexandre Wilhelm 1e1297378c Fixed: font cell of a CPTableView comes black when editing another cell
The font of a default dataView came black when editing another cell of the tableView.
Now it stays black.

Fixed #2130
2014-06-02 17:31:32 -07:00
daboe01 5ce543002d fix cut with empty selection 2014-06-02 20:39:53 +02:00
Alexandre Wilhelm ac53b30f25 Fixed: CPComboBox doesn't work in modal.
Previously a CPComboBox didn't work when its parent window was in modal. Now it works.

Fixed #2122
2014-06-01 21:18:14 -07:00
Alexandre Wilhelm a5448549b1 New: Added feature to select a set of dates with a shift click in CPDatePicker
Previously it wasn't possible to select a set of dates with a shift click, now we can.
This works only when the mode CPRangeDateMode is set.
It has the same behavior as in Cocoa.
2014-05-31 21:33:59 -07:00
Alexandre Wilhelm 700b1c50af Fixed: refactoring delegate methods 2014-05-30 12:27:43 -07:00
Alexandre Wilhelm 9e1c363a0a Fixed: changed a bit the readability of the file 2014-05-30 12:04:51 -07:00
Alexandre Wilhelm bbe3065f19 Merge branch 'NEW--CPTextView' of https://github.com/daboe01/cappuccino into NEW--CPTextView 2014-05-30 11:37:50 -07:00
Alexandre Wilhelm 1716a0ebca New: Added protocol CPTextViewDelegate 2014-05-30 11:37:37 -07:00
daboe01 ed66339e94 corrected inheritance 2014-05-30 20:36:14 +02:00
Alexandre Wilhelm 441774e61c New: Added protocol CPTextDelegate 2014-05-30 11:27:31 -07:00
Alexandre Wilhelm c6fd14afd2 Fixed: capp_lint 2014-05-30 11:12:29 -07:00
Alexandre Wilhelm 27ed9ca7fd Merge branch 'NEW--CPTextView' of https://github.com/daboe01/cappuccino into NEW--CPTextView 2014-05-30 10:58:29 -07:00
Alexandre Wilhelm 50fda906bd Fixed: CPLog.error is used instead of abstract exception 2014-05-30 10:49:10 -07:00
daboe01 6c7c60037b next try 2014-05-30 19:44:37 +02:00
daboe01 91a429ea77 another try 2014-05-30 19:19:15 +02:00
daboe01 2dbe01e90a more dom protection 2014-05-30 18:52:00 +02:00
daboe01 3d7dd41223 dom projection 2014-05-30 17:17:28 +02:00
Alexandre Wilhelm a83b9109bf Fixed: typo in CPDatePicker 2014-05-29 15:13:17 -07:00
Alexander Ljungberg fdb079548e Merge pull request #2103 from mrcarlberg/fast_msg_send
Fixed: Faster objj_msgSend
2014-05-29 21:51:57 +01:00
daboe01 91495c8595 more dom protection 2014-05-29 20:37:27 +02:00
daboe01 c3e997168a protecting document access with PLATFORM(DOM) 2014-05-29 20:31:55 +02:00
daboe01 c3e6f4f7b6 automated tests and cleanup 2014-05-29 16:27:07 +02:00
Antoine Mercadal effd837cd0 Merge pull request #2126 from Dogild/DatePickerTabIssue
Fixed: CPDatePicker firstResponder issue
2014-05-27 11:15:00 -07:00
Alexandre Wilhelm 089d564934 Fixed: CPDatePicker firstResponder issue
Previously, the textual datePicker didn't work because it couldn't become the firstResponder.
This PR fixed another issue as well. Previously it wasn't possible to modify a date when moving only with tab and when the datePicker came firstResponder with tabulation.
2014-05-27 10:12:02 -07:00
daboe01 e600ec95ed font panel fix 2014-05-25 09:27:54 +02:00
daboe01 cbd5853389 formatting 2014-05-24 19:32:25 +02:00
daboe01 4e3a086993 beginning/end of line navigation + cleanup 2014-05-24 08:53:53 +02:00
daboe01 5f23dfb034 smart cutting+cleanup 2014-05-23 21:46:59 +02:00
Alexander Ljungberg 90c65c2927 Merge pull request #2125 from Dogild/bootstrapRegex
Fixed: bootstrap doesn't handle specific OpenJDK Runtime Environment version
2014-05-23 11:55:14 -07:00
Alexandre Wilhelm 7958775c6a Fixed: bootstrap doesn't handle specific OpenJDK Runtime Environment version
Previously, bootstrap didn't handle some OpenJDK Runtime Environment version as: rhel-2.4.7.1.el6_5-x86_64 u55-b13.
Now it did, the regular expression to catch the version of the jdk was wrong.

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

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

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

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

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

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

This fix removes the semicolon in favour of a comma.

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

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

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

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

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

Added private - (void)_reloadDataForRowIndexes:(CPIndexSet)rowIndexes
columnIndexes:(CPIndexSet)columnIndexes
This is the internal method for reloading objectValues only.
2014-04-19 09:10:51 +02:00
cacaodev 57408d18ae New: ojunit tests for CPTableView -reloadData & -removeTableColumn:
-removeTableColumn: is failing with an « index out of bounds » error.
2014-04-19 09:05:14 +02:00
Alexandre Wilhelm 372372a0aa Fixed: capp_lint doesn't handle protocol
Previously capp_lint didn't handle protocol. Now it does

Fixed #2060
2014-04-18 18:41:27 -07:00
Alexandre Wilhelm 7f35ff5fe5 Fixed: capp_lint for the entire project is not launch from a thread 2014-04-18 11:18:53 -07:00
Alexandre Wilhelm c28cd8a270 Fixed: capp_lint on the entire project doesn't remove the content of the error tableview 2014-04-18 10:47:00 -07:00
cacaodev 3a97db804f Merge remote-tracking branch 'upstream/master' into CPTableView-enumerateRows
Possible regression from #fe260a8
Regression: -reloadData does not reload views any more even if the table is empty (see CPOutlineViewCibTest).
BUG: -removeTableColumn: error.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Unit test in Tests/AppKit/CPTableViewTest.j
2013-12-08 17:48:41 -08:00
Alexander Ljungberg 7662f89193 Update some more version numbers. 2013-11-28 19:51:15 +00:00
Alexander Ljungberg dbb59f57ea This will be Cappuccino 0.9.7. 2013-11-28 19:48:29 +00:00
Alexander Ljungberg c1f538ece5 Formatting: whitespace.
Refs #1974.
2013-11-28 18:39:01 +00:00
Alexander Ljungberg b4cabc97d1 Merge pull request #1974 from mrcarlberg/protocol
Protocol support for Objective-J
2013-11-28 17:18:16 +00:00
Antoine Mercadal cf2e66d7fe Merge pull request #2021 from Dogild/sheetDoubleClickBug
Fixed: when doubleClicking to open/close a sheet, issues with the parentWindow and the frameOrigin of the sheet
2013-11-25 15:49:08 -08:00
Martin Carlberg e511638962 Fixed: Cleaned up return and parameter types on methods. 2013-11-24 22:21:56 +01:00
Martin Carlberg 8419001810 Merge branch 'master' of https://github.com/cappuccino/cappuccino into protocol 2013-11-22 14:23:52 +01:00
Alexandre Wilhelm e058d2e143 Fixed: when doubleClicking to open/close a sheet, issues with the parentWindow and the frameOrigin of the sheet
When opening a sheet, with a double click the frame origin of the sheet changed and the parent disappeared.
This PR fix this issue.

Test app in Tests/Manual/AttachedSheet/AppController.j
2013-11-21 17:42:43 -08:00
daboe01 40da5a849d formatting 2013-11-19 20:14:35 +01:00
Antoine Mercadal 616f0c61ef Fixed: Typo introduced in previous PR merge 2013-11-18 16:26:50 -08:00
Antoine Mercadal d0ef8a2885 Merge pull request #2005 from adamsowinski/master
Fixes a bug with CPCursor push method.
2013-11-18 16:22:43 -08:00
Antoine Mercadal 985db21ed9 Merge pull request #1990 from spebbe/cpanimation_frame_rate
CPAnimation frame rate fixes.
2013-11-18 16:20:29 -08:00
Antoine Mercadal d0460ad202 Merge pull request #2017 from daboe01/fix-scrollview-sorting-while-editing
Fixed: _editingCellIndex is currently not considered when table columns are pressed
2013-11-18 16:08:57 -08:00
Antoine Mercadal 8ca7227185 Merge pull request #1970 from mrcarlberg/table_header_divider_thickness
New: Added themable attribute for divider thickness in table header view
2013-11-18 16:06:49 -08:00
Antoine Mercadal 6c8a21c1cc Merge pull request #1971 from mrcarlberg/table_view_grid_line_thickness
New: Added themable attribute for grid line thickness in table view
2013-11-18 16:06:01 -08:00
Antoine Mercadal 4a82dbc34d FIXED: Previous commit was actually missing to fill the drop view with the background color.
This patch restore the correct behavior and display corectly colors set as dropview-*-on-background-color
2013-11-15 17:59:41 -08:00
Antoine Mercadal 1cec1b0637 NEW: CPTableView drop view now supports theming
Previously, the style of the blueish view that shows up on CPTableView when user is about to drop something on it was hard coded.
This patch adds the following theme attributes in CPTableView

    // theme of the drop view for CPDragOperationOn on a non selected row
    dropview-on-background-color
    dropview-on-border-color
    dropview-on-border-width
    dropview-on-border-radius

    // theme of the drop view for CPDragOperationOn on a selected row
    dropview-on-selected-background-color
    dropview-on-selected-border-color
    dropview-on-selected-border-width
    dropview-on-selected-border-radius

    // theme of the drop view for CPDragOperationAbove on a non selected row
    dropview-above-border-color
    dropview-above-border-width

    // theme of the drop view for CPDragOperationAbove on a selected row
    dropview-above-selected-border-color
    dropview-above-selected-border-width

Aristo and Aristo2 have been updated, and use the same old hardcoded values.
2013-11-15 17:48:57 -08:00
Antoine Mercadal abd9506d40 Merge branch 'master' of https://github.com/cappuccino/cappuccino 2013-11-15 10:40:10 -08:00
Antoine Mercadal 8f7a32141b FIXED: CPTextField was sometimes returning YES even if disabled
Preiviously, CPTextField's acceptsFirstResponder was returning YES even if the textfield was disabled.
This patch restore the correct Cocoa behavior.
2013-11-15 10:38:31 -08:00
daboe01 ff067374bc fix first responder assignment when pressing a header column 2013-11-15 10:55:05 +01:00
Alexander Ljungberg 6cbfa30652 Fixed: view coordinate conversion broken by previous commit.
Without this fix, -CPView convertPoint:fromView was broken due to the changes made in #1998. In particular, the transform for the fromView would be calculated and then just thrown away if the views were in the same window. This happened to work in some specific cases and the lack of unit tests concealed the error.

This fix properly applies the transforms when two views are in the same window without one of them necessarily being inside the other.

Refs #1998.
2013-11-04 00:03:31 +00:00
Adam Sowinski f5a1a6725d Simplified currentCursor assignment. 2013-10-29 23:35:04 +00:00
Antoine Mercadal 2508fa7a97 Merge pull request #1998 from Dogild/scaling-support
New: Added support for scaling in CPView
2013-10-29 12:54:12 -07:00
Antoine Mercadal 0b351ac2d7 Merge pull request #2011 from Dogild/CPTextMovements
New: Added Movement Codes for CPTextDidEndEditingNotification
2013-10-29 11:27:17 -07:00
Antoine Mercadal 24b44c2acf Merge pull request #2010 from daboe01/fix-textFields-on-different-windows-can-clobber-each-others-contents
Fixed: editing textFields on different windows can clobber each others contents
2013-10-29 11:23:00 -07:00
Alexandre Wilhelm 8f70cebefc Typo 2013-10-29 11:22:55 -07:00
Antoine Mercadal 6e7fc5c887 Merge pull request #2008 from Dogild/souldSelectTableColumnFix
Fixed: shouldSelectTableColumn isn't called in CPTableView and CPOutlineView
2013-10-29 11:22:01 -07:00
Alexandre Wilhelm 7f53d15e75 Fixed: the userInfo of the notification from textDidEndEditing is wrong
Previously, when overriding the method textDidEndEditing, the userInfo notification didn't contain the information about CPTextMovement
2013-10-29 11:13:48 -07:00
daboe01 ad170ed854 Fixed: scroll wheel speed is way to low in firefox
I increased scroll wheel speed to a sensible value
2013-10-29 17:33:12 +01:00
Alexander Ljungberg d3ab2a0f3d New: "//site.com/x" style URL support in CPURL and CFURL.
With this feature, CFURL and CPURL can now correctly transform a relative scheme URL starting with a double-slash.

For example, + CPURL URLWithString:@"//a.se/a" relativeToURL:@"ftp://b.se/c" would represent an absolute URL of "ftp://a.se/a".
2013-10-29 15:03:37 +00:00
Alexander Ljungberg af26523e36 New: text underline support for private _CPImageAndTextView.
This features presents a less hack-y way to underline text for those not afraid to use private, internal APIs.
2013-10-29 11:40:25 +00:00
Alexandre Wilhelm ebc1025fd9 New: Added Movement Codes for CPTextDidEndEditingNotification
This PR adds a new feature for CPControl. Now when leaving the control, the userInfo of the notification CPTextDidEndEditingNotification contains the last movements of the control as in COCOA

Test app in Tests/Manual/CPTextFieldMovementsTest
2013-10-29 01:20:00 -07:00
Adam Sowinski a96242324a Merge branch 'master' of https://github.com/cappuccino/cappuccino 2013-10-28 17:00:42 +00:00
daboe01 d1406e1b8f Fixed: editing textFields on different windows can clobber each others contents
Was be caused by resignFirstResponder not checking that the input owner is self.

Fixes #1983
2013-10-27 13:46:00 +01:00
Alexandre Wilhelm c22f489ee9 Fixed: shouldSelectTableColumn isn't called in CPTableView and CPOutlineView
Previously shouldSelectTableColumn wasn't called in CPTableView and CPOutlineView.
This PR resolves this issue, shouldSelectTableColumn is now called between selectionShouldChangeInTableView and tableViewSelectionIsChanging as in COCOA.

Test app Tests/Manual/TableTest/DelegateSelectionTest/
2013-10-24 22:13:35 -07:00
Antoine Mercadal 0ac74fe16e Merge pull request #2007 from krodelin/fix-CPNumber-numberWithBool
Fixed: Return a Number from CPNumber>>numberWithBool:
2013-10-24 10:37:05 -07:00
Udo Schneider df2be926a5 Fixed: Return a Number from CPNumber>>numberWithBool:
The Cocoa signature for this method
	+ (NSNumber *)numberWithBool:(BOOL)value
implies that a number is being returned. In Cappuccino a Boolean is returned.

This leads to some problems e.g. in
addObserver:forKeyPath:options:context: with CPKeyValueObservingOptionPrior
and observeValueForKeyPath:ofObject:change:context: with CPKeyValueObservingOptionPrior.

Setting CPKeyValueObservingOptionPrior leads to CPKeyValueChangeNotificationIsPriorKey being set to 1 (which should be equal to [NSNumber numberWithBool:YES] as documented in https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Protocols/NSKeyValueObserving_Protocol/Reference/Reference.html. The actual value though is true as [CPNumber numberWithBool:YES] does not return a number but a boolean. This commit fixes this issue.
2013-10-24 19:20:45 +02:00
Adam Sowinski 71ed0d6cfc Merge branch 'master' of https://github.com/cappuccino/cappuccino 2013-10-22 11:19:21 +01:00
Antoine Mercadal 2d96875574 Merge pull request #2004 from Dogild/comboBox-trapMouse
Fixed: CPComboBox don't close when clicking on the scroll
2013-10-21 14:25:20 -07:00
Antoine Mercadal 949c618ff1 Merge pull request #2006 from Dogild/outlineView-selectItem
Fixed: The delegate method shouldSelectItem doesn't work in CPOutlineView
2013-10-21 14:24:35 -07:00
Alexandre Wilhelm 8909576a0b Changed comment 2013-10-20 21:01:10 -07:00
Alexandre Wilhelm 0afc903138 Fixed: The delegate method shouldSelectItem doesn't work in CPOutlineView
Previously the delegate method shouldSelectItem didn't work in CPOutlineView.
It didn't work because the checking method _delegateRespondsToSelectionIndexesForProposedSelection and _delegateRespondsToShouldSelectRow didn't check if the real delegate of the outlineView implemented the methods
2013-10-20 20:57:42 -07:00
Adam Sowinski 8971972a28 Fixed a bug where currentCursor variable was assigned a CPNumber instance instead of CPCursor instance. 2013-10-21 00:26:27 +01:00
Alexandre Wilhelm 2df13b7ffc Fixed: CPComboBox don't close when clicking on the scroll
Previously CPComboBox don't close when clicking on the scroll, now it does

Fixed #1991
2013-10-19 00:40:19 -07:00
Antoine Mercadal bb6b5c1232 Merge pull request #2003 from Dogild/refactor-tableView
Fixed: shouldSelectRow was called with selectionIndexesForProposedSelect...
2013-10-18 13:03:49 -07:00
Alexandre Wilhelm ab1c689e4e Optimization with menu. Fixed issue with unsigned bit and delegate Fixed #1994 2013-10-18 12:01:33 -07:00
Alexandre Wilhelm 7bdedca350 Delegate WillDisplayView is called before setNeedsDisplay now 2013-10-18 11:55:40 -07:00
Alexandre Wilhelm e1eac245a7 Changed naming of the private delegate call. Fixed small bugs 2013-10-18 11:47:46 -07:00
Alexandre Wilhelm cf19aef382 Added method selectionIndexesForProposedSelection in CPOutlineView 2013-10-17 15:54:40 -07:00
Alexandre Wilhelm d6e40332c4 Removed comments 2013-10-17 14:32:34 -07:00
Alexandre Wilhelm 4b8a6ee674 Fixed: shouldSelectRow was called with selectionIndexesForProposedSelection
Previously the method shouldSelectRow was called even it's the method selectionIndexesForProposedSelection was implemented by the delegate. Now it works as in Cocoa.
The method selectionIndexesForProposedSelection is called when it has to be called, like in Cocoa.
This PR adds new methods to check and call the delegate/datasource methods more easily

Test app in Tests/Manual/TableTest/DelegateSelectionTest/
2013-10-17 14:26:19 -07:00
Antoine Mercadal 406a049380 Fixed: Previous commit was preventing to select in the void if selectionShouldChangeInTableView: was not implemented
This patch restore the correct behavior
2013-10-16 16:48:50 -07:00
Antoine Mercadal b2dc9c225c Merge pull request #1999 from Dogild/delegate-CPTableView-Methods
Fixed: Delegate method of CPTableView aren't call in the good order
2013-10-16 16:28:48 -07:00
Antoine Mercadal 86e94178e3 Merge branch 'master' of https://github.com/cappuccino/cappuccino 2013-10-16 16:10:11 -07:00
Antoine Mercadal f75955bb04 Fixed: CPNumberFormatter minimum and maximum wrong encoding when set to nil
Previously, a decoded CPNumberFormatter was converting the minimum and maximum values to 0 if they were set to nil. This was causing unexpected behavior when creating a CPNumberFormatter from a xib. This patch actually decodes _minimum and _maximum values as objects to preserve nil.

Test added in Foundation/CPNumberFormatter.j
2013-10-16 16:07:00 -07:00
Alexandre Wilhelm f0a9696634 Fixed typo 2013-10-16 15:03:35 -07:00
Alexandre Wilhelm 016c267e69 Fixed: Delegate method of CPTableView aren't call in the good order
Previously the call of the delegate method of a CPTableView weren't call in the good order, specially the selecting method.
Now it works as in Cocoa.
Fixed typos

Test app in Tests/Manual/TableTest/DelegateSelectionTest
2013-10-16 15:01:28 -07:00
Antoine Mercadal f6028455b7 Merge pull request #1969 from Dogild/xCodeCappCreateProject
New: Added menu Create Project... in xCodeCapp
2013-10-15 14:05:12 -07:00
Antoine Mercadal ed99833894 Merge pull request #1996 from rgv151/master
PATCH: Implement shouldExpand/Collapse delegate for CPOutlineView
2013-10-15 14:04:46 -07:00
Alexandre Wilhelm ef5f26fd81 New: Added support for scaling in CPView
This PR adds the support of scaling in CPView.
There are two new public methods in CPView : -(void)scaleUnitSquareToSize: and -(void)setScaleSize:
-(void)scaleUnitSquareToSize: works exactly as in COCOA, it means if you set a first scale to 0.5 and then 0.5 again, the scaleSize of the view will be 0.25
-(void)setScaleSize: works with the value given. If you set 0.5 after you just seted 0.5 the scaleSize will be 0.5. This method is definitly better in using, specially when using the scaleSize binding with a slider.

Test app in Tests/Manual/ScalingTest
2013-10-15 14:03:26 -07:00
Antoine Mercadal 2f18218ce5 Merge branch 'master' of https://github.com/cappuccino/cappuccino 2013-10-15 12:41:20 -07:00
Antoine Mercadal 0b5a98d3fe FIXED: lineBreakMode set to CPLineBreakByTruncating* was trimming consecutive white spaces
Previously, using a truncating line break mode on a CPTextField and setting the string value to "test      test" was displaying "test test". This patch changes the css white-space property from "nowrap" to "pre" which preserves the white spaces.
2013-10-15 12:39:03 -07:00
Bruce Doan 918543d617 Merge branch 'master' of https://github.com/cappuccino/cappuccino 2013-10-12 23:00:12 +07:00
Bruce Doan 6f8d6a5b25 Some minor fixes to pass the capp_lint checks 2013-10-09 00:09:30 +07:00
aparajita 95082c3263 Merge pull request #1982 from Dogild/MenuFix
Fixed: Menu disappears when opening a submenu
2013-10-07 04:29:20 -07:00
Bruce Doan 8503081a6f PATCH: Implement shouldExpand/Collapse delegate for CPOutlineView 2013-10-06 23:47:25 +07:00
Alexander Ljungberg 6efefbedcd Test: disabling a highlighted menu item should deselect it.
Refs #1762.
2013-09-23 11:24:54 +01:00
Alexander Ljungberg eef91c0240 Merge pull request #1976 from Dogild/HighlightedDisabledMenu
Fixed: a disabled CPMenuItem could still have a selected background
2013-09-23 11:22:27 +01:00
Björn Sperber 5cefce1cf0 Respect frameRate when scheduling timer in CPAnimation. Treat a frameRate of 0 as "really fast" instead of CPTimer default (10 fps). 2013-09-19 13:52:49 +02:00
Martin Carlberg f0e2daf6c7 Fixed: Add get and set instance methods to class definition when ivar has accessors.
This caused 'Method is not implemented' warnings when a class implemented protocol declared set and get methods as 'accessors' on an ivar.
2013-09-12 21:54:57 +02:00
Martin Carlberg 9f0d8c54e4 Fixed: Uses current protocolDefs when compiling accessors
This caused 'null is not an object' type error when class declaration with 'accessors' declared ivars was in the same file as the protocol it was conforming to.
2013-09-12 21:47:15 +02:00
Alexander Ljungberg b20d711922 Merge pull request #1984 from mrcarlberg/if-empty-statement
Fixed: Compiler now generates correct empty statement after 'if (a);'
2013-09-09 15:53:21 +01:00
Martin Carlberg 23fb618596 Fixed: Compiler now generates correct empty statement after 'if (a);'
Earlier the compiler generated the 'if' without the last ';' when a empty statement is used, with sometimes devastating result. The same if an empty statement was after the 'else'.

I have also added a test case for some different empty statement senarios.
2013-09-09 16:38:38 +02:00
Aparajita Fishman 2dff348cca Fixed: text fields in full platform windows could not be selected. 2013-09-02 22:14:16 -04:00
Martin Carlberg ba0604320e Fixed: Should be 'objj_allocateProtocol' and 'objj_registerProtocol' not 'objc_allocateProtocol' and 'objc_registerProtocol' 2013-08-31 15:33:32 +02:00
Martin Carlberg c979a69e6b Fixed: Compiler can now handle only @action/IBAction declared return type when checking for 'Conflicting return type' method declaration.
Also made the warning message point to correct return type token when type is not declared.
2013-08-28 11:23:55 +02:00
Aparajita Fishman 40e06a634e Fixed: background-color was rendering subviews invisible. 2013-08-26 13:50:42 -04:00
Aparajita Fishman 30441b109f Fixed: windows that were autoresized and not constrainable would obey the global CPWindowConstrainToScreen flag.
Previously, if a window had an autoresizingMask and was marked as not being constrained (for example _CPMenuBarWindow), and the CPWindowConstrainToScreen was set to NO, resizing the platform window would not autoresize the window.

This commit ensures that windows that autoresize but don't care about constraining will resize with the platform window no matter what.

Fixes #1981.
2013-08-23 18:28:40 -04:00
Alexandre Wilhelm f17fd6a448 Fixed: Menu disappears when opening a submenu
Previously when opening a submenu from a menu, the main menu disappears because a issue with the poolMenuWindow.
This PR fixes this bug.
It also handle more properly the case when an user is making several right clicks on a responder (origin problem with the ghost menu).

Fixed #1887
2013-08-23 13:59:11 -07:00
Martin Carlberg 0e4ad998d8 Fixed: Remove all protocols in objj_resetRegisterClasses 2013-08-22 16:54:19 +02:00
Martin Carlberg 9eebb0a64b Fixed: Pass correct node to error message when finding duplicated protocol 2013-08-22 16:53:22 +02:00
Martin Carlberg 9f7d0578e5 New: Added the basic protocols CPObject and CPCoding 2013-08-22 14:31:15 +02:00
Martin Carlberg 0afe21dd29 Fixed: Copy method descriptions to an array instead of JSObject 2013-08-22 12:37:29 +02:00
Martin Carlberg cfc682c165 Fixed: Protocol methods is now registered in the correct place 2013-08-22 12:36:29 +02:00
Martin Carlberg c326168e83 Fixed: Protocol definition in compiler was not created correct from protocol definition in the runtime 2013-08-22 12:35:16 +02:00
Martin Carlberg b8b96a17d7 Fixed: Check if global function exists in correct way 2013-08-22 12:34:14 +02:00
Martin Carlberg 48d98f7ebd Fixed: Added theme attribute 'divider-thickness' to wrong class when doing manual merge. 2013-08-20 11:22:39 +02:00
Martin Carlberg 7044c1cda4 Merge branch 'master' of https://github.com/cappuccino/cappuccino into table_header_divider_thickness 2013-08-20 09:44:17 +02:00
Alexander Ljungberg 594ea6e5cb Simplify. 2013-08-19 22:31:21 +01:00
Alexander Ljungberg 957a572bcd Fixed: missing imports. 2013-08-19 22:31:21 +01:00
Alexander Ljungberg 08eff6ec22 New: grey out Edit menu non applicable items for text fields.
Copy, cut and delete are now disabled if there's no selection in the active text field. Cut, paste and delete are greyed out if the text field is not editable (a label).

Refs #1964.
2013-08-19 22:31:21 +01:00
Alexander Ljungberg 3fb12f6382 Clean up. 2013-08-19 22:31:21 +01:00
Alexander Ljungberg 5958220bdd New: CPTextField deleteForward:.
This enables delete forward to be activated through action connections to text fields (or the first responder).
2013-08-19 22:31:21 +01:00
Alexander Ljungberg 648dc6e86c New: Edit > Delete menu item support for text fields.
This menu item deletes the current selection if there is one.

Refs #1964.
2013-08-19 22:31:21 +01:00
Alexander Ljungberg 9d43a559fe Fixed: - CPTextField deleteBackward: required selection.
According to the spec, deleteBackward: should remove the element before the insertion point if there is no selection (e.g. actually delete backwards).
2013-08-19 22:31:21 +01:00
Alexander Ljungberg 168738fb93 Return false for mouse handler if propagation is stopped.
Refs #1964.
2013-08-19 22:31:20 +01:00
Alexander Ljungberg 376b3a496e Fixed: copy and paste by Cappuccino Edit menu not working.
When the Edit menu is used to cut or to paste, Cappuccino needs to do all the work of making it happen. But the current code relied on the browser doing part of the work.

This fix adds new state so CPTextField can know if it should expect the browser to do some of the work or not.

Refs #1964.
2013-08-19 22:31:20 +01:00
Alexander Ljungberg 58d5d7d731 Fixed: selectable text deselected when a menu was clicked.
This made it impossible to select some (non-editable) text, and then to click a Cappuccino menu option like Edit > Copy. Upon the click of Edit, the just selected text would be lost.

This was caused by some very mysterious code focusing and blurring an input every time propagation was stopped. Since it wasn't documented, the snippet was just removed for now. If it turns out it was useful we'll need to add it back and make sure it's not called in this scenario (while documenting it properly).

Refs #1964.
2013-08-19 22:31:20 +01:00
Antoine Mercadal f637931ba7 FIXED: Bug introduced with my previous commit, preventing popover to open in some cases.
Previously, addChildWindow:ordered: was setting the platform window of the child window.
This patch restore the correct behaviour, and fix a bug with _CPAutocompleteMenu. Now the autocomplete menu is opened as a child of its textfield window using the correct platform window.
2013-08-15 19:40:40 -07:00
Alexandre Wilhelm ec4b348369 Fixed: a disabled CPMenuItem could still have a selected background
Previously it was possible to have a highlighted CPMenuItem for a disabled CPMenuItem. (To get that, select an item, close the menu, disabled the item manually and then open the menu again).
Now it is not possible to get this behavior.
2013-08-15 17:15:51 -07:00
Alexandre Wilhelm 879ede5d70 Changed the format of the xib to 4.6 2013-08-15 16:37:07 -07:00
Antoine Mercadal 1e7dd0dc59 FIXED: Bug that could open a child window in the wrong platform window
Previously, addChildWindow:ordered: did not set not the child window's platform window. This could result to open them in the wrong browser window. This patch makes sure to set the parent's platform window as the child window's platform window.
2013-08-15 13:33:50 -07:00
Aparajita Fishman f1077719fb Fixed: main div in index.html had wrong id.
The div's id was changed to cappuccino, and it was supposed to be cappuccino-body, which broke code that relied on the DOM remaining stable during startup.
2013-08-15 10:40:18 -04:00
Aparajita Fishman c9dae8ced4 Revert "Fixed: nib2cib used a temp file for plutil output instead of using stdout."
This reverts commit 4e4fc389d2. It wasn't working reliably.
2013-08-15 10:35:25 -04:00
Aparajita Fishman 4e4fc389d2 Fixed: nib2cib used a temp file for plutil output instead of using stdout.
Previously, nib2cib sent the output of plutil to a temp file, then read that file. plutil supports writing to stdout, which avoids the temp file completely, so that is what we do now.
2013-08-15 10:21:45 -04:00
Aparajita Fishman fa86c54fff Fixed: missing semicolon. 2013-08-15 10:21:45 -04:00
Alexander Ljungberg 2065c7fbc8 Fixed: CPTextField deleteBackward: leaving 1 character.
Previously if - CPTextField `deleteBackward:` was invoked without it being a browser backspace key event for an actively edited text field, the first character in the current selection would not be deleted.

This fix makes it so that `deleteBackward:` works properly from any caller. The fix also undoes a mistake in a recent previous commit which prevented the text field from visually updating after deletion.
2013-08-14 16:23:57 +01:00
Alexander Ljungberg 100efc6450 Formatting. 2013-08-13 11:00:48 +01:00
Aparajita Fishman 987d2a2d73 Formatting 2013-08-12 23:31:34 -04:00
Martin Carlberg 63dac5553e Fixed: Updated test case to include '@required' and '@optional' keywords 2013-08-12 22:46:26 +02:00
Martin Carlberg 0b75876283 Fixed: Moved incorrect positioned parenthesis to handle '@required' token 2013-08-12 22:44:35 +02:00
Martin Carlberg beec0c5293 Fixed: Handle '@required' before any method declarations 2013-08-12 22:43:03 +02:00
Martin Carlberg 672ed6ed0c Fixed: Handle protocol declaration with no method declarations 2013-08-12 22:41:36 +02:00
Aparajita Fishman d6f1c2bc57 Fixed: attempting to use an unsupported built in image in IB would generate an error, but not explain why.
Previously, attempting to use an unsupported built in image such as NSActionTemplate would generate an error message that said, "The image “NSActionTemplate” cannot be found." This would lead the user to think that there was something wrong with nib2cib, instead of understanding that only certain built in images are supported (currently NSAddTemplate and NSRemoveTemplate).

With this commit, an attempt to use an unsupported built in image (where built in is assumed to be any name that matches /^NS[A-Z][A-Za-z]+$/) results in the error message "The built in image “<name>” is not supported."
2013-08-12 15:18:07 -04:00
Martin Carlberg 3b8aedf5aa Merge branch 'master' of https://github.com/cappuccino/cappuccino into protocol 2013-08-12 18:25:00 +02:00
Alexander Ljungberg d40449c469 Ignore XCC .xcodeproj files in tests. 2013-08-12 17:03:31 +01:00
Alexander Ljungberg 8bdbb5d333 Fixed: _CPImageAndTextView unguarded platform access.
This could cause issues during jake deploy or unit testing.
2013-08-12 16:57:50 +01:00
Alexander Ljungberg 638d8de472 New: triple click selectable text field to select all.
This matches Cocoa behaviour. Cocoa also supports double click to select the current word but we currently don't know what word is being clicked. In some browsers (e.g. Safari) this will work natively. Chrome on the other hand selects something random after double click on a non editable div.
2013-08-12 16:57:07 +01:00
Alexander Ljungberg 03acecdec9 New: selectable textfield Select All (Cmd-A, Ctrl-A) support.
Like in Cocoa, a non-editable but selectable text can now be clicked and all text can be selected with the Edit > Select All option or the associated keyboard equivalent. Just like in Cocoa this works on selectable text labels as well (text fields without a bezel).
2013-08-12 16:44:46 +01:00
Martin Carlberg f74312dc42 Fixed: Allow type on return or parameter type to be a class if superclass or protocol declared it as 'id' 2013-08-12 16:55:35 +02:00
Martin Carlberg 2e216d7e9a Fixed: Make default return type to 'void' for '@action' or 'IBAction' marked method. 2013-08-12 16:53:19 +02:00
Alexander Ljungberg 0e7b592786 Fixed: certain editing actions allowed for disabled text fields. 2013-08-12 15:52:36 +01:00
Martin Carlberg 29d7833fcb Fixed: Renamed local variable that used reserved variable name ('arguments') 2013-08-12 16:52:07 +02:00
Martin Carlberg 4eba639c73 Fixed: Allow some tokens to be identifiers 2013-08-12 16:50:34 +02:00
Martin Carlberg 361f421816 Fixed: Added 'id' as a token and enforce that protocol can only follow 'id' as a Objective-J type 2013-08-12 16:49:39 +02:00
Martin Carlberg bb58a206a8 Fixed: Removed all warnings of conflicting return and parameter types caused by the new compiler 2013-08-12 16:46:14 +02:00
Alexander Ljungberg 4775b594f5 Test: extended copy and paste manual test.
This change adds selectable text fields and labels to the potential copy sources.

Refs #1972.
2013-08-12 15:44:22 +01:00
Alexander Ljungberg a90180a92f Fixed: CPTextField copy: only worked for editable text fields.
A non-editable text field does not use an input field, and so does not track what is selected within it. We will use a workaround for now but in a CoreText based text field in the future we'd be likely to always have a correct selectedRange and be able to remove this hack.

Fixes #1972.
2013-08-12 15:43:24 +01:00
Alexander Ljungberg 377618dcd4 New: non-editable but selectable text fields can become the first responder.
Without this change, text fields with setEditable:NO but setSelectable:YES could not become the first responder, and so would not listen for copy: events.

This change allows selectable fields to become the first responder, taking advantage of the distinction between first responder and first key responder maintained internally in CPTextField - a merely selectable field does not become the first key responder.

Refs #1972.
2013-08-12 15:41:10 +01:00
Martin Carlberg 1cfc8139b9 Fixed: Removed double declared ivar 2013-08-12 16:39:54 +02:00
Alexander Ljungberg 4b4ac5d8b7 Fixed: certain actions would edit a non-editable text field. 2013-08-12 15:36:16 +01:00
Martin Carlberg 7c2c2a3114 Fixed: Allow protocols in interface declaration 2013-08-12 09:40:20 +02:00
Alexandre Wilhelm c0dce226bf Changed capp_buid to cap_build.... 2013-08-11 23:24:38 -07:00
Alexandre Wilhelm 2fcf1f4ac4 Added: Creating project with symlinks
Previously it wasn't possible to create project with symlink.
Now you can set in the preferences of xCodeCapp if you want to create your project with symlink or not with a radioButton.
When launching xCodeCapp, the system will check if $CAPP_BUILD is defined or not. If not, the button in the preference will be disabled and a toolTip will advice how to create a $CAPP_BUILD variable.
2013-08-11 14:04:50 -07:00
Aparajita Fishman 8d47b3f048 Fixed: CGContextAddArc would fail if the path was empty.
Previously, CGContextAddArc would not work with an empty path. In Cocoa, CGContextAddArc implicitly starts a path, so it does not require a non-empty path.

This commit allows CGContextAddArc to be used with an empty path.
2013-08-10 17:51:20 -04:00
Aparajita Fishman 06e392ee22 Fixed: CPApplicationDidChangeScreenParametersNotification was sent once for each window.
Should be sent only once per resize.
2013-08-09 15:01:30 -04:00
Martin Carlberg d38125db13 New: Added Objective-J protocol support
The Objective-J parser and compiler now handles protocol syntax. The Objective-J runtime has new functions to handle protocols. The method 'conformsToProtocol:' has been added to CPObject as an instance and a class method.
2013-08-09 19:02:45 +02:00
Aparajita Fishman 3beb753c63 Fixed: when constraining a window resize, the horizontal margin was fixed (and too large).
Previously a fixed margin of 40px was maintained at the left/right of a window when resizing it, which was excessive.

Now the minimum size allowed during a resize is the same as the minimum margin allowed when moving a window, which is determined based on the type of window.
2013-08-09 09:16:43 -04:00
Aparajita Fishman d751fea510 Fixed: constraining window's to the screen did not respect a window's minSize.
Previously, when the platform window was resized, windows were moved/resized to stay within the virtual screen, but if the window had a minimum size, it was not respected.

This commit ensures that if a window has a minimum size, it will always be respected.
2013-08-09 09:12:07 -04:00
Aparajita Fishman 42ad40d10d New: sort the keys in CPDictionary -description.
This makes it easier to find an item in a large dictionary.
2013-08-09 08:28:37 -04:00
Aparajita Fishman 86e5c15e3c Formatting, optimizations. 2013-08-09 08:28:37 -04:00
Aparajita Fishman 6bec4064b5 Fixed: window width was not constrained when platform window was resized.
Previously window heights were constrained to the usable screen when the platform window (virtual screen) resized, but widths were not. The code was there to constrain the width, but it wasn't being used.

This commit ensures the width constraining code is executed.
2013-08-09 08:28:36 -04:00
Aparajita Fishman fc931902d7 New: notify when the platform window resizes.
The platform window is the virtual screen for Cappuccino windows. Per Cocoa, when the screen (platform window) resizes, CPApplicationDidChangeScreenParametersNotification is sent and the CPApplication delegate method applicationDidChangeScreenParameters: is called.
2013-08-09 08:28:36 -04:00
Aparajita Fishman d336c30ab6 New: moved application constants to a separate file. 2013-08-09 08:28:36 -04:00
Aparajita Fishman 9fb966d0ca Docs 2013-08-09 08:28:36 -04:00
Aparajita Fishman 3c2a2f39fc Fixed: resizing a window did not attempt to maintain a minimum margin on screen.
Previously, window moves were constrained such that a minimum margin of the window was visible on screen, but window resizes were not constrained, allowing the user to effectively move the window off screen.

Now resizes are constrained such that a minimum margin of the window is always visible on screen so that the window does not get "lost".
2013-08-09 08:28:36 -04:00
Aparajita Fishman 2183c6d383 New: added methods to globally turn off window constraining when resizing the platform window.
Previously, whenever the platform window (virtual screen) resized, windows were moved or resized to keep them on screen. This could not be easily overridden by the user.

Two class methods have been added:

CPWindow +setConstrainWindowsToUsableScreen:
CPWindow +constrainWindowsToUsableScreen

If +setConstrainWindowsToUsableScreen:NO is called, then resizing the platform window will not move or resize user windows.
2013-08-09 08:28:36 -04:00
Antoine Mercadal e61b6783b3 FIXED: Crash when the autocomplete menu of a Token Field is visible while one of the superviews is removed
Previously, _CPAutocompleteMenu was trying to relayout itself using its related textfield's window frame. This was
causing a crash if one of the CPTokenField's superview has been removed. This fix ensures to stop layouting if the related text field has no window anymore.
2013-08-06 16:04:39 -07:00
Martin Carlberg 7f089972bd New: Added themable attribute for divider thickness in table header view 2013-08-06 11:54:13 +02:00
Martin Carlberg 5a7c2e5617 New: Added themable attribute for grid line thickness in table view 2013-08-06 11:53:13 +02:00
Alexandre Wilhelm ceb22a47c5 New: Added menu Create Project... in xCodeCapp
Previously it wasn't possible to create a capp project from xCodeCapp.
Now you can create one from the menu item Create Project, xCodeCapp will load the project as the same time is no error occurs.
When choosing an existing project, xCodeCapp removes the old one (this is asked to the user, would you like to replace the files...).
In case of errors, the errors panel appears.
2013-08-06 00:41:38 -07:00
Aparajita Fishman 3c9435ed21 Fixed: FileRequest was broken under CommonJS.
The progress event was being used even under CommonJS, which broke file loading and thus jake deploy.
2013-08-02 19:05:57 -04:00
Aparajita Fishman 9e7346f1e8 New: new index.html with loading progress by default.
Previously, the index[-debug].html in the default capp templates did not include a loading progress function. We just had the plain spinner, which gave no visible sign of progress.

Now the capp templates include a progress function and a nice iOS7-ish progress thermometer	is displayed during loading (except when run directly from source). 'jake debug' and 'jake release' will now generate the application/image sizes needed to display loading progress. The old spinner.gif has been removed.

In addition, the message displayed when JavaScript is unavailable has been simplified and shows a link to www.enable-javascript.com instead of the missing link to our old site.
2013-08-02 17:49:45 -04:00
Aparajita Fishman 4221acf3fd New: added support for continuous load progress notification.
Previously, Cappuccino only called OBJJ_PROGRESS_CALLBACK when an executable or image sprite file was finished loading. Only a slow connection, this would result in long periods with no visible progress.

Now OBJJ_PROGRESS_CALLBACK is called continuously during download via the XHR progress event. All supported browsers except IE 9 support this event.
2013-08-02 17:33:59 -04:00
Aparajita Fishman b49a872806 Fixed: IE would scroll entire app to the left, leaving white space on the right.
Previously, in IE you could scroll the entire browser window to the right a very long way, leaving white space to the right of the Cappuccino app. This was caused by a 100,000px wide measurement span that was supposed to be positioned at left:-100,000 but was mistakenly at left:-10,000, which left 90,000px on screen.

This commit fixes the left position of that span, eliminating the ability to scroll the app.

Fixes #1725
2013-08-01 16:20:47 -04:00
Aparajita Fishman 655bc0348b Formatting 2013-07-30 09:40:18 -04:00
Aparajita Fishman 2b23374ec7 New: CPAlert supports custom didEnd selector or block.
Previously, unless you were using a sheet alert, there was no way to set a custom dismissal handler for an alert. In Cocoa alerts are synchronous, in Cappuccino they are asynchronous, which meant that a single dismissal handler had to handle all possible non-sheet alerts.

This commit adds several methods which add two ways to specify a custom dismissal handler: via delegate/selector, and via a block (function). The new methods are:

setDidEndSelector:
runModalWithDidEndBlock:
beginSheetModalForWindow:didEndBlock:

Note that didEnd blocks are transient and take precedence over didEnd selectors.

The CPAlertTest demo was updated to fix some bugs and added the ability to run the tests using blocks.
2013-07-29 13:06:57 -04:00
Aparajita Fishman 1df1c1e9ab Merge branch 'refs/heads/contentViewResizeFix' 2013-07-27 13:42:05 -04:00
Aparajita Fishman 084bc84160 Fixed: removed redundant code. 2013-07-27 13:41:35 -04:00
Aparajita Fishman d8281a6e22 Fixed: simplified the overlay scroller test, documented the technique.
Previously the inner element's offsetWidth was tested before and after setting the overflow to scroll. This is unnecessary, we can just set the overflow to scroll and test the outer element's clientWidth vs. offsetWidth. By definition, clientWidth does not include scrollbars, whereas offsetWidth does. So if they are equal then overlay scrollers must be in use.

Note that FireFox (as of version 22) does not support overlay scrollers, so even if the system does, Cappuccino will not on FireFox unless the programmer forces overlay scrollers.
2013-07-27 09:27:58 -04:00
Aparajita Fishman bdd29936d7 Fixed: test for fixed scrollbars was broken by a previous commit. 2013-07-26 23:38:20 -04:00
Aparajita Fishman f3f1f72ae2 Fixed: variable move in previous commit broke selection notifications. 2013-07-26 12:17:52 -04:00
Aparajita Fishman 2da6c88fad Fixed: constant name was misleading.
Previously CPTimerMinTimeInterval was used as a constant for the *default* time interval used when a timer was initialized with an interval <= 0. It isn't the minimum, it is possible to create a timer with an interval less than that constant's value.

The name has been changed to CPTimerDefaultTimeInterval to make it clearer what it's purpose is. It has also been changed to a #define, that will result in smaller generated code.
2013-07-26 02:08:14 -04:00
aparajita b03e354dbf Merge pull request #1965 from Dogild/Timer
Fixed: CPTimer didn't allow a timeInterval < 0.1
2013-07-25 23:01:14 -07:00
Aparajita Fishman 5b62773a39 Fixed: off-by-one in row calculation caused drawing problems with variable-height rows in CPTableView.
Previously, if the last row's height was increased, empty rows below would not be pushed down. This was due to an off-by-one in -_unboundedRowsInRect (now _exposedRowsInRect) which caused the incorrect rect of the last row to be retrieved.

This commit fixes that bug and also makes the following changes:

- Added FULL_ROW_HEIGHT(), ROW_BOTTOM() and HAS_VARIABLE_ROW_HEIGHTS() macros to make the code clearer.
- Documentation cleanup.
- Eliminated some intermediate variables.
- Rewrote -_rectOfRow to reduce redundant code and fixed some logic errors.
- Renamed some variables to make their intention clearer (to me at least).
- Added an out of bounds check in -rowAtPoint: before doing the relatively expensive binary search.
- In -noteHeightOfRowsWithIndexesChanged:, the first valid index is used instead of the first index (which might be invalid).
- Fixed a bug in -noteHeightOfRowsWithIndexesChanged: where row height was not set correctly if a row was not in the index set.
- Fixed incorrect use of CEIL in -_unboundedRowsInRect, it was wrapped around the divisor instead of the entire expression.
- Fixed drawBackgroundInClipRect: drawing one too many rows.
- Fixed -rowAtPoint not checking for x in bounds.

BREAKING CHANGE:
Previously, CPTableView -rowAtPoint would incorrectly return a valid row index when the x value was outside of the table's bounds. Now an out of bounds x value will return -1, which is consistent with Cocoa (and the intent of the method).
2013-07-25 10:48:11 -04:00
Aparajita Fishman 5c211b350e Docs 2013-07-24 19:21:56 -04:00
Aparajita Fishman 2c6ab1714f Fixed: stray theme slice. 2013-07-24 11:10:35 -04:00
Aparajita Fishman 17fe9b0f60 Formatting 2013-07-23 18:03:17 -04:00
Aparajita Fishman 639670e47d Formatting 2013-07-23 10:15:49 -04:00
Aparajita Fishman 27165db513 Fixed: menu items would not obey enabled bindings for auto-enabling menus.
Previously, the auto-enabling logic for CPMenu would not check to see if a menu item had enabled bindings, and would ignore the state determined by those bindings.

Now, if a menu is auto-enabling and an item has an enabled binding, the binding is used to set the enabled state of the item.
2013-07-22 22:20:40 -04:00
Aparajita Fishman 650bc77b2c Fixed: number formatter was called twice for every setObjectValue.
Previously setObjectValue checked for a formatted value, and then called [self stringValue], which ended up formatting the value again.

Now all of the cases (no formatter, formatter succeeds, formatter fails) are handled explicitly in setObjectValue, eliminating the extra call to the formatter.
2013-07-22 21:26:18 -04:00
Aparajita Fishman a5e62ed132 Fixed: NSMenu autoEnablesItems was not supported by nib2cib. 2013-07-22 21:13:15 -04:00
Alexandre Wilhelm 56963d65f3 Fixed: CPTimer don't allow to put timeInterval below 0.1
Previously it wasn't possible to set the timeInterval below 0.1.
Now you can do it and the timeInterval will set to 0.1 if the timeInterval is less or equal to 0 as in cocoa.

Cocoa specs here:
https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSTimer_Class/Reference/NSTimer.html
2013-07-22 15:20:10 -07:00
Aparajita Fishman 771370e64b Docs: typos 2013-07-21 22:30:20 -04:00
Aparajita Fishman 0bd670b2a3 Fixed: extraneous colon in https scheme test.
And whitespace formatting.
2013-07-20 13:23:05 -04:00
Aparajita Fishman e0af5d0573 Fixed: changed magic number to constant, add missing space after comma. 2013-07-20 12:05:53 -04:00
aparajita 23d2a71649 Merge pull request #1962 from BlairDuncan/CPTimerMinimumInterval
Fixed: CPTimer number of seconds interval set to 0.1 if less than or equal to 0.0
2013-07-20 09:02:13 -07:00
Blair Duncan 3419f6fbb4 Fixed: CPTimer number of seconds interval set to 0.1 if less than or equal to 0.0
Cocoa specs here:
 https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSTimer_Class/Reference/NSTimer.html
...
"Parameters
seconds
The number of seconds between firings of the timer. If seconds is less than or equal to 0.0, this method chooses the nonnegative value of 0.1 milliseconds instead."
2013-07-18 09:33:12 -04:00
Aparajita Fishman 2ca020f3a9 Fixed: it seems setHidden must be called in CPView -initWithCoder.
Reverts change made in 64f962e29a.
2013-07-17 13:45:32 -04:00
Aparajita Fishman 778843593b Fixed: CPTextField would not become/resign key responder when first responder and unhidden/hidden.
Previously, no attempt was made to become/resign first key responder when a CPTextField was unhidden/hidden. This could lead to a case where a hidden CPTextField was made first responder, then unhidden (and have a focus ring), but would not receive key input.
2013-07-17 13:28:17 -04:00
Aparajita Fishman 64f962e29a Fixed: viewDidHide and viewDidUnhide were not called when being added to/removed from hidden ancestor.
Cocoa specifies that viewDidHide will be called when an unhidden view is added to a view hierarchy with a hidden ancestor view, and viewDidUnhide is called when an unhidden view is removed from a view hierarchy with a hidden ancestor view. This was not the case in Cappuccino.

This commit adds that functionality, and also removes a spurious viewDidHide/viewDidUnhide call that was generated as a side effect in initWithCoder.
2013-07-17 13:28:17 -04:00
Aparajita Fishman 90fe91d63e Formatting: @ignore requires /*! comment, whitespace cleanup 2013-07-17 13:28:17 -04:00
Alexander Ljungberg d404d027c2 Test: - CPImage initWithContentsOfFile:nil. 2013-07-15 10:48:58 +01:00
Alexander Ljungberg b0babdb7bb Formatting.
Refs #1959.
2013-07-15 10:48:14 +01:00
Alexander Ljungberg 0f53ceda30 Fixed: comparing a CPNumber vs nil or CPNull didn't throw an exception.
In Objective-C, both `[@34 compare:nil]` and `[@34 compare:[CPNull null]]` throw invalid argument exceptions.

This fix makes the same true in Objective-J.

Refs #1959.
2013-07-15 10:47:38 +01:00
Alexander Ljungberg 315e3fccf3 Formatting.
Refs #1959.
2013-07-15 10:36:48 +01:00
Alexander Ljungberg 2973743a0d Merge pull request #1959 from mrcarlberg/compare_sort_with_null
CPString 'compare:' method and sort using descriptors handles nil and CPNull in correct way
2013-07-15 10:28:43 +01:00
Aparajita Fishman 083310c44f Fixed: nib2cib did not allow xibs or images to be in subdirectories of Resources.
Previously, nib2cib would not correctly calculate the app/resource directories if the xib was in a subdirectory of Resources. Also, image resources in subdirectories did not have the subdirectory encoded with the image name.

Now xibs and images may be anywhere under Resources.

Fixes #1960.
2013-07-14 18:11:31 -04:00
Aparajita Fishman 54d13c8fc9 Fixed: CPImageView's _DOMImageElement was not created during initWithCoder.
Previously, _createDOMImageElement was not called until after [super initWithCoder] was called. But that call would end up in CPImageView -setObjectValue, which would attempt to access _DOMImageElement before it had been created.

Now _DOMImageElement is checked before being accessed or created.
2013-07-14 17:46:22 -04:00
Aparajita Fishman fbc869ad29 Fixed: in certain degenerate cases, CPTextField may not have a window within _isWithinUsablePlatformRect
Previously, a case could arise where a text field was set as the initial first responder but during cib loading was not yet assigned to a window. In this case _isWithinUsablePlatformRect would fail.

Now _isWithinUsablePlatformRect checks to make sure the text field has a window.
2013-07-14 15:59:23 -04:00
Martin Carlberg f52f11899a New: Sort using descriptors handles nil and CPNull in correct way
This is the same way as Cocoa works.
Also added test case.
2013-07-09 13:38:13 +02:00
Martin Carlberg fc403d679c New: CPString 'compare:' method handles nil and CPNull in correct way
This is the same way as Cocoa works.
Also added test case.
2013-07-09 13:37:12 +02:00
Alexander Ljungberg e8b2f2e39f Fixed: previous CPImageView revision not compiling with Rhino. 2013-07-08 17:28:48 +01:00
Alexander Ljungberg b258b1a164 New: appkit_tag_dom_elements now tags with UIDs too.
Tagging with UIDs can make it much easier to debug encoding/decoding related bugs where it's not clear that the right view ended up in the right spot.

The new data attribute is called "data-cappuccino-uid".

Also collect and simplify appkit_tag_dom_elements code a little.
2013-07-08 17:05:22 +01:00
Alexander Ljungberg 0badf30763 Simplify CPImageView code. 2013-07-08 17:02:41 +01:00
Alexander Ljungberg c68b174be5 Fixed: appkit_tag_dom_elements support by CPImageView.
Without this fix, the `appkit_tag_dom_elements` flag would only affect CPImageViews unarchived from a coder (e.g. in a collection view, from a cib). It would have no effect on a CPImageView created in code.

This change refactors the _DOMImageElement code to a shared method, reducing redundancy while fixing the bug.
2013-07-08 14:31:06 +01:00
Alexander Ljungberg d61d4ebbe7 Fixed: -CPImage initWithContentsOfFile:nil created broken image.
Without this fix, code like `[[[CPImage alloc] initWithContentsOfFile:nil] description]` would cause a crash.

This fix makes `[[CPImage alloc] initWithContentsOfFile:nil]` behave like its equivalent in Cocoa: it returns nil without warning or error.
2013-07-08 12:45:23 +01:00
Alexander Ljungberg e7ecd92cbc Fixed: custom CPWindow subclasses breaking flatten.
If a cib file had a custom CPWindow subclass, that cib file would not be properly processed by flatten as it'd fail to find the relevant class (the fact that the class can't be found is an issue in itself). This would cause an exception.

This fix makes CPCibWindowTemplate act similar to CPCibCustomView when the referenced class can't be found: it instantiates a regular CPWindow. This is sufficient for flatten's purposes.
2013-07-02 17:16:55 +01:00
Antoine Mercadal 93c27625b9 NEW: Added some themable attributes for CPPopover
The following theme attributes has been added
 - border-radius
 - stroke-width
 - shadow-size
 - shadow-blur
2013-06-28 17:48:32 -07:00
Glenn L. Austin 8d7c47a5e4 Fixed: Remove explicit use of Mac OS X 10.5 SDK, replace with "latest OS X"
The fontinfo and imagesize Xcode projects still explicitly refer to using the Mac OS X 10.5 SDK, while all other Xcode projects simply refer to the latest Mac OS X SDK, with no explicit OS version. This change modifies these two projects to mirror other Xcode projects in the project.

Fixes #1957
2013-06-28 10:26:44 -07:00
Alexander Ljungberg 6ef776e488 Fixed: - CPView nextValidKeyView infinite loop.
Previously, certain situations could easily lead to an infinite loop in - CPView nextValidKeyView. For instance, opening a sheet view with no responder returning YES for canBecomeKeyView would freeze Cappuccino.

This was caused by the cycle detection in nextValidKeyView not being able to pick up on cycles where the nextKeyView of the original receiver did not participate. Since content views often have a next key view inside of them, and the views inside rarely have a next key view back "up" to the content view, the content view would never be seen again even if there was a cycle.

This fix detects cycles at any level by remembering all previous visited responders.
2013-06-25 18:05:46 +01:00
Alexander Ljungberg d9e3542c34 Merge branch 'refs/heads/slevenbits-native-clipboard' 2013-06-17 00:54:41 +01:00
Alexander Ljungberg 093ac8cf54 Merge branch 'refs/heads/slevenbits-nsvalue-nib2cib' 2013-06-17 00:54:05 +01:00
Alexander Ljungberg 757c79d15c Refactor, restructure and simplify copy and paste handling.
This change brings nearly all copy and paste related into a single, self-contained class. This new class is still somewhat coupled to CPPlatformWindow+DOM.j in the sense that it's highly specific and meant to be called in a very specialised way. Despite this, it's still a significant decoupling and the new code is more readable and easier to follow.
2013-06-17 00:17:00 +01:00
Alexander Ljungberg 8dd252eee1 Cleanup: TableTest/Editing. 2013-06-16 13:23:22 +01:00
Alexander Ljungberg f318759a4a Fixed: menu items becoming permanently disabled, breaking e.g. Select All.
Without this fix, if a menu item was disabled it could only be automatically re-enabled if the menu item had a `validateMenuItem:` or `validateUserInterfaceItem:` enabled target.

This meant that for example if the Edit > Select All menu item was validated when the first responder was something like a collection view, it'd become disabled. If then the first responder was changed to a text field and revalidation occurred, the menu item would not become enabled and Select All would not be possible in the text field neither through the Edit menu nor the Cmd-A/Ctrl-A keyboard equivalent.

This fix ensures that menu item validation does not only take negative action (disabling enabled items which should be disabled), but also positive action (enabling disabled items which should be enabled), even when there's no `validateMenuItem:` or `validateUserInterfaceItem:`.
2013-06-16 13:22:44 +01:00
Alexander Ljungberg 85985add3c Fixed: objects without a superclass. 2013-06-15 17:53:54 +01:00
Alexander Ljungberg 9d435e0f8a Test: include an image in Copy and Paste test.
Image copy and paste to and from the system clipboard is not available in Cappuccino today. However, the image in the collection view can be used to test internal Cappuccino copy and paste (using Edit > Copy, Edit > Paste from the Cappuccino menu).
2013-06-15 17:53:17 +01:00
Alexander Ljungberg 2b0754c6a0 Simplify copy and paste code path.
This change begins to clean up the control flow of copy and paste. Before, copy and paste was dealt with partly in CPPlatformWindow, partly in CPApp and partly in CPTextField.

Now, CPApplication has been removed from the path, simplifying it down to the two more expected actors.
2013-06-15 17:08:11 +01:00
Alexander Ljungberg 0ead233cba Fixed: Safari "can't paste" code triggered even for a content editable target.
These targets might be rare but could occur in some Cappuccino text editor widget, in which case our standard native paste handling from Safari should work fine.
2013-06-15 14:42:15 +01:00
Alexander Ljungberg 5d07eb7316 Fixed: paste in Firefox.
The paste into input field hack requires that we don't stop the Cmd-V/Ctrl-V keydown propagation.
2013-06-15 13:23:01 +01:00
Alexander Ljungberg 198857e0ad Fixed: copying from a CPTextField would not actually but the string value in the Cappuccino pasteboard.
Without this fix, when text was copied from a CPTextField, the value would be copied into the system clipboard (if possible), but not into the Cappuccino pasteboard. This meant that the text could not be pasted back in Cappuccino using e.g. Edit > Paste from the Cappuccino menu.

This fix ensures the appropriate text is copied both into Cappuccino's pasteboard and the system clipboard (when possible).
2013-06-14 14:31:00 +01:00
Alexander Ljungberg a4aed913d7 Test: new copy and paste manual test.
This test makes it easy to test copy and paste both inside a Cappuccino app, and externally to and from other Cappuccino instances in other browser, or other applications, when using a text field or a collection view as the source/destination.
2013-06-14 14:27:40 +01:00
Alexander Ljungberg 613a20a639 New: native copy and paste support extended with copy and cut.
This fix switches to full native copy and paste in browsers which support it. This allows copy from anywhere - a collection view, a table view and so on - without the browser greying out the copy menu or beeping.

In the future this can easily be extended to copy and paste images as well.

This change also improves Safari paste support. In recent versions of Safari, pasting from the system clipboard into Cappuccino has been impossible. This remains impossible due to the lack of beforepaste events, but now the code cleanly switches to a Cappuccino-only paste at least.
2013-06-14 14:05:36 +01:00
Alexander Ljungberg e59389b0dd Fixed: crash in - CPArray/CPDictionary description containing self referential JS object.
Without this fix, certain JS contents could cause `- CPDictionary description` and `- CPArray description` to crash.

This change limits how deeply the description code will recurse before returning a default "…" description.
2013-06-13 20:14:22 +01:00
Alexander Ljungberg 22905745f1 Fixed: crash on -CPArray/CPDictionary description if a value was the window object.
Without this fix, code like `[@{ "a": window } description]` would crash with a "Maximum call stack size exceeded" exception.

Now`CPDescriptionOfObject()` function simply describes the window object as `window` rather than trying to serialise it into a huge description string.
2013-06-13 19:19:22 +01:00
Alexander Ljungberg d3a44cbc63 New: objj_getClassList().
This function obtains the list of registered classes at the time its called.
2013-06-13 18:18:13 +01:00
Alexander Ljungberg a9a0b1c7d9 New: JavaScript clipboard API support for pasting.
Without this feature, attempts to paste data into a Cappuccino app (outside of a text field) are handled by redirecting the paste into a hidden text field. Then a paste event is generated from whatever is captured in this field after a 0 timeout. This method is prone to timing related bugs where the paste event actually has an empty clipboard.

With this new feature we read the paste data directly from the browser's native paste event when the browser supports it (Chrome 10+, Safari 5+, Firefox 22+). This is much more dependable and may in the future also enable us to read other types of paste data such as images.
2013-06-13 13:26:16 +01:00
Alexander Ljungberg 72169e54d8 New: nib2cib support for runtime attributes of point, size, rect and range types.
This change adds nib2cib support for `NSValue` when the value represents a NSPoint, NSSize, NSRect or an NSRange, which enables user defined runtime attributes of these types to be set in Xcode and then properly decoded in a Cappuccino app.
2013-06-13 13:24:36 +01:00
Alexander Ljungberg bf94dd3a6e New: KVC setValue:forKey: now automatically unwraps CPValue.
This corresponds to the same KVC behaviour in Cocoa and is key when decoding cibs with certain properties set to struct values (such as NSSize).
2013-06-13 13:20:22 +01:00
Alexander Ljungberg fe79628034 Fixed: CGRectFromString made bad CGSizeFromString call.
Without this fix, CGRectFromString would call CGSizeFromString with a value like "{1, 2}}" (not the extra trailing "}"). Although CGSizeFromString didn't complain, it wasn't correct either.
2013-06-13 12:46:08 +01:00
Alexander Ljungberg 563300a16f Test: CGGeometry "string from" for point, size and rect. 2013-06-13 12:43:48 +01:00
Antoine Mercadal 29c336f7b8 Fixed: Wrong initial values for _lineDashesPhase and _lineDashes in CPBezierPath
Firefox is not accepting the initial values for these two attributes, making it crash with an ILLEGAL VALUE error in any application using CPBezierPath (especially ones with CPPredicateEditor that is using bezier path to draw the selection arrows.)
2013-06-12 13:21:46 -07:00
Alexander Ljungberg b0b0452647 Merge pull request #1943 from Dogild/EmptyTableView
Fixed: selection in a tableView without column
2013-06-12 13:07:40 +01:00
Alexander Ljungberg abd382d9c2 Merge pull request #1940 from krodelin/udos-Resources-Directory-in-Framework-Template
New: Added "Resources" directory to capp Framework template
2013-06-12 13:06:26 +01:00
Alexander Ljungberg 36c2672064 Merge pull request #1939 from Dogild/RemovedColumn
Fixed: removeTableColumn does not removes column from tableColumns array
2013-06-12 13:01:47 +01:00
Alexander Ljungberg 5bab2e1469 Merge pull request #1938 from ahankinson/fix-collectionview-shiftselect
Fixed: CPCollectionView range bounds exception if shift key was held for...
2013-06-12 12:55:10 +01:00
Alexander Ljungberg df7a6930c2 Test: expose a problem with - CPTabView insertTabViewItem:atIndex.
Refs #1920, #1921.
2013-06-12 12:31:30 +01:00
Alexander Ljungberg 45c75235a5 Merge pull request #1898 from ahankinson/fix-issue1396
Fixed: CPTokenField sends focus and blur notifications
2013-06-12 12:07:02 +01:00
Alexander Ljungberg 0d283231a2 New: automatically fix ulimit when possible.
Without this fix, trying to build Cappuccino or run a jake script with a too low `ulimit -n` would cause a fatal error.

This change will automatically increase the ulimit when possible and only error out when it's not. The automatic change does not permanently affect the terminal session as it only targets the soft limit.
2013-06-12 11:16:39 +01:00
Alexander Ljungberg 4652db7246 Formatting: semicolons. 2013-06-12 11:07:03 +01:00
Alexander Ljungberg 22dcacd8ce Fixed: remove non-standard CPDocument API "firstEligibleExistingWindowController".
This method did not actually do anything, and was not part of the expected CPDocument API.

Refs #1870.
2013-06-12 10:28:41 +01:00
Alexander Ljungberg e2339ee1c6 Formatting: whitespace.
Refs #1870.
2013-06-12 10:27:28 +01:00
Alexander Ljungberg 6ab650346b Merge pull request #1870 from BlairDuncan/documentControllerCurrentDocument
Fixed CPDocumentController missing method currentDocument
2013-06-12 10:20:25 +01:00
Blair Duncan 2cbc4d93bd Fixed: CPWindows contentView Autoresizes Subviews set in Cib is now honoured
Currently when a window is decoded from a cib, the contentView is set to always auto resize its subviews regardless of the setting in IB.
2013-06-07 07:05:44 -04:00
Alexandre Wilhelm 8bf2118b6e Fixed: selection in a tableView without column
Previously it was possible to select rows in a CPTableView even if there wasn't columns. It was also possible to make a drag/drop.
This PR fixes theses both problems.
2013-06-03 15:36:59 -07:00
Alexandre Wilhelm 566521f854 capp_lint 2013-06-03 11:32:05 -07:00
Alexandre Wilhelm c7c3bdd543 Fixed: CPTableView Drag and drop in void causes a crash
Previously the drag and drop and multiple selection from a void cells caused an exception.
With this fix, you can start a drag/drop and a multiple selection from a empty row.

Fixes #1857
2013-06-03 11:27:10 -07:00
Aparajita Fishman 50d3bfd456 Fixed: Frameworks/Source directory was being copied to Build 2013-06-01 15:48:02 -04:00
Udo Schneider 6a516873b7 New: Added "Resources" directory to cap Framework template
Added a new folder "Resources" in Tools/capp/Resources/Templates/Framework/. As the folder is empty be default for frameworks it contains a .gitignore file to be able to add it to git.

Motivation is to prevent (spelling) mistakes when manually creating a Resource folder for Frameworks (e.g. "Ressources").
2013-06-01 13:13:05 +02:00
Alexandre Wilhelm 827b9c4c57 Fixed small bugs with _reloadAllRows 2013-05-31 16:21:56 -07:00
Alexandre Wilhelm 3b48aafe66 Fixed: removeTableColumn does not removes column from tableColumns array
Previously the tableView didn't correctly remove a given tableColumn. It was removed in the method load (who is called by the layoutSubviews).
Now the tableColumns is removed before the layoutSubviews (as in cocoa).
It fixed also another problem, before this fixe it wasn't possible to remove all of the columns of a tableView (the last column was always displayed). This is fixed also

Fixes #1913

You can test that with the app of t00f
2013-05-31 16:11:11 -07:00
Andrew Hankinson 8d7e2f9ec6 Fixed: CPCollectionView range bounds exception if shift key was held for first selection
Previously, if you held down the shift key while making the first selection in a CPCollectionView it would raise an exception claiming {-1, XXX} was out of range. This was because `firstIndex` returns CPNotFound (-1) if nothing is selected.

In Cocoa, holding down the shift key while making the initial selection behaves as if you made an initial selection.

This commit catches a CPNotFound and sets the first index to the index of the item under the mouse pointer.
2013-05-31 17:19:09 -04:00
Alexander Ljungberg 295443f2e3 Merge pull request #1937 from mrcarlberg/colon_selector
Fixed: When selector is only a ':' in a send message statement the new compiler crashed.
2013-05-30 13:46:28 +01:00
Martin Carlberg 595736b8c6 Fixed: When selector is only a ':' in a send message statement the new compiler crashed.
The program below crashed on the last line with a 'null is not an object' error message. Also added a test case.

@implementation MyObject {
- (int):(int)a {
  return a;
}
@end
var a = [[MyObject alloc] init];
var b = [a:3];
2013-05-30 14:39:58 +02:00
Antoine Mercadal 8f17f904f2 Merge pull request #1935 from Dogild/CGPath
Fixed: CGPath is wrong when creating an arc
2013-05-29 10:11:39 -07:00
Aparajita Fishman 668eb1f8c4 Fixed: in some cases nib2cib would write to stdout, which wasn't captured by XcodeCapp.
Previously, only stderr was checked for response text. In some edge cases it would write an error message to stdout. In addition, the default error message provided when the return status was non-zero and the output was empty was implemented incorrectly.

Now all output from nib2cib is correctly captured.

Also updated help to indicate how to enable debug logging.
2013-05-25 19:23:10 -04:00
Aparajita Fishman 3159021d27 CPDatePicker fixes, optimizations, tweaks...
- CPImageInBundle() can't be used from a ThemeDescriptor. Replaced with PatternImage().
- DRY! Put clock image sizes in variables so they can be maintained in one place.
- When displayed from the theme showcase, the hand images in HandLayer -setImage: were still _CPCibCustomResources, not sure why. This condition is now explicitly handled by converting to the referenced image.
- Fixed a bug in _CPDatePickerClock -setEnabled where the sublayers would not update unless the event loop was pumped.
- Check for unchanged value in setters.
- Various code optimizations.
- Removed unnecessary method comments.
- Fixed typo in demo app.
2013-05-25 19:11:27 -04:00
Alexandre Wilhelm fc4413d56b Changed clockWise to isClockWise 2013-05-24 14:15:54 -07:00
Alexandre Wilhelm 8b7eb1815d Removed unused code 2013-05-24 13:40:46 -07:00
Alexandre Wilhelm cb187c3e8f Added tests 2013-05-24 11:53:47 -07:00
Alexandre Wilhelm 25f54c83ed Added method CGPathContainsPoint 2013-05-24 11:53:33 -07:00
Alexandre Wilhelm a79ac2e9e4 Removed unused code 2013-05-23 14:11:03 -07:00
Alexandre Wilhelm b5df5f730b Fixed: CGPath is wrong when creating an arc
Previously when creating a CGPath with an arc, the path was wrong. It added a line when it wasn't necessary and when it was necessary it added a line to a wrong point.
Now CGPath works like in cocoa (If the specified path already contains a subpath, Quartz implicitly adds a line connecting the subpath’s current point to the beginning of the arc. If the path is empty, Quartz creates a new subpath with a starting point set to the starting point of the arc.)

Test app in Tests/Manual/CGPath/AppController.j
2013-05-23 14:07:04 -07:00
Martin Carlberg a2257dab8f New: Empty loop test cases for compiler generator 2013-05-22 11:41:17 +02:00
Martin Carlberg ee4112b7f1 Fixed: Removed double spaces before '@ref' and '@selector' generated output from compiler.
'@ref' is generated to ' function(__input…' with the starting space if, for example, the code is 'return(@ref(a))'. This will create a space between 'return' and 'function(__input…'. When the compiler is generate the code this is not necessary.
2013-05-22 10:34:46 +02:00
Martin Carlberg 1d896c6ac9 Fixed: Code generator didn't generate ';' for empty loops
The line 'while (count--);' was generated to 'while (count--)'. The same with 'for(;;);' and 'for (a in []);'
2013-05-22 10:27:01 +02:00
Antoine Mercadal 42bc87d9ca Merge pull request #1934 from Dogild/showcase
Fixed: Aristo showcase is broken because CPDatePicker
2013-05-21 15:30:15 -07:00
Alexandre Wilhelm 85e71017d9 capp_lint and code style 2013-05-21 15:28:33 -07:00
Antoine Mercadal d8c8694c0d nib2cib the xib 2013-05-21 15:27:45 -07:00
Antoine Mercadal 305fbb8ce2 Merge branch 'RadialGradient' of https://github.com/Dogild/cappuccino into pr-1933 2013-05-21 15:18:25 -07:00
Alexandre Wilhelm 0c613f1dde Fixed bugs with showcase 2013-05-21 14:10:05 -07:00
Alexandre Wilhelm 14ab582a53 Fixed : Aristo showcase is broken because CPDatePicker
Previously the showcase of Aristo and Aristo2 didn't work because several bugs in the class CPDatePicker.

This PR fixes these problems :
- The first problem was when displaying a textual datePicker, the class tried to calculate different things for the calendar (good optimization as well).
- The second problem was about the calendar and the hands. It wasn't possible to display a PatternColor made with an image in a layer, now we use a PatternImage and the method CGContextDrawImage to draw the hands.
2013-05-21 13:53:16 -07:00
aparajita 6c2062c1f0 Merge pull request #1882 from ahankinson/fix-theme-disabled-controls
Theming fixes for disabled controls in Aristo2
2013-05-21 06:51:21 -07:00
Aparajita Fishman 7385f04d7f Fixed: theme showcase was failing due to various bugs. 2013-05-21 09:50:46 -04:00
Alexandre Wilhelm 9d76ab70fe Changed image for lineal gradient 2013-05-20 21:54:04 -07:00
Alexandre Wilhelm ce22cebf07 Removed the reverse colors (it was a bad idea) 2013-05-20 21:53:35 -07:00
Alexandre Wilhelm 22d66438fb Added test for linear/radial gradient 2013-05-20 19:08:44 -07:00
Alexandre Wilhelm de4e28b5cc Fixed bug with linear gradient when drawing it without CPGradient 2013-05-20 19:07:39 -07:00
Alexandre Wilhelm 5e0793c2ac Fixed small init bug in CPBezierPath 2013-05-20 19:06:48 -07:00
Alexandre Wilhelm 54dd027c15 Removes previous test 2013-05-20 19:06:08 -07:00
Alexandre Wilhelm ad33411ec6 New: CGContextDrawRadialGradient support
Canvas supports CGContextDrawRadialGradient as in cocoa. The CGGradientDrawingOptions is not actually supported.

Test app in Tests/Manual/CGCanvasContext
2013-05-20 15:08:46 -07:00
Aparajita Fishman 6bac934d0c Fixed: changed indentation of generated code to Cappuccino standard of 4 spaces. 2013-05-18 18:42:26 -04:00
Alexander Ljungberg 8c5015a0bc Test: verify compiler output for return statement without space.
Refs #1830.
2013-05-18 01:00:49 +01:00
Alexander Ljungberg 302138c257 Fixed: OutputTest reversed expectation and test value in error messages.
The message would read "expected x but was y", where y would actually be the correct expected value and x the wrong one.
2013-05-18 00:59:20 +01:00
Alexander Ljungberg 501310c058 Formatting: OldBrowserCompatibility.js.
Refs #1929.
2013-05-16 15:24:24 -07:00
Alexander Ljungberg cb2ba64a73 Merge branch 'master' of github.com:cappuccino/cappuccino 2013-05-16 14:18:46 -07:00
Alexander Ljungberg de1d6aad9c Test: check compiler output for selectors with keywords in them.
Refs #1929.
2013-05-16 14:17:31 -07:00
Aparajita Fishman 391ff7279d Fixed: capp_lint errors. 2013-05-16 15:02:45 -04:00
Alexander Ljungberg 1d1016f08e Test: reactivate the regex-simple-char-classes test.
This test failed with the old preprocessor but works fine now with the new compiler.

Refs #1929.
2013-05-16 11:15:03 -07:00
Alexander Ljungberg d040e60f60 Merge pull request #1929 from mrcarlberg/preprocess
Many compiler fixes
2013-05-16 10:03:38 -07:00
Martin Carlberg 3808427f24 Fixed: Accidental global variable 2013-05-16 16:15:29 +02:00
Martin Carlberg b3e6eb74b2 Fixed: Reset all the macros when compiling a new file in the default implementation of the macro store. 2013-05-16 12:07:44 +02:00
Martin Carlberg 392aafb360 Revert "Revert "New: Added test cases for some preprocess directives in OutputTest.j""
This reverts commit 5e6c89ca8b.

Conflicts:
	Tests/Objective-J/Preprocessor/OutputTests/OutputTest.j
2013-05-16 12:05:57 +02:00
Martin Carlberg 6556ccef80 Fixed: Removed use of global variable 2013-05-16 11:26:01 +02:00
Martin Carlberg f96e934cf8 Fixed: Removed use of in some cases undefined global variables 2013-05-16 11:25:42 +02:00
Alexander Ljungberg 44a872659a New: type check - CPPasteBoard setString:forType:.
When this method is given e,g, an array or CPData, it now crashes early instead of the pasteboard exhibiting strange behaviour.
2013-05-15 08:47:43 -07:00
Martin Carlberg 256c5b83da Fixed: Typo, changed comma to semicolon 2013-05-15 15:35:03 +02:00
Martin Carlberg 5e6c89ca8b Revert "New: Added test cases for some preprocess directives in OutputTest.j"
This reverts commit 9b709b85a9.
2013-05-15 15:21:49 +02:00
Martin Carlberg bf4a5b2c9a Merge branch 'master' of https://github.com/cappuccino/cappuccino into preprocess 2013-05-15 09:08:26 +02:00
Alexander Ljungberg 6701117945 Fixed: [pasteboard declareTypes:… owner:nil]; would emit a warning.
Without this fix, declaring a type with a nil owner would cause a "DEPRECATED: object cannot be nil" warning to be issued.

This fix now allows a nil owner without warning.
2013-05-14 14:44:00 -07:00
Alexander Ljungberg f2d9ef7720 Test: - CPPasteboard setString:forType: and stringForType:. 2013-05-14 14:40:41 -07:00
Alexander Ljungberg 3fb0dd725a Fixed: CPLocale for English, United Kingdom had the wrong identifier. 2013-05-14 13:06:53 -07:00
Alexander Ljungberg a324cb3306 Fixed: CPLocale detection didn't work.
Previously, if the browser provided a language string such as "en-US", CPLocale would try to look up the locale for "en_EN", which wouldn't exist so it'd always select the default language.

This fix uses the browser provided language string fully to select the appropriate locale.
2013-05-14 13:03:31 -07:00
Alexander Ljungberg 2a9f3deb0e Merge pull request #1930 from mrcarlberg/cplocal_cant_handle_unknown_country_codes
Fixed: CPLocal can't handle unknown language codes
2013-05-14 12:00:39 -07:00
Alexander Ljungberg 89e81e97d1 Merge branch 'master' of github.com:cappuccino/cappuccino 2013-05-14 11:59:29 -07:00
Alexander Ljungberg b4fb4ba941 Formatting: CPLocale.
Tabs to spaces and other whitespace changes.
2013-05-14 11:59:17 -07:00
Aparajita Fishman eb859d42a4 Fixed: framework image names without @framework would cause nib2cib to fail.
I wasn't properly handling the case where _resourcePathForName would be called with a nil framework.
2013-05-14 07:54:08 -04:00
Martin Carlberg 9d86391bdb Fixed: CPLocal can't handle unknown language codes
When the language code is not known it still sets the current language code
to the unknown code instead of the defualt 'en_US' code.
This makes the test cases for CPDateFormatter fail when run on a foreign system.
2013-05-14 13:30:30 +02:00
Martin Carlberg 9b709b85a9 New: Added test cases for some preprocess directives in OutputTest.j
Also fixed so OutputTest.j now uses the new compiler instead of the old.
2013-05-14 10:31:29 +02:00
Alexander Ljungberg 9bde63923c Formatting: CPPredicateTest.
Refs #1914.
2013-05-13 22:27:39 -07:00
Alexander Ljungberg d7c676893d Merge pull request #1914 from mrcarlberg/predicate_expression_equals_nil
CPExpression and CPPredicate can't handle nil as argument in method isEqual:
2013-05-13 22:21:05 -07:00
Alexander Ljungberg 8bc8ae4e3b Merge pull request #1928 from mrcarlberg/ie_negative_width_height_crash
Fixed: IE8/9 (maybe 10 too) can't handle negative width or height.
2013-05-13 22:17:18 -07:00
Alexander Ljungberg 35b4e8f653 Merge pull request #1915 from Dogild/PopUpListComboBox
Fixed: CPComboBox popupList should close if mouse is clicked outside
2013-05-13 21:56:28 -07:00
Martin Carlberg 7837277cbe Merge branch 'master' of https://github.com/cappuccino/cappuccino into preprocess 2013-05-13 16:38:39 +02:00
Martin Carlberg 8145df9613 Fixed: Removed all uses of preprocess macros in the compiler 2013-05-13 16:23:12 +02:00
Martin Carlberg 9ffa184056 Fixed: IE8/9 can't handle negative style width or height.
Functions are used everywhere to set width or height in the DOM except in the method lockFocus. This will cause IE8/9 to report error if the width or height is negative in this method.
2013-05-13 15:12:59 +02:00
Sergio Felix d7b5382c32 Fixed: CPTabView will now update its tabs labels when the layoutSubviews method is called. Fixes 1926 2013-05-13 01:08:32 -05:00
Aparajita Fishman e047212f5f New: xcc --reset resets the Xcode support before opening the project.
This will help in cases where the project is way out of sync and crashes XCC.
2013-05-12 16:18:41 -04:00
Aparajita Fishman 574672f15f Fixed: some error handling needed improving.
- Added ~/narwhal/bin to executable paths.
- Hopefully clearer error message when an executable is missing.
- Log PATH when executable is missing.
- Catch parse exceptions when parsing parser.j errors, log the returned text.
2013-05-11 09:34:23 -04:00
Aparajita Fishman 9b3676fa4f New: missing image/framework in xib is reported as an error.
Previously, if an image or framework in image@framework was missing, it was just a warning, and conversion would continue.

Now an exception is raised and conversion stops.
2013-05-10 09:27:47 -04:00
Alexander Ljungberg 57d5dac72a Merge branch 'master' of github.com:cappuccino/cappuccino 2013-05-09 14:06:39 -07:00
Alexander Ljungberg 626e1e770e Fixed: in the last few revisions, table rows could be selected despite delegate shouldSelectRow: returning NO.
This error was caused by 3612565e3a dropping the return statement.

Refs #1905.
2013-05-09 14:05:53 -07:00
Aparajita Fishman 75b3bf22e6 New: added xcc executable to open a project in XcodeCapp from command line.
Usage: xcc [directory]

Updated help accordingly.
2013-05-09 16:48:37 -04:00
Alexander Ljungberg 48be680fde Test: clean up and fix minor errors. 2013-05-09 11:32:09 -07:00
Alexander Ljungberg e95856dadd Merge pull request #1905 from ahankinson/fix-cptableview-shouldselectrow-delegate
Fixed: Delegate method fires twice when using keyboard to select rows in...
2013-05-09 11:25:44 -07:00
Aparajita Fishman 86d7ec4180 New: added "Show in Finder" item to XcodeCapp.
Shows the Cappuccino project folder. If Path Finder is installed, it says "Show in Path Finder" and that is used.

Reorganized the menu a bit and updated the help.
2013-05-09 09:26:44 -04:00
Aparajita Fishman a63bb155c2 New: nib2cib gives a more helpful message when unsupported classes are encountered.
Previously users saw the generic "-[CPKeyedUnarchiver decodeObjectForKey:]: cannot decode object of class (NSFoo)" message, which was not particularly instructive.

Now the message is: "NSFoo objects are not supported by nib2cib."

Closes #1923
2013-05-09 07:35:27 -04:00
Aparajita Fishman 01291591b7 Fixed: missing self. in call to _delegate.
Small formatting and code tweaks as well.
2013-05-09 07:31:11 -04:00
Aparajita Fishman e7ad1a1f7a New: bumped XcodeCapp version. 2013-05-09 07:02:53 -04:00
Aparajita Fishman 2e0b204b8d Fixed: Xcode project was being saved when no modifications were made.
Saving the project requires the xib to be selected again if it was being edited, which is not so nice.

Now we check the project's modified flag before saving and lazy-create the groups.
2013-05-08 22:28:07 -04:00
Aparajita Fishman 77f8136e79 New: give a download link for XcodeCapp 3. 2013-05-08 11:01:21 -04:00
Aparajita Fishman e45c05b08e Merge branch 'refs/heads/XcodeCapp3' 2013-05-08 10:24:21 -04:00
Aparajita Fishman 14eff74652 Docs: updated XCC help. 2013-05-08 10:19:46 -04:00
Aparajita Fishman 14fec1a608 Fixed: deleted xib or cib files were not processed correctly.
Now, deleting a xib file will delete its corresponding cib. Deleting the cib will mark its corresponding xib for updating.
2013-05-08 10:19:25 -04:00
Aparajita Fishman 7034635b8e Fixed: converting xib with Autolayout gave confusing error message.
Previously, attempting to nib2cib a xib with autolayout would give an error message that there was no class to archive NSLayoutConstraint, which was meaningless to most people.

Now an error message that says exactly why it failed and how to fix it is given.
2013-05-08 09:57:00 -04:00
Aparajita Fishman 19aee142de Fixed: headers were incorrect or missing. 2013-05-08 09:54:13 -04:00
Aparajita Fishman 218eed7e97 Fixed: Frameworks/Source was being ignored during directory scans.
Formatting tweaks also.
2013-05-07 19:00:55 -04:00
Antoine Mercadal ec3fb2bd33 Merge branch 'WindowSheet' of https://github.com/Dogild/cappuccino into pr-1918 2013-05-07 11:20:49 -07:00
Antoine Mercadal b4a2ba4fc6 Merge branch 'outlineViewDisclosureSelectedThemestate' of https://github.com/BlairDuncan/cappuccino into outlineViewDisclosureSelectedThemestate
Conflicts:
	AppKit/CPOutlineView.j
2013-05-07 11:13:35 -07:00
Aparajita Fishman 1e828b2e8d New: changed terminology from "Reset Project" to "Synchronize Project". 2013-05-07 12:39:59 -04:00
Aparajita Fishman 4c94691b6f Fixed: merge with master added spurious files. 2013-05-07 12:39:31 -04:00
Aparajita Fishman 2b273b1e12 Fixed: capp templates were missing configuration for new features.
- The new compiler requires the OBJJ_INCLUDE_PATHS environment variable to be set.
- The new XcodeCapp 3 support for Frameworks/Source requires that directory to be excluded from builds.
2013-05-07 12:38:58 -04:00
Blair Duncan f8faf5199d linting 2013-05-06 23:57:58 -04:00
Blair Duncan eb312d5f66 updated to take into account trailiing rows beyond the last disclosure control 2013-05-06 23:51:41 -04:00
Antoine Mercadal 7fc7632971 Fixed: Crash after deployment when importing CPDatePicker
Previously, CPStepper was delcared using a @class. If CPStepper was not manually imported anywhere else in the app, it caused a crash.
This patch explicitely import CPStepper.j in _CPDatePickerTextField.j
2013-05-06 15:37:25 -07:00
Alexandre Wilhelm e22d6e0217 Removed on pixel at the top of a sheet window 2013-05-06 15:28:49 -07:00
Antoine Mercadal a11de15e33 Merge branch 'master' of https://github.com/cappuccino/cappuccino 2013-05-06 15:11:18 -07:00
Antoine Mercadal eb04174e68 Revert "Merge branch 'outlineViewDisclosureSelectedThemestate' of https://github.com/BlairDuncan/cappuccino into pr-1917"
This reverts commit 345a54e8c9, reversing
changes made to 21301cae21.

This commit is reverted because it causes a non obvious crash when selecting the latest row of a CPOutlineView.

The crash is visible in Tests/Manual/CPOutlineViewTest
2013-05-06 15:07:26 -07:00
Aparajita Fishman 97f93a031f Merge branch 'refs/heads/master' into XcodeCapp3 2013-05-06 17:45:48 -04:00
Aparajita Fishman 1f280b3985 New: CPNumberFormatter -localizedStringFromNumber:numberStyle:
Added unit test as well.
2013-05-06 17:45:16 -04:00
Antoine Mercadal e0d33a8e3f Merge branch 'SheetToolBar' of https://github.com/Dogild/cappuccino into pr-1919 2013-05-06 13:29:09 -07:00
Antoine Mercadal 345a54e8c9 Merge branch 'outlineViewDisclosureSelectedThemestate' of https://github.com/BlairDuncan/cappuccino into pr-1917 2013-05-06 13:15:41 -07:00
Antoine Mercadal 21301cae21 Merge pull request #1912 from Dogild/CornerView
Fixed: CornerView in TableViews from cibs are not sized well
2013-05-06 13:13:31 -07:00
Antoine Mercadal f8513eae26 Merge pull request #1903 from Dogild/CPDateFormatterSupport
New: Added support for CPTimeZone and CPDateFormatter
2013-05-06 13:11:36 -07:00
Martin Carlberg ee9b04944a Merge branch 'master' of https://github.com/cappuccino/cappuccino into preprocess 2013-05-06 16:24:54 +02:00
Martin Carlberg e9ca7c7395 Fixed: IE8 Browser support.
The compiler can now run in IE8. Also found the use of the function .indexOf on Arrays in CPView.j.
It is not supported in IE8.

Added a new file (OldBrowserCompatibility.js) in the Objective-J framework that will add functions if they are not supported in the javascript runtime.
2013-05-06 16:17:09 +02:00
Aparajita Fishman 2abe573bfe Fixed: XcodeCapp would attempt to build on non-Mac OS X platforms. 2013-05-05 22:18:50 -04:00
Aparajita Fishman 0aad32ba86 Fixed: building on 10.6 failed.
There are features of Objective-C 2.0 used in XcodeCapp that cannot be compiled with Xcode 4.2, which is the maximum version that runs on OS X 10.6. Users on 10.6 would see compile errors.

Now a check for OS X 10.7+ is done, and on any version earlier than that, the user is presented with a message telling them to download XcodeCapp from the web site.
2013-05-05 16:13:43 -04:00
Aparajita Fishman a24aacdb3e Fixed: pbxprojModifier was not working on OS X 10.6.
It turns out it never worked on 10.6. I had to modify mod_pbxproj.py to make it work. In the process I was able to make it faster by skipping conversion to JSON.

Also, a backup of the pbxproj file is made before saving, just in case.
2013-05-05 10:37:52 -04:00
Aparajita Fishman d2b1968dec Fixed: About window icon was small in OS X 10.6
Previously I was using the app icns file for the image. Now I have a separate retina-ready image for the About window.
2013-05-03 12:14:48 -04:00
Aparajita Fishman 9ee7535039 Tweaked the parser error messages 2013-05-03 12:12:46 -04:00
Aparajita Fishman d723c7306a Fixed: XCC was crashing on startup in OS X 10.6
The Lumberjack logging library was using a function not present in 10.6.

This commit reverts to an earlier release that works with 10.6.
2013-05-03 12:12:15 -04:00
Aparajita Fishman 9dd642395f Merge branch 'refs/heads/master' into XcodeCapp3 2013-05-02 17:53:06 -04:00
Aparajita Fishman 2b5cf1a56d Fixed: renamed jsc to narwhal-jsc.
Also put the list of mandatory executables in Info.plist.
2013-05-02 17:52:21 -04:00
Aparajita Fishman 1f4b49c461 Fixed: missing help.pdf. 2013-05-02 17:38:25 -04:00
Aparajita Fishman e20f2b75f0 Fixed: Lumberjack files were missing. 2013-05-02 17:24:29 -04:00
Aparajita Fishman 550401dffe New: XcodeCapp 3 total overhaul part 2.
Whew, a complete overhaul of my previous complete overhaul. Changes in no particular order:

- Redesigned the About box.
- Converted tabs to spaces.
- Using Lumberjack for (much better) logging. When debugging, copious logging goes only to Xcode's console, not to the system log. In the release build, only basic info and errors goes to the system log.
- Reformatted the help using Pages, it's a PDF now (so I can use better fonts).
- Massive optimization across the board. All time-consuming operations are done with NSOperation, which uses Grand Central Dispatch, and can be interrupted. So the XCC menu remains fully responsive during source processing.
- Updates to the Xcode project are coalesced so only one read/update/write operation is done.
- Instead of launching a shell and reading the .profile, the target executable is directly launched, but it must reside somewhere in the default binary path + /usr/local/bin:/usr/local/narwhal/bin:~/bin. If jsc, python, objj and nib2cib cannot be found in that path, the user is alerted and XCC quits.
- Added a preference (true by default) to automatically load the Xcode project when a project is opened.
- Added a preference to turn off per-file processing notifications.
- Added a hidden preference to set the log level. Useful for debugging a user's release build.
- Redesigned the Preferences window.
- Renamed some methods/properties, eliminated some unused properties.
- All of the windows remember their position.
- Moved the fsevent_callback into XcodeCapp.m.
- Fixed a bug in mod_pbxproj.py not setting the type of PBXFileReferences which are directories to "folder".
- Added support for categories in parser.j. Woo-hoo!
- Rewrote pbxprojModifier.py to use a class.
- Renamed the Xcode project group names to "Cocoa Classes" and "Cappuccino Source". Within "Cappuccino Source", framework code is kept in a "Frameworks" group.
- Shadow filenames are all project-relative now, thus *much* shorter.
- pbxprojModifier.py keeps the groups and files in the project in sorted order: Resource folders are at the top, followed by Cocoa Classes, followed by Cappuccino Source. Within Cocoa Classes, non-framework files come first, followed by framework files, followed by xcc_general_include.h.
- If either .XcodeSupport or the .xcodeproj is missing, the other is regenerated to ensure they stay in sync.
- A compatibility version for .XcodeSupport is stored inside it in Info.plist. If that version < the app's compatibility version, the project is reset. This ensures that format changes in the future will not result in projects in an unknown state.
- If the Xcode project cannot be opened, the user is alerted and given the option of regenerating the project.
- Resetting the project deletes all .cibs to force the .xibs to be regenerated.
- All possible FSEvents are dealt with individually now, and in a way that (hopefully) maintains sync between Cappuccino and XCC.
- A file descriptor to the Xcode project is kept open so that If the project path changes it can be relocated. If it does move, the user is alerted ad given the option of reloading the project or quitting.
- If one of the watched paths changes, the project is reloaded.
- Xcode creates temporary files, they are properly filtered out now when handling FSEvents.
- NSRegularExpression was being used before, but that is OS X 10.7 only. NSPredicate is used instead now.
-
2013-05-02 17:04:46 -04:00
cacaodev 4d8f7c67d4 Fixed removeTableColumn: was not reloading views immediatly. Added test for issue 1913 in Manual/TableTest/TestTableColumn. Throws an exception when you click the button twice 2013-05-02 19:39:27 +02:00
Antoine Mercadal f9dad2c1b3 Merge branch 'master' of https://github.com/cappuccino/cappuccino 2013-05-01 15:29:11 -07:00
Antoine Mercadal eacc527c5f Fixed: Tooltips for a view in another view with tooltip was not shown
Previously, tooltip system was using bubbling event. This was actually making impossible to see a view's tooltip if the parent view also has a tooltip. This patch changes the capturing mode from bubbling to capture.
2013-05-01 15:25:59 -07:00
Alexandre Wilhelm 30e9389a92 Updated test 2013-04-30 15:25:23 -07:00
Alexandre Wilhelm e5fc452063 Added theme for Arsito1 2013-04-30 14:43:47 -07:00
Alexandre Wilhelm 7477294648 Added test for toolbar sheet 2013-04-30 14:39:31 -07:00
Alexandre Wilhelm 16b2334274 Refactor code 2013-04-30 14:35:01 -07:00
Alexandre Wilhelm 7b59ec93df Fixed: Windows with toolbars do not display correctly as sheets
Previously it wasn't possible to display a toolbar in a sheet window.
Now, a toobar is displayed well in a window. This PR allows every sheet window to have a toolbar, with the PR #1918 just the CPTitleWindow/HUD sheet could have a toolbar as in cocoa.

Fixes #1863
2013-04-30 14:11:45 -07:00
Blair Duncan 23ef587f68 added don't attempt to setthemestates if there are no disclosure controls
previous commit was failed the travis build test when there were no controls
2013-04-30 12:05:12 -04:00
Alexander Ljungberg 72455f43d4 Test: expose child window level crash bug if present.
This manual test exposes the bug addressed by issue #1911.
2013-04-30 00:57:42 +01:00
Alexander Ljungberg e8828fe0bc Merge branch 'slevenbits-child-windows-order-fix' of git://github.com/slevenbits/cappuccino into slevenbits-slevenbits-child-windows-order-fix 2013-04-30 00:44:56 +01:00
Alexander Ljungberg 3430684c22 Merge branch 'master' of github.com:cappuccino/cappuccino 2013-04-30 00:40:49 +01:00
Alexandre Wilhelm 3357162660 Added CPBorderlessBridgeWindowMask for the ToolBar 2013-04-29 16:21:56 -07:00
Alexandre Wilhelm 2e93e4abf7 Fixed: Sheet window under the toolbar
Previously when using a sheet window in a fullPlatform window, the sheet window started the animation under (the layout) the toolbar.
Now, the sheet animation starts below the toolbar as in cocoa.
It also fixed that only a CPBordelessWindow/CPTitleWindow/HUD can have a toolbar.
2013-04-29 16:16:29 -07:00
Blair Duncan 3e268a88b3 Fixed: OutlineView disclosure button selected themestate when selected
Previously, when a row with a disclosure control (triangle) was selected, the row was selected
but the control remained in the unselected themestate. Disclosure control themestate was only being
changed when the control itself was clicked on. This fix changes the controls themestate whenever
the row selection changes.
2013-04-29 11:29:57 -04:00
Aparajita Fishman 6de967345c Removed unused constant 2013-04-27 09:04:36 -04:00
Antoine Mercadal a38d6c11b4 Fixed: Tooltips always showing in primary platform window
Previously, the tooltip of a control was always shown on the primary platform window. This fixes sets the tooltip window's platform view to [[targetView window] platformWindow].
2013-04-26 14:56:20 -07:00
Antoine Mercadal 807387463f Merge pull request #1916 from Dogild/DatePickerHidden
Fixed: CPDatePicker freeze when hidden

Reviewed
2013-04-26 13:31:06 -07:00
Aparajita Fishman 52a53fb8d1 Fixed: if .xcodeproj was missing, it was not created.
Now if either .XcodeSupport or the .xcodeproj is missing, both are recreated to ensure they are in sync.

Also, when trying to open the Xcode project, if it is missing or cannot be opened, an alert is displayed and the user is given the option of regenerating the project.

Some code cleanup as well.
2013-04-26 14:27:47 -04:00
Antoine Mercadal 6bd9a08460 Fixed: CPAlert always shows on main platform window
Previously, a CPAlert was always shown on the main platform window. This behavior could result in a feeling that the application was hanging because of the modal nature of the alert when users are looking to another platform window. This fix ensure to set the CPAlert window's platformWindow to the current key window using [[CPApp keyWindow] platformWindow].
2013-04-26 10:34:48 -07:00
Antoine Mercadal 81a61c1412 Fixed: Trying to open a CPPopover in a secondary platform window opened in the main window
Previously, when opening a popover on a view from another platform window, the popover
was actually opened in the main window. This fix ensure to set the correct platform window
to the _CPPopoverWindow by setting it to the [[positioningView window] platformWindow];
2013-04-26 10:25:52 -07:00
Aparajita Fishman 811c7444df New: added documentation for using framework images.
This documentation is also in the nib2cib man page, but who will read that?
2013-04-26 11:41:42 -04:00
Aparajita Fishman a5a9bbf1a7 Fixed: XcodeCapp would attempt to open a path that did not exist or was not a directory.
The first defense against this is to validate the recent menu items to ensure they exist and are directories. If not, the item is disabled.

The next time a project is opened, the missing project is pruned from the recent menu.

The second defense is a check when an attempt is made to open a project.
2013-04-26 11:30:12 -04:00
Aparajita Fishman 12cf674595 Fixed: warning notification said "Error parsing…" instead of "Warning parsing…"
I was missing the variable in a test.
2013-04-26 11:07:37 -04:00
Ilya Kulakov 7ccf7c731c Consistent approach to handle child windows.
When added, level of child window is reset to level of the parent.
A user may change it aftewards to the level that may even break
specified relative position.

E.g. if a child window is added below the parent (Normal)
and its level is set to Floating it will be ordered above.

Whenever you change level of the parent window, levels of the child
windows are reset as well ignoring all your changes.

According to the example, if you set level of the parent to Normal+1,
child window' level will also be set to Normal+1 and its relative
order to the parent (below) will be restored.
2013-04-26 19:46:38 +07:00
Ilya Kulakov d3a4ce4608 Revert "Fix child windows may reside on other layers than parent."
This reverts commit 8e4f1fdd10.
2013-04-26 17:57:18 +07:00
Ilya Kulakov 920204fc63 Revert "It's important to order out child windows before parent window relationship is broken."
This reverts commit c6553016d3.
2013-04-26 17:57:00 +07:00
Aparajita Fishman 2d8d68dc5e Fixed: Jakefile for XcodeCapp did not install symlink correctly.
FILE.exists was being used to test for the existence of the symlink in /Applications, but that doesn't work.

The correct way is to use ln -sfh. Note that the -h was missing before, which prevents an existing target symlink from being followed, which is why the symlink would end up inside XcodeCapp.app.
2013-04-25 23:22:37 -04:00
Alexandre Wilhelm 736dffa334 capp_lint 2013-04-25 17:06:52 -07:00
Alexandre Wilhelm bd2a7b2b7b Fixed: CPDatePicker freeze when hidden
Previously the CPDatePicker freezed when trying to hide it when it was the firstResponder.
There was an intern problem in the CPDatePickerTextField about the nextKeyView. That's why there was a boundless loop and the freeze.
This PR also fixed a big about the previous and next textField in the CPDatePicker.
It also fixed a bug about the CPDatePicker when it becomes firstResponder.

Fixes #1909
2013-04-25 16:56:10 -07:00
Aparajita Fishman fc8ca14743 Updated XcodeCapp 3 help to reflect new features. 2013-04-25 19:27:18 -04:00
Aparajita Fishman 15cf818b1e Fixed: not enough space around status icon. 2013-04-25 19:03:10 -04:00
Aparajita Fishman cf9b630401 Fixed: Xcode created temporary files which were being processed.
When saving a xib, Xcode creates a temporary file with the name <filename>~.xib. The file event listener would sometimes pick this up and XcodeCapp would attempt to process it, but by the time nib2cib was launched it would be gone, generating an error.

Now .xib files whose filenames end with ~ are ignored.
2013-04-25 19:02:46 -04:00
Aparajita Fishman 3cc6b8dfbe New: better icons for XcodeCapp 3 2013-04-25 19:00:20 -04:00
Aparajita Fishman bf6ce64209 New: XcodeCapp 3 tweaks...
- Renamed XcodeSupport to .XcodeSupport.
- Added "Reset Project" to menu, it closes the project in Xcode if necessary, removes .XcodeSupport and .xcodeproj, then reloads.
- Added separate preferences for showing errors panel on warnings/errors. You may not want to see the panel if there are category warnings.
- New status icons (again).
- If an error occurs, the status icon turns red when all processing is done.
- Reworked notifications. Objective-J parsing is notified when done. Xib conversion notifies at beginning and end, because it typically takes a few seconds. Individual file notifications are suppressed if a project is being loaded.
2013-04-25 13:11:22 -04:00
Alexandre Wilhelm afdad97aad Added CPComboBox Aristo2 style 2013-04-24 17:47:30 -07:00
Alexandre Wilhelm 7e27de8a1e Updated slices 2013-04-24 17:46:53 -07:00
Aparajita Fishman 949af39041 New: the highest first launch version is saved.
The effect is that each minor point release (3.1 -> 3.2) will cause the help to display the first time it is launched, so that the user is encouraged to find out what is new.
2013-04-24 18:41:26 -04:00
Aparajita Fishman 2104c838bd Fixed: Resources directories in Frameworks/Source/<framework> were not picked up by XcodeCapp.
XcodeCapp would add a folder reference in the project for user framework Resources directories in Frameworks/Debug, but it didn't add references for framework Resources directories in Frameworks/Source.
2013-04-24 18:11:53 -04:00
Aparajita Fishman ee1c7a5f01 New: updated nib2cib man page to cover new features.
Framework image support and --no-colors option.
2013-04-24 18:09:48 -04:00
Aparajita Fishman 6d77faa7dd Fixed: order of framework image arguments was backwards.
Previously the order was <framework>@<image>, which seems backwards.

Now the order is <image>@<framework>.
2013-04-24 18:09:02 -04:00
Aparajita Fishman f4dc139675 Tweaked the About panel. 2013-04-24 17:26:34 -04:00
Aparajita Fishman 73d62029ba Various fixes...
- Accidentally deleted the Jakefile. It has been restored, and fixed the case where it would put a symlink to XcodeCapp.app within XcodeCapp.app.
- Minor changes to remove compiler warnings.
2013-04-24 16:01:55 -04:00
Aparajita Fishman b38f845643 New: high resolution status icons.
Also a help text tweak.
2013-04-24 15:39:23 -04:00
Aparajita Fishman cdef68034d New: 2x status icons. 2013-04-24 15:08:16 -04:00
Aparajita Fishman 467036bf34 Fixed: any .xcodecapp-ignore file was parsed.
Previously any .xcodecapp-ignore file within the monitored directories would be parsed. This commit ensures that only the project's root .xcodecapp-ignore file is parsed.
2013-04-24 15:07:59 -04:00
Aparajita Fishman 934dedecd2 Changed terminology to "Open" from "Listen" 2013-04-24 15:06:30 -04:00
Aparajita Fishman bd96d1b5e2 Updated help 2013-04-24 15:05:45 -04:00
Aparajita Fishman 01920e674d Fixed: Notification Center was suppressing notifications.
By default, Notification Center may suppress notifications if the application is frontmost. This commit ensures that all notifications are displayed.
2013-04-24 11:39:57 -04:00
Aparajita Fishman 0ec218a599 New: XcodeCapp preference to set maximum recent projects.
Previously the number of recent projects was unbounded, which made the recent menu unwieldy.

Now the recent projects list is pruned to the maximum set in the preferences, which defaults to 20.
2013-04-24 11:38:57 -04:00
Aparajita Fishman db21168a93 New: ignore XcodeSupport directories. 2013-04-24 10:58:52 -04:00
Aparajita Fishman 606205b58d New: XcodeCapp 3, a major overhaul.
- Updated project to Xcode 4.
- Reorganized files into preferred Xcode 4 hierarchy.
- Updated code to use properties.
- Eliminated unused/redundant code.
- Significantly optimized project scans.
- Added support for outlets, actions and resources in user frameworks.
- Now using bindings throughout.
- New application icon, Retina ready.
- New status menu icons.
- Reorganized menu.
- Added Preferences… menu item.
- Parsing errors and nib2cib errors are actually logged to the errors panel now.
- When an error occurs, the errors panel automatically opens, unless the "Automatically open Errors & Warnings panel" preference is off.
- Double-clicking an error or selecting an error and clicking Open opens the error in the preferred editor for .j files (or Xcode for .xibs). The cursor jumps to the offending line in the following editors: Sublime Text, TextWrangler, BBEdit, TextMate, Chocolate, MacVim.
- The Errors panel now remembers its position/size.
- When a project is loaded, the errors panel is cleared.
- When a file is modified, any pre-existing errors for that file are removed.
- Updated to Growl framework 2.0.1.
- If Notification Center is available (OS X 10.8+), that is used instead of Growl.
- .xcodecapp-ignore now supports ignoring a directory by suffixing the name with "/".
- .xcodecapp-ignore now supports include expressions prefixed with "!".
- Significantly optimized filename matching against ignored paths.
- .XcodeSupport has been renamed XcodeSupport to make it visible, so that trashing it is easier if things get out of sync.
- The template Xcode project now contains no frameworks or targets, so Xcode does not show any warnings or errors, and the user cannot accidentally try to build.
- Removing a file now removes the file from the Xcode project.
- Shadow files replace forward slash with U+2215 (DIVISION SLASH), which looks like forward slash but is a character that is extremely unlikely to be in a filename.
2013-04-24 10:57:59 -04:00
Alexander Ljungberg 1aa0956b4d Merge pull request #1915 from Dogild/PopUpListComboBox
Fixed: CPComboBox popupList should close if mouse is clicked outside
2013-04-24 13:51:10 +01:00
Martin Carlberg 14ee789df4 Fixed: Mark correct column position in 'Expected a Semicolon' errors in the parser. 2013-04-24 10:12:42 +02:00
Alexandre Wilhelm d400617c1b Added optimization 2013-04-24 00:41:06 -07:00
Alexandre Wilhelm 056a00e54e Fixed: CPComboBox popupList should close if mouse is clicked outside of the control
Previously the list of the CPComboBox didn't close when clicking outside of the control
Now the list has the same behavior as Cocoa

Fixes #1859
2013-04-24 00:33:56 -07:00
Aparajita Fishman 0b7e92aa53 New: better logging of image bundle info in nib2cib.
If an image comes from a framework, the framework's bundle identifier is logged if it is available.
2013-04-23 23:36:28 -04:00
Aparajita Fishman 9cb2c758c7 New: --no-colors option for nib2cib.
Previously error messages would always be colorized, which doesn't work well if you are piping the output.

Passing --no-colors turns off all colors in the output.
2013-04-23 23:34:55 -04:00
Martin Carlberg b6fd6a15f0 Fixed: Removed extra spaces in code generation between 'else' and 'if' in 'else if' statements 2013-04-23 17:07:26 +02:00
Martin Carlberg e35bfaf96c Fixed: Better looking code generation with correct indentation for 'if' - 'else if' statements 2013-04-23 15:48:25 +02:00
Martin Carlberg ffdee8c3d7 Fixed: Method isEqual: can handle nil as an argument for CPExpression and CPPredicate including sub classes. 2013-04-23 12:58:07 +02:00
Martin Carlberg 8a94c33a64 New: Added test cases checking that a CPObject, CPExpression and CPPredicate is not equal nil.
CPExpression and CPPredicate can't handle nil as an argument to method isEqual:. These test cases checks that this is working.
2013-04-23 12:54:26 +02:00
Alexandre Wilhelm 9d69ec739f Fixed: CornerView in TableViews from cibs sized
Previously the size of the cornerView was wrong in a TableView from cib.

Now the nib2cib of _CPCornerView set the good value.

Fixes #1865
2013-04-22 15:38:31 -07:00
Ilya Kulakov c6553016d3 It's important to order out child windows before parent window relationship is broken. 2013-04-23 01:32:08 +07:00
Alexander Ljungberg 6048814635 Merge branch 'refs/heads/slevenbits-cpcolor-hsb-fix' 2013-04-21 15:03:53 +01:00
Alexander Ljungberg fe26e6cfe0 New: + CPException raise:format:.
This method allows the exception reason to be a formatted string with parameter replacement.
2013-04-21 14:56:57 +01:00
Alexander Ljungberg 3e35e3d8a8 Fixed: CPColorPicker not working with fixed CPColor colorWithHue: implementation. 2013-04-21 14:32:10 +01:00
Alexander Ljungberg 70b5105daa Fixed: CPColor colorWithHue:saturation:brightness: returning undefined.
A hue of 1.0 would cause the CPColor colorWithHue:saturation:brightness: method to return `undefined` instead of a CPColor instance.
2013-04-21 14:22:34 +01:00
Alexander Ljungberg d00846aae7 Fixed: CPColor colorWithHue:saturation:brightness: parameters not clamped.
Previously, the parameters to CPColor colorWithHue:saturation:brightness: could be specified below 0 or above 1.0.

Now the values are clamped so that values below 0 are taken as 0 and values above 1.0 and taken as 1.0.
2013-04-21 14:21:47 +01:00
Aparajita Fishman 7ec660c509 New: record the source filename in SyntaxError. 2013-04-20 13:24:50 -04:00
Ilya Kulakov 8e4f1fdd10 Fix child windows may reside on other layers than parent.
Child windows should reside on the same layer as parent.
2013-04-20 21:08:32 +07:00
Alexander Ljungberg 0c2abf3629 Test: new CPColor HSB tests. 2013-04-20 13:56:49 +01:00
Alexander Ljungberg 95d4bef3ea New: - CPColor hueComponent, saturationComponent and brightnessComponent. 2013-04-20 13:42:05 +01:00
Alexander Ljungberg 4e1a1415f6 Fixed: - CPColor hsbComponents range.
Previously, - CPColor hsbComponents returned degrees and percents. With the latest change to - CPColor colorWithHue:saturation:brightness: this was inconsistent.

Now - CPColor hsbComponents returns its components as factors in the 0-1.0 range.
2013-04-20 13:41:16 +01:00
Alexander Ljungberg 40579b5d56 Fixed: parameter range of CPColor colorWithHue:saturation:brightness:.
Previously, + CPColor colorWithHue:saturation:brightness: took its parameters as degrees and percent (e.g. hue between 0º and 360º, saturation and brightness between 0% and 100%). However, in Cocoa the components are given as factors (0.0-1.0) like other colour methods.

This fix makes + CPColor colorWithHue:saturation:brightness: work like in Cocoa.
2013-04-20 12:41:13 +01:00
Antoine Mercadal 60f79bdf63 Merge pull request #1910 from Dogild/MenuColor
Fixed: CPMenu bar selected background color
2013-04-19 14:59:36 -07:00
Alexandre Wilhelm 96a772d4dc Fixed: CPMenu bar selected background color
- Previously the selected background color didn't have the right color.
2013-04-19 14:54:37 -07:00
Andrew Hankinson 2974bdc1d7 Fix formatting and enumerator problems 2013-04-19 16:45:40 -04:00
aparajita c7f4517490 Merge pull request #1881 from kerusan/cpruleeditor_post_row_change
Fixed: 'RowCountChanged' notification generates nil warning when dragging a row
2013-04-18 13:26:20 -07:00
aparajita 8f6efdaae0 Merge pull request #1902 from ahankinson/fix-issue1899
Fixed: Removing an item from a menu also removes its highlight state
2013-04-18 13:17:24 -07:00
aparajita e760ee39e5 Merge pull request #1906 from ahankinson/fix-cptableview-variabletypo
Fixed: Misspelled variable in CPTableView
2013-04-18 13:02:32 -07:00
aparajita 0bc95c069d Merge pull request #1818 from t00f/master
New: tableView:shouldReorderColumn:toColumn: CPTableView delegate method
2013-04-18 12:58:38 -07:00
Aparajita Fishman f883b6a182 Fixed: _CPPopoverWindow.j was not imported in CPApplication.j
This caused the isKindOfClass: test in _CPRunModalLoop to generate an error in a deployment.

Importing that file fixed the error.
2013-04-18 13:31:27 -04:00
Christophe Serafin 88a247c107 merged sources and show shouldReorderColumn usage in TableCibTest example 2013-04-17 01:57:07 +02:00
Alexandre Wilhelm de5fbd921e Fixed bug when changing timeZone of the CPDatePicker 2013-04-16 15:22:16 -07:00
Alexandre Wilhelm a8aeb8addb Added CPTimeZone test 2013-04-16 15:21:30 -07:00
Alexandre Wilhelm 13211b489d Added support for timeZone in CPDatePicker calendar 2013-04-16 14:20:18 -07:00
Alexandre Wilhelm 9f5e977bcd Added support for timeZone in CPDatePicker textual 2013-04-16 14:10:52 -07:00
Alexandre Wilhelm 28357bd57f Corrected bad test 2013-04-16 02:26:17 +02:00
Alexandre Wilhelm f39e224c48 Updated manual example 2013-04-15 16:33:00 -07:00
Alexandre Wilhelm 9b9b041263 Removed double action in CPDatePicker 2013-04-15 16:22:54 -07:00
Alexandre Wilhelm 98a59c4700 Fixed small bus about timeZone 2013-04-15 16:20:02 -07:00
Alexandre Wilhelm 3497e36f23 Fixed bunch of bugs in CPDateFormatter with TimeZone 2013-04-15 14:25:30 -07:00
Andrew Hankinson 3612565e3a Fix delegate selection to check the index first
In the previous patch the shouldSelectRow delegate was being stored and only called once. This changes its behaviour again to first fire the delegate to see if the row in question can be selected. If not, it will look for the next row (up or down) that may be selected and choose that one.
2013-04-15 16:38:37 -04:00
Andrew Hankinson c24a7712cd Fixed: Misspelled variable in CPTableView
This commit fixes a typo in CPTableView. `_contentBindingExpicitelySet` should be `_contentBindingExplicitlySet`. The misspelling was consistent, so this should have no functional change.
2013-04-15 11:58:13 -04:00
Alexander Ljungberg 83677dae83 Merge pull request #1904 from ahankinson/docs-fix-tableview-typo
Docs: Fix small but potentially confusing typo in CPTableView
2013-04-15 16:48:27 +01:00
Andrew Hankinson 6e2dcd5dcb Fixed: Delegate method fires twice when using keyboard to select rows in table view
Previously, navigating through the rows of a tableview with the arrow keys would cause the delegate method `- (BOOL)tableView:(CPTableView)aTableView shouldSelectRow:(int)rowIndex` to fire twice. This was due to the delegate method being called twice in checking whether the row could be selected.

This commit changes it so that the delegate method is called just once and the result stored.
2013-04-15 11:46:58 -04:00
Andrew Hankinson 5eea9c301c Docs: Fix small but potentially confusing typo in CPTableView
This commit fixes the delegate documentation for `- (void)tableViewSelectionIsChanging:(CPNotification)aNotification`, removing reference to "selection chaining." (should be "selection changing")
2013-04-15 11:21:29 -04:00
Andrew Hankinson efa2918ce9 Change how menu items are highlighted
This replaces the previous solution with one proposed by @BlairDuncan. It uses the _highlightItemAtIndex: method to maintain the highlight state, rather than setting the _highlightIndex variable directly.
2013-04-14 15:40:35 -04:00
cacaodev e53337bcdc Remove check in -hitTest: that was preventing reverse set binding 2013-04-13 21:39:20 +02:00
cacaodev e5d883f97e CAKeyframeAnimation
CPAnimatablePropertyContainer protocol (CPView)
CPAnimationContext
_CPObjectAnimator CPViewAnimator
CSS Animations wrapper

CPAnimatablePropertyContainerTest : animations of views with custom Layout / Regular Layout / Custom DrawRect: / No DrawRect: / Subviews / No Subviews and combinations of these situations.
controls animation (text field, button, popup, slider ...). They animate their size via their action.
2013-04-13 16:29:43 +02:00
cacaodev 548a55792c Merge remote-tracking branch 'upstream/master' into CPTableView-enumerateRows 2013-04-13 11:52:51 +02:00
cacaodev 43f0f2a0fd Simplified -numberOfRows
Added -_numberOfRows that computes the new number of rows. Removed the
nil check.

All tests in AppKit/CPTableViewTest are now passing with success.
2013-04-13 11:38:47 +02:00
Alexandre Wilhelm 0bbaec0829 New: Added support for CPTimeZone and CPDateFormatter
- Added support for CPDateFormatter in Foundation
- Added support for CPTimeZone in Foundation
- Added support fo CPDateFormatter in nib2cib

Test app in Tests/Manual/CPDateFormatter
UnitTest in Tests/Foundation/CPTimeZoneTest.j
UnitTest in Tests/Foundation/CPDateFormatterTest.j
2013-04-12 11:15:10 -07:00
cacaodev 7b1c696810 Fixed: CPTableViewTest: -deselectAll should send 1 CPtableViewSelectionDidChangeNotification, not 2.
Checked in cocoa.
Moved a failing test to the end of the method so it does not shadow other tests.
2013-04-12 19:48:07 +02:00
cacaodev 8d69c3764d Fixed: The data views were not loaded immediately
When reloading the table view, the actual loading (-load) is defered
until layout is needed (generally in the next run loop). This is an
advantage because it minimize reloads but in some case it is necessary
to force a reload, for example when we need to access data views, or
manually edit a view, or when we explicitely ask for a reload.
This commit adds _reloadDataViewsImmediately and make use of it when
necessary.

Tests: AppKit/CPTableViewTest -> -testEditCell
2013-04-12 19:35:03 +02:00
cacaodev 87acd9d7ee Fixed: in some circumstances, table views binded with the content binding were not correctly reloading the data.
Test: AppKit/WithOrWithoutbinding
2013-04-12 19:23:51 +02:00
cacaodev 06391c9de6 Fixed: data views were not reloaded after a CPTableColumn setDataView:
Cell-based table views with no identifier set for the table column:
Before this commit, the caching system was asking for a view identified
by the tableColumn UID. If the table column data view was changed
externaly, the previoulsy cached data views were loaded instead of the
new ones. The views are now identified by the -dataview UID.

Test: AppKit/TableTest -testLayout were a custom data view is set.
2013-04-12 19:21:16 +02:00
cacaodev b42b41216b Remove old code. Adds Equality check in -setDataView: 2013-04-12 19:08:27 +02:00
Martin Carlberg 689ab09555 New: Now supports 'defined' operator, which lets you check whether macros are defined in the middle of an ‘#if’.
Also the evaluation of expressions are now lazy.
2013-04-11 09:37:40 +02:00
Martin Carlberg 30ee1ad8cd New: Handles line continue token '\' on lines starting with '#'
We now support lines like this:
#define StopButtonTitle() \
        CPLocalizedString(@"Stop", @"Stop button title")
2013-04-11 09:32:41 +02:00
Andrew Hankinson cc9ff15142 Fixed: Removing an item from a menu also removes its highlight state
Previously when a menu item was instantiated outside of the context of the menu itself, its highlight state was maintained even after it was removed from the menu. If the menu was dismissed with the item highlighted, and then the item was used in another menu (e.g., re-added to a context menu for a table row) it would appear highlighted, even though the menu highlight index was not set.

This commit ensures that when removing items from a menu that the highlight state of the underlying view is set to NO as well.

Tests for this behaviour are included as well.

Fixes #1899
2013-04-10 00:04:53 -04:00
Alexander Ljungberg 4c756c7cbf Merge pull request #1900 from ahankinson/fix-aboutpanel-cib
Fixed: AboutPanel is now constructed in code, rather than in a CIB
2013-04-09 00:26:16 +01:00
Andrew Hankinson 100f1b0b41 Fixed: AboutPanel is now constructed in code, rather than in a CIB
Previously the default About panel was constructed in a CIB. Additionally, an Xcode-based XIB/CIB file was constructed to replace it.

This commit creates the default About panel in code and removes the additional CIB/XIB files in the AppKit/Resources panel.
2013-04-08 19:20:37 -04:00
Aparajita Fishman d9117bd9a0 Fixed: Converter was copying too much state from Nib2Cib, framework resources could not be referenced in Xcode.
* State *
Previously the Converter class needlessly copied a whole bunch of state from the Nib2Cib class, which was not only poor factoring, but made for easy omissions of state when instantiating a new Converter, such as was done in NSNib.j.

This commit pushes all state not specific to Converter up to Nib2Cib. This allowed removal of redundant code in NSNib -NS_initWithCoder.

* Resources *
Previously it was not possible to use custom images that were located in a framework, because only the app's Resources directory was searched.

This commit automatically searches all frameworks for Resources directories. When a custom image is specified in Xcode, first the app's Resources directory is searched, then all framework Resource directories. Alternately, the specific framework to use can be specified in Xcode by using the form framework@image.

At runtime, the framework is loaded by its identifier (as specified in Info.plist), and if there is no identifier, by searching next to the current AppKit framework.

All of this renders the nib2cib -R option completely obsolete, so it was removed from the NibApplication/Jakefile template.
2013-04-08 15:48:45 -04:00
Andrew Hankinson 6ef5b46dd6 Fixed: CPTokenField sends focus and blur notifications
This commit adds notifications for focus and blur on CPTokenField.

Attached is a modified Manual CPTokenFieldTest that observes these notifications.

Fixes #1396
2013-04-07 20:50:50 -04:00
Alexander Ljungberg b3c60e56a6 Merge pull request #1897 from ahankinson/fix-info-plist-templates
Fixed: Additional keys in default Info.plist templates
2013-04-08 00:35:42 +01:00
Alexander Ljungberg 8d345701da Merge pull request #1896 from ahankinson/fix-about-panel-xib
Fixed: New AboutPanel.xib replaces older CIB file
2013-04-07 23:18:48 +01:00
Alexander Ljungberg 016ed4f6ee Merge branch 'master' of github.com:cappuccino/cappuccino 2013-04-07 23:16:45 +01:00
Andrew Hankinson 3da7e45244 Fixed: Additional keys in default Info.plist templates
This fix adds two keys to the default Info.plist in the capp gen template for NibApplication, "CPBundleVersion" and "CPHumanReadableCopyright". These are introduced primarily to fill out the fields in the default "About" panel. (see #1896)
2013-04-07 17:02:54 -04:00
Andrew Hankinson b1229bce1d Fixed: New AboutPanel.xib replaces older CIB file
With the death of Atlas CIB files can no longer be edited directly. This commit replaces a CIB-only version of "AppKit/Resources/AboutPanel.cib" with a XIB-derived one that can be edited in Xcode.

This commit also moves some of the formatting of the about panel into the IB file (c.f. the FIXME note).
2013-04-07 16:54:15 -04:00
Aparajita Fishman fea6b37379 New: capp framework template provides a default CPPrincipalClass.
Previously no default principal class was declared in Info.plist for a framework.

This commit declares the principal class to be the same as the main framework class created with capp gen -t Framework.
2013-04-06 16:21:47 -04:00
Aparajita Fishman d64ea284fb Fixed: CPBundle -bundleWithIdentifier did not create CPBundle when necessary.
Previously, if a CFBundle with the given identifier had been loaded, but no CPBundle had yet been created with the given identifier, -bundleWithIdentifier would return nil instead of a newly constructed CPBundle with the CFBundle's URL.

This commit correctly returns a newly constructed CPBundle when a CFBundle is found.
2013-04-06 16:20:21 -04:00
Aparajita Fishman cc2503ac0f Fixed: CFBundle.prototype.bundleURL() did not return an absolute URL.
CFBundle internally stores its URL in relative form, and returned that relative URL in the bundleURL() function. However, in Cocoa an absolute URL is returned. It is reasonable to assume an absolute URL would be expected by some asking for the bundle's URL. Even within CFBundle, most times bundleURL() is called it is followed with absoluteURL().

This commit returns an absolute URL from bundleURL().
2013-04-06 15:51:09 -04:00
Aparajita Fishman 486bff44df Fixed: wrong display name for CFBundle.bundleContainingURL. 2013-04-06 15:48:41 -04:00
Aparajita Fishman 04d6b34bfe Fixed: tests broke because of change in CGRect/CGSize/CGPoint description. 2013-04-06 08:49:33 -04:00
Aparajita Fishman 0193632673 New: use a more compact representation of CGSize/CGPoint/CGRect in description. 2013-04-05 23:18:56 -04:00
Aparajita Fishman a3730812bc New: CFBundle.identifier, CFBundle.bundleWithIdentifier, CPBundle -bundleWithIdentifier.
Finding a bundle by identifier is theoretically better than using a class.
2013-04-05 23:16:05 -04:00
Antoine Mercadal 90e11039a1 Merge branch 'CPDatePickerTarget' of https://github.com/Dogild/cappuccino into pr-1895 2013-04-05 11:40:27 -07:00
Antoine Mercadal 80d928eff2 Merge branch 'menuKeyboardNavigationFix' of https://github.com/BlairDuncan/cappuccino into pr-1894 2013-04-05 11:37:21 -07:00
Antoine Mercadal 838041ef59 Merge pull request #1872 from ahankinson/fix-tableview-method-documentation
Docs: Out of date documentation for CPTableView
2013-04-05 11:31:23 -07:00
Antoine Mercadal 732f94a284 Merge pull request #1883 from ahankinson/fix-textfield-ib-enabled
Fixed: Allow Interface Builder to set CPTextField enabled state
2013-04-05 11:30:54 -07:00
Antoine Mercadal 70081e1118 Merge pull request #1873 from ahankinson/fix-issue1866
Fixed: XCodeCapp adding duplicate files to Xcode project
2013-04-05 11:30:17 -07:00
Antoine Mercadal 35c15c90e4 Merge pull request #1890 from Dogild/MenuItemColor
Fixed: CPMenuBar theming
2013-04-05 11:28:57 -07:00
Alexandre Wilhelm 812cd463db Fixed: CPDatePicker works with action and target
Previously the CPDatePicker didn't work with the action and target. Now each time the dateValue changed, the given action is sent to the target.
This commit fix also a bug with moving with tab and the arrows. Before, the left arrow worked liked a tab when the firstElementTextField was selected in a textual CPDatePicker.

Test app in Tests/Manual/CPDatePicker.
2013-04-05 11:28:41 -07:00
Alexandre Wilhelm 090d097a53 Added action and target 2013-04-05 11:19:20 -07:00
Alexandre Wilhelm 36b337e784 Fixed bug about left moving 2013-04-05 11:13:28 -07:00
cacaodev 0a1d215560 Fixed: -reloadData: was not reloading views after a change in model rows count 2013-04-04 20:00:56 +02:00
Blair Duncan 7d0d1056c0 Fixed – Menus no longer respond to keyboard navigation
When a menu is active, menu selection should change as characters are typed.
This can be seen in the manual CPMenuTest.

It used to work in the past but with all of the changes in the last few months to the compiler I
was not able to track down the exact commit that broke it. The code responsible for
clearing the _keybuffer after a brief delay in typing, was not being called,
resulting in a build up of characters.

This commit moves the check for delay to the interpretKeyEvent and takes care of
clearing the _keybuffer itself and removes that responsibility from the selection method.
2013-04-04 12:44:15 -04:00
Aparajita Fishman 21146ff49f Fixed: scrolling CPTextField to visible would cause unexpected behavior
Previously, when a text field became the key responder, first it was scrolled to visible, then a check was made to see if the text field was completely within the platform window bounds. The scrolling to visible would unfortunately cause problems because of the interaction between the blur handler in text fields and controls that can be clicked without becoming first responder.

This commit completely forbids text fields from becoming first responder if they are not completely within the platform window. That eliminates any possibility of unwanted browser scrolling of the text field.
2013-04-02 12:06:32 -04:00
Antoine Mercadal b76eedfc0e Merge pull request #1884 from Dogild/CPDatePickerSupport
New: CPDatePicker Support
2013-04-01 18:01:42 -07:00
Alexandre Wilhelm c547117223 Removed comments 2013-04-01 14:37:53 -07:00
Antoine Mercadal fc2132485d Merge branch 'CPMenuGhost' of https://github.com/Dogild/cappuccino into pr-1891 2013-04-01 14:26:47 -07:00
Alexandre Wilhelm 71cc825038 Fixed: CPMenu ghost his fixed #1887
Fixed the bug about ghost menu after several right click
2013-04-01 13:28:30 -07:00
Antoine Mercadal 59d1da77c2 Fixed: setting CPNullPlaceholderBindingOption in binding was setting the value
This commit fix a bug where declaring the binding option CPNullPlaceholderBindingOption was actually setting the
actual value of a text field instead of just its placeholder. This commit adds a test to determine if the binding source
implements setPlaceholderString:. In that case, we let the value to be nil.
2013-04-01 12:47:00 -07:00
cacaodev 44b6136ce2 Fixed CPOutlineView dragging column subclassing 2013-04-01 20:11:02 +02:00
cacaodev ba3c6023a8 Fixed CPOutlineView subclassing when settting CPThemeStateSelectedDataView 2013-04-01 20:11:02 +02:00
cacaodev be7f6ae7d1 Fixed CPOutlineView -reloadData and _layoutViewsForRowIndexes:columnIndexes: subclassing. 2013-04-01 20:11:02 +02:00
cacaodev 984c7a67f5 Fixed: -moveColumn:to: now preserve selected columns
Fixed: Starting a column drag is now faster.
Fixed: When dragging a selected column, selection is now drawn on the dragging view and the cursor is the closed hand.
Fixed: When dragging a table column, underlying columns were sliding according to the tracking location instead of the column lateral edges.
Fixed: In CPTableView, the drop indicator for rows could appear when dragging a column.

This commit creates directly the dragging column instead of relying on
built-in drag&drop. Also fixes a bug where the drop indicator would appear when
dragging a column if some rows were previously drag&dropped.
2013-04-01 20:08:37 +02:00
cacaodev a4bf6c1f7a Fixed: selectColumnIndexes:byExtendingSelection: returns early when there is no change in columns selection
Before this change, rows could be unselected even if the columns
selection did not change.
2013-04-01 20:08:36 +02:00
cacaodev 690ae1a7b6 Fixed: noteHeightOfRowsWithIndexesChanged: was not showing immediatly row height changes.
Todo: instead of reloading everything we should be able to just
relayout frames for visible views and then tile.
2013-04-01 19:52:37 +02:00
cacaodev eae9a10a7d Fixed: editingColumn and editingRow return the correct index in view based tables
Fixed: An edited view no longer send its action (view-based) or commit its object value (cell-based) when unexposed.
Fixed: Cell based tables support for editing any control, not just textfield and buttons.
2013-04-01 19:52:30 +02:00
cacaodev 7c6765b969 Fixed: After drag, views were cached.
This commit reverts #1478. It appears it is a bad idea to enqueue
visible views. The views generally stay in the cache forever and they
are repeatedly asked to be removed from the table at each load, causing
a performance penalty.
2013-04-01 19:50:41 +02:00
cacaodev a6c143a1c7 Fixed: -reloadDataForRowsIndexes:columnIndexes: behavior.
Fixed: Column dragging performance, content binding performance.

After this commit, -reloadDataForRowsIndexes:columnIndexes: reloads the data and the data only.
The -reloadData method no longer tries to reuse the views, instead it just reloads the data for visible views.
To flush and reload the views cache for visible rows, use _reloadDataViews.
To internaly layout the views geometry, use _layouViewsForRowIndexes:columnIndexes:

In CPTableView dragging column code, relayout the views whose frame changed instead of reloading everything.
2013-04-01 19:50:41 +02:00
cacaodev 714da0ab3b New: -enumerateAvailableViewsUsingBlock: and private -_enumerateViewsInRows:columns:usingBlock: and -_enumerateViewsInRows:tableColumns:usingBlock: methods.
New: preparedViewAtColumn:row:

These methods allow to enumerate visible data views or data views in specified columns and rows.
-enumerateAvailableViewsUsingBlock: is the counterpart of cocoa's -enumerateAvailableRowViewsUsingBlock: except that it enumerates data views instead of CPTableRowView and the block has an additional column parameter.

This commit reverses the way views are stored and accessed in the table view: rows>columns instead of columns>rows.
Applied the second method where it is relevant, making the code more compact and readable.
2013-04-01 19:49:41 +02:00
cacaodev 377ec37257 Fixed: In CPTrace, fixed error when an argument was not a cappuccino object.
Arguments such as CGPoint, CGRect and functions are now correctly
printed to the console.
2013-04-01 19:34:04 +02:00
Alexandre Wilhelm c6a59d7c59 Fixed: CPMenuBar theming
Previously it wasn't possible to theme the main menu of the app. With this fix the user can either theme the main menu with the theming system or with the method +setMenuBarAttributes from CPMenu.
2013-03-31 23:31:02 -07:00
Alexander Ljungberg 84559fae9c Merge pull request #1889 from saikat/master
Fix a memory leak in _CPImageAndTextView.  This closes #1888.
2013-03-31 09:56:14 +01:00
Saikat Chakrabarti aa0602dcbb Fix a memory leak in _CPImageAndTextView.j 2013-03-30 21:52:17 -07:00
Antoine Mercadal 6d0caacdeb Fixed: setAnimates: for CPPopover doesn't get forwarded to _CPPopoverWindow.
Without this fix, using setAnimates: on a popover would only be applied after closing/reopening of the popover.
2013-03-28 15:18:46 -07:00
Martin Carlberg 84df301f3e New: #if macro statement works for simple literals but not for macro identifiers and defined keyword 2013-03-28 22:43:26 +01:00
Andrew Hankinson 792a72af74 Fixed: Themed text values set via a single variable
Previously, the themed text values for controls were set directly on the control, which made modifying the theme values for text consistently across the controls difficult.

This commit introduces several file-scoped variables that are used to set the text colour, the disabled text colour for both regular and default controls, as well as a consistent text shadow colour for each of these as well.
2013-03-28 13:35:09 -04:00
Andrew Hankinson 8fee6578c2 Fixed: Minor typo in CPWindow comment 2013-03-28 10:36:46 -04:00
Andrew Hankinson 6d843e6aab Fixed: Removed duplicated method in CPToolbar
CPToolbar setDisplayMode has been implemented (L246). This commit removes a duplicate empty method that says it has not been implemented.
2013-03-28 10:19:08 -04:00
Alexandre Wilhelm 27bb85bb00 Fixed bug about firstResponder. Fixed bug about current date when changing the month (to pass from the 31 to 30) 2013-03-27 11:23:20 -07:00
Martin Carlberg 2751f4fea9 New: Added missed #ifdef derective 2013-03-27 14:52:05 +01:00
Martin Carlberg c21cfeb28e New: Added #ifdef, #ifndef, #else, #endif and #undef macro derectives 2013-03-27 14:50:55 +01:00
Martin Carlberg 8707247008 New: Always generate code when compiling 2013-03-27 14:45:25 +01:00
Andrew Hankinson 3d0bde6763 Stepper disabled graphics update 2013-03-27 00:20:20 -04:00
Andrew Hankinson 11f509933e Typos 2013-03-26 23:40:19 -04:00
Andrew Hankinson 7078dd92dd Restoring the segmented control theme descriptor settings 2013-03-26 23:23:35 -04:00
Andrew Hankinson f5e0addbcc Restoring circular slider disabled graphics 2013-03-26 23:22:34 -04:00
Andrew Hankinson fd88ac509f Slight tweak to the disabled slider knob graphic
The stroke opacity is reduced from 35% to 20% to bring it in line with the stroke opacity of other disabled controls
2013-03-26 23:22:02 -04:00
Andrew Hankinson d267ddcafa Reverse earlier commits that removed some images
The segmented control disabled state is not applied via CSS opacity, so the segmented control images must be present.
2013-03-26 23:20:40 -04:00
Andrew Hankinson 9084e9ed18 Fixed: Text shadow offset on enabled controls
Previously, the text shadow offset on a control that was active (e.g., a button that was set to default, or the active segment of a segmented control) would have a text shadow applied to it if the button was also disabled.

This commit negates the text-shadow offset so that the text appears correctly.
2013-03-26 23:17:23 -04:00
Andrew Hankinson bf29a4faa9 Defined file-level variables for text colors
This commit defines file-level variables for the disabled text colour, the disabled text shadow colour, and the placeholder text colour. It also adds or replaces these values in the controls where appropriate.
2013-03-26 23:14:57 -04:00
Andrew Hankinson 615380a70c Standardizing disabled text theming for popup and pulldown buttons 2013-03-26 22:46:49 -04:00
Antoine Mercadal d268013bf0 Fixed: Make build under rhino to work
Previously, rhino build was failing
2013-03-26 18:03:38 -07:00
Antoine Mercadal 835367e1bf Merge branch 'master' into CPDatePickerSupport 2013-03-26 18:02:27 -07:00
Antoine Mercadal 054421c978 Fixed: Crash with rhino in fontinfo due to missing import
fontinfo's Jakefile needed to import SYSTEM to call SYSTEM.env
2013-03-26 17:57:02 -07:00
Andrew Hankinson 20a2b2d330 Fixed: circular slider disabled image uses CSS opacity 2013-03-26 20:23:38 -04:00
Alexandre Wilhelm 1649ea64cc New: CPDatePicker Support
- Added CPDatePicker
- Added CPLocale
- nib2cib for CPDatePicker

Test app in Tests/Manual/CPDatePickerTest
2013-03-26 16:52:46 -07:00
Andrew Hankinson d50439161a Fixed: Combo box disabled state dims text
Previously, setting a CPComboBox to disabled would not dim the text. This commit fixes the theme state to include a setting for the text colour and text shadow colour.
2013-03-26 19:19:03 -04:00
Andrew Hankinson 7d6cdf1b7b Updated pulldown button disabled images
These updated images have an outer stroke opacity of 20%, compared to 35% for the active images
2013-03-26 19:01:08 -04:00
Andrew Hankinson abcb60ed4c Updated popup button disabled images
These updated images have an outer stroke opacity of 20%, compared to 35% for the active images
2013-03-26 19:00:52 -04:00
Andrew Hankinson 443b6ff4f9 Updated combo box disabled images
These updated images have an outer stroke opacity of 20%, compared to 35% for the active images
2013-03-26 19:00:14 -04:00
Andrew Hankinson de89eadcf2 Formatting and whitespace 2013-03-26 18:40:22 -04:00
Andrew Hankinson 4956218b10 Fixed: Change default disabled opacity
Previously some disabled controls would be set with an opacity of 0.35, which resulted in controls that were visually too light.

This commit changes the default disabled opacity to 0.5.

Refs #1788
2013-03-26 17:44:57 -04:00
Andrew Hankinson bcfaf3a37e Fix Pulldown Button disabled images
The new images are set at full opacity with the blue highlight colour removed
2013-03-26 17:43:02 -04:00
Andrew Hankinson b1c45e579a Fix CPPopupButton disabled images
The new images are set at full opacity with the blue highlight colour removed
2013-03-26 17:42:41 -04:00
Andrew Hankinson e627f60b16 Fix CPComboBox disabled images
The new images are set at full opacity with the blue highlight colour removed
2013-03-26 17:42:05 -04:00
Andrew Hankinson 7154252dff Fixed: Allow Interface Builder to set CPTextField enabled state
Previously, the enabled/disabled control for NSTextField in Interface Builder was ignored by nib2cib.

This change allows the enabled/disabled state on CPTextField to be set in interface builder.
2013-03-26 14:54:53 -04:00
Andrew Hankinson a368fe5825 Fix disabled theme for Aristo2 segmented controls
Disabled state is now set via CSS opacity alone
2013-03-26 13:39:46 -04:00
Andrew Hankinson 895a128ff7 Fix disabled theme for Aristo2 radio buttons
Disabled state is now set via CSS opacity alone
2013-03-26 13:33:55 -04:00
Andrew Hankinson 792a4dda7f Merge branch 'fix-theme-disabled-controls' of github.com:ahankinson/cappuccino into fix-theme-disabled-controls 2013-03-26 13:29:56 -04:00
Andrew Hankinson 4d828a01aa Fix disabled theme for Aristo2 checkboxes
Previously the Aristo2 checkboxes used dedicated images for disabled controls.

This commit removes the disabled controls and allows the disabled state to be set via CSS opacity on the "regular" checkbox controls.
2013-03-26 13:29:48 -04:00
Andrew Hankinson 195ee3ee2c Fix disabled theme for Aristo2 checkboxes
Previously the Aristo2 checkboxes used dedicated images for disabled controls.

This commit removes the disabled controls and allows the disabled state to be set via CSS opacity on the "regular" checkbox controls.
2013-03-26 13:23:11 -04:00
Kjell Nilsson d9e7912162 Fixed: constructing a 'RowCountChanged' notification generates a nil warning when dragging a row
Previously, when

- Dragging a row in the rule editor

would eventually try to generate a dictionary with key 'indexes' and a
nil value in the method __postRowCountChangedNotificationOfType:indexes:.
Generating an empty dictionary instead when there is no indexes solves
this issue.
2013-03-26 11:19:44 +01:00
Aparajita Fishman 2a580c675a Fixed: shared singleton Converter was being overwritten by incompletely constructed instance.
Previously, NSNib would create a Converter instance for converting table cell views. Unfortunately Converter did not expect to be instantiated more than once, and the singleton SharedConverter was unconditionally being set in the initializer. This might not have caused problems, except that NSNib did not copy all of the shared Converter's state to the copy, especially the resource path, which caused custom images in table cell views to fail.

This commit correctly ensures that the shared Converter instance is set only once, and also copies all of the shared Converter state to the instance that is used for converting the table cell view.
2013-03-25 16:07:58 -04:00
Aparajita Fishman 9f66de8422 Fixed: removed deprecated check for no resource path.
Long ago it was required to use the -R option with nib2cib if custom images were used. nib2cib now infers the resource path, so there will always be at least a default resource path. Thus the check for no resource path was unnecessary.

This commit removes that check.
2013-03-25 16:02:52 -04:00
Aparajita Fishman b26542136e Formatting 2013-03-25 15:59:10 -04:00
Christophe Serafin c135905e64 removed blank line and console messages 2013-03-25 13:37:49 +01:00
Christophe Serafin b7b7d33597 avoid to call the delegate when moving before the first column and after the last column 2013-03-25 13:22:43 +01:00
Aparajita Fishman 097d8e9b97 Fixed: adding object to CPArrayController generated warning.
Previously, if properties were bound to table columns in a cell-based table, and an object was added/inserted using CPArrayController, a warning was generated about a missing observer.

This commit is a temporary fix, the real fix is to implement more granular notifications during didChangeValueForKey:, which will eliminate the source of this problem.

Fixes #1781.
2013-03-24 20:12:22 -04:00
Aparajita Fishman 8c811ba9ca Fixed: instantiating a cib with no owner would generate nil warning
Previously, when a view-based table:

- Had no delegate.
- Used bindings for its data source, thus obviating the need for makeViewWithIdentifier:owner:.

it would eventually call CPCib -instantiateCibWithOwner:topLevelObjects: with a nil owner (the nil table delegate). This method would try to construct a dictionary with the nil owner, which would generate a deprecation warning, and will in the future fail altogether.

In Cocoa, this is exactly what happens, the owner is nil. And the documentation for -instantiateNibWithOwner:topLevelObjects: clearly states that the owner may be nil.

This commit only adds the owner to the name table dictionary if the owner is non-nil. Since objectForKey: with a non-existent key returns nil, this is the same as storing nil for that key.
2013-03-24 19:46:53 -04:00
Alexander Ljungberg b6cf557483 Merge pull request #1879 from cacaodev/CPDragServer-fixed-constrained-inside-bounds
Fixed: A dragged view was constrained inside a plaform window bounds.
2013-03-24 22:20:42 +00:00
Alexander Ljungberg 3562aed899 Merge pull request #1878 from ahankinson/fix-cpimage
Fixed: Typo in CPImageView Category
2013-03-24 22:17:16 +00:00
cacaodev 07222e92c2 Fixed: A dragged view was constrained inside a plaform window bounds.
For example, in CPTableView before this change, dragged rows could not move up if the table view was near the top of the platform window.

Fixes #1877
Test TableTest/ViewBasedCib/ and drag up the third row.
2013-03-24 22:08:15 +01:00
Andrew Hankinson 011c3c9c5b Fixed: Typo in CPImageView Category
The category name for CPImage (CachedImage) was spelled wrong. This commit fixes the typo.
2013-03-24 16:15:50 -04:00
Alexander Ljungberg 28b77fa02b Merge pull request #1876 from cacaodev/CPTableView-viewForRow-infinite-loop
Fixed: a view outside a CPTableView causing an infinite loop when becomes FR.
2013-03-24 20:00:02 +00:00
cacaodev a9ec90713e The FR can be a window, don't check if it's inside a table. 2013-03-24 20:33:22 +01:00
cacaodev 8663b7b3fa Merge remote-tracking branch 'upstream/master' into CPTableView-viewForRow-infinite-loop 2013-03-24 18:50:41 +01:00
cacaodev 3ef5cfe846 Fixed: Infinite loop when a first responder has a nil superview
This bug appears only if a table view have been added to the window.

CPTableView observes first responder changes and moves up in the view
hierarchy to determine the edited data view. If for some reason, a
superview in the hierarchy was nil, we entered an infinite loop.

This commit adds guards to the recursive method that searches the data
view. Also added an early return when the fr changes to a view outside
the table.

Fixes #1875
2013-03-24 18:37:12 +01:00
Aparajita Fishman 05fa505bb6 Fixed: CPArray did not allow binding to @count.
Previously, CPArray did not allow binding to the collection operator @count. In Cocoa this is allowed.

This commit allow the key path @count to be observed, so that @count can be bound to.

Formatting fixes as well.
2013-03-23 15:21:50 -04:00
Andrew Hankinson 5c3adfda29 Fixed: XCodeCapp adding duplicate files to Xcode project
Previously, XCC would indiscriminately add files to the Xcode project via the pbxprojModifier.py script. This resulted in duplicate references to a file.

This fix adds a check to see if the file is already included in the project's sourceGroup folder, and will return None if it is.

Fixes #1866
2013-03-22 09:44:02 -04:00
Andrew Hankinson 0013375eea Docs: Out of date documentation for CPTableView
A small documentation change to reflect the updated viewForTableColumn:row:
2013-03-21 16:24:55 -04:00
Blair Duncan 5868a4cefb added missing methods to CPDocumentController
documentForWindow
hasEditedDocuments

both are in cocoa
2013-03-21 11:15:25 -04:00
Blair Duncan 3178f0b57d Fixed CPDocumentController missing method currentDocument
In this commit I've added the currentDocument method to the document controller

Also removed the firstEligibleExistingWindowController method from CPDocument
It did nothing but add confusion as it was not used anywhere else in the frameworks.
And it is not in cocoa.
2013-03-21 10:38:06 -04:00
Alexander Ljungberg 31c06771f3 Fixed: CPBezierPath getLineDash:phase: typo. 2013-03-21 14:37:37 +00:00
Alexander Ljungberg 6f57b8a2de Merge pull request #1869 from sherab/stringByTrimmingCharactersInSet-fix
Fixed: stringByTrimmingCharactersInSet not removing characters at end
2013-03-21 13:52:55 +00:00
Tim Lewis bd6d2e71e7 Fixed: stringByTrimmingCharactersInSet not removing characters at end
If a string had characters from the set at both the start and end,
the end trim was one character less than required.
2013-03-21 13:44:00 +00:00
Martin Carlberg 89457845f9 Fixed: Made some smaller code generation changes to get better formatted compiled code 2013-03-21 14:32:21 +01:00
Martin Carlberg 53e98521f3 Merge branch 'master' of https://github.com/cappuccino/cappuccino into preprocess 2013-03-21 12:25:47 +01:00
Martin Carlberg 1842d7127a New: The generated code will now have correct indentation. 2013-03-21 11:33:13 +01:00
Martin Carlberg ecc1e774b9 New: Added macro/identifier concatenation with the '##' operator
Example:
#define first Martin
#define second Carlberg
var first##second = 13;

Compiles to:
var MartinCarlberg = 13;

Example 2:
#define _function(inline) function inline { return _##inline; }
#define _CGPointMake(x_, y_) { x:x_, y:y_ }
_function(CGPointMake(x, y))

Compiles to:
function CGPointMake (x, y) {
  return {x: x, y: y};
}
2013-03-20 21:00:36 +01:00
Martin Carlberg fa18095538 Fixed: Does not add extra parentheses for expression operators with the same precedence 2013-03-20 20:47:27 +01:00
Alexander Ljungberg da9333e884 Fixed: CPBezierPath getLineDash: nil arguments, setLineDash:count:phase: argument style.
Previously, passing nil to the first or last argument of getLineDash:count:phase: would cause a crash.

With this change, these references are simply not written to if nil.

Previously, setLineDash:count:phase: took references for its arguments to match getLineDash:count:phase:. This was however wrong and is not what is done in Cocoa.

This fix makes the setLineDash:count:phase: calling convention the same as in Cocoa.
2013-03-20 16:02:27 +00:00
Alexander Ljungberg af11431b09 Fixed: Firefox dashed stroke phase support (theoretically).
This fix should in theory make the phase argument work in Firefox, although in Firefox 19.0.2 it doesn't seem to work. Hopefully it'll kick in in a future version of Firefox.
2013-03-20 15:42:22 +00:00
Alexander Ljungberg 16134aa0de Test: dashed and phased CG strokes. 2013-03-20 15:27:48 +00:00
Alexander Ljungberg ffbd9815d5 New: CPBezierPath setLineDash: and getLineDash:.
Also includes Cocoa compatible methods for completeness.
2013-03-20 15:26:51 +00:00
Alexander Ljungberg ab692bb15d New: CGContextSetLineDash. 2013-03-20 14:06:01 +00:00
Alexander Ljungberg 085654e751 Fixed: nib2cib of combo box parsed enabled state twice.
It's sufficient to read the _enabled state in the superclass NSCell, no need to read it again in the subclass.

Refs #1868.
2013-03-19 23:17:35 +00:00
Alexander Ljungberg 5b3386af2f Merge pull request #1868 from ahankinson/fix-cpcombobox-ib-disable
Fixed: Allow Interface Builder to set CPComboBox enabled state
2013-03-19 23:05:59 +00:00
Andrew Hankinson d6545627aa Fixed: Allow Interface Builder to set CPComboBox enabled state
Previously, the enabled state of a CPComboBox could not be set in Interface Builder.

This commit allows Interface Builder to set the enabled state of a CPComboBox.

A modified test in Manual/CPComboBoxTest is included. This test simply adds a new disabled combo box to an existing window, and then checks to see if it is disabled, printing a descriptive message to the Javascript console.
2013-03-19 19:01:56 -04:00
Andrew Hankinson cb63013197 New: Higher Contrast XCodeCapp menubar icons
This commit changes the current XCodeCapp menubar icon to use higher contrast colours, making it easier to see when XCC is working or idle.

Previously, the colours were black and dark green. With this change, the colours are black and orange (taken from the Cappuccino logo).

This commit includes the original PSD artwork as well as rendered versions of the icons in PNG format.
2013-03-18 09:56:43 -04:00
Aparajita Fishman 5d2e4bf7cc Fixed: theme build failed
Previously CPTableView -_init was trying to reference a theme value, but that doesn't work because the theme creates a CPTableView and during that _init the theme value is not yet defined.

This commit uses lazy instantiation to avoid this problem.

Also, column selection was added to the CPDictionaryControllerTest to better visualize unfocused selection highlight colors.
2013-03-18 08:21:02 -04:00
Aparajita Fishman a4fb2deece Fixed: unfocused selection highlight colors were hard coded
Previously, the colors used for unfocused selection highlighting were hard coded. In Cocoa, they seem to be desaturations of the focused selection highlight colors.

This commit calculates the unfocused highlight colors from the focused colors.

It also removes some dangling commas.
2013-03-17 18:29:47 -04:00
Martin Carlberg 92ac8569b3 New: Full support for generate code instead of copy
The new compiler can now generate code. The old way of copy and alter the source
code is still supported.
2013-03-17 21:00:24 +01:00
Martin Carlberg 0c982b0999 Fixed: An ExpressionStatement with a Send message expression can be parsed wrongly
When a statement ends without a semicolon and a Send message expression is on the next line it was wrongly parsed as a single Send message expression. It should be an ExpressionStatement with a Send message expression inside.
2013-03-17 20:52:21 +01:00
Martin Carlberg bef0ca18c6 New: New option to generate code for the objjc tool
A new option flag '-G' can be added to let the compiler generate the code instead of copy and alter it from the source code
2013-03-17 20:45:34 +01:00
Aparajita Fishman afc2c17b5a Fixed: highlighted table cells with CPTableViewSelectionHighlightStyleNone had white text.
Previously, CPTableView was unconditionally setting the selected theme state for selected data views. When the selection highlight style is CPTableViewSelectionHighlightStyleNone, there is no row selection highlighting done. Since the default theme specifies white text for selected data views, we ended up with white text on a non-highlighted background, which was invisible on non-alternate rows and almost invisible on alternate rows.

This commit unsets the selected theme state flag for any redrawn data views when the selection highlight style is CPTableViewSelectionHighlightStyleNone, thus the text color does change at all when selected.

Fixes #1847
2013-03-16 15:41:24 -04:00
Blair DuncanandAparajita Fishman efdf0a6b84 Fixed: When editing a table cell, the row lost focus.
Previously, when a table cell was edited, the table thought it had lost focus and displayed the cell's row highlight in an unfocused state.

This fix updates the _isFocused test to include tests for cell editing in both cell-based and view-based tables.
2013-03-16 09:33:53 -04:00
Aparajita Fishman b36f8d794c Fixed: unfocused selection highlight in table upside down.
Previously the gradient in an unfocused selection highlight in CPTableViewSelectionHighlightStyleSourceList style was darker at the top and brighter at the bottom, which is the opposite direction of the gradient when focused.

This commit makes all of the unfocused highlight colors a strict 5% desaturation of the focused colors.

Refs #1839
2013-03-15 19:57:20 -04:00
Aparajita Fishman 5c022f86ea Fixed: table selection highlight gradient top/bottom too dark.
In CPTableViewSelectionHighlightStyleSourceList selection style, a table view draws the highlight on each row with a top line, linear gradient, and bottom line. Previously, the top and bottom lines were quite dark in relation to the gradient.

This commit makes the top and bottom line brighter, to make the transition to the gradient more subtle.

Refs #1839
2013-03-15 19:57:19 -04:00
Blair DuncanandAparajita Fishman fd20a8045e Fixed: table view selection color did not change when losing focus.
CPTableView has no focus ring, and currently gives no visual feedback of its firstResponder status. In Cocoa when the table view resigns firstResponder or its window loses key status, the selection color turns gray.

This commit sets the selection color to gray when a table view resign firstResponder or its window loses key status. A second window and a couple of textfields were added to the CPDictionaryControllerTest to demonstrate the changes.

Fixes #1839
2013-03-15 19:56:47 -04:00
Aparajita Fishman 9482d14160 Fixed: table view highlight update loop had high overhead
Previously the selection highlight update loop created two selectors and called an extra method for every row being updated.

The selectors are now calculated beforehand, and the method call has been eliminated.
2013-03-15 16:37:15 -04:00
Aparajita Fishman 61783021cc Fixed: default horizontal margin wasn't changed along with theme value 2013-03-15 13:30:26 -04:00
Andrew HankinsonandAparajita Fishman 64b5299c0d Fixed: menus were too far apart.
Previously the main menus were farther apart than the Aristo 2 PSD indicated, and too far apart visually.

This commit reduces the horizontal margin between menu items that have originated from Interface Builder. A value of 9.0 for horizontal margin (down from 12.0) reduces the margin on both sides of the menu by 3px, reducing the inter-menu spacing by a total of 6px.

Fixes #1809
2013-03-15 12:55:03 -04:00
Blair DuncanandAparajita Fishman 8d2077fc5d Fixed: views from other windows could be set as next/previous key view.
Previously, no check was done to ensure a next/previous key view belonged to the same window as the view to which it was being chained. This could lead to an infinite loop.

This commit will only set the next/previous key view if the proposed's views window is either nil or is the same as the receiver's window.

Closes pull request #1851
2013-03-15 12:39:08 -04:00
Alexander Ljungberg 720b61f4f6 New: close pull down menu on second click on its button.
Previously, if a pull down menu was brought down from a pop up button in pull down mode, clicking the button again would close and reopen the menu.

With this fix the behaviour becomes like in Cocoa, and clicking the button a second time simply closes the menu.
2013-03-15 14:47:16 +00:00
Alexander Ljungberg 9fa8867495 Fixed: infinite loop clicking on a pull down menu button.
This was caused by the menu opening up below the button. When the menu manager examined this event it saw a click outside of the menu and immediately closed the just opened menu. Then it put the opening event back on the event queue, causing the pop up button to try to open its menu again.

The fix ignores the opening event for purposes of detecting clicks which should close the menu.

Refs #1833.
2013-03-15 14:47:16 +00:00
Aparajita Fishman b198fee11a Fixed: default class theme value could be CPNull.
The class method +themeAttributes returns a dictionary, so CPNull has to be used instead of nil. Previously, if the class theme attribute was used, there was no attempt to convert CPNull to nil, which could have unintended consequences.
2013-03-15 10:02:31 -04:00
Aparajita Fishman 2f71b8d5c9 Fixed: improved handling of custom styled table text cells.
Previously more work was done than necessary to initialize custom table text cells.

Now the theme state is set before initializing table cells, which allows fonts and colors to be set correctly. The selected colors still have to be set explicitly.

BREAKING CHANGE:

Because this operates within nib2cib, all xibs should be re-converted.
2013-03-15 10:00:12 -04:00
cacaodevandAparajita Fishman 33858cfc3b Fixed: incorrect table column highlighting and row selection after column sort.
Previously in CPTableView, after clicking a sortable column, data views of the sorted column ended up in a selected state and a row was selected instead of the sorted column. As a result, the text of the rows would turn white as if they were selected, but there was no highlight, so the text was basically invisible.

This commit fixes that by reversing the order of operations when clicking a column. First the sort is done, then the selection.

Fixes #1337, #1688, #1779.
2013-03-15 08:26:37 -04:00
cacaodevandAparajita Fishman 7225e7e038 New: deprecate -tableView:dataViewForTableColumn:row: and -outlineView:dataViewForTableColumn:item:
-tableView:dataViewForTableColumn:row: and -outlineView:dataViewForTableColumn:item: are deprecated in favor of ...viewForTableColumn:...

Using the previous delegate API and not caching the view with an identifier was degrading performance. With this change, developers are encouraged to use the new caching system and the CPTableView method -makeViewWithIdentifier:owner: to get the view.

Also fixed a condition where a view-based outline view was not always asking for the view from its delegate. In some circumstances, an outline view could be considered as view-based instead of cell-based.

Test for deprecated delegate methods in CPOutlineViewViewBasedCib and TableTest/ViewBased examples.

Fixes #1823
2013-03-15 08:16:02 -04:00
Aparajita Fishman d25ff21030 Fixed: _CPThemeAttribute _parentAttribute had confusing name
Previously _CPThemeAttribute had an ivar called _parentAttribute, which represented the attribute from the theme descriptor, as opposed to the attribute for a particular instance of a view.

This commit renames that ivar to _themeDefaultAttribute, so it is clearer where it gets its values.
2013-03-14 23:57:39 -04:00
Aparajita Fishman 8055808235 Fixed: table view cells with custom font/color did not change properly when selected
Previously, if a cell-based table had a custom font or color in a table cell, when the cell was selected it would not change color. Also, edited cells did not maintain the original font/color.

This commit ensures that table cells uses the theme setting for selected text color, while maintaining all font and color attributes when selected or being edited.

BREAKING CHANGE:

Because this fix operates at the level of nib2cib, xibs that use customized cell-based table text cells should be reconverted.
2013-03-14 23:51:59 -04:00
Aparajita Fishman 9827f19c63 Fixed: selected table used bold font, text was fixed size
It used to be part of the theme to make the text in selected table rows bold. I never quite understood that, it really isn't necessary visually. Cocoa doesn't do it, I don't know of any toolkit that does.

Also, fixed sizes were used for text field theme fonts, which did not allow them to track runtime changes to the system font size.

This commit makes selected table row text plain, so selecting a row does not change the metrics of the text, just changes the color, which is much more pleasing visually.

Also, the special CPFontCurrentSystemSize constant, which tracks the actual font size at runtime, is used for text field font sizes.
2013-03-14 23:51:54 -04:00
Aparajita Fishman edb1a68952 Formatting 2013-03-14 23:49:14 -04:00
Aparajita Fishman 6dc9aa815a Fixed: eliminated duplicate CPThemeStateSelectedTableDataView state
CPThemeStateSelectedTableDataView and CPThemeStateSelectedDataView were the same, and were not used in any consistent or meaningful way.

This commit eliminates CPThemeStateSelectedTableDataView, only CPThemeStateSelectedDataView is used now.
2013-03-14 17:06:23 -04:00
Aparajita Fishman bf36c40f88 Fixed: optimized selector creation
Use @selector, that happens at compile time, instead of CPSelectorFromString, which happens at runtime.
2013-03-14 17:06:23 -04:00
Antoine Mercadal 099da1b071 Merge branch 'pr-1858' 2013-03-14 13:54:12 -07:00
Alexander LjungbergandAntoine Mercadal cd620b0c5a Fixed: more precise array controller insert index test.
Refs #1856.
2013-03-14 13:49:42 -07:00
Blair DuncanandAntoine Mercadal 21de08506c added in the xib that I modified for testing. 2013-03-14 13:49:42 -07:00
Blair DuncanandAntoine Mercadal 009ae1e14c Fixed ArrayController failed to recognize row 0 as the insert location
The logic is wrong in the test for last selection since it can be 0
and if there is no selection, [_selectionIndexes lastIndex] returns -1

Fixes #1723
2013-03-14 13:49:42 -07:00
cacaodev c8b812bbb5 FIXED: A data view edited in a table view was duplicated after a reload.
Previously in CPTableTView, a view being edited was not cached when unloaded, for example when made invisible after scrolling or when calling -reloadData.
This situation was causing a duplicated view to be added at the same place when the data view was loaded again.
After this commit, edited data views are cached and resign their first responder status just before they are added to the queue because they can be reused at another place.

Test: Added a "reload data" button in ViewBasedCib example.
2013-03-14 19:28:45 +01:00
Alexander Ljungberg be2234113b Fixed: more precise array controller insert index test.
Refs #1856.
2013-03-14 17:32:08 +00:00
Alexander Ljungberg 4dd4d17ef9 Merge pull request #1856 from BlairDuncan/arrayControllerFixFor1723
Fixed ArrayController failed to recognize row 0 as the insert location
2013-03-14 17:25:07 +00:00
Blair Duncan cac0555c43 added in the xib that I modified for testing. 2013-03-14 12:43:50 -04:00
Blair Duncan 35dd35d821 Fixed ArrayController failed to recognize row 0 as the insert location
The logic is wrong in the test for last selection since it can be 0
and if there is no selection, [_selectionIndexes lastIndex] returns -1

Fixes #1723
2013-03-14 12:33:17 -04:00
Aparajita Fishman 03b663463d Fixed: couldn't set the first responder of a sheet
Previously the sheet was made key at the beginning of the animation. It turns out events would not reliably make it to the sheet during animation. The other problem is that if a text field was the first responder, at the beginning of the animation it is offscreen, which means it refuses first responder and sets the first responder to nil.

Now we no longer try to make the sheet key before the animation ends, avoiding the text field problem.
2013-03-14 00:30:37 -04:00
Aparajita Fishman 9a28beb6b5 Fixed: makeFirstResponder didn't work for token fields
A change had been made to CPTextField _becomeFirstKeyResponder that wasn't propagated to CPTokenField.
2013-03-13 19:46:43 -04:00
Aparajita Fishman dc96b3862b Fixed: popovers were not constrained to the usable content frame
Previously, popovers did not properly stay below the menu bar.

This commit ensures they stay within whatever is the usable content frame for the platform window.
2013-03-13 17:00:54 -04:00
Aparajita Fishman facd97c09d Fixed: if orderOut: was not called for a popover, it would not detach from its parent
When a transient popover was closed by clicking, in some cases it would not detach from its parent, leaving it in the window list. This caused problems later on.

This commit ensures the popover is detached from its parent when it is ordered out.
2013-03-13 16:39:14 -04:00
Aparajita Fishman 3696986a5c Fixed: removed stray #import.
Build was failing on Linux because of it.
2013-03-13 15:36:41 -04:00
Aparajita Fishman 1e98c66b3c Fixed: under some circumstances, blur function could be called with no CPTextFieldInputOwner set
This would cause a crash because the blur function was trying to access the DOM element.

Now we check if the owner is null.
2013-03-13 15:32:54 -04:00
Aparajita Fishman 7df34cc709 Fixed: windows with sheets were filtering mouse move events.
Previously, if a window had a sheet, a mouse move event was passed to the sheet and then filtered. This disabled resize cursors for the parent window of a sheet.

This commit allows mouse move events to continue to the parent window so that resize cursors will work on the parent window as well.
2013-03-13 15:09:02 -04:00
Aparajita Fishman 3301754af2 Fixed: a sheet's parent window did not become main
Sheets are like child windows, they can never become main. Previously, when an attempt was made to make a sheet the main window, its parent window did not become main as it should have. Thus the title bar would remain dimmed, even though the sheet was the key window.

With this commit, when a sheet is made main, it defers to the parent window.
2013-03-13 15:04:34 -04:00
Aparajita Fishman 25d5441444 Fixed: sheet opening animation was not cleaned up when sheet immediately closed
Previously, if an event occurred during the sheet opening animation that would close the sheet, the animation was not properly cleaned up and the subsequent closing animation would die horribly.

The animation is always cleaned up with this commit.
2013-03-13 14:52:45 -04:00
Aparajita Fishman 07d35d606c Fixed: resize masks for a few views in AttachedSheet2 demo were not set
Previously they floated, now they are anchored.
2013-03-13 14:50:07 -04:00
Aparajita Fishman 2dd7ba6e28 Fixed: sheet top shadow would not adjust when parent window was resized
It is possible to resize the parent window of a sheet while it is open. Previously, the sheet's top shadow was not adjusted when the parent window was resized, which could lead to it being out of synch.

Now the sheet shadow is adjusted whenever the parent window's size changes.
2013-03-13 12:47:14 -04:00
Aparajita Fishman 92fb9eade5 Fixed: if a sheet's parent window frame was changed, the sheet did not reposition
Previously, sheets were only repositioned if the parent window's setFrameOrigin: method was called. This did not cover all possible cases for parent window repositioning.

Now the sheet is repositioned any time the parent window's origin changes.
2013-03-13 12:37:46 -04:00
Aparajita Fishman 2f4b0f8563 Formatting 2013-03-13 12:36:04 -04:00
Aparajita Fishman afd5925499 Fixed: _CG and _CP macros were confusing and could degrade performance
Previously, Cappuccino was using preprocessor macros internally for the CGPoint/Size/Rect/Inset/Affine functions, as well as for CPRange. These macros had the same name as the corresponding function, but began with _. The functions were actually defined using the macros.

The motivation behind using macros was to increase performance by reducing function calls. However, there were a number of problems with this approach:

- There was an artificial dichotomy between _CG macros and the corresponding CG functions. We never completely replaced CG function calls with _CG macros. In fact, they were often mixed up in the same file. There was an extra burden on the programmer to remember to use the macro instead of the function.
- If a method call was passed as an argument to a macro, performance could actually be significantly *worse* than a function call. For example, _CGGetRectMakeCopy([view frame]) would expand to `{ origin:{ x:[view frame].origin.x, y:[view frame].origin.y }, size:{ width:[view frame].size.width, height:[view frame].size.height } }`. So instead of a single objj_msgSend and a single simple function call, we ended up with 4 objj_msgSend calls, which are way more expensive than simple function calls.
- Because of this expansion problem, to use macros efficiently required us to remember to use variables for all macro parameters. This didn't happen, and shouldn't have to happen.
- Finally, with modern Javascript engines, function call overhead is so small that it really isn't worth using the macros.

This commit eliminates the _CGGeometry, CGAffineTransformation and CPRange macros and replaces them with function calls.

BREAKING CHANGE:
The macros are no longer available. They could only be used with compiled code, but if there is any user code that used them, they will have to be replaced with the corresponding functions.
2013-03-13 12:22:10 -04:00
Aparajita Fishman 10b588a19c Fixed: CPGraphicsTest window wouldn't fit in 15" screen
I'm happy for those who have 27" screens, but on my poor MPB 15" screen, the CPGraphicsTest window was too tall to see everything.

I split the window into two windows so everything can be seen.
2013-03-13 12:05:54 -04:00
Aparajita Fishman 843e5016e5 Fixed: modal sheet would appear briefly before animation
The AttachedSheet2 demo was calling runModalForWindow:, which caused the sheet to appear briefly as an application modal.

That call was removed, beginSheet: does everything.

Also:

- Wrapped _attachSheetWindow method into _attachSheet:modalDelegate: method.
- Just to be safe, in CPWindow -_sheetShouldAnimateIn:, the sheet is moved offscreen before being ordered front.
2013-03-13 11:51:27 -04:00
Alexander Ljungberg 8d54c0123b Fixed: menus not closing on left click.
Previously, clicking outside a menu on a control would not close the menu. Also clicking on the menu header again would open a second menu.

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

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

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

Fixes #1833.
2013-03-13 14:01:08 +00:00
Alexander Ljungberg 677124da49 Fixed: another tab view decoding error.
Without this fix, CPTabView would still make view hierarchy changes in `initWithCoder:` despite the fix in f805b6b. Making view hierarchy changes before a cib is fully decoded can easily result in a corrupted hierarchy.

In this case, the decoding of a tab view item view, A, lead to the decoder to try to decode A's next responder, which was the tab view, B. B then tried to set the selected tab, which involved adding A as a subview. But since A wasn't done decoding, A._superview would change later in the process, corrupting this change.

This fix delays `_updateItems` to `awakeFromCib` at which time changing the view hierarchy is safe.

Refs #1409.
2013-03-13 12:41:47 +00:00
Aparajita Fishman 50ca0d4b34 Fixed: menubar title was set to document title.
Currently, if a window controller has a document, its title is put in menubar. I cannot remember any Cocoa application that ever did this.

This commit removes the synchronizing of the document title with the menubar title.
2013-03-13 00:27:39 -04:00
Aparajita Fishman 54bc851159 Fixed: missing theme image, window sizing/moving was broken.
After bbfaac5, all kinds of strange behavior occurred with window sizing and moving due to overzealous constraining.

Cocoa does not constrain the frame of hidden windows. When a hidden window is ordered in, it is constrained to the usable screen content rect. A visible window has its height constrained when its frame is set. Its origin is constrained such that a minimum margin at the left, right and top is visible, and the top is constrained to be below the menu bar.

This commit fixes a number of problems related to window moving and resizing that were introduced by bbfaac5:

- Sheets are not constrained at all.
- Moving a window does not constrain its size.

In addition, when a window is moved, tracking is relative to the initial click point, which provides proper behavior when the movement is constrained and the mouse keeps moving.
2013-03-12 21:49:15 -04:00
Aparajita Fishman 481f7c61b8 Fixed: browser would scroll text fields into view when they focused.
Previously, there were two instances in which a browser would forcibly scroll a text field into view, out of Cappuccino's control:

- A text field is first responder in the key window, is partially or fully offscreen, and you click somewhere else within the same window. If the target of the click does not accept first responder, the text field is refocused.

- A text field is first responder in a non-key window, is partially or fully offscreen, and you make its window the key window. In that case the text field is made first responder and is focused.

In both cases, focusing the text field causes the browser to scroll the viewport out of Cappuccino's control such that the text field is completely onscreen.

With this commit, before a text field is focused, it is checked to ensure it is completely within the usable content rect of the platform window. If not, it refuses first responder. If the window is becoming key, the first responder is set to nil.
2013-03-12 21:19:09 -04:00
Aparajita Fishman 69bda9427a Fixed: some window subclasses should not be constrained to the usable screen content
Previously, all window subclasses were constrained to the usable screen content. Unfortunately that included the menu bar window, which ended up appearing below itself!

This commit introduces an ivar that indicates whether instances of the window subclass should be constrained or not.
2013-03-12 15:00:26 -04:00
Aparajita Fishman bbfaac5468 Fixed: windows were allowed to extend beyond the usable screen content.
Previously, no bounds were placed on the placement or sizing of windows, which allowed them to extend beyond the usable screen content (the area bounded by the menu bar at the top and the platform window on the other sides).

Cocoa enforces the following restrictions:

- When a window is ordered in, it is forced within the usable screen content (below the menu bar) and its size and width are clipped to the usable screen content as well.

- If a window is already visible, any methods that move or resize the window will ensure the top and bottom of the window are within the usable screen content. The width is unchanged.

This commit implements Cocoa's restrictions in CPWindow.

Fixes #1690
2013-03-12 13:49:42 -04:00
Alexander Ljungberg d15550cacb Merge branch 'refs/heads/slevenbits-platform-resize-fix' 2013-03-12 17:03:33 +00:00
Alexander Ljungberg 784eed9b1a Merge branch 'refs/heads/slevenbits-autocomplete-modal-fix' 2013-03-12 17:03:24 +00:00
Alexander Ljungberg 7b11411b61 Merge branch 'refs/heads/slevenbits-popover-override-modality-fix' 2013-03-12 17:03:13 +00:00
Alexander Ljungberg 921b30a892 Merge branch 'refs/heads/slevenbits-popover-child-window-close-fix' 2013-03-12 17:02:57 +00:00
Alexander Ljungberg baa75a8b64 Merge branch 'master' of github.com:cappuccino/cappuccino 2013-03-12 16:56:23 +00:00
aparajita fd49bd2f2d Update CONTRIBUTING.md
Updated commit message section.
2013-03-12 13:40:18 -03:00
Aparajita Fishman 445045565b Fixed: frame/bounds change notification was sent unconditionally.
Previously, calling setPostsFrameChangedNotifications:YES or setPostsBoundsChangedNotifications:YES would immediately result in the notification being sent. Cocoa will only send in this context if:

- setPosts[Frame/Bounds]ChangedNotifications:NO was called.
- The frame/bounds changed between that call and the call to setPosts[Frame/Bounds]ChangedNotifications:YES.

We are currently not tracking pending changes, so this commit removes the sending of the notification completely in those methods.

Fixes #1076
2013-03-12 12:20:58 -04:00
Andrew HankinsonandAparajita Fishman 6c80d1f883 Fixed: resizeWithOldSuperviewSize did not maintain size ratio
Previously, Cappuccino would resize in such a way that a view's size ratio to its superview would not be maintained.

This commit ensures that size ratios are maintained during resizing.

Patch contributed by @davidkhess

Fixes #357
2013-03-12 11:38:09 -04:00
Aparajita Fishman 3af2314a70 Fixed: sheet resizing displayed incorrectly
Previously, when a sheet was resized, there were a number of problems:

- Sheets in Cocoa resize their width symmetrically, such that they always remain centered. This was not happening in Cappuccino.

- When a sheet is resized wider than its parent window, the shadow at the top of the sheet was growing wider than the bounds of the parent window's title bar, which makes no sense since the shadow is supposed to be cast by the title bar.

- Sheets had no top border, so when they were resized wider than the parent window, the top edge looked like it was cut off. In Cocoa, sheets have a top border that sits under the title bar of the parent window, and which is visible when the sheet is resized wider than the parent window.

This commit addresses these problems as follows:

- Sheet width is now resized symmetrically.

- Sheet resizing is pinned to the screen bounds.

- The top sheet shadow is pinned to the width of the parent window's content view.

- Sheets now have a top border.

In addition to these changes, a redundant sheet top shadow was eliminated from one of the _CPWindowView subclasses.

Fixes #1846
2013-03-12 10:20:14 -04:00
Aparajita Fishman 17f9304adc Fixed: sheet animation was resizing the sheet to zero, causing problems
Previously sheet animation was performed by sizing the sheet from zero to full height when animating in, and then back to zero height when animating out. This caused problems with the resize algorithms, which are not designed to deal with sizing from zero.

Analyzing Cocoa behavior revealed that sheets slide in and out with no resizing.

With this commit, a general purpose mechanism for clipping a window to a rect was added to CPDOMWindowLayer. Clipping was put in CPDOMWindowLayer because that is the class that deals with windows at the global level. CPWindow uses the clipping mechanism to slide the sheet in and out, thus avoiding all resizing problems.

Fixes #1840
2013-03-12 10:20:13 -04:00
Aparajita Fishman f208ff52fd Fixed: attached sheet shadow had extra width, was too dark
Previously the attached sheet shadow (that appears below the title bar of the window a sheet is attached to) was 9x8, and it was quite dark.

With this commit the width has been reduced to 1 (to reduce the image size) and it has been lightened up.

Also changed "height-shadow" theme attribute to "shadow-height".
2013-03-12 10:20:13 -04:00
Aparajita Fishman 2dca00c4a0 Fixed: sheets should not be resizable from the top
Previously, sheets could be resized from the top, which would destroy the illusion of being attached to the top of the parent window.

With this commit, sheets are prevented from being resized by the user from the top edge.
2013-03-12 10:20:13 -04:00
aparajita 1443fff315 Merge pull request #1811 from stewa/fix-menu-custom-views-reverse-mouse-event
Fixed: mouseEntered and mouseExited mixed up for custom views in menu

Previously, when clicking and dragging inside a menu, mouseEntered and mouseExited were sent to the wrong views.

This commit correctly sends mouseExited to the previous hovered view, then mouseEntered to the new hovered view.
2013-03-12 07:16:02 -07:00
aparajita 96605826ba Merge pull request #1842 from stewa/empty-collectionview-keyboard-navigation-problem
Fixed: using keyboard navigation in empty CPCollectionView threw exception

Previously, if an empty CPCollectionView was first responder and keyboard navigation was used, a CPInvalidArgumentException (Range {-1, 1} is out of bounds) was thrown.

This commit checks for an empty collection, eliminating the exception.
2013-03-12 07:01:53 -07:00
Martin Carlberg 22cdbd7ec7 Merge branch 'master' of https://github.com/cappuccino/cappuccino into preprocess
Conflicts:
	Objective-J/ObjJAcornCompiler.js
	Objective-J/acorn.js
2013-03-12 11:20:56 +01:00
Martin Carlberg 362f3b890e Added first try for compiler to generate code 2013-03-12 09:22:26 +01:00
aparajita da69a6e339 Merge pull request #1845 from cacaodev/CPCollectionView-doc
Docs: CPCollectionView-setItemPrototype: method documentation
2013-03-11 21:20:14 -07:00
Stefan Wallström a549c191da lint 2013-03-11 21:09:22 +01:00
Antoine Mercadal 26213491a3 Revert "don't allow views from another window to be next/previouskeyViews"
This reverts commit 7fab8d9782.

This breaks the repsonder chain if it is defined in a view that has no window yet.
Details and reduction here: https://github.com/cappuccino/cappuccino/commit/7fab8d9782d4604c4441e48701f9207e4a2b4229#commitcomment-2781849
2013-03-11 13:01:22 -07:00
Alexander Ljungberg 5f086b11b8 Fixed: platform windows resizable.
Without this fix, a platform window could be resized by clicking just under the menu bar and dragging downwards, even that platform windows are supposed to be the size of the browser window by definition.
2013-03-11 17:40:11 +00:00
cacaodev 0d168a4518 Remove //@class CPClipView 2013-03-11 17:52:21 +01:00
Alexander Ljungberg 59b766eb93 Fixed: token field autocomplete menu not receiving mouse events in presence of modal window.
Without this fix, the presence of a modal ancestor window to a token field would lock down the autocomplete menu from mouse interaction.

This fix ensures the token field autocomplete menu accepts mouse events even during the presence of modal widows, just like other auxiliary windows such as pop up menus.
2013-03-11 16:41:06 +00:00
cacaodev 0e4f5e9203 Uncomment import 2013-03-11 17:14:00 +01:00
aparajita bbc7d2f29e Merge pull request #1848 from ahankinson/cptableview-documentation-formatting
Formatting: various CPTableView fixes
2013-03-11 09:08:46 -07:00
cacaodev a98def4326 Added doc for -setItemPrototype: explaining how to setup the item prototype when you want to use bindings for the view. 2013-03-11 16:49:19 +01:00
Andrew Hankinson b274c63395 CPTableView formatting
Formatting, whitespace and typo correction.
2013-03-11 10:01:46 -04:00
Alexander Ljungberg 6327d8c92e Fixed: transient popovers broke modal windows.
Without this fix, opening a transient popover would allow windows other than the modal window (or its children) to be interacted with.

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

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

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

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

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

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

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

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

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

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

The reason not to allow dereferencing of expressions with side effects is that we might need to evaluate the expression twice in certain uses of deref, which is not obvious when you look at the deref operator in plain code.
2013-03-10 17:32:28 +00:00
Stefan Wallström 2bf2442096 Fixed: Using keyboard navigation in empty CPCollectionView threw exception. 2013-03-10 17:38:08 +01:00
Christophe Serafin ef4ba78ab7 removed extra blank and added a blank line above if condition 2013-03-10 17:05:53 +01:00
Christophe Serafin 85cb1b7a76 removed an extra blank and changed _shouldReorderColumn format 2013-03-10 17:04:45 +01:00
Christophe Serafin fe260a85f5 added _lastDragDestinationColumnIndex to call delegate method only once 2013-03-10 16:41:37 +01:00
Alexander Ljungberg f201ab0721 New: update operators on references, such as @deref(x)++.
This fix implements support for both prefix and postfix update operators on a dereference.
2013-03-10 14:02:37 +00:00
Alexander Ljungberg 767a7a7177 Test: expand CPNumberFormatter test to be more complete.
- Cover the formatting of @"" to nil.
- Check error messages by reference.
- Check output values.
- use @ref() instead of hand coded AT_REF.

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

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

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

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

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

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

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

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

Tooltip text was hardcoded in English. Now they use the localizer.
2013-03-09 07:56:44 -08:00
Andrew Hankinson 5fd241f7d7 Fix #1284: Update Emacs documentation
Small fix to update documentation for emacs. Fixes #1284.
2013-03-08 23:04:23 -05:00
Christophe Serafin 159941696d changed condition order for optimization 2013-03-08 19:35:10 +01:00
Blair Duncan 7fab8d9782 don't allow views from another window to be next/previouskeyViews 2013-03-08 12:27:19 -05:00
Christophe Serafin 152fd66bbe fixed reordering column with a restriction on a targeted column 2013-03-08 18:11:27 +01:00
Christophe Serafin ae4c77a6d4 Merge branch 'master' of https://github.com/cappuccino/cappuccino 2013-03-08 16:53:07 +01:00
Andrew HankinsonandAparajita Fishman 5fac631f6f New: minimum/maximum support for CPNumberFormatter
Previously, minimum and maximum were not supported in CPNumberFormatter.

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

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

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

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

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

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

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

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

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

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

Because table cell classes needed to use the same initialization code as the NS_initWithCoder methods, it was necessary to refactor the initialization code into separate NS_initWithCell methods and call them separately from NS_initWithCoder.
2013-02-27 18:02:55 -05:00
Stefan Wallström b7ff643a34 Fixed: when clicking and dragging inside a menu, mouseEntered and mouseExited was mixed up for custom views. 2013-02-27 22:26:52 +01:00
Aparajita Fishman 07f9b94548 Fixed: initializer did not allow programmers to pass arbitrary types
Originally the initializer had coerced the parameter to a string, even though it is clearly documented that it should be a string. A later commit removed that coercion.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Closes #1803

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

This fix avoids calling addSubview:.
2013-02-24 21:26:02 +00:00
Martin Carlberg 340f1e3258 Made the acorn parser able to run outside of the Cappuccino world 2013-02-24 22:25:00 +01:00
Alexander Ljungberg 75b72d601a Fixed: eliminate jake deploy warnings from default apps in 0.9.7. 2013-02-24 18:20:39 +00:00
cacaodev d2143844e3 Fix for issue #1357 2013-02-24 18:47:37 +01:00
Alexander Ljungberg ce7e5122e0 Fixes #829. Improve - CPView removeFromSuperview performance.
In the modified test described in #829 performance improves by at least 30% and that's with a significant addSubview: component diluting the test.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

- Updated the theme descriptor to include the default height.

- Updated Aristo 2 PSD progress indicator artwork.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

This fix prints such errors and avoids crashing later when the result of the compilation is undefined.
2013-01-21 01:08:28 +00:00
Alexander Ljungberg 806c7935c5 Lint. 2013-01-20 19:10:41 +00:00
Alexander Ljungberg e7f0400580 Formatting. 2013-01-20 18:24:48 +00:00
Alexander Ljungberg ad109532be It's enough to read flattensSources once. 2013-01-20 18:09:55 +00:00
Alexander Ljungberg 9dbfa99284 Lint. 2013-01-20 17:14:44 +00:00
Alexander Ljungberg 3c684404ed Eliminate mystery CGPointPointer. 2013-01-20 16:44:40 +00:00
Alexander Ljungberg d818615472 Missing import. 2013-01-20 16:35:48 +00:00
Alexander Ljungberg 06694061d2 Fix nib2cib error introduced by c3d8f4f.
This fixes `- [NSWindowTemplate setFullBridge:] unrecognized selector sent to instance` errors when running nib2cib.
2013-01-20 16:05:06 +00:00
Alexander Ljungberg 75c305ae0f Clean up manual CPBox test. 2013-01-20 16:03:56 +00:00
Alexander Ljungberg cb786a0166 Small CPBox optimisation.
No need to call `setNeedsDisplay:` after `setValue:forThemeAttribute:`.
2013-01-20 13:19:29 +00:00
Aparajita Fishman e292bf01d7 Fixed mouse down within the resize slop outside a window not resizing 2013-01-20 09:13:17 +07:00
Aparajita Fishman 17f07ee888 capp_lint will not flag CPRectEdge, more linking 2013-01-20 07:24:00 +07:00
Antoine Mercadal 51c09a1b02 Merge branch 'CPRuleEditor-fixes' of https://github.com/cacaodev/cappuccino into pr-1718 2013-01-19 11:48:18 -08:00
cacaodev fe7befa845 Fix missing @end 2013-01-19 17:11:11 +01:00
cacaodev eca5ef6f84 Fix textfield in rules croped 2013-01-19 17:08:34 +01:00
cacaodev c023a38544 Remove unused code 2013-01-19 17:07:11 +01:00
Aparajita Fishman 7c831fa19d capp_lint flags deprecated CPPoint/Rect/Size types/functions
- Changed to corresponding CG types/functions in all files
- Fixed some demo app bugs
2013-01-19 16:51:56 +07:00
Aparajita Fishman 24c0f2aedc Merge branch 'refs/heads/inactive-window'
Conflicts:
	AppKit/Themes/Aristo/ThemeDescriptors.j
	AppKit/Themes/Aristo2/ThemeDescriptors.j
2013-01-19 15:15:51 +07:00
Antoine Mercadal 6170a274d7 Merge branch 'master' of https://github.com/cappuccino/cappuccino 2013-01-18 23:24:22 -08:00
Antoine Mercadal 155796b0e0 Linting Aristo1 2013-01-18 23:24:00 -08:00
Aparajita Fishman 3b7262681c Added inactive state to window title bar
- When a window is neither key nor main the title bar is clearly different
- capp_lint ThemeDescriptors.j
- Renamed some layers in Aristo2 PSD to be more descriptive
- New artwork files for window close buttons
- Removed stray Aristo2 image
2013-01-19 14:20:51 +07:00
Antoine Mercadal 988ab9722c Linting 2013-01-18 23:20:44 -08:00
Alexander Ljungberg 8eae427591 Merge branch 'master' of github.com:cappuccino/cappuccino 2013-01-19 02:27:55 +00:00
Alexander Ljungberg b4fe13dfb1 Merge branch 'refs/heads/0.9.6' 2013-01-19 02:27:43 +00:00
Martin Carlberg f435a15b43 Merge branch 'experimental_class_and_global_implementation' of https://github.com/cappuccino/cappuccino into objj_compiler2
Conflicts:
	Tools/capp/Configuration.j
2013-01-18 23:51:36 +01:00
Martin Carlberg 08d5be5ce3 Fixed imports in Tools/capp 2013-01-18 23:49:22 +01:00
Antoine Mercadal c3d8f4f80b Fix bug in NSWindowTemplate.j where using a non existing ivar 2013-01-18 14:46:49 -08:00
Antoine Mercadal bbb8bdb687 Fix other small bugs 2013-01-18 14:38:37 -08:00
Antoine Mercadal 4138a6d6dc Merge branch 'objj_compiler2' into experimental_class_and_global_implementation 2013-01-18 14:35:03 -08:00
Antoine Mercadal 6b172cd3a6 remove useless usage of self. in NSWindowTemplate.j 2013-01-18 14:34:22 -08:00
Antoine Mercadal 86e0282011 Fix nib2cib warnings 2013-01-18 14:29:25 -08:00
Martin Carlberg f1250ae5eb Merge branch 'experimental_class_and_global_implementation' of https://github.com/cappuccino/cappuccino into objj_compiler2 2013-01-18 22:27:54 +01:00
Martin Carlberg 586c9d3139 Fixed "Can't find superclass 'MyClass' <Context File: Accessors>" problem when
compiling accessors to class with superclass in same file.
2013-01-18 21:23:11 +01:00
cacaodev 00fea3e02f nib2cibed example 2013-01-18 20:24:18 +01:00
cacaodev 6a72855de8 Merge remote-tracking branch 'upstream/master' into CPCollectionViewItem-loading 2013-01-18 20:20:06 +01:00
Antoine Mercadal 6b0edaecc6 Move the editable property to _CPRuleEditorViewSlice.j as it is used in this class 2013-01-18 10:38:35 -08:00
Antoine Mercadal a4bfd2c9f7 Add missing imports 2013-01-18 10:38:03 -08:00
Antoine Mercadal 7a419c262e Add missing @class 2013-01-18 10:37:51 -08:00
Antoine Mercadal 40ac3210c4 Add missing import 2013-01-18 10:37:37 -08:00
Antoine Mercadal 3bb9e234d8 Add missing import 2013-01-18 10:37:27 -08:00
Antoine Mercadal 75a4ef99c9 Add some missing globals in CPTextField 2013-01-18 10:37:16 -08:00
Antoine Mercadal 1e4b6b6c49 Add missing import 2013-01-18 10:30:13 -08:00
Antoine Mercadal c9eeab09a1 Add missing import in _CPWindow.j 2013-01-18 10:17:19 -08:00
Antoine Mercadal 1a61fc832e Fix a bug in wrong code order in _CPMenuManager.j making usage of undeclared variable. Also add some missing imports 2013-01-18 10:16:55 -08:00
Antoine Mercadal 1d232fd263 Add missing import in BKShowcaseController.j 2013-01-18 10:03:11 -08:00
Martin Carlberg 197f3665bc Fixed removed import 2013-01-18 17:33:09 +01:00
cacaodev ce62e32dfa Removed isa in CPTableCellView (Objj2 compat). nib2cibed all examples (Aristo2 compat). 2013-01-18 17:28:36 +01:00
cacaodev 2cc3521989 Merge remote-tracking branch 'upstream/master' into CPTableViewLion
Conflicts:
	Tests/Manual/CPOutlineViewCibTest/Resources/MainMenu.cib
	Tests/Manual/TableTest/TableBindings/Resources/MainMenu.cib
2013-01-18 16:57:46 +01:00
Martin Carlberg 6fbab322cf Fixed warning messages in compiler 2013-01-18 14:25:05 +01:00
Martin Carlberg 458fa9d02e Fixed a lot of small bugs found by new warning message from compiler 2013-01-18 14:24:37 +01:00
daboe01 9f85d2bdb3 fix for scrollwheel in FF>3 (issue #1244) 2013-01-17 20:43:37 +01:00
Martin Carlberg ff20822b47 Merge branch 'master' of https://github.com/cappuccino/cappuccino into objj_compiler2_experiment 2013-01-17 18:20:07 +01:00
Aparajita Fishman eff0621966 Formatting 2013-01-17 15:32:53 +07:00
Antoine Mercadal 6aeb6199f7 Restore line 2013-01-16 18:10:46 -08:00
Alexandre Wilhelm 072fac837c Merge branch 'master' of github.mv.usa.alcatel.com:amercada/Cappuccino 2013-01-16 18:06:59 -08:00
Alexandre Wilhelm f1fa185383 Fixed bug about sheet/titled/window 2013-01-16 18:06:42 -08:00
Antoine Mercadal c471bc0f82 Update CPScrollView manual test to be able to switch scroller mode 2013-01-16 14:21:08 -08:00
Alexandre Wilhelm 37e29949ef Merge branch 'master' of github.mv.usa.alcatel.com:amercada/Cappuccino 2013-01-16 14:12:13 -08:00
Alexandre Wilhelm e840e4a547 Fixed bug about the width of legacy scrollView 2013-01-16 14:12:07 -08:00
Antoine Mercadal 82bb9a6008 Remove useless code in simple line CPBox 2013-01-16 13:42:46 -08:00
Antoine Mercadal 15ed959da7 Merge branch 'master' of github.mv.usa.alcatel.com:amercada/Cappuccino 2013-01-16 13:35:07 -08:00
Antoine Mercadal a0f4c46cb5 Add missing import 2013-01-16 13:35:01 -08:00
Alexandre Wilhelm 71d5655ab2 Increased the content-inset left in textField 2013-01-16 11:57:04 -08:00
Alexandre Wilhelm 29d56b63f7 Fixed bug about border in CPBox lineBorder 2013-01-16 11:48:23 -08:00
Alexandre Wilhelm 35f495ef5b Fixed bug about tableview row height in Aristo1 2013-01-16 11:16:04 -08:00
Antoine Mercadal 1006890b6e Add missing import in nib2cib. 2013-01-16 10:50:33 -08:00
Antoine Mercadal 083d7304fd Fix some adjustment of the tokenfields. Still need to tweak a little the image files for the tokens 2013-01-15 10:45:08 -08:00
Antoine Mercadal 2d8f651674 Merge branch 'objj_compiler2' 2013-01-15 10:20:10 -08:00
Antoine Mercadal e8ee370499 Merge branch 'master' into objj2integration 2013-01-15 09:49:25 -08:00
Alexander Ljungberg 5c3d71258d Merge branch 'master' of github.com:cappuccino/cappuccino 2013-01-15 16:08:49 +00:00
Alexander Ljungberg 519031a10e Merge branch 'refs/heads/0.9.6' 2013-01-15 16:08:40 +00:00
Martin Carlberg 0799ce190d Merge branch 'master' of https://github.com/cappuccino/cappuccino into objj_compiler2 2013-01-15 08:48:30 +01:00
Antoine Mercadal a7c4802446 Merge branch 'master' into objj2integration 2013-01-14 18:22:30 -08:00
Antoine Mercadal 094c6fd273 Update Aristo2 to correctly render CPComboxBoxes 2013-01-14 18:22:12 -08:00
Antoine Mercadal 72a601371e Merge branch 'master' into objj2integration 2013-01-14 17:34:36 -08:00
Antoine Mercadal 2a80ad8344 Fix bezel inset of focused textfields 2013-01-14 17:34:09 -08:00
Alexandre WilhelmandAntoine Mercadal 7e502fffe6 Fixed bug in CPStepper for the automatic size of it when calling a static constructor 2013-01-14 15:54:14 -08:00
Antoine Mercadal e5de031423 Merge branch 'objj_compiler2' into objj2integration
Conflicts:
	AppKit/CPWindow/CPWindow.j
2013-01-14 11:43:24 -08:00
Martin Carlberg d064ecd842 Merge branch 'master' of https://github.com/cappuccino/cappuccino into objj_compiler2
Conflicts:
	AppKit/CPWindow/CPWindow.j
2013-01-14 20:39:08 +01:00
Antoine Mercadal c0d33a1a19 Merge branch 'master' into Aristo2
Conflicts:
	AppKit/CPAlert.j
2013-01-14 10:57:03 -08:00
Martin Carlberg e78f211e8a Added @class and @global declaration and will now make a warning if class or global is not declared. 2013-01-14 18:36:39 +01:00
Martin Carlberg 77d66fa0c9 Fix for: Track spaces will take the spaces after the next token instead of the current. Also do "delete" of property instead of setting it to null for cleaner AST tree. 2013-01-13 22:08:42 +01:00
Martin Carlberg a652fdf8d2 Fix for: Track comments will take the comment after the next token instead of the current. Also do "delete" of property instead of setting it to null for cleaner AST tree. 2013-01-13 22:08:29 +01:00
Aparajita FishmanandMartin Carlberg 85481225a3 Use a better error message for missing semicolons, trailing whitespace elimination 2013-01-13 22:06:18 +01:00
Martin Carlberg 6210bd2e6d Merge branch 'master' of https://github.com/cappuccino/cappuccino into objj_compiler2
Conflicts:
	AppKit/CPWindow/CPWindow.j
2013-01-13 22:01:43 +01:00
Antoine Mercadal 7dd7dca99a Update some HUD art files 2013-01-12 13:37:16 -08:00
Antoine Mercadal 48991e6c3b Update some HUD slices 2013-01-12 13:37:05 -08:00
Antoine Mercadal 825d045143 Remove bg in textfield slices 2013-01-12 11:35:11 -08:00
Antoine Mercadal 86593cc0f4 Update art files for textfields 2013-01-12 11:24:18 -08:00
Antoine Mercadal d987bcf0d0 Add missing slices in PSD 2013-01-12 11:24:04 -08:00
Antoine Mercadal c52a72ec90 small update in art files 2013-01-11 18:38:16 -08:00
Antoine Mercadal b82f7061a0 Small fixes in psd 2013-01-11 18:38:04 -08:00
Antoine Mercadal 55d651ad27 Readd missing art file 2013-01-11 18:14:45 -08:00
Antoine Mercadal 5239749580 Optimize all images 2013-01-11 18:01:49 -08:00
Antoine Mercadal fe5b6d40ac Update art files 2013-01-11 17:59:27 -08:00
Antoine Mercadal 5fa42279bd CLeanup PSD 2013-01-11 17:59:13 -08:00
Alexandre Wilhelm b7a2ab57cc Updated Aristo1 and 2 2013-01-11 17:39:11 -08:00
Alexandre Wilhelm 78949f3620 Changed the way to theme the head of a window 2013-01-11 17:38:54 -08:00
Alexandre Wilhelm 924bf07950 Added missing picturs for toolbar in Aristo1 2013-01-11 17:16:02 -08:00
Alexandre Wilhelm 181f7acbb8 Changed the attribute theme background selected menu bar to _CPMenuView 2013-01-11 17:13:58 -08:00
Alexandre Wilhelm d331de6683 Merge branch 'Aristo2' of github.mv.usa.alcatel.com:amercada/Cappuccino into Aristo2 2013-01-11 16:27:57 -08:00
Alexandre Wilhelm 41dbc66d24 Added disabled token field 2013-01-11 16:27:43 -08:00
Antoine Mercadal 6230319f63 Merge branch 'Aristo2' of 172.21.51.218:amercada/Cappuccino into Aristo2 2013-01-11 16:14:03 -08:00
Antoine Mercadal b7e768820f Tweak theme 2013-01-11 16:13:51 -08:00
Antoine Mercadal 5dc2595159 Add missing HUD Slices 2013-01-11 16:13:43 -08:00
Antoine Mercadal 919aa2622d Add some HUD art 2013-01-11 16:13:28 -08:00
Alexandre Wilhelm 025c66db7e Fixed disable stepper 2013-01-11 16:01:55 -08:00
Alexandre Wilhelm b3361100da Updated Aristo2 2013-01-11 15:38:58 -08:00
Alexandre Wilhelm e0ffde1614 Fuxed bug with disabled combobox 2013-01-11 15:38:43 -08:00
Alexandre Wilhelm 4bfe607f64 Fixed bug with disabled popup 2013-01-11 15:38:20 -08:00
Alexandre Wilhelm c0cbe8e0ab Fixed bug with disabled knob 2013-01-11 15:37:42 -08:00
Alexandre Wilhelm 1e6d41e113 Fixed bug with disabled CPSegmentedButton 2013-01-11 15:14:01 -08:00
Alexandre Wilhelm 54f0a49281 Merge branch 'Aristo2' of github.mv.usa.alcatel.com:amercada/Cappuccino into Aristo2 2013-01-11 14:10:25 -08:00
Alexandre Wilhelm 618f5360ae Added disbaled textField for Aristo2 2013-01-11 14:10:15 -08:00
Antoine Mercadal 6f8b5afd56 Merge branch 'Aristo2' of 172.21.51.218:amercada/Cappuccino into Aristo2 2013-01-11 14:05:54 -08:00
Antoine Mercadal 6432528d37 Merge branch 'master' into Aristo2
Conflicts:
	AppKit/CPWindow/CPWindow.j
2013-01-11 14:05:27 -08:00
Alexandre Wilhelm b62e2c0b78 Merge branch 'Aristo2' of github.mv.usa.alcatel.com:amercada/Cappuccino into Aristo2 2013-01-11 13:54:27 -08:00
Alexandre Wilhelm f30e846f09 Added theme value to set the position of the buttons relative to the type of window 2013-01-11 13:54:18 -08:00
Alexandre Wilhelm 0a9b4bdc11 Fixed bug in CPAlert theme 2013-01-11 13:53:51 -08:00
Antoine Mercadal 0102e99d3c Show actual progress bar in indeterminate state 2013-01-11 12:28:42 -08:00
Antoine Mercadal 19548c196e Add some missing slices in Aristo2 HUD 2013-01-11 12:25:56 -08:00
Antoine Mercadal 46ee987742 Merge branch 'Aristo2' of 172.21.51.218:amercada/Cappuccino into Aristo2 2013-01-11 12:25:18 -08:00
Antoine Mercadal 34428d82c7 Add missing art files 2013-01-11 12:25:12 -08:00
Antoine Mercadal bab27b8be1 Update Art for HUD progress bar in Aristo2 2013-01-11 12:24:41 -08:00
Alexandre Wilhelm 6d06970c0f Merge branch 'Aristo2' of github.mv.usa.alcatel.com:amercada/Cappuccino into Aristo2 2013-01-11 12:08:53 -08:00
Alexandre Wilhelm c16a965eb7 Added head window Aristo1 2013-01-11 12:08:33 -08:00
Alexandre Wilhelm 5cb7b82415 Added standard window Aristo1 2013-01-11 11:56:48 -08:00
Alexandre Wilhelm 4d9a4267f4 Removed unused images 2013-01-11 11:56:23 -08:00
Antoine Mercadal fdbc7cc585 Add showcase for HUD progress indicators 2013-01-11 11:49:55 -08:00
Martin Carlberg ed6c35a59f Merge branch 'master' of https://github.com/cappuccino/cappuccino into objj_compiler2
Conflicts:
	AppKit/CPWindow/CPWindow.j
2013-01-11 20:40:35 +01:00
Antoine Mercadal eca14a8868 Add missing art files 2013-01-11 11:39:31 -08:00
Antoine Mercadal fc719cb1c2 Backport art for new themable CPProgressIndicator, CPToolbar, CPMenu, CPMenuBar 2013-01-11 11:39:16 -08:00
Martin Carlberg 3dc6a30c4c Code clean up 2013-01-11 20:36:19 +01:00
Martin Carlberg 3e93e180f1 Turn off test case that don't apply to the new compiler 2013-01-11 20:36:12 +01:00
Alexandre Wilhelm 3446f8f6ae Added modal window for Aristo1 2013-01-11 11:33:06 -08:00
Alexandre Wilhelm 541dd9eac7 Added shadow window 2013-01-11 11:19:04 -08:00
Alexandre Wilhelm 62d866b60f Upadted Aristo1 with HUD window 2013-01-11 11:17:07 -08:00
Antoine Mercadal f8f0444503 Add missing @end 2013-01-11 11:02:35 -08:00
Antoine Mercadal 7eaf84d066 Backport Aristo2 descriptors to Aristo1 2013-01-11 11:00:34 -08:00
Antoine Mercadal 317e9881b8 Make text fields bigger in the showcase 2013-01-10 23:11:36 -08:00
Martin Carlberg c4e06bd2f7 Merge branch 'master' of https://github.com/cappuccino/cappuccino into objj_compiler2 2013-01-11 08:09:12 +01:00
Antoine Mercadal fb1532be1c Re-add the BKLearnMore* keys in Info.plist 2013-01-10 23:08:15 -08:00
Martin Carlberg f076b05e7e More information: Shows that the new compiler is used when doing "objjc --help". New output: "Usage (objjc 2.0):…" 2013-01-11 08:06:51 +01:00
Antoine Mercadal 5e1ac06375 Merge branch 'master' into Aristo2 2013-01-10 22:42:20 -08:00
Antoine Mercadal 959a8e7594 Add some widgets in the showcase 2013-01-10 22:33:22 -08:00
Antoine Mercadal 4fde060510 readd modified art files 2013-01-10 20:14:45 -08:00
Antoine Mercadal 6da4c54f9e Add Aristo2 HUD art files 2013-01-10 19:49:30 -08:00
Antoine Mercadal ad0e3441a1 Add missing slices for HUD theme 2013-01-10 19:49:05 -08:00
Antoine Mercadal 56e9e436cf Add theme descriptors for rounded buttons 2013-01-10 19:11:48 -08:00
Antoine Mercadal 6fde1e459d Add rounded button artwork 2013-01-10 19:11:35 -08:00
Antoine Mercadal fa314611bc Merge branch 'Aristo2' of 172.21.51.218:amercada/Cappuccino into Aristo2 2013-01-10 18:23:20 -08:00
Antoine Mercadal c34ebfa2e8 Add rounded button theme descriptors 2013-01-10 18:23:08 -08:00
Alexandre Wilhelm c6f0589ed5 Merge branch 'Aristo2' of github.mv.usa.alcatel.com:amercada/Cappuccino into Aristo2 2013-01-10 18:15:03 -08:00
Alexandre Wilhelm 8ffa8b6657 Fixed bug in _CPMenuView 2013-01-10 18:14:56 -08:00
Antoine Mercadal 0a92b98110 Comment out non-implemented HUD descriptors 2013-01-10 18:13:02 -08:00
Antoine Mercadal b6c31757a7 fix a bug in CPWindow using old AppKit resource 2013-01-10 17:55:06 -08:00
Antoine Mercadal 676efe247f make toolbar art pixel perfect 2013-01-10 17:50:51 -08:00
Antoine Mercadal f6defc091c cleanup 2013-01-10 17:50:25 -08:00
Alexandre Wilhelm 8bb779ea9e Merge branch 'Aristo2' of github.mv.usa.alcatel.com:amercada/Cappuccino into Aristo2 2013-01-10 17:32:55 -08:00
Alexandre Wilhelm 18d0cf51ef Removed unused code 2013-01-10 17:32:47 -08:00
Alexandre Wilhelm 8b7b363440 Changed default color 2013-01-10 17:32:22 -08:00
Antoine Mercadal 6ba77c146b Backport Aristo2 changes to Aristo1 2013-01-10 17:26:12 -08:00
Antoine Mercadal 54ab7ea9ee use _CPMenuItemView to get general open/save/new icons 2013-01-10 17:23:22 -08:00
Antoine Mercadal b9c0e96933 Add theme descriptors for new/open/save icons 2013-01-10 17:23:03 -08:00
Antoine Mercadal 41650d58a2 Add new theme attribute to get general open/save/new icons 2013-01-10 17:22:34 -08:00
Antoine Mercadal 3519f4f9c7 Remove unused AppKit resources 2013-01-10 17:07:05 -08:00
Alexandre Wilhelm 991e40e089 Fixed bug about the color of the colorPanel 2013-01-10 16:59:50 -08:00
Alexandre Wilhelm 9e845ec580 Updated psd 2013-01-10 16:31:49 -08:00
Alexandre Wilhelm c95fb32d0a Fixed bug with size of highlighted menuItem 2013-01-10 16:31:38 -08:00
Alexandre Wilhelm bfe64ea153 Merge branch 'Aristo2' of github.mv.usa.alcatel.com:amercada/Cappuccino into Aristo2 2013-01-10 16:14:04 -08:00
Alexandre Wilhelm 146d641f97 Updated Aristo2 2013-01-10 16:13:48 -08:00
Alexandre Wilhelm 6a94ea066d Added support for _CPMenuBarWindow theme 2013-01-10 16:13:36 -08:00
Alexandre Wilhelm 477ec44b75 Added support for _CPMenuWindow 2013-01-10 16:12:12 -08:00
Antoine Mercadal 284b00fa78 Add missing import 2013-01-10 15:31:37 -08:00
Antoine Mercadal 0f94ba3d39 Merge branch 'Aristo2' of 172.21.51.218:amercada/Cappuccino into Aristo2 2013-01-10 14:12:15 -08:00
Antoine Mercadal 2e157dd969 Starting to backport new themeable stuff from Aristo2. Missing art will follow 2013-01-10 14:12:09 -08:00
Antoine Mercadal f945845a77 Style fix 2013-01-10 14:11:35 -08:00
Alexandre Wilhelm 457cf98089 Merge branch 'Aristo2' of github.mv.usa.alcatel.com:amercada/Cappuccino into Aristo2 2013-01-10 13:58:20 -08:00
Alexandre Wilhelm ab65b53201 Updated Aristo2 2013-01-10 13:58:12 -08:00
Alexandre Wilhelm 3da4daeed5 Removed unused code 2013-01-10 13:57:57 -08:00
Alexandre Wilhelm f9c5f89595 Added support for _CPMenuItemStandardView 2013-01-10 13:57:32 -08:00
Antoine Mercadal d71947cb63 Remove unused AppKit Resource 2013-01-10 11:57:49 -08:00
Antoine Mercadal cdf29b6c56 Add missing theme descriptors for CPTableView 2013-01-10 11:57:39 -08:00
Antoine Mercadal 73ddadc0f0 Add missing theme attribute in CPTableView 2013-01-10 11:57:17 -08:00
Antoine Mercadal bd8431504d Merge branch 'Aristo2' of 172.21.51.218:amercada/Cappuccino into Aristo2 2013-01-10 11:49:01 -08:00
Antoine Mercadal efcee75f30 Remove unused AppKit resource 2013-01-10 11:48:56 -08:00
Antoine Mercadal b283e05f9c Fix bug in CPButtonTest 2013-01-10 11:48:45 -08:00
Antoine Mercadal d15757755a use themed minus and plus button image in _CPCibResource 2013-01-10 11:47:20 -08:00
Antoine Mercadal b3259e4b49 Add theme for CPButtonBar plus, minus and action button 2013-01-10 11:42:38 -08:00
Antoine Mercadal cebf8d3579 Make image plus, minus and action themable 2013-01-10 11:42:08 -08:00
Alexandre Wilhelm 9451a6a1ec Merge branch 'Aristo2' of github.mv.usa.alcatel.com:amercada/Cappuccino into Aristo2 2013-01-10 11:42:07 -08:00
Alexandre Wilhelm 5d3321839d Updated Aristo2 2013-01-10 11:41:59 -08:00
Alexandre Wilhelm 594458235b Added support for theme in_CPMenuItemMenuBarView 2013-01-10 11:41:41 -08:00
Antoine Mercadal a3273dedc1 Remove unused art 2013-01-10 11:29:33 -08:00
Antoine Mercadal 42824713e3 Add application's menu default icon in theme 2013-01-10 11:29:24 -08:00
Antoine Mercadal 4ad40ee00d Pull menu default icon from theme instead of AppKit resource 2013-01-10 11:28:43 -08:00
Antoine Mercadal ddf33a13cd Use new CPThemeBlend bundle accessor 2013-01-10 11:28:25 -08:00
Antoine Mercadal 4ce8ea9ce9 make CPThemeBlend's bundle property readonly 2013-01-10 11:27:52 -08:00
Antoine Mercadal 5b84fd6e40 Remove unused AppKit resources 2013-01-10 11:15:41 -08:00
Antoine Mercadal d7af63877e Add system cursors in theme 2013-01-10 11:15:19 -08:00
Antoine Mercadal 844ed59dd8 CPCursor will now look in the theme to get system cursors 2013-01-10 11:14:59 -08:00
Antoine Mercadal 35e29a0615 Fix bug introducing during previous merge 2013-01-10 10:38:10 -08:00
Martin Carlberg 7c71cd1f80 The new compiler takes care of hoisted variables 2013-01-10 19:30:34 +01:00
Martin Carlberg 74ad0faffa Merge branch 'master' of https://github.com/cappuccino/cappuccino into objj_compiler2
Conflicts:
	AppKit/CPWindow/CPWindow.j
2013-01-10 19:28:42 +01:00
Antoine Mercadal e13948957c Merge branch 'master' into Aristo2
Conflicts:
	AppKit/CPWindow/CPWindow.j
	AppKit/CPWindow/_CPWindowView.j
2013-01-10 10:24:33 -08:00
Martin Carlberg 0d6a962344 Merge branch 'master' of https://github.com/cappuccino/cappuccino into objj_compiler2 2013-01-10 11:22:41 +01:00
Martin Carlberg c192f3b47b Fix to make the Cappuccino framework compile with rhino 2013-01-10 11:21:45 +01:00
Antoine Mercadal 53fa384608 make nib2cib work either with Aristo1 or Aristo2 for dynamic widget adjustment 2013-01-09 20:25:32 -08:00
Antoine Mercadal 1448791fcd Declare default row height 2013-01-09 20:25:02 -08:00
Antoine Mercadal a66a4210c3 Use theme attribute for default row height 2013-01-09 20:24:42 -08:00
Antoine Mercadal b1ffd8d556 Make default row height a theme attribute 2013-01-09 20:24:27 -08:00
Antoine Mercadal 4548696c73 Remove unused AppKit resources 2013-01-09 19:43:12 -08:00
Antoine Mercadal 0d460dd6b1 Add missing art for toolbar item separator 2013-01-09 19:42:31 -08:00
Antoine Mercadal 4333e3da67 Add theme for CPToolbarItemSeparator 2013-01-09 19:41:56 -08:00
Antoine Mercadal 352ccb21ff Make CPToolbarItemSeparator themable 2013-01-09 19:41:22 -08:00
Antoine Mercadal 2ac57642a4 Remove PSD from ressource folder 2013-01-09 19:01:32 -08:00
Antoine Mercadal af1ddf2fc6 Remove unused AppKit Ressources 2013-01-09 18:59:30 -08:00
Antoine Mercadal e23c519fac Merge branch 'Aristo2' of 172.21.51.218:amercada/Cappuccino into Aristo2 2013-01-09 18:58:05 -08:00
Antoine Mercadal 664a31fc87 Remove unused AppKit Resource 2013-01-09 18:57:58 -08:00
Antoine Mercadal cbcc988625 Add theme for CPBrowser 2013-01-09 18:57:45 -08:00
Antoine Mercadal ce33737a38 Make CPBrowser themable 2013-01-09 18:57:18 -08:00
Alexandre Wilhelm f4e243255a Merge branch 'Aristo2' of github.mv.usa.alcatel.com:amercada/Cappuccino into Aristo2 2013-01-09 18:53:37 -08:00
Alexandre Wilhelm 8df8479716 Updated Aristo2 2013-01-09 18:53:23 -08:00
Alexandre Wilhelm f28ac43446 Added support for _CPBorderlessBridgeWindowView.j theme 2013-01-09 18:53:09 -08:00
Antoine Mercadal 263df059a4 Remove another unused AppKit ressource 2013-01-09 18:30:25 -08:00
Antoine Mercadal 64d1e9ca46 Remove unused AppKit ressource 2013-01-09 18:29:56 -08:00
Antoine Mercadal 286ec29f91 Remove unused AppKit ressource 2013-01-09 18:29:18 -08:00
Antoine Mercadal 66ca5c0d34 Merge branch 'Aristo2' of 172.21.51.218:amercada/Cappuccino into Aristo2 2013-01-09 18:26:50 -08:00
Antoine Mercadal 919335b4f5 Remove unused ressource 2013-01-09 18:25:46 -08:00
Antoine Mercadal c5a4b2605c Add missing theme attributes for CPSearchField 2013-01-09 18:25:11 -08:00
Antoine Mercadal 2da0142387 Make find/search/cancel buttons themable 2013-01-09 18:24:41 -08:00
Alexandre Wilhelm 7ba759b08a Updated Aristo2 for toolBar 2013-01-09 18:24:32 -08:00
Alexandre Wilhelm fdd5aa0a5a Removed unused comments 2013-01-09 18:24:06 -08:00
Alexandre Wilhelm 6ee80f6182 Added support for theme 2013-01-09 18:23:09 -08:00
Alexandre Wilhelm d4bf45a8b8 Moved psd to Artwork 2013-01-09 17:54:07 -08:00
Alexandre Wilhelm d30425b2bd Merge branch 'Aristo2' of github.mv.usa.alcatel.com:amercada/Cappuccino into Aristo2 2013-01-09 17:51:22 -08:00
Antoine Mercadal cff8fbbd79 Remove unused artwork 2013-01-09 17:49:53 -08:00
Antoine Mercadal 8b52c99604 Improve CPImageViewTest to test heavy shadow view too 2013-01-09 17:49:42 -08:00
Antoine Mercadal 5dee254fca Add theme for CPShadowView 2013-01-09 17:49:22 -08:00
Antoine Mercadal 2ab0f494b4 Make CPShadowView themable 2013-01-09 17:49:11 -08:00
Alexandre Wilhelm b4a58b47b3 Updated Aristo2 2013-01-09 17:35:59 -08:00
Alexandre Wilhelm b19450684b Fixed bug with toolBar 2013-01-09 17:34:32 -08:00
Antoine Mercadal 6451e3b3e3 Remove another Ressources not used anymore 2013-01-09 17:04:48 -08:00
Antoine Mercadal 14e2a169e4 Remove unused AppKit Ressources (moved to theme) 2013-01-09 17:03:54 -08:00
Alexandre Wilhelm f809919561 Update Aristo2 2013-01-09 16:02:37 -08:00
Alexandre Wilhelm 68d4b9d2cd Fixed bug with indicator 2013-01-09 16:02:24 -08:00
Alexandre Wilhelm 5e1c6ae30d Added class method for the title height 2013-01-09 16:01:51 -08:00
Alexandre Wilhelm e1ba234a76 Fixed bug about the position of closable buttons. Fixed bug about theme attribute for sheet window 2013-01-09 16:01:18 -08:00
Alexandre Wilhelm b9b84fe692 Improved code. Removed comments 2013-01-09 16:00:28 -08:00
Alexandre Wilhelm a3f5c461c3 Removed comments 2013-01-09 15:59:50 -08:00
Alexandre Wilhelm 91479543fa Removed unused theme attribute 2013-01-09 15:59:17 -08:00
Alexandre Wilhelm 4dfa724972 Removed comments 2013-01-09 15:58:47 -08:00
Alexandre Wilhelm f8e72504e5 Fixed bug with closable button in CPWindow 2013-01-09 14:43:33 -08:00
Alexandre Wilhelm 51d6ba98d7 Updated aristo2 2013-01-09 14:21:53 -08:00
Alexandre Wilhelm 2309e18eb7 Added themable support for shadow window 2013-01-09 14:21:41 -08:00
Alexandre Wilhelm 6ddb891c29 Fixed import 2013-01-09 14:19:56 -08:00
Alexandre Wilhelm 5100f6cb72 Updated psd with slices 2013-01-09 13:14:15 -08:00
Alexandre Wilhelm 73e56d820b Merge branch 'Aristo2' of github.mv.usa.alcatel.com:amercada/Cappuccino into Aristo2 2013-01-09 13:10:15 -08:00
Alexandre Wilhelm 803cbae1dc Updated Aristo2 2013-01-09 13:09:59 -08:00
Alexandre Wilhelm 9b9f877942 Added themable _CPWindowView 2013-01-09 13:09:43 -08:00
Alexandre Wilhelm 0e6df9d299 Added themable _CPDocModalWindowView 2013-01-09 13:09:20 -08:00
Antoine Mercadal 1cbe1cfaeb Merge branch 'master' into Aristo2 2013-01-09 11:59:01 -08:00
Antoine Mercadal 97a766517b Set content-margin size to zero for CPBox 2013-01-09 10:54:51 -08:00
Alexandre Wilhelm 42868ecbee Merge branch 'Aristo2' of github.mv.usa.alcatel.com:amercada/Cappuccino into Aristo2 2013-01-09 10:35:02 -08:00
Alexandre Wilhelm 4fd4b145d7 Updated Aristo2 2013-01-09 10:34:44 -08:00
Alexandre Wilhelm d5f7dc851e Themable _CPStandardWindowView 2013-01-09 10:34:10 -08:00
Antoine Mercadal 06fae21c76 Merge branch 'master' into Aristo2 2013-01-09 09:55:20 -08:00
Martin Carlberg 89da16afec Fixed objjc to output compiled source not the input source 2013-01-09 14:58:22 +01:00
Martin Carlberg 1dfc77a4ba Fixed objjc to use new acorn based compiler 2013-01-09 14:12:58 +01:00
Martin Carlberg 4fb8fa1311 Code clean up 2013-01-09 14:03:38 +01:00
Martin Carlberg 7eba982278 Merge branch 'master' of https://github.com/cappuccino/cappuccino into objj_compiler2 2013-01-09 11:11:45 +01:00
Martin Carlberg df78df5908 Fixed class method that access isa property 2013-01-09 10:37:33 +01:00
Martin Carlberg 0dd98b56bc "self." is only added to instance variables when compiling an instance method 2013-01-09 10:21:16 +01:00
Martin Carlberg 0a573f9da1 Removed unused 6th parameter 2013-01-09 09:29:43 +01:00
Antoine Mercadal 6d43387c55 Remove actually useless chunck of code in NSSearchField.j 2013-01-08 22:23:08 -08:00
Antoine Mercadal ed4094016b Update nib2cib NSSearchField.j to use correct field height 2013-01-08 22:21:51 -08:00
Antoine Mercadal 56100f150d Merge branch 'master' into Aristo2 2013-01-08 18:43:25 -08:00
Antoine Mercadal 4e06ed80d1 Merge branch 'Aristo2' of 172.21.51.218:amercada/Cappuccino into Aristo2 2013-01-08 18:09:35 -08:00
Antoine Mercadal a0c294f689 Merge branch 'master' into Aristo2 2013-01-08 18:09:24 -08:00
Alexandre Wilhelm 02bd640aab Merge branch 'Aristo2' of github.mv.usa.alcatel.com:amercada/Cappuccino into Aristo2 2013-01-08 17:59:29 -08:00
Alexandre Wilhelm 06b1060a45 Fixed bug in scrollview 2013-01-08 17:59:19 -08:00
Antoine Mercadal 0f0dcb9eae Remove old static theme for CPSplitView 2013-01-08 17:22:19 -08:00
Antoine Mercadal 5ec6d571eb Improve theme for CPSplitView 2013-01-08 17:22:10 -08:00
Antoine Mercadal 347de2cb8b CPSplitView is now fully themable 2013-01-08 17:21:32 -08:00
Antoine Mercadal f6a923ad56 remove old non themable CPProgressIndicator art files 2013-01-08 17:09:38 -08:00
Antoine Mercadal 43455ee661 Remove old CPLevelIndicator ressources 2013-01-08 17:06:13 -08:00
Antoine Mercadal 911df72aeb Add theme for CPLevelIndicator 2013-01-08 17:05:58 -08:00
Antoine Mercadal b82225e279 Make CPLevelIndicator themable 2013-01-08 17:05:33 -08:00
Antoine Mercadal bb3cc58ad0 Merge branch 'Aristo2' of 172.21.51.218:amercada/Cappuccino into Aristo2 2013-01-08 16:30:24 -08:00
Antoine Mercadal 804a345fec Merge branch 'master' into Aristo2 2013-01-08 16:29:52 -08:00
Alexandre Wilhelm 7f05164a7f Merge branch 'Aristo2' of github.mv.usa.alcatel.com:amercada/Cappuccino into Aristo2 2013-01-08 16:24:24 -08:00
Alexandre Wilhelm 52a6806022 Update Aristo2 2013-01-08 16:23:51 -08:00
Alexandre Wilhelm 1a9d47c554 Fixed bug about scroller-width attribute theme 2013-01-08 16:22:49 -08:00
Antoine Mercadal 2c3b3be3ee Adjust menubar height 2013-01-08 15:51:53 -08:00
Antoine Mercadal cdaed50939 Readd Aristo1 build process
Cappuccino will now continue to support Aristo1
By default Aristo2 will be used, unless you add in your Info.plist

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

In that case Aristo2 will be use.

If you put

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

It will use your custom theme as usual from your app's Resource folder
2013-01-08 15:03:14 -08:00
Antoine Mercadal 5a155020e6 Merge branch 'master' into Aristo2 2013-01-08 15:02:50 -08:00
Martin Carlberg 957b34d169 Added the option trackSpaces to attach spacesBefore and spacesAfter properties to AST nodes. 2013-01-08 22:23:34 +01:00
Martin Carlberg 79d2ac0566 Fixed some comments and removed unwanted spaces 2013-01-08 22:19:55 +01:00
Martin Carlberg 547f9ff61f Merge with latest from Acorn master 2013-01-08 22:18:19 +01:00
Martin Carlberg 9f0da2ec41 Fixed spelling error 2013-01-08 22:13:36 +01:00
Martin Carlberg c755dc3ed9 Added some more detailed error messages in parser 2013-01-08 17:00:54 +01:00
Martin Carlberg d20fb2039a Missed some lines in manual merge 2013-01-08 14:34:29 +01:00
Martin Carlberg 1c3411f808 Merge remote-tracking branch 'upstream/master' into objj_compiler2
Conflicts:
	AppKit/CPWindow/CPWindow.j
2013-01-08 09:25:54 +01:00
Antoine Mercadal 7357be3c35 Finish Aristo HUD 2013-01-07 20:03:20 -08:00
Antoine Mercadal 5dd1bed913 Add the HUD version of Aristo2 2013-01-07 18:40:34 -08:00
Antoine Mercadal 18eda8aade Add the HUD version of Aristo2 2013-01-07 17:34:43 -08:00
Martin Carlberg 8100cdb17f Fixed "Can't find variable: ObjJCompiler" error 2013-01-07 23:13:54 +01:00
Antoine Mercadal 7fa01fa4f3 Merge branch 'master' into Aristo2
Conflicts:
	Tests/Manual/CPPopover/Resources/MainMenu.cib
2013-01-07 13:23:05 -08:00
Martin Carlberg d49e78c43e Removal of old compiler 2013-01-07 20:29:56 +01:00
Martin Carlberg cf46768ac7 Removal of logs 2013-01-07 20:29:45 +01:00
Martin Carlberg cfe718f4ef Handle preprocessor lines like "#pragma" 2013-01-07 20:29:35 +01:00
Martin Carlberg bf32b90702 Allow signed, unsigned, char, short, int and long to be an identifier 2013-01-07 20:29:13 +01:00
Martin Carlberg 9cb14d6db3 Added new faster compiler based on acorn parser 2013-01-07 09:59:10 +01:00
Martin Carlberg 140cf0debe Code cleanup 2013-01-07 09:55:12 +01:00
Antoine Mercadal 7e9b12b475 Update and improve CPBoxTest manual test 2013-01-04 18:46:16 -08:00
Antoine Mercadal 63a3a8a731 Use API to set themable attribute in nib2cib for CPBox 2013-01-04 18:45:53 -08:00
Antoine Mercadal c95421f307 Add theme for CPBox (and it's an improved look) 2013-01-04 18:45:28 -08:00
Antoine Mercadal edc62449f6 Make CPBox themable 2013-01-04 18:45:05 -08:00
Antoine Mercadal a7f1192402 Ignore .XcodeSupport folder 2013-01-04 18:22:08 -08:00
Antoine Mercadal 6bbda8a8e7 Merge branch 'Aristo2' of 172.21.51.218:amercada/Cappuccino into Aristo2 2013-01-04 12:21:07 -08:00
Antoine Mercadal 2431dbc16f rerun nib2cib on CPSegmentedControlTest's MainMenu.xib 2013-01-04 12:20:57 -08:00
Antoine Mercadal d87f86b2a4 Adjust CPSegmentedControl height to match new Aristo2 art 2013-01-04 12:20:36 -08:00
Antoine Mercadal 55a0652c2b Merge branch 'master' into Aristo2 2013-01-04 12:15:51 -08:00
Alexandre Wilhelm aa1559b159 Added missing images 2013-01-04 11:57:12 -08:00
Alexandre Wilhelm 88dd2f1495 Fixed bug with tokenfield 2013-01-04 11:52:36 -08:00
Alexandre Wilhelm eb2cd75370 Fixed bug in BKShowcasController with popUpButtons size 2013-01-04 10:32:35 -08:00
Alexandre Wilhelm 4757648349 CPAlert can be moved now 2013-01-03 18:34:22 -08:00
Alexandre Wilhelm a1f166942c Added new modal window 2013-01-03 18:14:13 -08:00
Antoine Mercadal 7dbe0c2899 readd removed art.. 2013-01-03 18:01:36 -08:00
Antoine Mercadal 9bc4873721 Update the menubar art 2013-01-03 17:55:06 -08:00
Antoine Mercadal 15005f5754 Update selection color 2013-01-03 16:59:10 -08:00
Antoine Mercadal c959ca9821 Update static art to match Aristo2 2013-01-03 16:51:10 -08:00
Antoine Mercadal 26687226f4 Merge branch 'Aristo2' of 172.21.51.218:amercada/Cappuccino into Aristo2 2013-01-03 15:04:58 -08:00
Antoine Mercadal 408b5b517b Run ImageOptim on all Aristo2 ressources 2013-01-03 15:04:31 -08:00
Alexandre Wilhelm f403699fb2 Fixed bug with content-inset in textField 2013-01-03 14:51:23 -08:00
Alexandre Wilhelm 193b289e8e CPButtonBar Aristo2 2013-01-03 14:46:05 -08:00
Antoine Mercadal 533fd0574a Merge branch 'master' into Aristo2 2013-01-03 14:25:42 -08:00
Antoine Mercadal 48ffdf419f Restore art for ButtonBar 2013-01-03 14:16:50 -08:00
Antoine Mercadal 93e931e2b6 Fix Aristo2 Build process 2013-01-03 13:47:50 -08:00
Alexandre Wilhelm 6561e4f84e Init of Aristo2 2013-01-03 11:22:46 -08:00
Stefan Wallström 24d6e581a6 Fixed: CPPredicate: TRUEPREDICATE didn't work
CPPredicate_BOOL didn't implement any methods necessary for TRUEPREDICATE to evaluate to true.
2013-01-03 11:04:53 +01:00
Martin Carlberg d5748474d0 Forgot some more lines 2012-12-20 22:55:58 +01:00
Martin Carlberg 2277fb04b9 Missed to commit some stuff for scope handling 2012-12-20 18:19:39 +01:00
Martin Carlberg 78b2d30905 Added better support for scope 2012-12-20 18:01:47 +01:00
Martin Carlberg ed81d75815 Removes #pragma lines 2012-12-20 17:49:23 +01:00
Martin Carlberg ac3a399df3 Set to use new compiler when compiling with jake 2012-12-20 15:20:38 +01:00
Martin Carlberg 619f90c677 Removed debug stuff 2012-12-20 15:20:12 +01:00
Martin Carlberg 0f3d5f4b10 Added support to choose which compiler should be used when compiling in the browser. Default is old compiler but add "ObjJCompilerSetUsedVersion("objj_compiler2");" in the index.html (and/or index-debug.html) to use new compiler in browser. 2012-12-20 14:26:49 +01:00
Martin Carlberg 26be5bf264 Better error message when importing file that is not found 2012-12-20 14:23:54 +01:00
Martin Carlberg 227c696750 Removed circular imports in CPToolbarItem.j 2012-12-20 14:22:09 +01:00
Martin Carlberg b1cec9480e New test cases to test ivar handling in new compiler 2012-12-20 09:37:52 +01:00
Martin Carlberg 982da962e5 Fixed problems due to the removal of with(self) 2012-12-19 23:51:42 +01:00
Martin Carlberg 803c8ce6b5 A little code clean up. 2012-12-17 17:14:33 +01:00
Martin Carlberg ca99114b16 Forgot to add one file 2012-12-17 15:12:02 +01:00
Martin Carlberg 897adf27f0 Fixed import statements in nib2cib, bug in load system and some more fixes to test cases 2012-12-17 14:57:18 +01:00
Martin Carlberg fd59efe41f Bug fixes for failing test cases 2012-12-17 11:15:50 +01:00
Martin Carlberg b52217e8a0 Tried to make the import mess a little better. Fixed a lot of bugs. Changed some class names in the test cases. Looks like all the tests are being run in the same space. Has to look into this….. 2012-12-17 00:40:26 +01:00
Martin Carlberg 0280a10832 More changes now when we don't have with(self) 2012-12-16 19:20:59 +01:00
Martin Carlberg c297e926f9 Compiler now works with jake and can compiler the whole Cappuccino framework. A lot of test cases still fail 2012-12-16 17:38:47 +01:00
Martin Carlberg 59fa5c27b6 Added support for new compiler when loading objj files in the browsers 2012-12-15 23:35:36 +01:00
cacaodev 6b7b63dff4 Drop support with drop indicator.
FIXED: undefined _horizontalMargin
Test app: UI for switching uniformSubviewsResizing.
2012-12-08 23:15:41 +01:00
cacaodev dd5bd17e2b Simplify the "layout computing" method and change its name
There is not need to use that much arguments because the result is stored in ivars.
CPCollectionViewItem -copy: set properties correctly even if the collectionView overrides them.
2012-12-08 17:43:53 +01:00
cacaodev 2ab1493d27 Merge branch 'CPCollectionView-dragged-view' into CPCollectionView-dragAndDrop 2012-12-07 16:51:23 +01:00
cacaodev 9a1e75712d test app: CPSelectionIndexesBinding test 2012-12-07 16:51:11 +01:00
cacaodev 4c1ebfbdd4 -setItemPrototype:
Do not cache removed items in -reloadContent when the item prototype changes.

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

Fixed: incorrect position when num items < numberOfColumns.

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

Added shared -init. Whitespace cleaning.

CPCollectionviewCibTest:
    Add ability to set the 2 kinds of prototypes, one loading its view from a cib, the other with a view outlet in the same cib.
    Loaded protoype: the bound textfield can commit its value to the model.
    UI for setting maxNumberOfColumns|Rows min|maxItemSize
2012-12-06 19:42:03 +01:00
cacaodev 34d6d0695f Freeze autoresizingMask
The mask is 0 and cannot be changed.
Cocoa allows any value but ignores them for layout.
2012-11-30 15:01:44 +01:00
cacaodev 524bd52a56 Partially rewrote layout.
it is not optimal but certainly better than the previous  version. A
collection view was unusable when resized through its scroll view.
2012-11-30 15:01:44 +01:00
cacaodev efc5b8faaa Update min/maxItemSize lazylly instead of subclassing -awakeFromCib
Binders can set values before -awakeFromCib. We were too late
and the bound content was not visible.
2012-11-30 15:00:28 +01:00
cacaodev 112c6bd594 CPCollectionView test. Nib test and bindings test.
Bindings:
collectionView CPContentBinding -> arrayController.selectedObjects
prototypeView CPValueBinding -> owner.representedObject
2012-11-30 14:58:52 +01:00
cacaodev 8b5c0fb715 CPCollectionView : Allow the prototype view to be loaded from a cib
With this commit CPCollectionView can load subviews from an external
cib. Outlets, actions and bindings between the view and the
prototype are restaured when the view is loaded.
2012-11-30 14:56:36 +01:00
Martin Carlberg 82337b8baa Merge branch 'master' into scroll_before_focus_text_field
Conflicts:
	AppKit/CPTokenField.j
2012-11-30 14:43:46 +01:00
Martin Carlberg 744f3d70ed nib2cib allows CPCheckBox and CPRadio to have themed height and adjusts it correctly 2012-11-29 15:37:33 +01:00
cacaodev cd22b29ff1 Adds a binded popup to the ViewBasedCib example. 2012-11-14 16:02:05 +01:00
cacaodev 1d8c46216f Do not enqueue editing data views. No need to clean FR and action if it is not enqueued. Clean up corresponding code. 2012-11-13 21:18:20 +01:00
cacaodev b5d70b90d9 Code style following alexander comments 2012-11-13 19:20:49 +01:00
cacaodev 9b03abaeef ViewBasedCib example now uses a separate table delegate, which is the owner of table cell views.
It shows that the loaded view (intenal or external) has an outlet owned by the table delegate and is available for initial setup in -awakeFromCib
2012-11-13 18:52:45 +01:00
cacaodev 8a3d832b4c NSNib.j : use a UUID to create the temp nib file (for safety). Remove ref to NSTableCellView in info message 2012-11-13 18:37:58 +01:00
cacaodev d2848fc519 Do not search for custom cibs if we are in a cell-based table view 2012-11-13 12:08:37 +01:00
cacaodev 48092bd7ba makeViewWithIdentifier:owner: search for a custom cib in owner's bundle or main bundle if nil. (was main bundle) 2012-11-13 12:05:03 +01:00
cacaodev 5c15ceedc4 Make the cached list of inexistent custom cibs an ivar 2012-11-13 11:57:18 +01:00
cacaodev f568a2407b Merge remote-tracking branch 'upstream/master' into CPTableViewLion 2012-11-13 11:22:03 +01:00
Martin Carlberg 7bf5f6f5a9 Added scrollRectToVisible when CPTokenField becomeFirstResponder 2012-10-27 15:13:57 +02:00
cacaodev 5b1cf49170 Merge remote-tracking branch 'upstream/master' into CPTableViewLion 2012-10-15 14:23:24 +02:00
Martin Carlberg 182f4c369a Make sure the text field is visible before focus so the browser
will not scroll without the NSScrollView knowing about it
Issue #1675 and maybe a little of issue #1301
This fix will not work without pull
request #1678 - Fixed scrollRectToVisible in CPView
2012-09-28 12:57:13 +02:00
Martin Carlberg 1d1f2d73ca Fixed scrollRectToVisible in CPView:
Earlier it only worked when the receiver was the document view of the clip view.
Added test case.
2012-09-28 12:27:23 +02:00
Martin Carlberg 23401d37d8 Fixed error in function CPDescriptionOfObject when a JSON object property has a null value.
The function can't handle the following JSON object: {name:null}.
Also added a test case for this.
2012-09-14 10:54:41 +02:00
Blair Duncan ada73a16ce Fix for left/right cursors in CPBrowser 2012-08-24 16:01:31 -04:00
cacaodev 7ecf6ece7c Tests for previous commit 2012-07-28 12:50:17 +02:00
cacaodev 1c3d658ca1 CPURLConnection -sendSynchronousRequest: return nil if CPHTTPRequest failed. 2012-07-27 20:11:59 +02:00
cacaodev 9cbb8fd5bc Support for external cibs (a view in an individual cib). Added such view to ViewBasedCib. Also added an example of a view created manually in the delegate 2012-07-27 20:00:00 +02:00
cacaodev f4904b8915 CPCib -initWithContentsOfURL: return nil if the returned data is nil (non existent URL, request failed for some reason ...) 2012-07-27 19:17:45 +02:00
cacaodev 176440eeae CPURLConnection -sendSynchronousRequest: return nil if CPHTTPRequest failed 2012-07-27 19:16:38 +02:00
cacaodev 1a0434fd85 Fix action sent when an edited control is enqueued (see action log in test app).
A non bezeled text field is now bezeled when edited and unbezeled when editing ends - including when you hit enter (but text has to be modified, see comment in code)
2012-07-27 16:32:02 +02:00
cacaodev c6ccf1d487 -rowForView: early return if arg is not a CPView. Was causing an error when you click on table whose window was not frontmost.
Simplify -hitTest:, limit select-row behavior to left mouse events and extend to all data views accepting FR.
2012-07-27 09:48:36 +02:00
cacaodev 0faf38a1e1 From within the delegate method, if you ask for an IB view (makeviewWithIdentifier:owner:), the view is now automatically reusable.
Before that, IB views were reusable only if the delegate method was not implemented.
If you create a view in code, you still need to make it reusable by calling -setIdentifier:

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

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

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

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

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

When the view is found automatically in the cib, instantiate with _delegate as the owner (cocoa behavior).
2012-04-13 09:19:23 +02:00
cacaodev c2cad3cca3 nib2cib NSNib support. NSNib are represented as data inside nib files. We need to extract them, write, nib2cib, feed CPCib with the data. 2012-04-13 09:19:23 +02:00
cacaodev 5a99011feb nib2cib support for CPView identifier property. 2012-04-13 09:19:23 +02:00
cacaodev 392702cc18 nib2cib Converter.j : Add a flag to disable ibtool step in case the input is already compiled. Set SharedConverter class var in init (not a singleton, represents the current Converter). 2012-04-13 09:18:54 +02:00
Blair Duncan ed2e637219 Merge branch 'master' of git://github.com/cappuccino/cappuccino into afterDocumentLoadFix 2012-04-11 06:53:53 -04:00
Blair Duncan 3649b0ed9c Added test 2012-04-10 19:28:00 -04:00
Blair Duncan 13fbfb6cac fix to enables the startup loader to continue if dynamically loaded 2012-04-10 16:55:42 -04:00
cacaodev 27cda34f8b CPTableView: When columns or rows dragging ends, enqueue the dragged views so they can be available when you drag again the column if they haven't been unloaded before.
The 2nd time you drag the same column/row, reduces -dragViewFor... duration by 90% according to webkit profiling.
2012-03-17 16:10:54 +01:00
cacaodev 57c8d223ad CPCollectionView dragging: fix a bug where the dragging view was created from content instead of selection 2012-02-29 18:45:11 +01:00
cacaodev 8641738777 Merge remote-tracking branch 'upstream/master' into CPCollectionView-dragged-view 2012-02-29 18:42:25 +01:00
cacaodev bafd62d42d CPCollectionView Implemented - (CPView)draggingViewForItemsAtIndexes:(CPIndexSet)indexes withEvent:(CPEvent)event offset:(CGPoint)dragImageOffset
and the corresponding delegate method from where you can ask for the default dragged view. Multiple selection not implemented yet.
2012-01-25 17:25:23 +01:00
cncolder 1a88651e4e Merge branch 'master' into fontinfo-path-fix 2011-04-28 10:28:04 +08:00
cncolder 229e43f20c Fix build path when $CAPP_BUILD not defined. 2011-04-19 09:14:00 +08:00
2388 changed files with 210996 additions and 65455 deletions
+8
View File
@@ -5,8 +5,16 @@ Demos
./Aristo
WebSite
.push-package
*.xcodeproj*
*.xcodeproj/*.pbxuser
*.xcodeproj/*.perspectivev3
xcuserdata/
!*.xcodeproj/project.pbxproj
*.xCodeSupport/
*.XcodeSupport/
*XcodeSupport/
Tests/Manual/**/*.xcodeproj
*.sublime-project
*.sublime-workspace
*.tm_properties
*.idea
+2 -4
View File
@@ -1,8 +1,6 @@
language: node_js
node_js:
- 0.8
before_install:
- jdk_switcher use openjdk6
install: ./bootstrap.sh --quiet --noprompt --directory ./narwhal
install: ./bootstrap.sh --noprompt --directory ./narwhal
script: jake test
env: PATH=/home/travis/builds/cappuccino/cappuccino/narwhal/bin:$PATH CAPP_BUILD=/home/travis/builds/cappuccino/cappuccino/Build NARWHAL_ENGINE=rhino
env: PATH="$TRAVIS_BUILD_DIR/narwhal/bin:$PATH" CAPP_BUILD="$TRAVIS_BUILD_DIR/Build" NARWHAL_ENGINE=rhino
+9 -1
View File
@@ -20,12 +20,15 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "_CPObject+Theme.j"
@import "_CPToolTip.j"
@import "CALayer.j"
@import "CGGeometry.j"
@import "CPAccordionView.j"
@import "CPAlert.j"
@import "CPAnimation.j"
@import "CPAnimationContext.j"
@import "CPAppearance.j"
@import "CPApplication.j"
@import "CPArrayController.j"
@import "CPBezierPath.j"
@@ -55,6 +58,7 @@
@import "CPController.j"
@import "CPCookie.j"
@import "CPCursor.j"
@import "CPDatePicker.j"
@import "CPDocument.j"
@import "CPDocumentController.j"
@import "CPEvent.j"
@@ -97,15 +101,19 @@
@import "CPTabView.j"
@import "CPText.j"
@import "CPTextField.j"
@import "CPTextView.j"
@import "CPTokenField.j"
@import "CPToolbar.j"
@import "CPToolbarItem.j"
@import "CPTrackingArea.j"
@import "CPTreeNode.j"
@import "CPUserDefaultsController.j"
@import "CPView.j"
@import "CPViewAnimator.j"
@import "CPViewAnimation.j"
@import "CPViewController.j"
@import "CPVisualEffectView.j"
@import "CPWebView.j"
@import "CPWindow.j"
@import "CPWindowController.j"
@import "CPWorkspace.j"
@import "CPWorkspace.j"
+15 -15
View File
@@ -106,7 +106,7 @@ var secondItem = [[CPAccordionViewItem alloc] initWithIdentifier:@"secondSection
_itemViews = [];
_expandedItemIndexes = [CPIndexSet indexSet];
[self setItemHeaderPrototype:[[CPButton alloc] initWithFrame:_CGRectMake(0.0, 0.0, 100.0, 24.0)]];
[self setItemHeaderPrototype:[[CPButton alloc] initWithFrame:CGRectMake(0.0, 0.0, 100.0, 24.0)]];
}
return self;
@@ -227,7 +227,7 @@ var secondItem = [[CPAccordionViewItem alloc] initWithIdentifier:@"secondSection
{
var indexSet = [CPIndexSet indexSetWithIndexesInRange:CPMakeRange(0, _items.length)];
[indexSet removeIndexes:_expandedIndexes];
[indexSet removeIndexes:_expandedItemIndexes];
return indexSet;
}
@@ -258,18 +258,18 @@ var secondItem = [[CPAccordionViewItem alloc] initWithIdentifier:@"secondSection
- (void)setFrameSize:(CGSize)aSize
{
var width = _CGRectGetWidth([self frame]);
var width = CGRectGetWidth([self frame]);
[super setFrameSize:aSize];
if (width !== _CGRectGetWidth([self frame]))
if (width !== CGRectGetWidth([self frame]))
[self _invalidateItemsStartingAtIndex:0];
}
- (void)layoutSubviews
{
if (_items.length <= 0)
return [self setFrameSize:_CGSizeMake(_CGRectGetWidth([self frame]), 0.0)];
return [self setFrameSize:CGSizeMake(CGRectGetWidth([self frame]), 0.0)];
if (_dirtyItemIndex === CPNotFound)
return;
@@ -278,7 +278,7 @@ var secondItem = [[CPAccordionViewItem alloc] initWithIdentifier:@"secondSection
var index = _dirtyItemIndex,
count = _itemViews.length,
width = _CGRectGetWidth([self bounds]),
width = CGRectGetWidth([self bounds]),
y = index > 0 ? CGRectGetMaxY([_itemViews[index - 1] frame]) : 0.0;
// Do this now (instead of after looping), so that if we are made dirty again in the middle we don't blow this value away.
@@ -293,7 +293,7 @@ var secondItem = [[CPAccordionViewItem alloc] initWithIdentifier:@"secondSection
y = CGRectGetMaxY([itemView frame]);
}
[self setFrameSize:_CGSizeMake(_CGRectGetWidth([self frame]), y)];
[self setFrameSize:CGSizeMake(CGRectGetWidth([self frame]), y)];
}
@end
@@ -310,7 +310,7 @@ var secondItem = [[CPAccordionViewItem alloc] initWithIdentifier:@"secondSection
- (id)initWithAccordionView:(CPAccordionView)anAccordionView
{
self = [super initWithFrame:_CGRectMakeZero()];
self = [super initWithFrame:CGRectMakeZero()];
if (self)
{
@@ -376,21 +376,21 @@ var secondItem = [[CPAccordionViewItem alloc] initWithIdentifier:@"secondSection
- (void)setFrameY:(float)aY width:(float)aWidth
{
var headerHeight = _CGRectGetHeight([_headerView frame]);
var headerHeight = CGRectGetHeight([_headerView frame]);
// Size to fit or something?
[_headerView setFrameSize:_CGSizeMake(aWidth, headerHeight)];
[_contentView setFrameOrigin:_CGPointMake(0.0, headerHeight)];
[_headerView setFrameSize:CGSizeMake(aWidth, headerHeight)];
[_contentView setFrameOrigin:CGPointMake(0.0, headerHeight)];
if ([self isCollapsed])
[self setFrame:_CGRectMake(0.0, aY, aWidth, headerHeight)];
[self setFrame:CGRectMake(0.0, aY, aWidth, headerHeight)];
else
{
var contentHeight = _CGRectGetHeight([_contentView frame]);
var contentHeight = CGRectGetHeight([_contentView frame]);
[_contentView setFrameSize:_CGSizeMake(aWidth, contentHeight)];
[self setFrame:_CGRectMake(0.0, aY, aWidth, contentHeight + headerHeight)];
[_contentView setFrameSize:CGSizeMake(aWidth, contentHeight)];
[self setFrame:CGRectMake(0.0, aY, aWidth, contentHeight + headerHeight)];
}
}
+222 -109
View File
@@ -28,15 +28,23 @@
@import <Foundation/CPObject.j>
@import <Foundation/CPString.j>
@import "CPApplication.j"
@import "CPButton.j"
@import "CPColor.j"
@import "CPFont.j"
@import "CPImage.j"
@import "CPImageView.j"
@import "CPPanel.j"
@import "CPText.j"
@import "CPTextField.j"
@class CPCheckBox
@global CPApp
var CPAlertDelegate_alertShowHelp_ = 1 << 0,
CPAlertDelegate_alertDidEnd_returnCode_ = 1 << 1;
@typedef CPAlertStyle
/*
@global
@group CPAlertStyle
@@ -53,6 +61,64 @@ CPInformationalAlertStyle = 1;
*/
CPCriticalAlertStyle = 2;
var bottomHeight = 71;
@protocol CPAlertDelegate <CPObject>
@optional
- (BOOL)alertShowHelp:(CPAlert)alert;
- (void)alertDidEnd:(CPAlert)theAlert returnCode:(int)returnCode;
@end
@implementation _CPAlertThemeView : CPView
+ (CPString)defaultThemeClass
{
return @"alert";
}
+ (CPDictionary)themeAttributes
{
return @{
@"size": CGSizeMake(400.0, 110.0),
@"content-inset": CGInsetMake(15, 15, 15, 50),
@"informative-offset": 6,
@"button-offset": 10,
@"message-text-alignment": CPJustifiedTextAlignment,
@"message-text-color": [CPColor blackColor],
@"message-text-font": [CPFont boldSystemFontOfSize:13.0],
@"message-text-shadow-color": [CPNull null],
@"message-text-shadow-offset": CGSizeMakeZero(),
@"informative-text-alignment": CPJustifiedTextAlignment,
@"informative-text-color": [CPColor blackColor],
@"informative-text-font": [CPFont systemFontOfSize:12.0],
@"informative-text-shadow-color": [CPNull null],
@"informative-text-shadow-offset": CGSizeMakeZero(),
@"image-offset": CGPointMake(15, 12),
@"information-image": [CPNull null],
@"warning-image": [CPNull null],
@"error-image": [CPNull null],
@"help-image": [CPNull null],
@"help-image-left-offset": 15,
@"help-image-pressed": [CPNull null],
@"suppression-button-y-offset": 0.0,
@"suppression-button-x-offset": 0.0,
@"default-elements-margin": 3.0,
@"suppression-button-text-color": [CPColor blackColor],
@"suppression-button-text-font": [CPFont systemFontOfSize:12.0],
@"suppression-button-text-shadow-color": [CPNull null],
@"suppression-button-text-shadow-offset": 0.0,
@"modal-window-button-margin-y": 0.0,
@"modal-window-button-margin-x": 0.0,
@"standard-window-button-margin-y": 0.0,
@"standard-window-button-margin-x": 0.0,
};
}
@end
/*!
@ingroup appkit
@@ -77,31 +143,33 @@ CPCriticalAlertStyle = 2;
*/
@implementation CPAlert : CPObject
{
BOOL _showHelp @accessors(property=showsHelp);
BOOL _showSuppressionButton @accessors(property=showsSuppressionButton);
BOOL _showHelp @accessors(property=showsHelp);
BOOL _showSuppressionButton @accessors(property=showsSuppressionButton);
CPAlertStyle _alertStyle @accessors(property=alertStyle);
CPString _title @accessors(property=title);
CPView _accessoryView @accessors(property=accessoryView);
CPImage _icon @accessors(property=icon);
CPAlertStyle _alertStyle @accessors(property=alertStyle);
CPString _title @accessors(property=title);
CPView _accessoryView @accessors(property=accessoryView);
CPImage _icon @accessors(property=icon);
CPArray _buttons @accessors(property=buttons,readonly);
CPCheckBox _suppressionButton @accessors(property=suppressionButton,readonly);
CPArray _buttons @accessors(property=buttons, readonly);
CPCheckBox _suppressionButton @accessors(property=suppressionButton, readonly);
id _delegate @accessors(property=delegate);
id _modalDelegate;
SEL _didEndSelector;
id <CPAlertDelegate> _delegate @accessors(property=delegate);
id _modalDelegate;
SEL _didEndSelector @accessors(property=didEndSelector);
Function _didEndBlock;
unsigned _implementedDelegateMethods;
_CPAlertThemeView _themeView @accessors(property=themeView, readonly);
CPWindow _window @accessors(property=window,readonly);
int _defaultWindowStyle;
_CPAlertThemeView _themeView @accessors(property=themeView, readonly);
CPWindow _window @accessors(property=window, readonly);
int _defaultWindowStyle;
CPImageView _alertImageView;
CPTextField _informativeLabel;
CPTextField _messageLabel;
CPButton _alertHelpButton;
CPImageView _alertImageView;
CPTextField _informativeLabel;
CPTextField _messageLabel;
CPButton _alertHelpButton;
BOOL _needsLayout;
BOOL _needsLayout;
}
#pragma mark Creating Alerts
@@ -164,7 +232,7 @@ CPCriticalAlertStyle = 2;
_alertStyle = CPWarningAlertStyle;
_showHelp = NO;
_needsLayout = YES;
_defaultWindowStyle = CPTitledWindowMask;
_defaultWindowStyle = _CPModalWindowMask;
_themeView = [_CPAlertThemeView new];
_messageLabel = [CPTextField labelWithTitle:@"Alert"];
@@ -180,6 +248,30 @@ CPCriticalAlertStyle = 2;
return self;
}
#pragma mark -
#pragma mark Delegate
/*!
Set the delegate of the receiver
@param aDelegate the delegate object for the alert.
*/
- (void)setDelegate:(id <CPAlertDelegate>)aDelegate
{
if (_delegate === aDelegate)
return;
_delegate = aDelegate;
_implementedDelegateMethods = 0;
if ([_delegate respondsToSelector:@selector(alertShowHelp:)])
_implementedDelegateMethods |= CPAlertDelegate_alertShowHelp_;
if ([_delegate respondsToSelector:@selector(alertDidEnd:returnCode:)])
_implementedDelegateMethods |= CPAlertDelegate_alertDidEnd_returnCode_;
}
#pragma mark Accessors
- (CPTheme)theme
@@ -212,22 +304,21 @@ CPCriticalAlertStyle = 2;
[_themeView setValue:aValue forThemeAttribute:aName];
}
- (void)setValue:(id)aValue forThemeAttribute:(CPString)aName inState:(CPThemeState)aState
- (void)setValue:(id)aValue forThemeAttribute:(CPString)aName inState:(ThemeState)aState
{
[_themeView setValue:aValue forThemeAttribute:aName inState:aState];
}
/*! @deprecated
*/
- (void)setWindowStyle:(int)aStyle
/*! @deprecated */
- (void)setWindowStyle:(int)style
{
CPLog.warn("DEPRECATED: setWindowStyle: is deprecated. use setTheme: instead");
[self setTheme:(aStyle === CPHUDBackgroundWindowMask) ? [CPTheme defaultHudTheme] : [CPTheme defaultTheme]];
[self setTheme:(style === CPHUDBackgroundWindowMask) ? [CPTheme defaultHudTheme] : [CPTheme defaultTheme]];
}
/*! @deprecated
*/
/*! @deprecated */
- (int)windowStyle
{
CPLog.warn("DEPRECATED: windowStyle: is deprecated. use theme instead");
@@ -236,18 +327,19 @@ CPCriticalAlertStyle = 2;
/*!
set the text of the alert's message
Set the text of the alert's message.
@param aText CPString containing the text
*/
- (void)setMessageText:(CPString)aText
- (void)setMessageText:(CPString)text
{
[_messageLabel setStringValue:aText];
[_messageLabel setStringValue:text];
_needsLayout = YES;
}
/*!
return the content of the message text
Return the content of the message text.
@return CPString containing the message text
*/
- (CPString)messageText
@@ -256,13 +348,13 @@ CPCriticalAlertStyle = 2;
}
/*!
set the text of the alert's informative text
Set the text of the alert's informative text.
@param aText CPString containing the informative text
*/
- (void)setInformativeText:(CPString)aText
- (void)setInformativeText:(CPString)text
{
[_informativeLabel setStringValue:aText];
[_informativeLabel setStringValue:text];
_needsLayout = YES;
}
@@ -279,6 +371,7 @@ CPCriticalAlertStyle = 2;
/*!
Sets the title of the alert window.
This API is not present in Cocoa.
@param aTitle CPString containing the window title
*/
- (void)setTitle:(CPString)aTitle
@@ -288,7 +381,7 @@ CPCriticalAlertStyle = 2;
}
/*!
set the accessory view
Set the accessory view.
@param aView the accessory view
*/
@@ -299,7 +392,7 @@ CPCriticalAlertStyle = 2;
}
/*!
set if alert shows the suppression button
Set if the alert shows the suppression button.
@param shouldShowSuppressionButton YES or NO
*/
@@ -450,6 +543,9 @@ CPCriticalAlertStyle = 2;
defaultElementsMargin = [_themeView currentValueForThemeAttribute:@"default-elements-margin"],
panelSize = [[_window contentView] frame].size,
buttonsOriginY,
buttonMarginY,
buttonMarginX,
theme = [self theme],
offsetX;
[aRepresentativeButton setTheme:[self theme]];
@@ -462,6 +558,19 @@ CPCriticalAlertStyle = 2;
buttonsOriginY = panelSize.height - [aRepresentativeButton frameSize].height + buttonOffset;
offsetX = panelSize.width - inset.right;
switch ([_window styleMask])
{
case _CPModalWindowMask:
buttonMarginY = [_themeView currentValueForThemeAttribute:@"modal-window-button-margin-y"];
buttonMarginX = [_themeView currentValueForThemeAttribute:@"modal-window-button-margin-x"];
break;
default:
buttonMarginY = [_themeView currentValueForThemeAttribute:@"standard-window-button-margin-y"];
buttonMarginX = [_themeView currentValueForThemeAttribute:@"standard-window-button-margin-x"];
break;
}
for (var i = [_buttons count] - 1; i >= 0 ; i--)
{
var button = _buttons[i];
@@ -473,7 +582,7 @@ CPCriticalAlertStyle = 2;
height = CGRectGetHeight(buttonFrame);
offsetX -= width;
[button setFrame:CGRectMake(offsetX, buttonsOriginY, width, height)];
[button setFrame:CGRectMake(offsetX + buttonMarginX, buttonsOriginY + buttonMarginY, width, height)];
offsetX -= 10;
}
@@ -546,6 +655,12 @@ CPCriticalAlertStyle = 2;
[_window setFrameSize:finalSize];
[_window center];
if ([_window styleMask] & _CPModalWindowMask || [_window styleMask] & CPHUDBackgroundWindowMask)
{
[_window setMovable:YES];
[_window setMovableByWindowBackground:YES];
}
_needsLayout = NO;
}
@@ -568,6 +683,17 @@ CPCriticalAlertStyle = 2;
[CPApp runModalForWindow:_window];
}
/*!
The same as \c runModal, but executes the code in \c block when the
alert is dismissed.
*/
- (void)runModalWithDidEndBlock:(Function /*(CPAlert alert, int returnCode)*/)block
{
_didEndBlock = block;
[self runModal];
}
/*!
Runs the receiver modally as an alert sheet attached to a specified window.
@@ -602,6 +728,20 @@ CPCriticalAlertStyle = 2;
[self beginSheetModalForWindow:aWindow modalDelegate:nil didEndSelector:nil contextInfo:nil];
}
/*!
Runs the receiver modally as an alert sheet attached to a specified window.
Executes the code in \c block when the alert is dismissed.
@param window The parent window for the sheet.
@param block Code block to execute on dismissal
*/
- (void)beginSheetModalForWindow:(CPWindow)aWindow didEndBlock:(Function /*(CPAlert alert, int returnCode)*/)block
{
_didEndBlock = block;
[self beginSheetModalForWindow:aWindow modalDelegate:nil didEndSelector:nil contextInfo:nil];
}
#pragma mark Private
/*!
@@ -612,8 +752,9 @@ CPCriticalAlertStyle = 2;
var frame = CGRectMakeZero();
frame.size = [_themeView currentValueForThemeAttribute:@"size"];
_window = [[CPWindow alloc] initWithContentRect:frame styleMask:forceStyle || _defaultWindowStyle];
_window = [[CPPanel alloc] initWithContentRect:frame styleMask:forceStyle || _defaultWindowStyle];
[_window setLevel:CPStatusWindowLevel];
[_window setPlatformWindow:[[CPApp keyWindow] platformWindow]];
if (_title)
[_window setTitle:_title];
@@ -640,8 +781,7 @@ CPCriticalAlertStyle = 2;
*/
- (@action)_showHelp:(id)aSender
{
if ([_delegate respondsToSelector:@selector(alertShowHelp:)])
[_delegate alertShowHelp:self];
[self _sendDelegateAlertShowHelp];
}
/*
@@ -668,84 +808,57 @@ CPCriticalAlertStyle = 2;
*/
- (void)_alertDidEnd:(CPWindow)aWindow returnCode:(int)returnCode contextInfo:(id)contextInfo
{
if (_didEndSelector)
objj_msgSend(_modalDelegate, _didEndSelector, self, returnCode, contextInfo);
if (_didEndBlock)
{
if (typeof(_didEndBlock) === "function")
_didEndBlock(self, returnCode);
else
CPLog.warn("%s: didEnd block is not a function", [self description]);
_modalDelegate = nil;
_didEndSelector = nil;
if ([_delegate respondsToSelector:@selector(alertDidEnd:returnCode:)])
[_delegate alertDidEnd:self returnCode:returnCode];
// didEnd blocks are transient
_didEndBlock = nil;
}
else if (_modalDelegate)
{
if (_didEndSelector)
_modalDelegate.isa.objj_msgSend3(_modalDelegate, _didEndSelector, self, returnCode, contextInfo);
}
else if (_delegate)
{
if (_didEndSelector)
_delegate.isa.objj_msgSend2(_delegate, _didEndSelector, self, returnCode);
else
[self _sendDelegateAlertDidEndReturnCode:returnCode];
}
}
@end
@implementation _CPAlertThemeView : CPView
+ (CPString)defaultThemeClass
@implementation CPAlert (CPAlertDelegate)
/*!
@ignore
Call the delegate alertDidEnd:returnCode
*/
- (void)_sendDelegateAlertDidEndReturnCode:(int)returnCode
{
return @"alert";
if (!(_implementedDelegateMethods & CPAlertDelegate_alertDidEnd_returnCode_))
return;
[_delegate alertDidEnd:self returnCode:returnCode];
}
+ (id)themeAttributes
/*!
@ignore
Call the delegate alertShowHelp:
*/
- (BOOL)_sendDelegateAlertShowHelp
{
return [CPDictionary dictionaryWithObjects:[
CGSizeMake(400.0, 110.0),
CGInsetMake(15, 15, 15, 50), 6, 10,
CPJustifiedTextAlignment,
[CPColor blackColor],
[CPFont boldSystemFontOfSize:13.0],
[CPNull null], CGSizeMakeZero(),
CPJustifiedTextAlignment,
[CPColor blackColor],
[CPFont systemFontOfSize:12.0],
[CPNull null], CGSizeMakeZero(),
CGPointMake(15, 12),
[CPNull null],
[CPNull null],
[CPNull null],
[CPNull null],
[CPNull null],
[CPNull null],
0.0,
0.0,
3.0,
[CPColor blackColor],
[CPFont systemFontOfSize:12.0],
[CPNull null],
0.0
]
forKeys:[
@"size",
@"content-inset",
@"informative-offset",
@"button-offset",
@"message-text-alignment",
@"message-text-color",
@"message-text-font",
@"message-text-shadow-color",
@"message-text-shadow-offset",
@"informative-text-alignment",
@"informative-text-color",
@"informative-text-font",
@"informative-text-shadow-color",
@"informative-text-shadow-offset",
@"image-offset",
@"information-image",
@"warning-image",
@"error-image",
@"help-image",
@"help-image-left-offset",
@"help-image-pressed",
@"suppression-button-y-offset",
@"suppression-button-x-offset",
@"default-elements-margin",
@"suppression-button-text-color",
@"suppression-button-text-font",
@"suppression-button-text-shadow-color",
@"suppression-button-text-shadow-offset"
]
];
if (!(_implementedDelegateMethods & CPAlertDelegate_alertShowHelp_))
return YES;
return [_delegate alertShowHelp:self];
}
@end
+131 -45
View File
@@ -26,25 +26,26 @@
@import "CAMediaTimingFunction.j"
/*
@global
@group CPAnimationCurve
*/
@protocol CPAnimationDelegate <CPObject>
@optional
- (BOOL)animationShouldStart:(CPAnimation)animation;
- (float)animation:(CPAnimation)animation valueForProgress:(float)progress;
- (void)animationDidEnd:(CPAnimation)animation;
- (void)animationDidStop:(CPAnimation)animation;
@end
var CPAnimationDelegate_animationShouldStart_ = 1 << 1,
CPAnimationDelegate_animation_valueForProgress_ = 1 << 2,
CPAnimationDelegate_animationDidEnd_ = 1 << 3,
CPAnimationDelegate_animationDidStop_ = 1 << 4;
@typedef CPAnimationCurve
CPAnimationEaseInOut = 0;
/*
@global
@group CPAnimationCurve
*/
CPAnimationEaseIn = 1;
/*
@global
@group CPAnimationCurve
*/
CPAnimationEaseOut = 2;
/*
@global
@group CPAnimationCurve
*/
CPAnimationLinear = 3;
ACTUAL_FRAME_RATE = 0;
@@ -80,17 +81,18 @@ ACTUAL_FRAME_RATE = 0;
*/
@implementation CPAnimation : CPObject
{
CPTimeInterval _lastTime;
CPTimeInterval _duration;
CPTimeInterval _lastTime;
CPTimeInterval _duration;
CPAnimationCurve _animationCurve;
CAMediaTimingFunction _timingFunction;
CPAnimationCurve _animationCurve;
CAMediaTimingFunction _timingFunction;
float _frameRate;
float _progress;
float _frameRate;
float _progress;
id _delegate;
CPTimer _timer;
id <CPAnimationDelegate> _delegate;
CPTimer _timer;
unsigned _implementedDelegateMethods;
}
/*!
@@ -123,23 +125,29 @@ ACTUAL_FRAME_RATE = 0;
- (void)setAnimationCurve:(CPAnimationCurve)anAnimationCurve
{
var timingFunctionName;
switch (anAnimationCurve)
{
case CPAnimationEaseInOut: timingFunctionName = kCAMediaTimingFunctionEaseInEaseOut;
break;
case CPAnimationEaseInOut:
timingFunctionName = kCAMediaTimingFunctionEaseInEaseOut;
break;
case CPAnimationEaseIn: timingFunctionName = kCAMediaTimingFunctionEaseIn;
break;
case CPAnimationEaseIn:
timingFunctionName = kCAMediaTimingFunctionEaseIn;
break;
case CPAnimationEaseOut: timingFunctionName = kCAMediaTimingFunctionEaseOut;
break;
case CPAnimationEaseOut:
timingFunctionName = kCAMediaTimingFunctionEaseOut;
break;
case CPAnimationLinear: timingFunctionName = kCAMediaTimingFunctionLinear;
break;
case CPAnimationLinear:
timingFunctionName = kCAMediaTimingFunctionLinear;
break;
default: [CPException raise:CPInvalidArgumentException
reason:"Invalid value provided for animation curve"];
break;
default:
[CPException raise:CPInvalidArgumentException
reason:@"Invalid value provided for animation curve"];
break;
}
_animationCurve = anAnimationCurve;
@@ -208,9 +216,25 @@ ACTUAL_FRAME_RATE = 0;
Sets the animation's delegate.
@param aDelegate the new delegate
*/
- (void)setDelegate:(id)aDelegate
- (void)setDelegate:(id <CPAnimationDelegate>)aDelegate
{
if (_delegate === aDelegate)
return;
_delegate = aDelegate;
_implementedDelegateMethods = 0;
if ([_delegate respondsToSelector:@selector(animationShouldStart:)])
_implementedDelegateMethods |= CPAnimationDelegate_animationShouldStart_;
if ([_delegate respondsToSelector:@selector(animationDidEnd:)])
_implementedDelegateMethods |= CPAnimationDelegate_animationDidEnd_;
if ([_delegate respondsToSelector:@selector(animationDidStop:)])
_implementedDelegateMethods |= CPAnimationDelegate_animationDidStop_;
if ([_delegate respondsToSelector:@selector(animation:valueForProgress:)])
_implementedDelegateMethods |= CPAnimationDelegate_animation_valueForProgress_;
}
/*!
@@ -221,7 +245,7 @@ ACTUAL_FRAME_RATE = 0;
- (void)startAnimation
{
// If we're already animating, or our delegate stops us, animate.
if (_timer || _delegate && [_delegate respondsToSelector:@selector(animationShouldStart:)] && ![_delegate animationShouldStart:self])
if (_timer || ![self _sendDelegateAnimationShouldStart])
return;
if (_progress === 1.0)
@@ -230,7 +254,9 @@ ACTUAL_FRAME_RATE = 0;
ACTUAL_FRAME_RATE = 0;
_lastTime = new Date();
_timer = [CPTimer scheduledTimerWithTimeInterval:0.0 target:self selector:@selector(animationTimerDidFire:) userInfo:nil repeats:YES];
var timerInterval = _frameRate <= 0.0 ? 0.0001 : 1.0 / _frameRate;
_timer = [CPTimer scheduledTimerWithTimeInterval:timerInterval target:self selector:@selector(animationTimerDidFire:) userInfo:nil repeats:YES];
}
/*
@@ -252,8 +278,7 @@ ACTUAL_FRAME_RATE = 0;
[_timer invalidate];
_timer = nil;
if ([_delegate respondsToSelector:@selector(animationDidEnd:)])
[_delegate animationDidEnd:self];
[self _sendDelegateAnimationDidEnd];
}
}
@@ -268,8 +293,7 @@ ACTUAL_FRAME_RATE = 0;
[_timer invalidate];
_timer = nil;
if ([_delegate respondsToSelector:@selector(animationDidStop:)])
[_delegate animationDidStop:self];
[self _sendDelegateAnimationDidStop];
}
/*!
@@ -305,8 +329,8 @@ ACTUAL_FRAME_RATE = 0;
{
var t = [self currentProgress];
if ([_delegate respondsToSelector:@selector(animation:valueForProgress:)])
return [_delegate animation:self valueForProgress:t];
if ([self _delegateRespondsToAnimationValueForProgress])
return [self _sendDelegateAnimationValueForProgress:t];
if (_animationCurve == CPAnimationLinear)
return t;
@@ -322,10 +346,72 @@ ACTUAL_FRAME_RATE = 0;
@end
@implementation CPAnimation (CPAnimationDelegate)
/*!
@ignore
Check if the delegate responds to animation:valueForProgress:
*/
- (BOOL)_delegateRespondsToAnimationValueForProgress
{
return _implementedDelegateMethods & CPAnimationDelegate_animation_valueForProgress_;
}
/*!
@ignore
Call delegate animationShouldStart:
*/
- (BOOL)_sendDelegateAnimationShouldStart
{
if (!(_implementedDelegateMethods & CPAnimationDelegate_animationShouldStart_))
return YES;
return [_delegate animationShouldStart:self];
}
/*!
@ignore
Call delegate animation:valueForProgress:
*/
- (float)_sendDelegateAnimationValueForProgress:(float)aProgress
{
if (!(_implementedDelegateMethods & CPAnimationDelegate_animation_valueForProgress_))
return aProgress;
return [_delegate animation:self valueForProgress:aProgress];
}
/*!
@ignore
Call delegate animationDidEnd:
*/
- (void)_sendDelegateAnimationDidEnd
{
if (!(_implementedDelegateMethods & CPAnimationDelegate_animationDidEnd_))
return;
[_delegate animationDidEnd:self];
}
/*!
@ignore
Call delegate animationDidStop:
*/
- (void)_sendDelegateAnimationDidStop
{
if (!(_implementedDelegateMethods & CPAnimationDelegate_animationDidStop_))
return;
[_delegate animationDidStop:self];
}
@end
// currently used function to determine time
// 1:1 conversion to js from webkit source files
// UnitBezier.h, WebCore_animation_AnimationBase.cpp
var CubicBezierAtTime = function CubicBezierAtTime(t, p1x, p1y, p2x, p2y, duration)
var CubicBezierAtTime = function(t, p1x, p1y, p2x, p2y, duration)
{
var ax = 0,
bx = 0,
+162
View File
@@ -0,0 +1,162 @@
/*
* CPAppearance.j
* AppKit
*
* Created by Antoine Mercadal.
* Copyright 2015, Cappuccino Project.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import <Foundation/Foundation.j>
@import "CPTheme.j"
CPAppearanceNameAqua = @"CPAppearanceNameAqua";
CPAppearanceNameLightContent = @"CPAppearanceNameLightContent";
CPAppearanceNameVibrantDark = @"CPAppearanceNameVibrantDark";
CPAppearanceNameVibrantLight = @"CPAppearanceNameVibrantLight";
var _CPAppearanceCurrent = nil,
_CPAppearancesRegistry = @{};
@protocol CPAppearanceCustomization <CPObject>
@required
- (CPAppearance)appearance;
- (void)setAppearance:(CPAppearance)appearance;
- (CPAppearance)effectiveAppearance;
- (void)setEffectiveAppearance:(CPAppearance)appearance;
@end
CPThemeStateAppearanceAqua = CPThemeState("appearance-aqua");
CPThemeStateAppearanceLightContent = CPThemeState("appearance-light-content");
CPThemeStateAppearanceVibrantLight = CPThemeState("appearance-vibrant-light");
CPThemeStateAppearanceVibrantDark = CPThemeState("appearance-vibrant-dark");
/*!
@ingroup appkit
A CPAppareance represents the appearance of an to a subset of UI elements.
This is a very lightweight implementation of the NSAppearance system, but
We are using it for compliance, and especially for the CPVisualEffectView
*/
@implementation CPAppearance : CPObject
{
BOOL _allowsVibrancy @accessors(property=allowsVibrancy);
CPString _name;
}
#pragma mark -
#pragma mark Class Methods
/*! Returns the current default CPAppearance
*/
+ (CPAppearance)currentAppearance
{
if (!_CPAppearanceCurrent)
_CPAppearanceCurrent = [CPAppearance appearanceNamed:CPAppearanceNameAqua];
return _CPAppearanceCurrent;
}
/*! Sets the current default CPAppearance
@param appearance the new current appearance
*/
+ (void)setCurrentAppearance:(CPAppearance)anAppearance
{
_CPAppearanceCurrent = anAppearance;
}
/*! Returns the CPAppearance object with the given name
@param name the name of the appearance
*/
+ (CPAppearance)appearanceNamed:(CPString)aName
{
if (![_CPAppearancesRegistry containsKey:aName])
{
[_CPAppearancesRegistry setObject:[[CPAppearance alloc] initWithAppearanceNamed:aName bundle:nil]
forKey:aName];
}
return [_CPAppearancesRegistry objectForKey:aName];
}
#pragma mark -
#pragma mark Initialization
/*! Creates a CPAppearance object initialized to the specified appearance file in the specified bundle
This method does actually nothing special. It just creates a default appearance object
*/
- (id)initWithAppearanceNamed:(CPString)aName bundle:(CPBundle)bundle
{
if (self = [super init])
{
_name = aName;
_allowsVibrancy = YES;
if ([_CPAppearancesRegistry containsKey:aName])
[CPException raise:CPInternalInconsistencyException reason:"Appearance with name '" + aName + "' is already declared."];
[_CPAppearancesRegistry setObject:self forKey:aName];
}
return self;
}
#pragma mark -
#pragma mark Implementation
- (BOOL)isEqual:(id)anObject
{
if (![anObject isKindOfClass:CPAppearance])
return NO;
return self._name == anObject._name;
}
- (CPString)description
{
return @"<CPAppearance @" + [self UID] + @" name: " + _name + ">";
}
#pragma mark -
#pragma mark CPCoding
- (id)initWithCoder:(CPCoder)aCoder
{
if (self = [super init])
{
_name = [aCoder decodeObjectForKey:@"_name"];
_allowsVibrancy = [aCoder decodeBoolForKey:@"_allowsVibrancy"];
}
return self;
}
- (void)encodeWithCoder:(CPCoder)aCoder
{
[aCoder encodeObject:_name forKey:@"_name"];
[aCoder encodeBool:_allowsVibrancy forKey:@"_allowsVibrancy"];
}
@end
+203 -142
View File
@@ -20,41 +20,48 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#import "../Foundation/CPRange.h"
@import <Foundation/CPBundle.j>
@import "CPApplication_Constants.j"
@import "CPCompatibility.j"
@import "CPColorPanel.j"
@import "CPCursor.j"
@import "CPDocumentController.j"
@import "CPEvent.j"
@import "CPMenu.j"
@import "CPResponder.j"
@import "CPDocumentController.j"
@import "CPThemeBlend.j"
@import "CPCibLoading.j"
@import "CPPanel.j"
@import "CPPlatform.j"
@import "CPWindowController.j"
@import "_CPPopoverWindow.j"
@typedef CPModalSession
var CPMainCibFile = @"CPMainCibFile",
CPMainCibFileHumanFriendly = @"Main cib file base name",
CPEventModifierFlags = 0;
CPApp = nil;
CPApplicationWillFinishLaunchingNotification = @"CPApplicationWillFinishLaunchingNotification";
CPApplicationDidFinishLaunchingNotification = @"CPApplicationDidFinishLaunchingNotification";
CPApplicationWillTerminateNotification = @"CPApplicationWillTerminateNotification";
CPApplicationWillBecomeActiveNotification = @"CPApplicationWillBecomeActiveNotification";
CPApplicationDidBecomeActiveNotification = @"CPApplicationDidBecomeActiveNotification";
CPApplicationWillResignActiveNotification = @"CPApplicationWillResignActiveNotification";
CPApplicationDidResignActiveNotification = @"CPApplicationDidResignActiveNotification";
@protocol CPApplicationDelegate <CPObject>
CPTerminateNow = YES;
CPTerminateCancel = NO;
CPTerminateLater = -1; // not currently supported
@optional
- (CPApplicationTerminateReply)applicationShouldTerminate:(CPApplication)sender;
- (CPString)applicationShouldTerminateMessage:(CPApplication)sender;
- (void)applicationDidBecomeActive:(CPNotification)aNotification;
- (void)applicationDidChangeScreenParameters:(CPNotification)aNotification;
- (void)applicationDidFinishLaunching:(CPNotification)aNotification;
- (void)applicationDidResignActive:(CPNotification)aNotification;
- (void)applicationWillBecomeActive:(CPNotification)aNotification;
- (void)applicationWillFinishLaunching:(CPNotification)aNotification;
- (void)applicationWillResignActive:(CPNotification)aNotification;
- (void)applicationWillTerminate:(CPNotification)aNotification;
CPRunStoppedResponse = -1000;
CPRunAbortedResponse = -1001;
CPRunContinuesResponse = -1002;
@end
var CPApplicationDelegate_applicationShouldTerminate_ = 1 << 0,
CPApplicationDelegate_applicationShouldTerminateMessage_ = 1 << 1;
/*!
@ingroup appkit
@@ -83,35 +90,38 @@ CPRunContinuesResponse = -1002;
*/
@implementation CPApplication : CPResponder
{
CPArray _eventListeners;
CPArray _eventListeners;
int _eventListenerInsertionIndex;
CPEvent _currentEvent;
CPWindow _lastMouseMoveWindow;
CPEvent _currentEvent;
CPWindow _lastMouseMoveWindow;
CPArray _windows;
CPWindow _keyWindow;
CPWindow _mainWindow;
CPWindow _previousKeyWindow;
CPWindow _previousMainWindow;
CPArray _windows;
CPWindow _keyWindow;
CPWindow _mainWindow;
CPWindow _previousKeyWindow;
CPWindow _previousMainWindow;
CPDocumentController _documentController;
CPDocumentController _documentController;
CPModalSession _currentSession;
CPModalSession _currentSession;
//
id _delegate;
BOOL _finishedLaunching;
BOOL _isActive;
id <CPApplicationDelegate> _delegate;
CPInteger _implementedDelegateMethods;
CPDictionary _namedArgs;
CPArray _args;
CPString _fullArgsString;
BOOL _finishedLaunching;
BOOL _isActive;
CPImage _applicationIconImage;
CPDictionary _namedArgs;
CPArray _args;
CPString _fullArgsString;
CPPanel _aboutPanel;
CPImage _applicationIconImage;
CPThemeBlend _themeBlend @accessors(property=themeBlend);
CPPanel _aboutPanel;
CPThemeBlend _themeBlend @accessors(property=themeBlend);
}
/*!
@@ -141,6 +151,7 @@ CPRunContinuesResponse = -1002;
if (self)
{
_eventListeners = [];
_eventListenerInsertionIndex = 0;
_windows = [[CPNull null]];
}
@@ -156,11 +167,13 @@ CPRunContinuesResponse = -1002;
react to these events.
@param aDelegate the delegate object
*/
- (void)setDelegate:(id)aDelegate
- (void)setDelegate:(id <CPApplicationDelegate>)aDelegate
{
if (_delegate == aDelegate)
return;
_implementedDelegateMethods = 0;
var defaultCenter = [CPNotificationCenter defaultCenter],
delegateNotifications =
[
@@ -170,7 +183,8 @@ CPRunContinuesResponse = -1002;
CPApplicationDidBecomeActiveNotification, @selector(applicationDidBecomeActive:),
CPApplicationWillResignActiveNotification, @selector(applicationWillResignActive:),
CPApplicationDidResignActiveNotification, @selector(applicationDidResignActive:),
CPApplicationWillTerminateNotification, @selector(applicationWillTerminate:)
CPApplicationWillTerminateNotification, @selector(applicationWillTerminate:),
CPApplicationDidChangeScreenParametersNotification, @selector(applicationDidChangeScreenParameters:)
],
count = [delegateNotifications count];
@@ -200,6 +214,12 @@ CPRunContinuesResponse = -1002;
if ([_delegate respondsToSelector:selector])
[defaultCenter addObserver:_delegate selector:selector name:notificationName object:self];
}
if ([_delegate respondsToSelector:@selector(applicationShouldTerminate:)])
_implementedDelegateMethods |= CPApplicationDelegate_applicationShouldTerminate_;
if ([_delegate respondsToSelector:@selector(applicationShouldTerminateMessage:)])
_implementedDelegateMethods |= CPApplicationDelegate_applicationShouldTerminateMessage_
}
/*!
@@ -368,22 +388,32 @@ CPRunContinuesResponse = -1002;
applicationVersion = [options objectForKey:@"ApplicationVersion"] || [mainInfo objectForKey:@"CPBundleShortVersionString"],
copyright = [options objectForKey:@"Copyright"] || [mainInfo objectForKey:@"CPHumanReadableCopyright"];
var aboutPanelPath = [[CPBundle bundleForClass:[CPWindowController class]] pathForResource:@"AboutPanel.cib"],
aboutPanelController = [CPWindowController alloc],
aboutPanelController = [aboutPanelController initWithWindowCibPath:aboutPanelPath owner:aboutPanelController],
aboutPanel = [aboutPanelController window],
contentView = [aboutPanel contentView],
imageView = [contentView viewWithTag:1],
applicationLabel = [contentView viewWithTag:2],
versionLabel = [contentView viewWithTag:3],
copyrightLabel = [contentView viewWithTag:4],
standardPath = [[CPBundle bundleForClass:[self class]] pathForResource:@"standardApplicationIcon.png"];
var windowWidth = 275,
windowHeight = 223,
imgWidth = 100,
imgHeight = 100,
interField = 8,
aboutPanel = [[CPWindow alloc] initWithContentRect:CGRectMake(0, 0, windowWidth, windowHeight) styleMask:CPClosableWindowMask],
imageView = [[CPImageView alloc] initWithFrame:CGRectMake((windowWidth / 2) - (imgWidth / 2), interField, imgWidth, imgHeight)],
applicationLabel = [[CPTextField alloc] initWithFrame:CGRectMake(17, imgHeight + 16, windowWidth - 34, 24)],
versionLabel = [[CPTextField alloc] initWithFrame:CGRectMake(17, imgHeight + 48, windowWidth - 34, 16)],
copyrightLabel = [[CPTextField alloc] initWithFrame:CGRectMake(17, imgHeight + 72, windowWidth - 34, 32)],
contentView = [aboutPanel contentView];
// FIXME move this into the CIB eventually
[applicationLabel setFont:[CPFont boldSystemFontOfSize:[CPFont systemFontSize] + 2]];
[applicationLabel setAlignment:CPCenterTextAlignment];
[versionLabel setFont:[CPFont systemFontOfSize:[CPFont systemFontSize] - 1]];
[versionLabel setAlignment:CPCenterTextAlignment];
[copyrightLabel setFont:[CPFont systemFontOfSize:[CPFont systemFontSize] - 1]];
[copyrightLabel setAlignment:CPCenterTextAlignment];
[copyrightLabel setLineBreakMode:CPLineBreakByWordWrapping];
[contentView addSubview:imageView];
[contentView addSubview:applicationLabel];
[contentView addSubview:versionLabel];
[contentView addSubview:copyrightLabel];
var standardPath = [[CPBundle bundleForClass:[self class]] pathForResource:@"standardApplicationIcon.png"];
[imageView setImage:applicationIcon || [[CPImage alloc] initWithContentsOfFile:standardPath
size:CGSizeMake(256, 256)]];
@@ -397,7 +427,7 @@ CPRunContinuesResponse = -1002;
else
[versionLabel setStringValue:@""];
[copyrightLabel setStringValue:copyright || ""];
[copyrightLabel setStringValue:copyright || @""];
[aboutPanel center];
_aboutPanel = aboutPanel;
@@ -407,16 +437,11 @@ CPRunContinuesResponse = -1002;
}
- (void)_documentController:(NSDocumentController *)docController didCloseAll:(BOOL)didCloseAll context:(Object)info
- (void)_documentController:(CPDocumentController)docController didCloseAll:(BOOL)didCloseAll context:(Object)info
{
// callback method for terminate:
if (didCloseAll)
{
if ([_delegate respondsToSelector:@selector(applicationShouldTerminate:)])
[self replyToApplicationShouldTerminate:[_delegate applicationShouldTerminate:self]];
else
[self replyToApplicationShouldTerminate:YES];
}
[self replyToApplicationShouldTerminate:[self _sendDelegateApplicationShouldTerminate]];
}
- (void)replyToApplicationShouldTerminate:(BOOL)terminate
@@ -430,16 +455,22 @@ CPRunContinuesResponse = -1002;
- (void)activateIgnoringOtherApps:(BOOL)shouldIgnoreOtherApps
{
if (_isActive)
return;
[self _willBecomeActive];
[CPPlatform activateIgnoringOtherApps:shouldIgnoreOtherApps];
_isActive = YES;
[self _willResignActive];
[self _didBecomeActive];
}
- (void)deactivate
{
if (!_isActive)
return;
[self _willResignActive];
[CPPlatform deactivate];
@@ -465,6 +496,15 @@ CPRunContinuesResponse = -1002;
- (void)run
{
[self finishLaunching];
[self sendEvent:[CPEvent otherEventWithType:CPAppKitDefined
location:CGPointMakeZero()
modifierFlags:0
timestamp:[CPEvent currentTimestamp]
windowNumber:[_keyWindow windowNumber]
context:nil
subtype:nil
data1:nil
data2:nil]];
}
// Managing the Event Loop
@@ -506,6 +546,8 @@ CPRunContinuesResponse = -1002;
if (_eventListeners[count]._callback === _CPRunModalLoop)
{
_eventListeners.splice(count, 1);
if (count <= _eventListenerInsertionIndex)
_eventListenerInsertionIndex--;
return;
}
@@ -553,7 +595,7 @@ CPRunContinuesResponse = -1002;
// [theWindow._bridge _obscureWindowsBelowModalWindow];
[CPApp setCallback:_CPRunModalLoop forNextEventMatchingMask:CPAnyEventMask untilDate:nil inMode:0 dequeue:NO];
[CPApp setCallback:_CPRunModalLoop forNextEventMatchingMask:CPAnyEventMask untilDate:nil inMode:0 dequeue:YES];
}
/*!
@@ -571,8 +613,8 @@ CPRunContinuesResponse = -1002;
/* @ignore */
- (BOOL)_handleKeyEquivalent:(CPEvent)anEvent
{
return [[self keyWindow] performKeyEquivalent:anEvent] ||
[[self mainMenu] performKeyEquivalent:anEvent];
return [[self keyWindow] performKeyEquivalent:anEvent] ||
[[self mainMenu] performKeyEquivalent:anEvent];
}
/*!
@@ -586,41 +628,10 @@ CPRunContinuesResponse = -1002;
var theWindow = [anEvent window];
#if PLATFORM(DOM)
var willPropagate = [[theWindow platformWindow] _willPropagateCurrentDOMEvent];
// temporarily pretend we won't propagate the event. we'll restore the saved value later
// we do this outside the if so that changes user code might make in _handleKeyEquiv. are preserved
[[theWindow platformWindow] _propagateCurrentDOMEvent:NO];
#endif
// Check if this is a candidate for key equivalent...
if ([anEvent _couldBeKeyEquivalent] && [self _handleKeyEquivalent:anEvent])
{
#if PLATFORM(DOM)
var characters = [anEvent characters],
modifierFlags = [anEvent modifierFlags];
// Unconditionally propagate on these keys to solve browser copy paste bugs
if ((characters == "c" || characters == "x" || characters == "v") && (modifierFlags & CPPlatformActionKeyMask))
[[theWindow platformWindow] _propagateCurrentDOMEvent:YES];
#endif
// The key equivalent was handled.
return;
}
#if PLATFORM(DOM)
// if we make it this far, then restore the original willPropagate value
[[theWindow platformWindow] _propagateCurrentDOMEvent:willPropagate];
#endif
if (_eventListeners.length)
{
if (_eventListeners[_eventListeners.length - 1]._mask & (1 << [anEvent type]))
_eventListeners.pop()._callback(anEvent);
return;
}
if ([anEvent type] == CPMouseMoved)
{
@@ -630,6 +641,34 @@ CPRunContinuesResponse = -1002;
_lastMouseMoveWindow = theWindow;
}
/*
Event listeners are processed from back to front so that newer event listeners normally take
precedence. If during the execution of a callback a new event listener is added, it should
be inserted after the current callback but before any higher priority callbacks. This makes
repeating event listeners (those that reinsert themselves) stable relative to each other.
*/
for (var i = _eventListeners.length - 1; i >= 0; i--)
{
var listener = _eventListeners[i];
if (listener._mask & (1 << [anEvent type]))
{
_eventListeners.splice(i, 1);
// In case the callback wants to add more listeners.
_eventListenerInsertionIndex = i;
listener._callback(anEvent);
if (listener._dequeue)
{
// Don't process the event normally and don't send it to any other listener.
_eventListenerInsertionIndex = _eventListeners.length;
return;
}
}
}
_eventListenerInsertionIndex = _eventListeners.length;
if (theWindow)
[theWindow sendEvent:anEvent];
}
@@ -680,7 +719,7 @@ CPRunContinuesResponse = -1002;
- (CPArray)windows
{
// Return all windows, but not the CPNull placeholder in _windows[0].
return [_windows subarrayWithRange:_CPMakeRange(1, [_windows count] - 1)];
return [_windows subarrayWithRange:CPMakeRange(1, [_windows count] - 1)];
}
/*!
@@ -908,31 +947,44 @@ CPRunContinuesResponse = -1002;
/*!
Fires a callback function when an event matching a given mask occurs.
@param aCallback - A js function to be fired.
@prarm aMask - An event mask for the next event.
@param anExpiration - The date for which this callback expires (not implemented).
If multiple callbacks are set which match the same event, later callbacks
take priority over earlier callbacks, unless a new callback is set while
an existing callback is being processed in which case it's given the same
priority as the currently processing callback.
@param aCallback A js function to be fired.
@prarm aMask An event mask for the next event.
@param anExpiration The date for which this callback expires (not implemented).
@param inMode (not implemented).
@param shouldDequeue (not implemented).
@param shouldDequeue YES to remove the event from the queue after calling the callback,
NO to deliver it normally.
*/
- (void)setCallback:(Function)aCallback forNextEventMatchingMask:(unsigned int)aMask untilDate:(CPDate)anExpiration inMode:(CPString)aMode dequeue:(BOOL)shouldDequeue
{
_eventListeners.push(_CPEventListenerMake(aMask, aCallback));
_eventListeners.splice(_eventListenerInsertionIndex++, 0, _CPEventListenerMake(aMask, aCallback, shouldDequeue));
}
/*!
Assigns a target and action for the next event matching a given event mask.
The callback method called will be passed the CPEvent when it fires.
@param aTarget - The target object for the callback.
@param aSelector - The selector which should be called on the target object.
@param aMask - The mask for a given event which should trigger the callback.
@param anExpiration - The date for which the callback expires (not implemented).
If multiple callbacks are set which match the same event, later callbacks
take priority over earlier callbacks, unless a new callback is set while
an existing callback is being processed in which case it's given the same
priority as the currently processing callback.
@param aTarget The target object for the callback.
@param aSelector The selector which should be called on the target object.
@param aMask The mask for a given event which should trigger the callback.
@param anExpiration The date for which the callback expires (not implemented).
@param aMode (not implemented).
@param shouldDequeue (not implemented).
@param shouldDequeue YES to remove the event from the queue after calling the callback,
NO to deliver it normally.
*/
- (void)setTarget:(id)aTarget selector:(SEL)aSelector forNextEventMatchingMask:(unsigned int)aMask untilDate:(CPDate)anExpiration inMode:(CPString)aMode dequeue:(BOOL)shouldDequeue
{
_eventListeners.push(_CPEventListenerMake(aMask, function (anEvent) { objj_msgSend(aTarget, aSelector, anEvent); }));
_eventListeners.splice(_eventListenerInsertionIndex++, 0, _CPEventListenerMake(aMask, function (anEvent) { if (aTarget != null) aTarget.isa.objj_msgSend1(aTarget, aSelector, anEvent); }, shouldDequeue));
}
/*!
@@ -950,10 +1002,10 @@ CPRunContinuesResponse = -1002;
@param aSheet the window to display as a sheet
@param aWindow the window that will hold the sheet as a child
@param aModalDelegate
@param aDidEndSelector
@param aContextInfo
@param didEndSelector
@param contextInfo
*/
- (void)beginSheet:(CPWindow)aSheet modalForWindow:(CPWindow)aWindow modalDelegate:(id)aModalDelegate didEndSelector:(SEL)aDidEndSelector contextInfo:(id)aContextInfo
- (void)beginSheet:(CPWindow)aSheet modalForWindow:(CPWindow)aWindow modalDelegate:(id)aModalDelegate didEndSelector:(SEL)didEndSelector contextInfo:(id)contextInfo
{
if ([aWindow isSheet])
{
@@ -961,17 +1013,10 @@ CPRunContinuesResponse = -1002;
return;
}
[aSheet._windowView _enableSheet:YES];
if (![aWindow attachedSheet])
[aSheet._windowView _enableSheet:YES inWindow:aWindow];
// -dw- if a sheet is already visible, we skip this since it serves no purpose and causes
// orderOut: to be called on the sheet, which is not what we want.
if (![aWindow isVisible])
{
[aWindow orderFront:self];
[aSheet setPlatformWindow:[aWindow platformWindow]];
}
[aWindow _attachSheet:aSheet modalDelegate:aModalDelegate didEndSelector:aDidEndSelector contextInfo:aContextInfo];
[aWindow _attachSheet:aSheet modalDelegate:aModalDelegate didEndSelector:didEndSelector contextInfo:contextInfo];
}
/*!
@@ -996,7 +1041,7 @@ CPRunContinuesResponse = -1002;
var aWindow = [_windows objectAtIndex:count],
context = aWindow._sheetContext;
if (context != nil && context["sheet"] === sheet)
if (context && context["sheet"] === sheet)
{
context["returnCode"] = returnCode;
[aWindow _endSheet];
@@ -1157,7 +1202,7 @@ CPRunContinuesResponse = -1002;
[[self keyWindow] orderFront:self];
else if ([self mainWindow])
[[self mainWindow] makeKeyAndOrderFront:self];
else
else if ([self mainMenu])
[[self mainMenu]._menuWindow makeKeyWindow]; //FIXME this may not actually work
_previousKeyWindow = nil;
@@ -1175,6 +1220,22 @@ CPRunContinuesResponse = -1002;
userInfo:nil];
}
- (BOOL)_sendDelegateApplicationShouldTerminate
{
if (!(_implementedDelegateMethods & CPApplicationDelegate_applicationShouldTerminate_))
return YES;
return [_delegate applicationShouldTerminate:self];
}
- (CPString)_sendDelegateApplicationShouldTerminateMessage
{
if (!(_implementedDelegateMethods & CPApplicationDelegate_applicationShouldTerminateMessage_))
return @"You have attempted to leave this page. Are you sure you want to exit this page?";
return [_delegate applicationShouldTerminateMessage:self];
}
- (void)_didResignActive
{
if (self._activeMenu)
@@ -1199,7 +1260,7 @@ CPRunContinuesResponse = -1002;
+ (CPString)defaultThemeName
{
return ([[CPBundle mainBundle] objectForInfoDictionaryKey:"CPDefaultTheme"] || @"Aristo");
return ([[CPBundle mainBundle] objectForInfoDictionaryKey:"CPDefaultTheme"] || @"Aristo2");
}
@end
@@ -1209,28 +1270,29 @@ var _CPModalSessionMake = function(aWindow, aStopCode)
return { _window:aWindow, _state:CPRunContinuesResponse , _previous:nil };
};
var _CPEventListenerMake = function(anEventMask, aCallback)
var _CPEventListenerMake = function(anEventMask, aCallback, shouldDequeue)
{
return { _mask:anEventMask, _callback:aCallback };
return { _mask:anEventMask, _callback:aCallback, _dequeue:shouldDequeue };
};
// Make this a global for use in CPPlatformWindow+DOM.j.
_CPRunModalLoop = function(anEvent)
{
[CPApp setCallback:_CPRunModalLoop forNextEventMatchingMask:CPAnyEventMask untilDate:nil inMode:0 dequeue:NO];
[CPApp setCallback:_CPRunModalLoop forNextEventMatchingMask:CPAnyEventMask untilDate:nil inMode:0 dequeue:YES];
var theWindow = [anEvent window],
modalSession = CPApp._currentSession;
// The special case for popovers here is not clear. In Cocoa the popover window does not respond YES to worksWhenModal,
// yet it works when there is a modal window. Maybe it starts its own modal session, but interaction with the original
// modal window seems to continue working as well. Regardless of correctness, this solution beats popovers not working
// at all from sheets.
/*
The special case for popovers here is not clear. In Cocoa the popover window does not respond YES to worksWhenModal, yet it works when there is a modal window. Maybe it starts its own modal session, but interaction with the original modal window seems to continue working as well. Regardless of correctness, this solution beats popovers not working at all from sheets.
*/
if (theWindow == modalSession._window ||
[theWindow worksWhenModal] ||
[theWindow attachedSheet] == modalSession._window || // -dw- allow modal parent of sheet to be repositioned
([theWindow isKindOfClass:_CPAttachedWindow] && [[theWindow targetView] window] === modalSession._window))
([theWindow isKindOfClass:_CPPopoverWindow] && [[theWindow targetView] window] === modalSession._window))
{
[theWindow sendEvent:anEvent];
}
};
/*!
@@ -1296,7 +1358,7 @@ var _CPAppBootstrapperActions = nil;
{
var action = _CPAppBootstrapperActions.shift();
if (objj_msgSend(self, action))
if (self.isa.objj_msgSend0(self, action))
return;
}
@@ -1313,7 +1375,7 @@ var _CPAppBootstrapperActions = nil;
var defaultThemeName = [CPApplication defaultThemeName],
themeURL = nil;
if (defaultThemeName === @"Aristo")
if (defaultThemeName === @"Aristo" || defaultThemeName === @"Aristo2")
themeURL = [[CPBundle bundleForClass:[CPApplication class]] pathForResource:defaultThemeName + @".blend"];
else
themeURL = [[CPBundle mainBundle] pathForResource:defaultThemeName + @".blend"];
@@ -1340,8 +1402,8 @@ var _CPAppBootstrapperActions = nil;
if (mainCibFile)
{
[mainBundle loadCibFile:mainCibFile
externalNameTable:[CPDictionary dictionaryWithObject:CPApp forKey:CPCibOwner]
loadDelegate:self];
externalNameTable:@{ CPCibOwner: CPApp }
loadDelegate:self];
return YES;
}
@@ -1358,26 +1420,25 @@ var _CPAppBootstrapperActions = nil;
// FIXME: We should implement autoenabling.
[mainMenu setAutoenablesItems:NO];
var bundle = [CPBundle bundleForClass:[CPApplication class]],
newMenuItem = [[CPMenuItem alloc] initWithTitle:@"New" action:@selector(newDocument:) keyEquivalent:@"n"];
var newMenuItem = [[CPMenuItem alloc] initWithTitle:@"New" action:@selector(newDocument:) keyEquivalent:@"n"];
[newMenuItem setImage:[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPApplication/New.png"] size:CGSizeMake(16.0, 16.0)]];
[newMenuItem setAlternateImage:[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPApplication/NewHighlighted.png"] size:CGSizeMake(16.0, 16.0)]];
[newMenuItem setImage:[[CPTheme defaultTheme] valueForAttributeWithName:@"menu-general-icon-new" forClass:_CPMenuView]];
[newMenuItem setAlternateImage:[[CPTheme defaultTheme] valueForAttributeWithName:@"menu-general-icon-new" inState:CPThemeStateHighlighted forClass:_CPMenuView]];
[mainMenu addItem:newMenuItem];
var openMenuItem = [[CPMenuItem alloc] initWithTitle:@"Open" action:@selector(openDocument:) keyEquivalent:@"o"];
[openMenuItem setImage:[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPApplication/Open.png"] size:CGSizeMake(16.0, 16.0)]];
[openMenuItem setAlternateImage:[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPApplication/OpenHighlighted.png"] size:CGSizeMake(16.0, 16.0)]];
[openMenuItem setImage:[[CPTheme defaultTheme] valueForAttributeWithName:@"menu-general-icon-open" forClass:_CPMenuView]];
[openMenuItem setAlternateImage:[[CPTheme defaultTheme] valueForAttributeWithName:@"menu-general-icon-open" inState:CPThemeStateHighlighted forClass:_CPMenuView]];
[mainMenu addItem:openMenuItem];
var saveMenu = [[CPMenu alloc] initWithTitle:@"Save"],
saveMenuItem = [[CPMenuItem alloc] initWithTitle:@"Save" action:@selector(saveDocument:) keyEquivalent:nil];
[saveMenuItem setImage:[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPApplication/Save.png"] size:CGSizeMake(16.0, 16.0)]];
[saveMenuItem setAlternateImage:[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPApplication/SaveHighlighted.png"] size:CGSizeMake(16.0, 16.0)]];
[saveMenuItem setImage:[[CPTheme defaultTheme] valueForAttributeWithName:@"menu-general-icon-save" forClass:_CPMenuView]];
[saveMenuItem setAlternateImage:[[CPTheme defaultTheme] valueForAttributeWithName:@"menu-general-icon-save" inState:CPThemeStateHighlighted forClass:_CPMenuView]];
[saveMenu addItem:[[CPMenuItem alloc] initWithTitle:@"Save" action:@selector(saveDocument:) keyEquivalent:@"s"]];
[saveMenu addItem:[[CPMenuItem alloc] initWithTitle:@"Save As" action:@selector(saveDocumentAs:) keyEquivalent:nil]];
@@ -1419,7 +1480,7 @@ var _CPAppBootstrapperActions = nil;
+ (void)cibDidFailToLoad:(CPCib)aCib
{
throw new Error("Could not load main cib file (Did you forget to nib2cib it?).");
throw new Error("Could not load main cib file. Did you forget to nib2cib it?");
}
+ (void)reset
+41
View File
@@ -0,0 +1,41 @@
/*
* CPApplication_Constants.j
* AppKit
*
* Created by Aparajita Fishman.
* Copyright 2013 The Cappuccino Project
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
CPApp = nil;
CPApplicationWillFinishLaunchingNotification = @"CPApplicationWillFinishLaunchingNotification";
CPApplicationDidFinishLaunchingNotification = @"CPApplicationDidFinishLaunchingNotification";
CPApplicationWillTerminateNotification = @"CPApplicationWillTerminateNotification";
CPApplicationWillBecomeActiveNotification = @"CPApplicationWillBecomeActiveNotification";
CPApplicationDidBecomeActiveNotification = @"CPApplicationDidBecomeActiveNotification";
CPApplicationWillResignActiveNotification = @"CPApplicationWillResignActiveNotification";
CPApplicationDidResignActiveNotification = @"CPApplicationDidResignActiveNotification";
CPApplicationDidChangeScreenParametersNotification = @"CPApplicationDidChangeScreenParametersNotification";
@typedef CPApplicationTerminateReply
CPTerminateNow = YES;
CPTerminateCancel = NO;
CPTerminateLater = -1; // not currently supported
CPRunStoppedResponse = -1000;
CPRunAbortedResponse = -1001;
CPRunContinuesResponse = -1002;
+44 -20
View File
@@ -23,7 +23,7 @@
*/
@import <Foundation/CPIndexSet.j>
@import <Foundation/CPPredicate.j>
@import "CPObjectController.j"
@import "CPKeyValueBinding.j"
@@ -65,51 +65,51 @@
+ (CPSet)keyPathsForValuesAffectingContentArray
{
return [CPSet setWithObjects:"content"];
return [CPSet setWithObjects:@"content"];
}
+ (CPSet)keyPathsForValuesAffectingArrangedObjects
{
// Also depends on "filterPredicate" but we'll handle that manually.
return [CPSet setWithObjects:"content", "sortDescriptors"];
return [CPSet setWithObjects:@"content", @"sortDescriptors"];
}
+ (CPSet)keyPathsForValuesAffectingSelection
{
return [CPSet setWithObjects:"selectionIndexes"];
return [CPSet setWithObjects:@"selectionIndexes"];
}
+ (CPSet)keyPathsForValuesAffectingSelectionIndex
{
return [CPSet setWithObjects:"selectionIndexes"];
return [CPSet setWithObjects:@"selectionIndexes"];
}
+ (CPSet)keyPathsForValuesAffectingSelectionIndexes
{
// When the arranged objects change, selection preservation may cause the indexes
// to change.
return [CPSet setWithObjects:"arrangedObjects"];
return [CPSet setWithObjects:@"arrangedObjects"];
}
+ (CPSet)keyPathsForValuesAffectingSelectedObjects
{
// Don't need to depend on arrangedObjects here because selectionIndexes already does.
return [CPSet setWithObjects:"selectionIndexes"];
return [CPSet setWithObjects:@"selectionIndexes"];
}
+ (CPSet)keyPathsForValuesAffectingCanRemove
{
return [CPSet setWithObjects:"selectionIndexes"];
return [CPSet setWithObjects:@"selectionIndexes"];
}
+ (CPSet)keyPathsForValuesAffectingCanSelectNext
{
return [CPSet setWithObjects:"selectionIndexes"];
return [CPSet setWithObjects:@"selectionIndexes"];
}
+ (CPSet)keyPathsForValuesAffectingCanSelectPrevious
{
return [CPSet setWithObjects:"selectionIndexes"];
return [CPSet setWithObjects:@"selectionIndexes"];
}
@@ -563,7 +563,7 @@
*/
- (BOOL)setSelectionIndexes:(CPIndexSet)indexes
{
[self _selectionWillChange]
[self _selectionWillChange];
var r = [self __setSelectionIndexes:indexes avoidEmpty:NO];
[self _selectionDidChange];
return r;
@@ -744,6 +744,7 @@
return;
var willClearPredicate = NO;
if (_clearsFilterPredicateOnInsertion && _filterPredicate)
{
[self willChangeValueForKey:@"filterPredicate"];
@@ -792,10 +793,18 @@
// not appear in arrangedObjects and we do not have to update at all.
*/
// This will also send notificaitons for arrangedObjects.
// TODO: Remove these lines when granular notifications are implemented
var proxy = [_CPKVOProxy proxyForObject:self];
[proxy setAdding:YES];
// This will also send notifications for arrangedObjects.
[self didChangeValueForKey:@"content"];
if (willClearPredicate)
[self didChangeValueForKey:@"filterPredicate"];
// TODO: Remove this line when granular notifications are implemented
[proxy setAdding:NO];
}
/*!
@@ -811,6 +820,7 @@
return;
var willClearPredicate = NO;
if (_clearsFilterPredicateOnInsertion && _filterPredicate)
{
[self willChangeValueForKey:@"filterPredicate"];
@@ -848,9 +858,15 @@
if ([self avoidsEmptySelection] && [[self selectionIndexes] count] <= 0 && [_contentObject count] > 0)
[self __setSelectionIndexes:[CPIndexSet indexSetWithIndex:0]];
var proxy = [_CPKVOProxy proxyForObject:self];
[proxy setAdding:YES];
[self didChangeValueForKey:@"content"];
if (willClearPredicate)
[self didChangeValueForKey:@"filterPredicate"];
[proxy setAdding:NO];
}
/*!
@@ -897,7 +913,9 @@
if (![self canAdd])
return;
[self insert:sender];
var newObject = [self automaticallyPreparesContent] ? [self newObject] : [self _defaultNewObject];
[self addObject:newObject];
}
/*!
@@ -909,9 +927,13 @@
if (![self canInsert])
return;
var newObject = [self automaticallyPreparesContent] ? [self newObject] : [self _defaultNewObject];
var newObject = [self automaticallyPreparesContent] ? [self newObject] : [self _defaultNewObject],
lastSelectedIndex = [_selectionIndexes lastIndex];
[self addObject:newObject];
if (lastSelectedIndex !== CPNotFound)
[self insertObject:newObject atArrangedObjectIndex:lastSelectedIndex];
else
[self addObject:newObject];
}
/*!
@@ -964,7 +986,7 @@
// be the 'wrong' one - as in not the one the user selected - but the wrong
// one is still just another pointer to the same object, so the user will not
// be able to see any difference.
contentIndex = [_contentObject indexOfObjectIdenticalTo:object];
var contentIndex = [_contentObject indexOfObjectIdenticalTo:object];
[_contentObject removeObjectAtIndex:contentIndex];
}
[arrangedObjects removeObjectAtIndex:anIndex];
@@ -1073,12 +1095,12 @@
@implementation CPArrayController (CPBinder)
+ (Class)_binderClassForBinding:(CPString)theBinding
+ (Class)_binderClassForBinding:(CPString)aBinding
{
if (theBinding == @"contentArray")
if (aBinding == @"contentArray")
return [_CPArrayControllerContentBinder class];
return [super _binderClassForBinding:theBinding];
return [super _binderClassForBinding:aBinding];
}
@end
@@ -1093,7 +1115,8 @@
isCompound = [self handlesContentAsCompoundValue],
dotIndex = keyPath.lastIndexOf("."),
firstPart = dotIndex !== CPNotFound ? keyPath.substring(0, dotIndex) : nil,
isSelectionProxy = firstPart && [[destination valueForKeyPath:firstPart] isKindOfClass:CPControllerSelectionProxy];
isSelectionProxy = firstPart && [[destination valueForKeyPath:firstPart] isKindOfClass:CPControllerSelectionProxy],
newValue;
if (!isCompound && !isSelectionProxy)
{
@@ -1113,6 +1136,7 @@
}
var isPlaceholder = CPIsControllerMarker(newValue);
if (isPlaceholder)
{
if (newValue === CPNotApplicableMarker && [options objectForKey:CPRaisesForNotApplicableKeysBindingOption])
+59 -5
View File
@@ -48,6 +48,8 @@ var DefaultLineWidth = 1.0;
{
CGPath _path;
float _lineWidth;
CPArray _lineDashes;
float _lineDashesPhase;
}
/*!
@@ -61,11 +63,11 @@ var DefaultLineWidth = 1.0;
/*!
Create a new CPBezierPath object initialized with an oval path drawn within a rectangular path.
*/
+ (CPBezierPath)bezierPathWithOvalInRect:(CGRect)rect
+ (CPBezierPath)bezierPathWithOvalInRect:(CGRect)aRect
{
var path = [self bezierPath];
[path appendBezierPathWithOvalInRect:rect];
[path appendBezierPathWithOvalInRect:aRect];
return path;
}
@@ -73,11 +75,20 @@ var DefaultLineWidth = 1.0;
/*!
Create a new CPBezierPath object initialized with a rectangular path.
*/
+ (CPBezierPath)bezierPathWithRect:(CGRect)rect
+ (CPBezierPath)bezierPathWithRect:(CGRect)aRect
{
var path = [self bezierPath];
[path appendBezierPathWithRect:rect];
[path appendBezierPathWithRect:aRect];
return path;
}
+ (CPBezierPath)bezierPathWithRoundedRect:(CGRect)aRect xRadius:(float)xRadius yRadius:(float)yRadius
{
var path = [self bezierPath];
[path appendBezierPathWithRoundedRect:aRect xRadius:xRadius yRadius:yRadius];
return path;
}
@@ -136,6 +147,8 @@ var DefaultLineWidth = 1.0;
{
_path = CGPathCreateMutable();
_lineWidth = [[self class] defaultLineWidth];
_lineDashesPhase = 0;
_lineDashes = [];
}
return self;
@@ -168,7 +181,7 @@ var DefaultLineWidth = 1.0;
- (CGRect)bounds
{
// TODO: this should return this. The controlPointBounds is not a tight fit.
// return CGPathGetPathBoundingBox(_path);
// return CGPathGetBoundingBox(_path);
return [self controlPointBounds];
}
@@ -196,6 +209,7 @@ var DefaultLineWidth = 1.0;
CGContextBeginPath(ctx);
CGContextAddPath(ctx, _path);
CGContextSetLineWidth(ctx, [self lineWidth]);
CGContextSetLineDash(ctx, _lineDashesPhase, _lineDashes);
CGContextStrokePath(ctx);
}
@@ -209,10 +223,50 @@ var DefaultLineWidth = 1.0;
CGContextBeginPath(ctx);
CGContextAddPath(ctx, _path);
CGContextSetLineWidth(ctx, [self lineWidth]);
CGContextSetLineDash(ctx, _lineDashesPhase, _lineDashes);
CGContextClosePath(ctx);
CGContextFillPath(ctx);
}
/*!
Cocoa compatibility.
*/
- (void)getLineDash:(CPArrayRef)patternRef count:(NSInteger)count phase:(CGFloatRef)phaseRef
{
return [self getLineDash:patternRef phase:phaseRef];
}
/*!
Retrieve the line dash pattern and phase and write them into the provided references.
*/
- (void)getLineDash:(CPArrayRef)patternRef phase:(CGFloatRef)phaseRef
{
if (patternRef)
@deref(patternRef) = [_lineDashes copy];
if (phaseRef)
@deref(phaseRef) = _lineDashesPhase;
}
/*!
Cocoa compatibility.
*/
- (void)setLineDash:(CPArray)aPattern count:(NSInteger)count phase:(CGFloat)aPhase
{
[self setLineDash:aPattern phase:aPhase];
}
/*!
Set stroke line dash pattern.
@param aPattern an array of stroke-skip lengths such as [2, 2, 4, 4]
@param aPhase amount of shift for the starting position of the first stroke
*/
- (void)setLineDash:(CPArray)aPattern phase:(CGFloat)aPhase
{
_lineDashes = aPattern;
_lineDashesPhase = aPhase;
}
/*!
Get the line width.
*/
+186 -104
View File
@@ -20,9 +20,11 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "CPTextField.j"
@import "CPView.j"
// CPBoxType
@typedef CPBoxType
CPBoxPrimary = 0;
CPBoxSecondary = 1;
CPBoxSeparator = 2;
@@ -30,12 +32,14 @@ CPBoxOldStyle = 3;
CPBoxCustom = 4;
// CPBorderType
@typedef CPBorderType
CPNoBorder = 0;
CPLineBorder = 1;
CPBezelBorder = 2;
CPGrooveBorder = 3;
// CPTitlePosition
@typedef CPTitlePosition
CPNoTitle = 0;
CPAboveTop = 1;
CPAtTop = 2;
@@ -55,14 +59,6 @@ CPBelowBottom = 6;
{
CPBoxType _boxType;
CPBorderType _borderType;
CPColor _borderColor;
CPColor _fillColor;
float _cornerRadius;
float _borderWidth;
CPSize _contentMargin;
CPView _contentView;
CPString _title @accessors(getter=title);
@@ -70,6 +66,33 @@ CPBelowBottom = 6;
CPTextField _titleView;
}
+ (Class)_binderClassForBinding:(CPString)aBinding
{
if ([aBinding hasPrefix:CPDisplayPatternTitleBinding])
return [CPTitleWithPatternBinding class];
return [super _binderClassForBinding:aBinding];
}
+ (CPString)defaultThemeClass
{
return @"box";
}
+ (CPDictionary)themeAttributes
{
return @{
@"background-color": [CPNull null],
@"border-color": [CPNull null],
@"border-width": 1.0,
@"corner-radius": 3.0,
@"inner-shadow-offset": CGSizeMakeZero(),
@"inner-shadow-size": 6.0,
@"inner-shadow-color": [CPNull null],
@"content-margin": CGSizeMakeZero(),
};
}
+ (id)boxEnclosingView:(CPView)aView
{
var box = [[self alloc] initWithFrame:CGRectMakeZero()],
@@ -85,18 +108,13 @@ CPBelowBottom = 6;
return box;
}
- (id)initWithFrame:(CPRect)frameRect
- (id)initWithFrame:(CGRect)frameRect
{
self = [super initWithFrame:frameRect];
if (self)
{
_borderType = CPBezelBorder;
_fillColor = [CPColor clearColor];
_borderColor = [CPColor blackColor];
_borderWidth = 1.0;
_contentMargin = CGSizeMake(0.0, 0.0);
_titlePosition = CPNoTitle;
_titleView = [CPTextField labelWithTitle:@""];
@@ -118,7 +136,7 @@ CPBelowBottom = 6;
@return the border rectangle of the box
*/
- (CPRect)borderRect
- (CGRect)borderRect
{
return [self bounds];
}
@@ -208,58 +226,54 @@ CPBelowBottom = 6;
- (CPColor)borderColor
{
return _borderColor;
return [self valueForThemeAttribute:@"border-color"];
}
- (void)setBorderColor:(CPColor)color
{
if ([color isEqual:_borderColor])
if ([color isEqual:[self borderColor]])
return;
_borderColor = color;
[self setNeedsDisplay:YES];
[self setValue:color forThemeAttribute:@"border-color"];
}
- (float)borderWidth
{
return _borderWidth;
return [self valueForThemeAttribute:@"border-width"];
}
- (void)setBorderWidth:(float)width
{
if (width === _borderWidth)
if (width === [self borderWidth])
return;
_borderWidth = width;
[self setNeedsDisplay:YES];
[self setValue:width forThemeAttribute:@"border-width"];
}
- (float)cornerRadius
{
return _cornerRadius;
return [self valueForThemeAttribute:@"corner-radius"];
}
- (void)setCornerRadius:(float)radius
{
if (radius === _cornerRadius)
if (radius === [self cornerRadius])
return;
_cornerRadius = radius;
[self setNeedsDisplay:YES];
[self setValue:radius forThemeAttribute:@"corner-radius"];
}
- (CPColor)fillColor
{
return _fillColor;
return [self valueForThemeAttribute:@"background-color"];
}
- (void)setFillColor:(CPColor)color
{
if ([color isEqual:_fillColor])
if ([color isEqual:[self fillColor]])
return;
_fillColor = color;
[self setNeedsDisplay:YES];
[self setValue:color forThemeAttribute:@"background-color"];
}
- (CPView)contentView
@@ -272,34 +286,43 @@ CPBelowBottom = 6;
if (aView === _contentView)
return;
[aView setFrame:CGRectInset([self bounds], _contentMargin.width + _borderWidth, _contentMargin.height + _borderWidth)];
var borderWidth = [self borderWidth],
contentMargin = [self valueForThemeAttribute:@"content-margin"];
[aView setFrame:CGRectInset([self bounds], contentMargin.width + borderWidth, contentMargin.height + borderWidth)];
[aView setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
[self replaceSubview:_contentView with:aView];
// A nil contentView is allowed (tested in Cocoa 2013-02-22).
if (!aView)
[_contentView removeFromSuperview];
else if (_contentView)
[self replaceSubview:_contentView with:aView];
else
[self addSubview:aView];
_contentView = aView;
}
- (CPSize)contentViewMargins
- (CGSize)contentViewMargins
{
return _contentMargin;
return [self valueForThemeAttribute:@"content-margin"];
}
- (void)setContentViewMargins:(CPSize)size
- (void)setContentViewMargins:(CGSize)size
{
if (size.width < 0 || size.height < 0)
[CPException raise:CPGenericException reason:@"Margins must be positive"];
_contentMargin = CGSizeMakeCopy(size);
[self setNeedsDisplay:YES];
[self setValue:CGSizeMakeCopy(size) forThemeAttribute:@"content-margin"];
}
- (void)setFrameFromContentFrame:(CPRect)aRect
- (void)setFrameFromContentFrame:(CGRect)aRect
{
var offset = [self _titleHeightOffset];
var offset = [self _titleHeightOffset],
borderWidth = [self borderWidth],
contentMargin = [self valueForThemeAttribute:@"content-margin"];
[self setFrame:CGRectInset(aRect, -(_contentMargin.width + _borderWidth), -(_contentMargin.height + offset[0] + _borderWidth))];
[self setNeedsDisplay:YES];
[self setFrame:CGRectInset(aRect, -(contentMargin.width + borderWidth), -(contentMargin.height + offset[0] + borderWidth))];
}
- (void)setTitle:(CPString)aTitle
@@ -360,7 +383,7 @@ CPBelowBottom = 6;
case CPAtTop:
case CPAboveTop:
case CPBelowTop:
[_titleView setFrameOrigin:CPPointMake(5.0, 0.0)];
[_titleView setFrameOrigin:CGPointMake(5.0, 0.0)];
[_titleView setAutoresizingMask:CPViewNotSizable];
break;
@@ -368,7 +391,7 @@ CPBelowBottom = 6;
case CPAtBottom:
case CPBelowBottom:
var h = [_titleView frameSize].height;
[_titleView setFrameOrigin:CPPointMake(5.0, [self frameSize].height - h)];
[_titleView setFrameOrigin:CGPointMake(5.0, [self frameSize].height - h)];
[_titleView setAutoresizingMask:CPViewMinYMargin];
break;
}
@@ -380,17 +403,13 @@ CPBelowBottom = 6;
- (void)sizeToFit
{
var contentFrame = [_contentView frame],
offset = [self _titleHeightOffset];
offset = [self _titleHeightOffset],
contentMargin = [self valueForThemeAttribute:@"content-margin"];
if (!contentFrame)
return;
[_contentView setAutoresizingMask:CPViewNotSizable];
[self setFrameSize:CGSizeMake(contentFrame.size.width + _contentMargin.width * 2,
contentFrame.size.height + _contentMargin.height * 2 + offset[0])];
[_contentView setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
[_contentView setFrameOrigin:CGPointMake(_contentMargin.width, _contentMargin.height + offset[1])];
[_contentView setFrameOrigin:CGPointMake(contentMargin.width, contentMargin.height + offset[1])];
}
- (float)_titleHeightOffset
@@ -411,12 +430,17 @@ CPBelowBottom = 6;
}
}
- (void)drawRect:(CPRect)rect
- (void)setValue:(id)aValue forKey:(CPString)aKey
{
if (_borderType === CPNoBorder)
return;
if (aKey === CPDisplayPatternTitleBinding)
[self setTitle:aValue || @""];
else
[super setValue:aValue forKey:aKey];
}
var bounds = CGRectMakeCopy([self bounds]);
- (void)drawRect:(CGRect)rect
{
var bounds = [self bounds];
switch (_boxType)
{
@@ -424,9 +448,9 @@ CPBelowBottom = 6;
// NSBox does not include a horizontal flag for the separator type. We have to determine
// the type of separator to draw by the width and height of the frame.
if (CGRectGetWidth(bounds) === 5.0)
return [self _drawVerticalSeperatorInRect:bounds];
return [self _drawVerticalSeparatorInRect:bounds];
else if (CGRectGetHeight(bounds) === 5.0)
return [self _drawHorizontalSeperatorInRect:bounds];
return [self _drawHorizontalSeparatorInRect:bounds];
break;
}
@@ -441,84 +465,141 @@ CPBelowBottom = 6;
bounds.size.height -= [_titleView frameSize].height;
}
// Primary or secondary type boxes always draw the same way, unless they are CPNoBorder.
if ((_boxType === CPBoxPrimary || _boxType === CPBoxSecondary) && _borderType !== CPNoBorder)
{
[self _drawPrimaryBorderInRect:bounds];
return;
}
switch (_borderType)
{
case CPBezelBorder:
[self _drawBezelBorderInRect:bounds];
break;
default:
case CPGrooveBorder:
case CPLineBorder:
[self _drawLineBorderInRect:bounds];
break;
case CPNoBorder:
[self _drawNoBorderInRect:bounds];
break;
}
}
- (void)_drawHorizontalSeperatorInRect:(CGRect)aRect
- (void)_drawHorizontalSeparatorInRect:(CGRect)aRect
{
var context = [[CPGraphicsContext currentContext] graphicsPort];
CGContextSetStrokeColor(context, [self borderColor]);
CGContextSetLineWidth(context, 1.0);
CGContextMoveToPoint(context, CGRectGetMinX(aRect), CGRectGetMinY(aRect) + 0.5);
CGContextAddLineToPoint(context, CGRectGetWidth(aRect), CGRectGetMinY(aRect) + 0.5);
CGContextMoveToPoint(context, CGRectGetMinX(aRect), CGRectGetMidY(aRect));
CGContextAddLineToPoint(context, CGRectGetWidth(aRect), CGRectGetMidY(aRect));
CGContextStrokePath(context);
}
- (void)_drawVerticalSeperatorInRect:(CGRect)aRect
- (void)_drawVerticalSeparatorInRect:(CGRect)aRect
{
var context = [[CPGraphicsContext currentContext] graphicsPort];
CGContextSetStrokeColor(context, [self borderColor]);
CGContextSetLineWidth(context, 1.0);
CGContextMoveToPoint(context, CGRectGetMinX(aRect) + 0.5, CGRectGetMinY(aRect));
CGContextAddLineToPoint(context, CGRectGetMinX(aRect) + 0.5, CGRectGetHeight(aRect));
CGContextMoveToPoint(context, CGRectGetMidX(aRect), CGRectGetMinY(aRect));
CGContextAddLineToPoint(context, CGRectGetMidX(aRect), CGRectGetHeight(aRect));
CGContextStrokePath(context);
}
- (void)_drawLineBorderInRect:(CGRect)aRect
{
var context = [[CPGraphicsContext currentContext] graphicsPort],
cornerRadius = [self cornerRadius],
borderWidth = [self borderWidth];
aRect = CGRectInset(aRect, borderWidth / 2.0, borderWidth / 2.0);
CGContextSetFillColor(context, [self fillColor]);
CGContextSetStrokeColor(context, [self borderColor]);
CGContextSetLineWidth(context, borderWidth);
CGContextFillRoundedRectangleInRect(context, aRect, cornerRadius, YES, YES, YES, YES);
CGContextStrokeRoundedRectangleInRect(context, aRect, cornerRadius, YES, YES, YES, YES);
}
- (void)_drawBezelBorderInRect:(CGRect)aRect
{
var context = [[CPGraphicsContext currentContext] graphicsPort],
sides = [CPMinYEdge, CPMaxXEdge, CPMaxYEdge, CPMinXEdge],
sideGray = 190.0 / 255.0,
grays = [142.0 / 255.0, sideGray, sideGray, sideGray],
borderWidth = _borderWidth;
cornerRadius = [self cornerRadius],
borderWidth = [self borderWidth],
shadowOffset = [self valueForThemeAttribute:@"inner-shadow-offset"],
shadowSize = [self valueForThemeAttribute:@"inner-shadow-size"],
shadowColor = [self valueForThemeAttribute:@"inner-shadow-color"];
while (borderWidth--)
aRect = CPDrawTiledRects(aRect, aRect, sides, grays);
var baseRect = aRect;
aRect = CGRectInset(aRect, borderWidth / 2.0, borderWidth / 2.0);
CGContextSaveGState(context);
CGContextSetStrokeColor(context, [self borderColor]);
CGContextSetLineWidth(context, borderWidth);
CGContextSetFillColor(context, [self fillColor]);
CGContextFillRect(context, aRect);
CGContextFillRoundedRectangleInRect(context, aRect, cornerRadius, YES, YES, YES, YES);
CGContextStrokeRoundedRectangleInRect(context, aRect, cornerRadius, YES, YES, YES, YES);
CGContextRestoreGState(context);
}
- (void)_drawLineBorderInRect:(CGRect)aRect
- (void)_drawPrimaryBorderInRect:(CGRect)aRect
{
// Draw the "primary" style CPBox.
var context = [[CPGraphicsContext currentContext] graphicsPort],
cornerRadius = [self cornerRadius],
borderWidth = [self borderWidth],
shadowOffset = [self valueForThemeAttribute:@"inner-shadow-offset"],
shadowSize = [self valueForThemeAttribute:@"inner-shadow-size"],
shadowColor = [self valueForThemeAttribute:@"inner-shadow-color"],
baseRect = aRect;
aRect = CGRectInset(aRect, borderWidth / 2.0, borderWidth / 2.0);
CGContextSaveGState(context);
CGContextSetStrokeColor(context, [self borderColor]);
CGContextSetLineWidth(context, borderWidth);
CGContextSetFillColor(context, [self fillColor]);
CGContextFillRoundedRectangleInRect(context, aRect, cornerRadius, YES, YES, YES, YES);
CGContextBeginPath(context);
// Note we can't use the 0.5 inset rectangle when setting up clipping. The clipping has to be
// on integer coordinates for this to look right in Chrome.
CGContextAddPath(context, CGPathWithRoundedRectangleInRect(baseRect, cornerRadius, cornerRadius, YES, YES, YES, YES));
CGContextClip(context);
CGContextSetShadowWithColor(context, shadowOffset, shadowSize, shadowColor);
CGContextStrokeRoundedRectangleInRect(context, aRect, cornerRadius, YES, YES, YES, YES);
CGContextRestoreGState(context);
}
- (void)_drawNoBorderInRect:(CGRect)aRect
{
var context = [[CPGraphicsContext currentContext] graphicsPort];
aRect = CGRectInset(aRect, _borderWidth / 2.0, _borderWidth / 2.0);
CGContextSetFillColor(context, [self fillColor]);
CGContextSetStrokeColor(context, [self borderColor]);
CGContextSetLineWidth(context, _borderWidth);
CGContextFillRoundedRectangleInRect(context, aRect, _cornerRadius, YES, YES, YES, YES);
CGContextStrokeRoundedRectangleInRect(context, aRect, _cornerRadius, YES, YES, YES, YES);
CGContextFillRect(context, aRect);
}
@end
var CPBoxTypeKey = @"CPBoxTypeKey",
CPBoxBorderTypeKey = @"CPBoxBorderTypeKey",
CPBoxBorderColorKey = @"CPBoxBorderColorKey",
CPBoxFillColorKey = @"CPBoxFillColorKey",
CPBoxCornerRadiusKey = @"CPBoxCornerRadiusKey",
CPBoxBorderWidthKey = @"CPBoxBorderWidthKey",
CPBoxContentMarginKey = @"CPBoxContentMarginKey",
CPBoxTitle = @"CPBoxTitle",
CPBoxTitlePosition = @"CPBoxTitlePosition",
CPBoxTitleView = @"CPBoxTitleView";
CPBoxTitleView = @"CPBoxTitleView",
CPBoxContentView = @"CPBoxContentView";
@implementation CPBox (CPCoding)
@@ -531,20 +612,29 @@ var CPBoxTypeKey = @"CPBoxTypeKey",
_boxType = [aCoder decodeIntForKey:CPBoxTypeKey];
_borderType = [aCoder decodeIntForKey:CPBoxBorderTypeKey];
_borderColor = [aCoder decodeObjectForKey:CPBoxBorderColorKey];
_fillColor = [aCoder decodeObjectForKey:CPBoxFillColorKey];
_cornerRadius = [aCoder decodeFloatForKey:CPBoxCornerRadiusKey];
_borderWidth = [aCoder decodeFloatForKey:CPBoxBorderWidthKey];
_contentMargin = [aCoder decodeSizeForKey:CPBoxContentMarginKey];
_title = [aCoder decodeObjectForKey:CPBoxTitle];
_titlePosition = [aCoder decodeIntForKey:CPBoxTitlePosition];
_titleView = [aCoder decodeObjectForKey:CPBoxTitleView] || [CPTextField labelWithTitle:_title];
_contentView = [self subviews][0];
if (_boxType != CPBoxSeparator)
{
// FIXME: we have a problem with CIB decoding here.
// We should be able to simply add : _contentView = [self subviews][0]
// but first box subview seems to be malformed (badly decoded).
// For example, when deployed, this view doesn't have its _trackingAreas array initialized.
// As a (temporary) workaround, we encode/decode the _contentView property. We then transfer the subview hierarchy
// and replace the first (and only) box subview with this _contentView
_contentView = [aCoder decodeObjectForKey:CPBoxContentView] || [[CPView alloc] initWithFrame:[self bounds]];
var malformedContentView = [self subviews][0];
[_contentView setSubviews:[malformedContentView subviews]];
[self replaceSubview:malformedContentView with:_contentView];
}
else
{
_titlePosition = CPNoTitle;
}
[self setAutoresizesSubviews:YES];
[_contentView setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
@@ -560,18 +650,10 @@ var CPBoxTypeKey = @"CPBoxTypeKey",
[aCoder encodeInt:_boxType forKey:CPBoxTypeKey];
[aCoder encodeInt:_borderType forKey:CPBoxBorderTypeKey];
[aCoder encodeObject:_borderColor forKey:CPBoxBorderColorKey];
[aCoder encodeObject:_fillColor forKey:CPBoxFillColorKey];
[aCoder encodeFloat:_cornerRadius forKey:CPBoxCornerRadiusKey];
[aCoder encodeFloat:_borderWidth forKey:CPBoxBorderWidthKey];
[aCoder encodeObject:_title forKey:CPBoxTitle];
[aCoder encodeInt:_titlePosition forKey:CPBoxTitlePosition];
[aCoder encodeObject:_titleView forKey:CPBoxTitleView];
[aCoder encodeSize:_contentMargin forKey:CPBoxContentMarginKey];
[aCoder encodeObject:_contentView forKey:CPBoxContentView];
}
@end
+316 -134
View File
@@ -20,63 +20,111 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import <Foundation/CPObject.j>
@import <Foundation/CPIndexSet.j>
@import "CPControl.j"
@import "CPImage.j"
@import "CPScrollView.j"
@import "CPTableView.j"
@import "CPTextField.j"
@import "CPScrollView.j"
@global CPApp
@protocol CPBrowserDelegate <CPObject>
@optional
- (BOOL)browser:(CPBrowser)browser acceptDrop:(id)info atRow:(CPInteger)row column:(CPInteger)column dropOperation:(CPTableViewDropOperation)dropOperation;
- (BOOL)browser:(CPBrowser)browser canDragRowsWithIndexes:(CPIndexSet)rowIndexes inColumn:(CPInteger)column withEvent:(CPEvent )event;
- (BOOL)browser:(CPBrowser)browser isLeafItem:(id)item;
- (BOOL)browser:(CPBrowser)browser shouldSelectRowIndexes:(CPIndexSet)anIndexSet inColumn:(CPInteger)column;
- (BOOL)browser:(CPBrowser)browser writeRowsWithIndexes:(CPIndexSet)rowIndexes inColumn:(CPInteger)column toPasteboard:(CPPasteboard)pasteboard;
- (CPDragOperation)browser:(CPBrowser)browser validateDrop:(id)info proposedRow:(CPInteger)row column:(CPInteger)column dropOperation:(CPTableViewDropOperation)dropOperation;
- (CPImage)browser:(CPBrowser)browser imageValueForItem:(id)anItem;
- (CPImage)browser:(CPBrowser)browser draggingImageForRowsWithIndexes:(CPIndexSet)rowIndexes inColumn:(CPInteger)column withEvent:(CPEvent)event offset:(CGPoint)dragImageOffset;
- (CPImage)browser:(CPBrowser)browser imageValueForItem:(id)item;
- (CPIndexSet)browser:(CPBrowser)browser selectionIndexesForProposedSelection:(CPIndexSet)proposedSelectionIndexes inColumn:(CPInteger)column;
- (CPInteger)browser:(CPBrowser)browser numberOfChildrenOfItem:(id)item;
- (CPView)browser:(CPBrowser)browser draggingViewForRowsWithIndexes:(CPIndexSet)rowIndexes inColumn:(CPInteger)column withEvent:(CPEvent)event offset:(CGPoint)dragImageOffset;
- (id)browser:(CPBrowser)browser child:(CPInteger)index ofItem:(id)item;
- (id)browser:(CPBrowser)browser objectValueForItem:(id)item;
- (id)rootItemForBrowser:(CPBrowser)browser;
- (void)browser:(CPBrowser)browser didChangeLastColumn:(CPInteger)oldLastColumn toColumn:(CPInteger)column;
- (void)browser:(CPBrowser)browser didResizeColumn:(CPInteger)column;
- (void)browserSelectionIsChanging:(CPBrowser)browser;
- (void)browserSelectionDidChange:(CPBrowser)browser;
@end
var CPBrowserDelegate_browser_acceptDrop_atRow_column_dropOperation_ = 1 << 1,
CPBrowserDelegate_browser_canDragRowsWithIndexes_inColumn_withEvent_ = 1 << 2,
CPBrowserDelegate_browser_isLeafItem_ = 1 << 3,
CPBrowserDelegate_browser_shouldSelectRowIndexes_inColumn_ = 1 << 4,
CPBrowserDelegate_browser_writeRowsWithIndexes_inColumn_toPasteboard_ = 1 << 5,
CPBrowserDelegate_browser_validateDrop_proposedRow_column_dropOperation_ = 1 << 6,
CPBrowserDelegate_browser_imageValueForItem_ = 1 << 7,
CPBrowserDelegate_browser_draggingImageForRowsWithIndexes_inColumn_withEvent_offset_ = 1 << 8,
CPBrowserDelegate_browser_imageValueForItem_ = 1 << 9,
CPBrowserDelegate_browser_selectionIndexesForProposedSelection_inColumn_ = 1 << 10,
CPBrowserDelegate_browser_numberOfChildrenOfItem_ = 1 << 11,
CPBrowserDelegate_browser_draggingViewForRowsWithIndexes_inColumn_withEvent_offset_ = 1 << 12,
CPBrowserDelegate_browser_child_ofItem_ = 1 << 13,
CPBrowserDelegate_browser_objectValueForItem_ = 1 << 14,
CPBrowserDelegate_rootItemForBrowser_ = 1 << 15,
CPBrowserDelegate_browser_didChangeLastColumn_toColumn_ = 1 << 16,
CPBrowserDelegate_browser_didResizeColumn_ = 1 << 17,
CPBrowserDelegate_browserSelectionIsChanging_ = 1 << 18,
CPBrowserDelegate_browserSelectionDidChange_ = 1 << 19;
/*!
@ingroup appkit
@class CPBrowser
*/
@implementation CPBrowser : CPControl
{
id _delegate;
CPString _pathSeparator;
id <CPBrowserDelegate> _delegate;
CPString _pathSeparator;
unsigned _implementedDelegateMethods;
CPView _contentView;
CPScrollView _horizontalScrollView;
CPView _prototypeView;
CPView _contentView;
CPScrollView _horizontalScrollView;
CPView _prototypeView;
CPArray _tableViews;
CPArray _tableDelegates;
CPArray _tableViews;
CPArray _tableDelegates;
id _rootItem;
id _rootItem;
BOOL _delegateSupportsImages;
BOOL _delegateSupportsImages;
SEL _doubleAction @accessors(property=doubleAction);
SEL _doubleAction @accessors(property=doubleAction);
BOOL _allowsMultipleSelection;
BOOL _allowsEmptySelection;
BOOL _allowsMultipleSelection;
BOOL _allowsEmptySelection;
Class _tableViewClass @accessors(property=tableViewClass);
Class _tableViewClass @accessors(property=tableViewClass);
float _rowHeight;
float _imageWidth;
float _leafWidth;
float _minColumnWidth;
float _defaultColumnWidth @accessors(property=defaultColumnWidth);
float _rowHeight;
float _imageWidth;
float _leafWidth;
float _minColumnWidth;
float _defaultColumnWidth @accessors(property=defaultColumnWidth);
CPArray _columnWidths;
CPArray _columnWidths;
}
+ (CPImage)branchImage
+ (CPString)defaultThemeClass
{
return [[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:[CPBrowser class]]
pathForResource:"browser-leaf.png"]
size:CGSizeMake(9,9)];
return "browser";
}
+ (CPImage)highlightedBranchImage
+ (CPDictionary)themeAttributes
{
return [[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:[CPBrowser class]]
pathForResource:"browser-leaf-highlighted.png"]
size:CGSizeMake(9,9)];
return @{
@"image-control-resize": [CPNull null],
@"image-control-leaf": [CPNull null],
@"image-control-leaf-pressed": [CPNull null]
};
}
- (id)initWithFrame:(CGRect)aFrame
@@ -136,10 +184,74 @@
[CPKeyedArchiver archivedDataWithRootObject:_prototypeView]];
}
- (void)setDelegate:(id)anObject
- (void)setDelegate:(id <CPBrowserDelegate>)anObject
{
if (_delegate === anObject)
return;
_delegate = anObject;
_delegateSupportsImages = [_delegate respondsToSelector:@selector(browser:imageValueForItem:)];
_implementedDelegateMethods = 0;
_delegateSupportsImages = NO;
if ([_delegate respondsToSelector:@selector(browser:acceptDrop:atRow:column:dropOperation:)])
_implementedDelegateMethods |= CPBrowserDelegate_browser_acceptDrop_atRow_column_dropOperation_;
if ([_delegate respondsToSelector:@selector(browser:canDragRowsWithIndexes:inColumn:withEvent:)])
_implementedDelegateMethods |= CPBrowserDelegate_browser_canDragRowsWithIndexes_inColumn_withEvent_;
if ([_delegate respondsToSelector:@selector(browser:isLeafItem:)])
_implementedDelegateMethods |= CPBrowserDelegate_browser_isLeafItem_;
if ([_delegate respondsToSelector:@selector(browser:shouldSelectRowIndexes:inColumn:)])
_implementedDelegateMethods |= CPBrowserDelegate_browser_shouldSelectRowIndexes_inColumn_;
if ([_delegate respondsToSelector:@selector(browser:writeRowsWithIndexes:inColumn:toPasteboard:)])
_implementedDelegateMethods |= CPBrowserDelegate_browser_writeRowsWithIndexes_inColumn_toPasteboard_;
if ([_delegate respondsToSelector:@selector(browser:validateDrop:proposedRow:column:dropOperation:)])
_implementedDelegateMethods |= CPBrowserDelegate_browser_validateDrop_proposedRow_column_dropOperation_;
if ([_delegate respondsToSelector:@selector(browser:imageValueForItem:)])
_implementedDelegateMethods |= CPBrowserDelegate_browser_imageValueForItem_;
if ([_delegate respondsToSelector:@selector(browser:draggingImageForRowsWithIndexes:inColumn:withEvent:offset:)])
_implementedDelegateMethods |= CPBrowserDelegate_browser_draggingImageForRowsWithIndexes_inColumn_withEvent_offset_;
if ([_delegate respondsToSelector:@selector(browser:imageValueForItem:)])
{
_delegateSupportsImages = YES;
_implementedDelegateMethods |= CPBrowserDelegate_browser_imageValueForItem_;
}
if ([_delegate respondsToSelector:@selector(browser:selectionIndexesForProposedSelection:inColumn:)])
_implementedDelegateMethods |= CPBrowserDelegate_browser_selectionIndexesForProposedSelection_inColumn_;
if ([_delegate respondsToSelector:@selector(browser:numberOfChildrenOfItem:)])
_implementedDelegateMethods |= CPBrowserDelegate_browser_numberOfChildrenOfItem_;
if ([_delegate respondsToSelector:@selector(browser:draggingViewForRowsWithIndexes:inColumn:withEvent:offset:)])
_implementedDelegateMethods |= CPBrowserDelegate_browser_draggingViewForRowsWithIndexes_inColumn_withEvent_offset_;
if ([_delegate respondsToSelector:@selector(browser:child:ofItem:)])
_implementedDelegateMethods |= CPBrowserDelegate_browser_child_ofItem_;
if ([_delegate respondsToSelector:@selector(browser:objectValueForItem:)])
_implementedDelegateMethods |= CPBrowserDelegate_browser_objectValueForItem_;
if ([_delegate respondsToSelector:@selector(rootItemForBrowser:)])
_implementedDelegateMethods |= CPBrowserDelegate_rootItemForBrowser_;
if ([_delegate respondsToSelector:@selector(browser:didChangeLastColumn:toColumn:)])
_implementedDelegateMethods |= CPBrowserDelegate_browser_didChangeLastColumn_toColumn_;
if ([_delegate respondsToSelector:@selector(browser:didChangeLastColumn:)])
_implementedDelegateMethods |= CPBrowserDelegate_browser_didResizeColumn_;
if ([_delegate respondsToSelector:@selector(browserSelectionIsChanging:)])
_implementedDelegateMethods |= CPBrowserDelegate_browserSelectionIsChanging_;
if ([_delegate respondsToSelector:@selector(browserSelectionDidChange:)])
_implementedDelegateMethods |= CPBrowserDelegate_browserSelectionDidChange_;
[self loadColumnZero];
}
@@ -161,16 +273,13 @@
- (void)loadColumnZero
{
if ([_delegate respondsToSelector:@selector(rootItemForBrowser:)])
_rootItem = [_delegate rootItemForBrowser:self];
else
_rootItem = nil;
_rootItem = [self _sendDelegateRootItemForBrowser];
[self setLastColumn:-1];
[self addColumn];
}
- (void)setLastColumn:(int)columnIndex
- (void)setLastColumn:(CPInteger)columnIndex
{
if (columnIndex >= _tableViews.length)
return;
@@ -178,14 +287,18 @@
var oldValue = _tableViews.length - 1,
indexPlusOne = columnIndex + 1; // unloads all later columns.
if (columnIndex > 0)
[_tableViews[columnIndex - 1] setNeedsDisplay:YES];
[_tableViews[columnIndex] setNeedsDisplay:YES];
[[_tableViews.slice(indexPlusOne) valueForKey:"enclosingScrollView"]
makeObjectsPerformSelector:@selector(removeFromSuperview)];
_tableViews = _tableViews.slice(0, indexPlusOne);
_tableDelegates = _tableDelegates.slice(0, indexPlusOne);
if ([_delegate respondsToSelector:@selector(browser:didChangeLastColumn:toColumn:)])
[_delegate browser:self didChangeLastColumn:oldValue toColumn:columnIndex];
[self _sendDelegateBrowserDidChangeLastColumn:oldValue toColumn:columnIndex];
[self tile];
}
@@ -276,8 +389,8 @@
var column = [[CPTableColumn alloc] initWithIdentifier:@"Leaf"],
view = [[_CPBrowserLeafView alloc] initWithFrame:CGRectMakeZero()];
[view setBranchImage:[[self class] branchImage]];
[view setHighlightedBranchImage:[[self class] highlightedBranchImage]];
[view setBranchImage:[self valueForThemeAttribute:@"image-control-leaf"]];
[view setHighlightedBranchImage:[self valueForThemeAttribute:@"image-control-leaf-pressed"]];
[column setDataView:view];
[column setResizingMask:CPTableColumnNoResizing];
@@ -285,7 +398,7 @@
[aTableView addTableColumn:column];
}
- (void)reloadColumn:(int)column
- (void)reloadColumn:(CPInteger)column
{
[[self tableViewInColumn:column] reloadData];
}
@@ -353,17 +466,17 @@
// ITEMS
- (id)itemAtRow:(int)row inColumn:(int)column
- (id)itemAtRow:(CPInteger)row inColumn:(CPInteger)column
{
return [_tableDelegates[column] childAtIndex:row];
}
- (BOOL)isLeafItem:(id)item
{
return [_delegate respondsToSelector:@selector(browser:isLeafItem:)] && [_delegate browser:self isLeafItem:item];
return (_implementedDelegateMethods & CPBrowserDelegate_browser_isLeafItem_) && [_delegate browser:self isLeafItem:item];
}
- (id)parentForItemsInColumn:(int)column
- (id)parentForItemsInColumn:(CPInteger)column
{
return [_tableDelegates[column] _item];
}
@@ -425,11 +538,26 @@
- (void)keyDown:(CPEvent)anEvent
{
var column = [self selectedColumn];
if (column === -1)
var key = [anEvent charactersIgnoringModifiers],
column = [self selectedColumn];
if (column === CPNotFound)
return;
[_tableViews[column] keyDown:anEvent];
if (key === CPLeftArrowFunctionKey || key === CPRightArrowFunctionKey)
{
if (key === CPLeftArrowFunctionKey)
{
var previousColumn = column - 1,
selectedRow = [self selectedRowInColumn:previousColumn];
[self selectRow:selectedRow inColumn:previousColumn];
}
else
[self selectRow:0 inColumn:column + 1];
}
else
[_tableViews[column] keyDown:anEvent];
}
// SIZING
@@ -472,9 +600,7 @@
{
_columnWidths[column] = aWidth;
if ([_delegate respondsToSelector:@selector(browser:didResizeColumn:)])
[_delegate browser:self didResizeColumn:column];
[self _sendDelegateBrowserDidResizeColumn:column];
[self tile];
}
@@ -589,15 +715,12 @@
if (column < 0 || column > [self lastColumn] + 1)
return;
if ([_delegate respondsToSelector:@selector(browser:selectionIndexesForProposedSelection:inColumn:)])
indexSet = [_delegate browser:self selectionIndexesForProposedSelection:indexSet inColumn:column];
indexSet = [self _sendDelegateBrowserSelectionIndexesForProposedSelection:indexSet inColumn:column];
if ([_delegate respondsToSelector:@selector(browser:shouldSelectRowIndexes:inColumn:)] &&
![_delegate browser:self shouldSelectRowIndexes:indexSet inColumn:column])
if (![self _sendDelegateBrowserShouldSelectRowIndexes:indexSet inColumn:column])
return;
if ([_delegate respondsToSelector:@selector(browserSelectionIsChanging:)])
[_delegate browserSelectionIsChanging:self];
[self _sendDelegateBrowserSelectionIsChanging];
if (column > [self lastColumn])
[self addColumn];
@@ -608,8 +731,7 @@
[self scrollColumnToVisible:column];
if ([_delegate respondsToSelector:@selector(browserSelectionDidChange:)])
[_delegate browserSelectionDidChange:self];
[self _sendDelegateBrowserSelectionDidChange];
}
- (void)setBackgroundColor:(CPColor)aColor
@@ -631,30 +753,6 @@
[_tableViews makeObjectsPerformSelector:@selector(registerForDraggedTypes:) withObject:types];
}
- (BOOL)canDragRowsWithIndexes:(CPIndexSet)rowIndexes inColumn:(int)columnIndex withEvent:(CPEvent)dragEvent
{
if ([_delegate respondsToSelector:@selector(browser:canDragRowsWithIndexes:inColumn:withEvent:)])
return [_delegate browser:self canDragRowsWithIndexes:rowIndexes inColumn:columnIndex withEvent:dragEvent];
return YES;
}
- (CPImage)draggingImageForRowsWithIndexes:(CPIndexSet)rowIndexes inColumn:(int)columnIndex withEvent:(CPEvent)dragEvent offset:(CGPoint)dragImageOffset
{
if ([_delegate respondsToSelector:@selector(browser:draggingImageForRowsWithIndexes:inColumn:withEvent:offset:)])
return [_delegate browser:self draggingImageForRowsWithIndexes:rowIndexes inColumn:columnIndex withEvent:dragEvent offset:dragImageOffset];
return nil;
}
- (CPView)draggingViewForRowsWithIndexes:(CPIndexSet)rowIndexes inColumn:(int)columnIndex withEvent:(CPEvent)dragEvent offset:(CGPoint)dragImageOffset
{
if ([_delegate respondsToSelector:@selector(browser:draggingViewForRowsWithIndexes:inColumn:withEvent:offset:)])
return [_delegate browser:self draggingViewForRowsWithIndexes:rowIndexes inColumn:columnIndex withEvent:dragEvent offset:dragImageOffset];
return nil;
}
@end
@implementation CPBrowser (CPCoding)
@@ -704,8 +802,6 @@
@end
var _CPBrowserResizeControlBackgroundImage = nil;
@implementation _CPBrowserResizeControl : CPView
{
CGPoint _mouseDownX;
@@ -714,22 +810,14 @@ var _CPBrowserResizeControlBackgroundImage = nil;
unsigned _width;
}
+ (CPImage)backgroundImage
{
if (!_CPBrowserResizeControlBackgroundImage)
{
var path = [[CPBundle bundleForClass:[self class]] pathForResource:"browser-resize-control.png"];
_CPBrowserResizeControlBackgroundImage = [[CPImage alloc] initWithContentsOfFile:path
size:CGSizeMake(15, 14)];
}
return _CPBrowserResizeControlBackgroundImage;
}
- (id)initWithFrame:(CGRect)aFrame
{
if (self = [super initWithFrame:aFrame])
[self setBackgroundColor:[CPColor colorWithPatternImage:[[self class] backgroundImage]]];
{
var browser = [[CPBrowser alloc] init];
[self setBackgroundColor:[CPColor colorWithPatternImage:[browser valueForThemeAttribute:@"image-control-resize"]]];
}
return self;
}
@@ -760,7 +848,7 @@ var _CPBrowserResizeControlBackgroundImage = nil;
CPBrowser _browser @accessors;
}
- (void)initWithFrame:(CGRect)aFrame
- (id)initWithFrame:(CGRect)aFrame
{
if (self = [super initWithFrame:aFrame])
{
@@ -814,18 +902,26 @@ var _CPBrowserResizeControlBackgroundImage = nil;
return _browser;
}
/*!
@ignore
*/
- (BOOL)_isFocused
{
return ([super _isFocused] || [_browser tableViewInColumn:[_browser selectedColumn]] === self);
}
- (BOOL)canDragRowsWithIndexes:(CPIndexSet)rowIndexes atPoint:(CGPoint)mouseDownPoint
{
return [_browser canDragRowsWithIndexes:rowIndexes inColumn:[_browser columnOfTableView:self] withEvent:[CPApp currentEvent]];
}
- (CPImage)dragImageForRowsWithIndexes:(CPIndexSet)dragRows tableColumns:(CPArray)theTableColumns event:(CPEvent)dragEvent offset:(CPPointPointer)dragImageOffset
- (CPImage)dragImageForRowsWithIndexes:(CPIndexSet)dragRows tableColumns:(CPArray)theTableColumns event:(CPEvent)dragEvent offset:(CGPoint)dragImageOffset
{
return [_browser draggingImageForRowsWithIndexes:dragRows inColumn:[_browser columnOfTableView:self] withEvent:dragEvent offset:dragImageOffset] ||
[super dragImageForRowsWithIndexes:dragRows tableColumns:theTableColumns event:dragEvent offset:dragImageOffset];
}
- (CPView)dragViewForRowsWithIndexes:(CPIndexSet)dragRows tableColumns:(CPArray)theTableColumns event:(CPEvent)dragEvent offset:(CPPoint)dragViewOffset
- (CPView)dragViewForRowsWithIndexes:(CPIndexSet)dragRows tableColumns:(CPArray)theTableColumns event:(CPEvent)dragEvent offset:(CGPoint)dragViewOffset
{
var count = theTableColumns.length;
while (count--)
@@ -838,35 +934,9 @@ var _CPBrowserResizeControlBackgroundImage = nil;
[super dragViewForRowsWithIndexes:dragRows tableColumns:theTableColumns event:dragEvent offset:dragViewOffset];
}
- (void)moveUp:(id)sender
{
[super moveUp:sender];
[_browser selectRow:[self selectedRow] inColumn:[_browser selectedColumn]];
}
- (void)moveDown:(id)sender
{
[super moveDown:sender];
[_browser selectRow:[self selectedRow] inColumn:[_browser selectedColumn]];
}
- (void)moveLeft:(id)sender
{
var previousColumn = [_browser selectedColumn] - 1,
selectedRow = [_browser selectedRowInColumn:previousColumn];
[_browser selectRow:selectedRow inColumn:previousColumn];
}
- (void)moveRight:(id)sender
{
[_browser selectRow:0 inColumn:[_browser selectedColumn] + 1];
}
@end
@import <Foundation/CPObject.j>
@implementation _CPBrowserTableDelegate : CPObject
{
CPBrowser _browser @accessors;
@@ -907,22 +977,22 @@ var _CPBrowserResizeControlBackgroundImage = nil;
[_browser selectRowIndexes:selectedIndexes inColumn:_index];
}
- (id)childAtIndex:(unsigned)index
- (id)childAtIndex:(CPUInteger)index
{
return [_delegate browser:_browser child:index ofItem:_item];
}
- (BOOL)tableView:(CPTableView)aTableView acceptDrop:(id)info row:(int)row dropOperation:(CPTableViewDropOperation)operation
- (BOOL)tableView:(CPTableView)aTableView acceptDrop:(id)info row:(CPInteger)row dropOperation:(CPTableViewDropOperation)operation
{
if ([_delegate respondsToSelector:@selector(browser:acceptDrop:atRow:column:dropOperation:)])
if (_browser._implementedDelegateMethods & CPBrowserDelegate_browser_acceptDrop_atRow_column_dropOperation_)
return [_delegate browser:_browser acceptDrop:info atRow:row column:_index dropOperation:operation];
else
return NO;
}
- (CPDragOperation)tableView:(CPTableView)aTableView validateDrop:(id)info proposedRow:(int)row proposedDropOperation:(CPTableViewDropOperation)operation
- (CPDragOperation)tableView:(CPTableView)aTableView validateDrop:(id)info proposedRow:(CPInteger)row proposedDropOperation:(CPTableViewDropOperation)operation
{
if ([_delegate respondsToSelector:@selector(browser:validateDrop:proposedRow:column:dropOperation:)])
if (_browser._implementedDelegateMethods & CPBrowserDelegate_browser_validateDrop_proposedRow_column_dropOperation_)
return [_delegate browser:_browser validateDrop:info proposedRow:row column:_index dropOperation:operation];
else
return CPDragOperationNone;
@@ -930,7 +1000,7 @@ var _CPBrowserResizeControlBackgroundImage = nil;
- (BOOL)tableView:(CPTableView)aTableView writeRowsWithIndexes:(CPIndexSet)rowIndexes toPasteboard:(CPPasteboard)pboard
{
if ([_delegate respondsToSelector:@selector(browser:writeRowsWithIndexes:inColumn:toPasteboard:)])
if (_browser._implementedDelegateMethods & CPBrowserDelegate_browser_writeRowsWithIndexes_inColumn_toPasteboard_)
return [_delegate browser:_browser writeRowsWithIndexes:rowIndexes inColumn:_index toPasteboard:pboard];
else
return NO;
@@ -985,7 +1055,7 @@ var _CPBrowserResizeControlBackgroundImage = nil;
var imageView = [self layoutEphemeralSubviewNamed:@"image-view"
positioned:CPWindowAbove
relativeToEphemeralSubviewNamed:nil],
isHighlighted = [self themeState] & CPThemeStateSelectedDataView;
isHighlighted = [self hasThemeState:CPThemeStateSelectedDataView];
[imageView setImage: _isLeaf ? (isHighlighted ? _highlightedBranchImage : _branchImage) : nil];
[imageView setImageScaling:CPImageScaleNone];
@@ -1000,7 +1070,7 @@ var _CPBrowserResizeControlBackgroundImage = nil;
[aCoder encodeObject:_highlightedBranchImage forKey:"_CPBrowserLeafViewHighlightedBranchImageKey"];
}
- (void)initWithCoder:(CPCoder)aCoder
- (id)initWithCoder:(CPCoder)aCoder
{
if (self = [super initWithCoder:aCoder])
{
@@ -1013,3 +1083,115 @@ var _CPBrowserResizeControlBackgroundImage = nil;
}
@end
@implementation CPBrowser (CPBrowserDelegate)
/*!
@ignore
Call delegate rootItemForBrowser:
*/
- (id)_sendDelegateRootItemForBrowser
{
if (!(_implementedDelegateMethods & CPBrowserDelegate_rootItemForBrowser_))
return nil;
return [_delegate rootItemForBrowser:self];
}
/*!
@ignore
Call delegate browser:didChangeLastColumn:toColumn:
*/
- (void)_sendDelegateBrowserDidChangeLastColumn:(CPInteger)lastColumn toColumn:(CPInteger)newColumn
{
if (!(_implementedDelegateMethods & CPBrowserDelegate_browser_didChangeLastColumn_toColumn_))
return;
[_delegate browser:self didChangeLastColumn:lastColumn toColumn:newColumn];
}
/*!
@ignore
Call delegate browser:didResizeColumn:
*/
- (void)_sendDelegateBrowserDidResizeColumn:(CPInteger)column
{
if (!(_implementedDelegateMethods & CPBrowserDelegate_browser_didResizeColumn_))
return;
[_delegate browser:self didResizeColumn:column];
}
/*!
@ignore
Call delegate browserSelectionIsChanging:
*/
- (void)_sendDelegateBrowserSelectionIsChanging
{
if (!(_implementedDelegateMethods & CPBrowserDelegate_browserSelectionIsChanging_))
return;
[_delegate browserSelectionIsChanging:self];
}
/*!
@ignore
Call delegate browser:shouldSelectRowIndexes:inColumn:
*/
- (BOOL)_sendDelegateBrowserShouldSelectRowIndexes:(CPIndexSet)anIndexSet inColumn:(CPInteger)aColumn
{
if (!(_implementedDelegateMethods & CPBrowserDelegate_browser_shouldSelectRowIndexes_inColumn_))
return YES;
return [_delegate browser:self shouldSelectRowIndexes:anIndexSet inColumn:aColumn];
}
/*!
@ignore
Call delegate browser:selectionIndexesForProposedSelection:inColumn:
*/
- (CPIndexSet)_sendDelegateBrowserSelectionIndexesForProposedSelection:(CPIndexSet)anIndexSet inColumn:(CPInteger)aColumn
{
if (!(_implementedDelegateMethods & CPBrowserDelegate_browser_selectionIndexesForProposedSelection_inColumn_))
return anIndexSet;
return [_delegate browser:self selectionIndexesForProposedSelection:anIndexSet inColumn:aColumn];
}
/*!
@ignore
Call delegate browserSelectionDidChange
*/
- (void)_sendDelegateBrowserSelectionDidChange
{
if (!(_implementedDelegateMethods & CPBrowserDelegate_browserSelectionDidChange_))
return;
[_delegate browserSelectionDidChange:self];
}
- (BOOL)canDragRowsWithIndexes:(CPIndexSet)rowIndexes inColumn:(CPInteger)columnIndex withEvent:(CPEvent)dragEvent
{
if (_implementedDelegateMethods & CPBrowserDelegate_browser_canDragRowsWithIndexes_inColumn_withEvent_)
return [_delegate browser:self canDragRowsWithIndexes:rowIndexes inColumn:columnIndex withEvent:dragEvent];
return YES;
}
- (CPImage)draggingImageForRowsWithIndexes:(CPIndexSet)rowIndexes inColumn:(CPInteger)columnIndex withEvent:(CPEvent)dragEvent offset:(CGPoint)dragImageOffset
{
if (_implementedDelegateMethods & CPBrowserDelegate_browser_draggingImageForRowsWithIndexes_inColumn_withEvent_offset_)
return [_delegate browser:self draggingImageForRowsWithIndexes:rowIndexes inColumn:columnIndex withEvent:dragEvent offset:dragImageOffset];
return nil;
}
- (CPView)draggingViewForRowsWithIndexes:(CPIndexSet)rowIndexes inColumn:(CPInteger)columnIndex withEvent:(CPEvent)dragEvent offset:(CGPoint)dragImageOffset
{
if (_implementedDelegateMethods & CPBrowserDelegate_browser_draggingViewForRowsWithIndexes_inColumn_withEvent_offset_)
return [_delegate browser:self draggingViewForRowsWithIndexes:rowIndexes inColumn:columnIndex withEvent:dragEvent offset:dragImageOffset];
return nil;
}
@end
+90 -53
View File
@@ -25,11 +25,11 @@
@import "CPControl.j"
@import "CPStringDrawing.j"
@import "CPText.j"
@import "CPWindow_Constants.j"
/* @group CPBezelStyle */
// IB style
@typedef CPBezelStyle
CPRoundedBezelStyle = 1; // Push
CPRegularSquareBezelStyle = 2; // Bevel
CPThickSquareBezelStyle = 3;
@@ -48,6 +48,7 @@ CPHUDBezelStyle = -1;
/* @group CPButtonType */
@typedef CPButtonType
CPMomentaryLightButton = 0;
CPPushOnPushOffButton = 1;
CPToggleButton = 2;
@@ -59,11 +60,11 @@ CPMomentaryPushInButton = 7;
CPMomentaryPushButton = 0;
CPMomentaryLight = 7;
CPNoButtonMask = 0;
CPContentsButtonMask = 1;
CPPushInButtonMask = 2;
CPGrayButtonMask = 4;
CPBackgroundButtonMask = 8;
CPNoButtonMask = 0;
CPContentsButtonMask = 1;
CPPushInButtonMask = 2;
CPGrayButtonMask = 4;
CPBackgroundButtonMask = 8;
CPNoCellMask = CPNoButtonMask;
CPContentsCellMask = CPContentsButtonMask;
@@ -73,14 +74,18 @@ CPChangeBackgroundCellMask = CPBackgroundButtonMask;
CPButtonStateMixed = CPThemeState("mixed");
CPButtonStateBezelStyleRounded = CPThemeState("rounded");
CPButtonStateBezelStyleRoundRect = CPThemeState("roundRect");
// add all future correspondance between bezel styles and theme state here.
var CPButtonBezelStyleStateMap = [CPDictionary dictionaryWithObjects:[CPButtonStateBezelStyleRounded, nil]
forKeys:[CPRoundedBezelStyle, CPRoundRectBezelStyle]];
var CPButtonBezelStyleStateMap = @{
CPRoundedBezelStyle: CPButtonStateBezelStyleRounded,
CPRoundRectBezelStyle: CPButtonStateBezelStyleRoundRect,
};
CPButtonDefaultHeight = 24.0;
/// @cond IGNORE
CPButtonDefaultHeight = 25.0;
CPButtonImageOffset = 3.0;
/// @endcond
/*!
@ingroup appkit
@@ -103,7 +108,6 @@ CPButtonImageOffset = 3.0;
// NS-style Display Properties
CPBezelStyle _bezelStyle;
CPControlSize _controlSize;
CPString _keyEquivalent;
unsigned _keyEquivalentModifierMask;
@@ -116,6 +120,14 @@ CPButtonImageOffset = 3.0;
BOOL _isTracking;
}
+ (Class)_binderClassForBinding:(CPString)aBinding
{
if (aBinding === CPTargetBinding || [aBinding hasPrefix:CPArgumentBinding])
return [CPActionBinding class];
return [super _binderClassForBinding:aBinding];
}
+ (id)buttonWithTitle:(CPString)aTitle
{
return [self buttonWithTitle:aTitle theme:[CPTheme defaultTheme]];
@@ -137,10 +149,15 @@ CPButtonImageOffset = 3.0;
return @"button";
}
+ (id)themeAttributes
+ (CPDictionary)themeAttributes
{
return [CPDictionary dictionaryWithObjects:[[CPNull null], 0.0, _CGInsetMakeZero(), _CGInsetMakeZero(), [CPNull null]]
forKeys:[@"image", @"image-offset", @"bezel-inset", @"content-inset", @"bezel-color"]];
return @{
@"image": [CPNull null],
@"image-offset": 0.0,
@"bezel-inset": CGInsetMakeZero(),
@"content-inset": CGInsetMakeZero(),
@"bezel-color": [CPNull null],
};
}
/*!
@@ -171,8 +188,6 @@ CPButtonImageOffset = 3.0;
- (void)_init
{
_controlSize = CPRegularControlSize;
_keyEquivalent = @"";
_keyEquivalentModifierMask = 0;
@@ -183,6 +198,20 @@ CPButtonImageOffset = 3.0;
[self setButtonType:CPMomentaryPushInButton];
}
#pragma mark -
#pragma mark Control Size
- (void)setControlSize:(CPControlSize)aControlSize
{
[super setControlSize:aControlSize];
if ([self isBordered])
[self _sizeToControlSize];
}
#pragma mark -
// Setting the state
/*!
Returns a Boolean value indicating whether the button allows a mixed state.
@@ -221,7 +250,7 @@ CPButtonImageOffset = 3.0;
else if (![anObjectValue isKindOfClass:[CPNumber class]])
anObjectValue = CPOnState;
else if (anObjectValue >= CPOnState)
anObjectValue = CPOnState
anObjectValue = CPOnState;
else if (anObjectValue < CPOffState)
if ([self allowsMixedState])
anObjectValue = CPMixedState;
@@ -251,7 +280,7 @@ CPButtonImageOffset = 3.0;
break;
case CPOffState:
[self unsetThemeState:CPThemeStateSelected | CPButtonStateMixed | CPThemeStateHighlighted];
[self unsetThemeStates:[CPThemeStateSelected, CPButtonStateMixed, CPThemeStateHighlighted]];
}
}
@@ -275,7 +304,7 @@ CPButtonImageOffset = 3.0;
}
/*!
Sets the button's next state to \c aState.
Sets the button's state to the next available state.
@param aState Possible states are any of the CPButton globals:
\c CPOffState, \c CPOnState, \c CPMixedState
*/
@@ -349,7 +378,7 @@ CPButtonImageOffset = 3.0;
- (void)setImage:(CPImage)anImage
{
[self setValue:anImage forThemeAttribute:@"image"];
[self setValue:anImage forThemeAttribute:@"image" inState:CPThemeStateNormal];
}
- (CPImage)image
@@ -431,38 +460,47 @@ CPButtonImageOffset = 3.0;
{
switch (aButtonType)
{
case CPMomentaryLightButton: [self setHighlightsBy:CPChangeGrayCellMask | CPChangeBackgroundCellMask];
[self setShowsStateBy:CPNoCellMask];
break;
case CPMomentaryLightButton:
[self setHighlightsBy:CPChangeGrayCellMask | CPChangeBackgroundCellMask];
[self setShowsStateBy:CPNoCellMask];
break;
case CPMomentaryPushInButton: [self setHighlightsBy:CPPushInCellMask | CPChangeGrayCellMask | CPChangeBackgroundCellMask];
[self setShowsStateBy:CPNoCellMask];
break;
case CPMomentaryPushInButton:
[self setHighlightsBy:CPPushInCellMask | CPChangeGrayCellMask | CPChangeBackgroundCellMask];
[self setShowsStateBy:CPNoCellMask];
break;
case CPMomentaryChangeButton: [self setHighlightsBy:CPContentsCellMask];
[self setShowsStateBy:CPNoCellMask];
break;
case CPMomentaryChangeButton:
[self setHighlightsBy:CPContentsCellMask];
[self setShowsStateBy:CPNoCellMask];
break;
case CPPushOnPushOffButton: [self setHighlightsBy:CPPushInCellMask | CPChangeGrayCellMask | CPChangeBackgroundCellMask];
[self setShowsStateBy:CPChangeBackgroundCellMask | CPChangeGrayCellMask];
break;
case CPPushOnPushOffButton:
[self setHighlightsBy:CPPushInCellMask | CPChangeGrayCellMask | CPChangeBackgroundCellMask];
[self setShowsStateBy:CPChangeBackgroundCellMask | CPChangeGrayCellMask];
break;
case CPOnOffButton: [self setHighlightsBy:CPChangeGrayCellMask | CPChangeBackgroundCellMask];
[self setShowsStateBy:CPChangeGrayCellMask | CPChangeBackgroundCellMask];
break;
case CPOnOffButton:
[self setHighlightsBy:CPChangeGrayCellMask | CPChangeBackgroundCellMask];
[self setShowsStateBy:CPChangeGrayCellMask | CPChangeBackgroundCellMask];
break;
case CPToggleButton: [self setHighlightsBy:CPPushInCellMask | CPContentsCellMask];
[self setShowsStateBy:CPContentsCellMask];
break;
case CPToggleButton:
[self setHighlightsBy:CPPushInCellMask | CPContentsCellMask];
[self setShowsStateBy:CPContentsCellMask];
break;
case CPSwitchButton: [CPException raise:CPInvalidArgumentException
reason:"The CPSwitchButton type is not supported in Cappuccino, use the CPCheckBox class instead."];
case CPSwitchButton:
[CPException raise:CPInvalidArgumentException
reason:"The CPSwitchButton type is not supported in Cappuccino, use the CPCheckBox class instead."];
case CPRadioButton: [CPException raise:CPInvalidArgumentException
reason:"The CPRadioButton type is not supported in Cappuccino, use the CPRadio class instead."];
case CPRadioButton:
[CPException raise:CPInvalidArgumentException
reason:"The CPRadioButton type is not supported in Cappuccino, use the CPRadio class instead."];
default: [CPException raise:CPInvalidArgumentException
reason:"Unknown button type."];
default:
[CPException raise:CPInvalidArgumentException
reason:"Unknown button type."];
}
[self setImageDimsWhenDisabled:YES];
@@ -522,6 +560,7 @@ CPButtonImageOffset = 3.0;
_isTracking = YES;
var startedTracking = [super startTrackingAt:aPoint];
if (_highlightsBy & (CPPushInCellMask | CPChangeGrayCellMask))
{
if (_showsStateBy & (CPChangeGrayCellMask | CPChangeBackgroundCellMask))
@@ -536,6 +575,7 @@ CPButtonImageOffset = 3.0;
else
[self highlight:NO];
}
return startedTracking;
}
@@ -577,7 +617,7 @@ CPButtonImageOffset = 3.0;
{
var contentInset = [self currentValueForThemeAttribute:@"content-inset"];
return _CGRectInsetByInset(bounds, contentInset);
return CGRectInsetByInset(bounds, contentInset);
}
- (CGRect)bezelRectForBounds:(CGRect)bounds
@@ -588,7 +628,7 @@ CPButtonImageOffset = 3.0;
var bezelInset = [self currentValueForThemeAttribute:@"bezel-inset"];
return _CGRectInsetByInset(bounds, bezelInset);
return CGRectInsetByInset(bounds, bezelInset);
}
- (CGSize)_minimumFrameSize
@@ -648,14 +688,14 @@ CPButtonImageOffset = 3.0;
{
if (aName === "bezel-view")
{
var view = [[CPView alloc] initWithFrame:_CGRectMakeZero()];
var view = [[CPView alloc] initWithFrame:CGRectMakeZero()];
[view setHitTests:NO];
return view;
}
else
return [[_CPImageAndTextView alloc] initWithFrame:_CGRectMakeZero()];
return [[_CPImageAndTextView alloc] initWithFrame:CGRectMakeZero()];
}
- (void)layoutSubviews
@@ -988,6 +1028,3 @@ var CPButtonImageKey = @"CPButtonImageKey",
}
@end
@import "CPCheckBox.j"
@import "CPRadio.j"
+80 -15
View File
@@ -1,6 +1,35 @@
/*
* CPButtonBar.j
* AppKit
*
* Created by Francisco Tolmasky.
* Copyright 2009, 280 North, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "CPView.j"
@import "CPWindow_Constants.j"
@class CPSplitView
@global CPPopUpButtonStatePullsDown
@global CPKeyValueChangeOldKey
@global CPKeyValueChangeNewKey
@global CPKeyValueObservingOptionNew
@global CPKeyValueObservingOptionOld
@implementation CPButtonBar : CPView
{
@@ -12,7 +41,7 @@
+ (id)plusButton
{
var button = [[CPButton alloc] initWithFrame:CGRectMake(0, 0, 35, 25)],
image = [[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:[CPButtonBar class]] pathForResource:@"plus_button.png"] size:CGSizeMake(11, 12)];
image = [[CPTheme defaultTheme] valueForAttributeWithName:@"button-image-plus" forClass:[CPButtonBar class]];
[button setBordered:NO];
[button setImage:image];
@@ -24,7 +53,7 @@
+ (id)minusButton
{
var button = [[CPButton alloc] initWithFrame:CGRectMake(0, 0, 35, 25)],
image = [[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:[CPButtonBar class]] pathForResource:@"minus_button.png"] size:CGSizeMake(11, 4)];
image = [[CPTheme defaultTheme] valueForAttributeWithName:@"button-image-minus" forClass:[CPButtonBar class]];
[button setBordered:NO];
[button setImage:image];
@@ -36,7 +65,7 @@
+ (id)actionPopupButton
{
var button = [[CPPopUpButton alloc] initWithFrame:CGRectMake(0, 0, 35, 25)],
image = [[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:[CPButtonBar class]] pathForResource:@"action_button.png"] size:CGSizeMake(22, 14)];
image = [[CPTheme defaultTheme] valueForAttributeWithName:@"button-image-action" forClass:[CPButtonBar class]];
[button addItemWithTitle:nil];
[[button lastItem] setImage:image];
@@ -53,10 +82,19 @@
return @"button-bar";
}
+ (id)themeAttributes
+ (CPDictionary)themeAttributes
{
return [CPDictionary dictionaryWithObjects:[CGInsetMake(0.0, 0.0, 0.0, 0.0), CGSizeMakeZero(), [CPNull null], [CPNull null], [CPNull null], [CPNull null]]
forKeys:[@"resize-control-inset", @"resize-control-size", @"resize-control-color", @"bezel-color", @"button-bezel-color", @"button-text-color"]];
return @{
@"resize-control-inset": CGInsetMake(0.0, 0.0, 0.0, 0.0),
@"resize-control-size": CGSizeMakeZero(),
@"resize-control-color": [CPNull null],
@"bezel-color": [CPNull null],
@"button-bezel-color": [CPNull null],
@"button-text-color": [CPNull null],
@"button-image-plus": [CPNull null],
@"button-image-minus": [CPNull null],
@"button-image-action": [CPNull null],
};
}
- (id)initWithFrame:(CGRect)aFrame
@@ -74,6 +112,8 @@
- (void)awakeFromCib
{
[super awakeFromCib];
var view = [self superview],
subview = self;
@@ -94,10 +134,20 @@
- (void)setButtons:(CPArray)buttons
{
for (var i = [_buttons count] - 1; i >= 0; i--)
{
[_buttons[i] removeFromSuperview];
[_buttons[i] removeObserver:self forKeyPath:@"hidden"];
}
_buttons = [CPArray arrayWithArray:buttons];
for (var i = 0, count = [_buttons count]; i < count; i++)
for (var i = [_buttons count] - 1; i >= 0; i--)
{
[_buttons[i] addObserver:self forKeyPath:@"hidden" options:CPKeyValueObservingOptionNew | CPKeyValueObservingOptionOld context:nil];
[_buttons[i] setBordered:YES];
}
[self setNeedsLayout];
}
@@ -183,8 +233,15 @@
count = [buttonsNotHidden count];
while (count--)
if ([buttonsNotHidden[count] isHidden])
[buttonsNotHidden removeObject:buttonsNotHidden[count]];
{
var button = buttonsNotHidden[count];
if ([button isHidden])
{
[button removeFromSuperview];
[buttonsNotHidden removeObject:button];
}
}
var currentButtonOffset = _resizeControlIsLeftAligned ? CGRectGetMaxX([self bounds]) + 1 : -1,
bounds = [self bounds],
@@ -215,15 +272,15 @@
currentButtonOffset += width - 1;
}
[button setValue:normalColor forThemeAttribute:@"bezel-color" inState:CPThemeStateNormal | CPThemeStateBordered];
[button setValue:highlightedColor forThemeAttribute:@"bezel-color" inState:CPThemeStateHighlighted | CPThemeStateBordered];
[button setValue:disabledColor forThemeAttribute:@"bezel-color" inState:CPThemeStateDisabled | CPThemeStateBordered];
[button setValue:normalColor forThemeAttribute:@"bezel-color" inStates:[CPThemeStateNormal, CPThemeStateBordered]];
[button setValue:highlightedColor forThemeAttribute:@"bezel-color" inStates:[CPThemeStateHighlighted, CPThemeStateBordered, ]];
[button setValue:disabledColor forThemeAttribute:@"bezel-color" inStates:[CPThemeStateDisabled, CPThemeStateBordered]];
[button setValue:textColor forThemeAttribute:@"text-color" inState:CPThemeStateBordered];
// FIXME shouldn't need this
[button setValue:normalColor forThemeAttribute:@"bezel-color" inState:CPThemeStateNormal | CPThemeStateBordered | CPPopUpButtonStatePullsDown];
[button setValue:highlightedColor forThemeAttribute:@"bezel-color" inState:CPThemeStateHighlighted | CPThemeStateBordered | CPPopUpButtonStatePullsDown];
[button setValue:disabledColor forThemeAttribute:@"bezel-color" inState:CPThemeStateDisabled | CPThemeStateBordered | CPPopUpButtonStatePullsDown];
[button setValue:normalColor forThemeAttribute:@"bezel-color" inStates:[CPThemeStateNormal, CPThemeStateBordered, CPPopUpButtonStatePullsDown]];
[button setValue:highlightedColor forThemeAttribute:@"bezel-color" inStates:[CPThemeStateHighlighted, CPThemeStateBordered, CPPopUpButtonStatePullsDown]];
[button setValue:disabledColor forThemeAttribute:@"bezel-color" inStates:[CPThemeStateDisabled, CPThemeStateBordered, CPPopUpButtonStatePullsDown]];
[self addSubview:button];
}
@@ -239,6 +296,14 @@
}
}
- (void)observeValueForKeyPath:(CPString)keyPath ofObject:(id)object change:(CPDictionary)change context:(id)context
{
if ([change objectForKey:CPKeyValueChangeOldKey] == [change objectForKey:CPKeyValueChangeNewKey])
return;
[self setNeedsLayout];
}
- (void)setFrameSize:(CGSize)aSize
{
[super setFrameSize:aSize];
+27 -3
View File
@@ -44,12 +44,12 @@ CPCheckBoxImageOffset = 4.0;
return @"check-box";
}
+ (Class)_binderClassForBinding:(CPString)theBinding
+ (Class)_binderClassForBinding:(CPString)aBinding
{
if (theBinding === CPValueBinding)
if (aBinding === CPValueBinding)
return [_CPCheckBoxValueBinder class];
return [super _binderClassForBinding:theBinding];
return [super _binderClassForBinding:aBinding];
}
- (id)initWithFrame:(CGRect)aFrame
@@ -111,6 +111,30 @@ CPCheckBoxImageOffset = 4.0;
return startedTracking;
}
#pragma mark -
#pragma mark Override methods from CPButton
- (CGSize)_minimumFrameSize
{
var size = [super _minimumFrameSize],
contentView = [self ephemeralSubviewNamed:@"content-view"];
if (!contentView && [[self title] length])
{
var minSize = [self currentValueForThemeAttribute:@"min-size"],
maxSize = [self currentValueForThemeAttribute:@"max-size"];
// Here we always add the min size to the control which is the size of the view of the checkBox
size.width += minSize.width + CPCheckBoxImageOffset;
if (maxSize.width >= 0.0)
size.width = MIN(size.width, maxSize.width);
}
return size;
}
@end
@implementation _CPCheckBoxValueBinder : CPBinder
+15 -36
View File
@@ -22,6 +22,7 @@
@import "CPView.j"
@class CPScrollView
/*!
@ingroup appkit
@@ -44,44 +45,13 @@
if (_documentView == aView)
return;
var defaultCenter = [CPNotificationCenter defaultCenter];
if (_documentView)
{
[defaultCenter
removeObserver:self
name:CPViewFrameDidChangeNotification
object:_documentView];
[defaultCenter
removeObserver:self
name:CPViewBoundsDidChangeNotification
object:_documentView];
[_documentView removeFromSuperview];
}
_documentView = aView;
if (_documentView)
{
[self addSubview:_documentView];
[_documentView setPostsFrameChangedNotifications:YES];
[_documentView setPostsBoundsChangedNotifications:YES];
[defaultCenter
addObserver:self
selector:@selector(viewFrameChanged:)
name:CPViewFrameDidChangeNotification
object:_documentView];
[defaultCenter
addObserver:self
selector:@selector(viewBoundsChanged:)
name:CPViewBoundsDidChangeNotification
object:_documentView];
}
}
/*!
@@ -101,19 +71,19 @@
- (CGPoint)constrainScrollPoint:(CGPoint)aPoint
{
if (!_documentView)
return _CGPointMakeZero();
return CGPointMakeZero();
var documentFrame = [_documentView frame];
aPoint.x = MAX(0.0, MIN(aPoint.x, MAX(_CGRectGetWidth(documentFrame) - _CGRectGetWidth(_bounds), 0.0)));
aPoint.y = MAX(0.0, MIN(aPoint.y, MAX(_CGRectGetHeight(documentFrame) - _CGRectGetHeight(_bounds), 0.0)));
aPoint.x = MAX(0.0, MIN(aPoint.x, MAX(CGRectGetWidth(documentFrame) - CGRectGetWidth(_bounds), 0.0)));
aPoint.y = MAX(0.0, MIN(aPoint.y, MAX(CGRectGetHeight(documentFrame) - CGRectGetHeight(_bounds), 0.0)));
return aPoint;
}
- (void)setBoundsOrigin:(CGPoint)aPoint
{
if (_CGPointEqualToPoint(_bounds.origin, aPoint))
if (CGPointEqualToPoint(_bounds.origin, aPoint))
return;
[super setBoundsOrigin:aPoint];
@@ -223,6 +193,11 @@
return [self scrollToPoint:CGPointMake(bounds.origin.x - deltaX, bounds.origin.y - deltaY)];
}
- (CGRect)documentVisibleRect
{
return [_documentView visibleRect];
}
@end
@@ -233,7 +208,11 @@ var CPClipViewDocumentViewKey = @"CPScrollViewDocumentView";
- (id)initWithCoder:(CPCoder)aCoder
{
if (self = [super initWithCoder:aCoder])
[self setDocumentView:[aCoder decodeObjectForKey:CPClipViewDocumentViewKey]];
{
// Don't call setDocumentView: here. It calls addSubview:, but it's A) not necessary since the
// view hierarchy is fully encoded and B) dangerous if the subview is not fully decoded.
_documentView = [aCoder decodeObjectForKey:CPClipViewDocumentViewKey];
}
return self;
}
+834 -286
View File
File diff suppressed because it is too large Load Diff
+26 -1
View File
@@ -22,13 +22,38 @@
@import "CPViewController.j"
/*!
Represents an object inside a CPCollectionView.
*/
@implementation CPCollectionViewItem : CPViewController
{
BOOL _isSelected;
CPData _cachedArchive;
}
- (id)copy
{
var cibName = [self cibName],
copy;
if (cibName)
{
copy = [[[self class] alloc] initWithCibName:cibName bundle:[self cibBundle]];
}
else
{
if (!_cachedArchive)
_cachedArchive = [CPKeyedArchiver archivedDataWithRootObject:self];
copy = [CPKeyedUnarchiver unarchiveObjectWithData:_cachedArchive];
// copy connections
}
[copy setRepresentedObject:[self representedObject]];
[copy setSelected:_isSelected];
return copy;
}
// Setting the Represented Object
+947 -88
View File
File diff suppressed because it is too large Load Diff
+40 -35
View File
@@ -20,12 +20,35 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "CPApplication.j"
@import "CPButton.j"
@import "CPCookie.j"
@import "CPPanel.j"
@import "CPPasteboard.j"
@import "CPView.j"
@class CPSlider
@class _CPColorPanelToolbar
@class _CPColorPanelSwatches
@class _CPColorPanelPreview
@global CPApp
/*
A color wheel
@global
@group CPColorPanelMode
*/
CPWheelColorPickerMode = 1;
/*
Slider based picker
@global
@group CPColorPanelMode
*/
CPSliderColorPickerMode = 2;
CPColorPickerViewWidth = 265;
CPColorPickerViewHeight = 370;
CPColorPanelColorDidChangeNotification = @"CPColorPanelColorDidChangeNotification";
@@ -38,22 +61,6 @@ var PREVIEW_HEIGHT = 20.0,
var SharedColorPanel = nil,
ColorPickerClasses = [];
/*
A color wheel
@global
@group CPColorPanelMode
*/
CPWheelColorPickerMode = 1;
/*
Slider based picker
@global
@group CPColorPanelMode
*/
CPSliderColorPickerMode = 2;
CPColorPickerViewWidth = 265;
CPColorPickerViewHeight = 370;
/*!
@ingroup appkit
@class CPColorPanel
@@ -64,7 +71,6 @@ CPColorPickerViewHeight = 370;
*/
@implementation CPColorPanel : CPPanel
{
_CPColorPanelToolbar _toolbar;
_CPColorPanelSwatches _swatchView;
_CPColorPanelPreview _previewView;
@@ -123,7 +129,7 @@ CPColorPickerViewHeight = 370;
if (self)
{
[[self contentView] setBackgroundColor:[CPColor colorWithWhite:0.95 alpha:1.0]];
//[[self contentView] setBackgroundColor:[CPColor colorWithWhite:0.95 alpha:1.0]];
[self setTitle:@"Color Panel"];
[self setLevel:CPFloatingWindowLevel];
@@ -248,8 +254,8 @@ CPColorPickerViewHeight = 370;
var height = (TOOLBAR_HEIGHT + 10 + PREVIEW_HEIGHT + 5 + SWATCH_HEIGHT + 32),
bounds = [[self contentView] bounds];
[view setFrameSize:CPSizeMake(bounds.size.width - 10, bounds.size.height - height)];
[view setFrameOrigin:CPPointMake(5, height)];
[view setFrameSize:CGSizeMake(bounds.size.width - 10, bounds.size.height - height)];
[view setFrameOrigin:CGPointMake(5, height)];
}
[_currentView removeFromSuperview];
@@ -419,7 +425,7 @@ var CPColorPanelSwatchesCookie = "CPColorPanelSwatchesCookie";
CPCookie _swatchCookie;
}
- (id)initWithFrame:(CPRect)aFrame
- (id)initWithFrame:(CGRect)aFrame
{
self = [super initWithFrame:aFrame];
@@ -437,7 +443,7 @@ var CPColorPanelSwatchesCookie = "CPColorPanelSwatchesCookie";
for (var i = 0; i < 50; i++)
{
// FIXME: http://280north.lighthouseapp.com/projects/13294-cappuccino/tickets/25-implement-cpbox
var view = [[CPView alloc] initWithFrame:CPRectMake(13 * i + 1, 1, 12, 12)],
var view = [[CPView alloc] initWithFrame:CGRectMake(13 * i + 1, 1, 12, 12)],
fillView = [[CPView alloc] initWithFrame:CGRectInset([view bounds], 1.0, 1.0)];
[view setBackgroundColor:whiteColor];
@@ -477,13 +483,12 @@ var CPColorPanelSwatchesCookie = "CPColorPanelSwatchesCookie";
];
}
var cookieValue = eval(cookieValue),
result = [];
var cookieValue = eval(cookieValue);
for (var i = 0; i < cookieValue.length; i++)
result.push([CPColor colorWithHexString:cookieValue[i]]);
return result;
return [cookieValue arrayByApplyingBlock:function(value)
{
return [CPColor colorWithHexString:value];
}];
}
- (CPArray)saveColorList
@@ -572,7 +577,7 @@ var CPColorPanelSwatchesCookie = "CPColorPanelSwatchesCookie";
[aPasteboard setData:[CPKeyedArchiver archivedDataWithRootObject:_dragColor] forType:aType];
}
- (void)performDragOperation:(id <CPDraggingInfo>)aSender
- (void)performDragOperation:(id /*<CPDraggingInfo>*/)aSender
{
var location = [self convertPoint:[aSender draggingLocation] fromView:nil],
pasteboard = [aSender draggingPasteboard],
@@ -592,7 +597,7 @@ var CPColorPanelSwatchesCookie = "CPColorPanelSwatchesCookie";
CPColorPanel _colorPanel;
}
- (id)initWithFrame:(CPRect)aFrame
- (id)initWithFrame:(CGRect)aFrame
{
self = [super initWithFrame:aFrame];
@@ -611,7 +616,7 @@ var CPColorPanelSwatchesCookie = "CPColorPanelSwatchesCookie";
return _colorPanel;
}
- (void)performDragOperation:(id <CPDraggingInfo>)aSender
- (void)performDragOperation:(id /*<CPDraggingInfo>*/)aSender
{
var pasteboard = [aSender draggingPasteboard];
@@ -633,7 +638,7 @@ var CPColorPanelSwatchesCookie = "CPColorPanelSwatchesCookie";
[[CPPasteboard pasteboardWithName:CPDragPboard] declareTypes:[CPColorDragType] owner:self];
var bounds = CPRectMake(0, 0, 15, 15);
var bounds = CGRectMake(0, 0, 15, 15);
// FIXME: http://280north.lighthouseapp.com/projects/13294-cappuccino/tickets/25-implement-cpbox
var dragView = [[CPView alloc] initWithFrame:bounds],
@@ -645,8 +650,8 @@ var CPColorPanelSwatchesCookie = "CPColorPanelSwatchesCookie";
[dragView addSubview:dragFillView];
[self dragView:dragView
at:CPPointMake(point.x - bounds.size.width / 2.0, point.y - bounds.size.height / 2.0)
offset:CPPointMake(0.0, 0.0)
at:CGPointMake(point.x - bounds.size.width / 2.0, point.y - bounds.size.height / 2.0)
offset:CGPointMake(0.0, 0.0)
event:anEvent
pasteboard:nil
source:self
+25 -16
View File
@@ -24,6 +24,14 @@
@import "CPView.j"
@class CPSlider
@class CPColorPanel
@class __CPColorWheel
@global CPColorPickerViewWidth
@global CPColorPickerViewHeight
@global CPWheelColorPickerMode
/*!
@ingroup appkit
@@ -109,15 +117,16 @@
- (id)initView
{
var aFrame = _CGRectMake(0, 0, CPColorPickerViewWidth, CPColorPickerViewHeight);
var aFrame = CGRectMake(0, 0, CPColorPickerViewWidth, CPColorPickerViewHeight);
_pickerView = [[CPView alloc] initWithFrame:aFrame];
[_pickerView setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
_brightnessSlider = [[CPSlider alloc] initWithFrame:_CGRectMake(0, (aFrame.size.height - 34), aFrame.size.width, 15)];
_brightnessSlider = [[CPSlider alloc] initWithFrame:CGRectMake(0, (aFrame.size.height - 34), aFrame.size.width, 15)];
[_brightnessSlider setValue:15.0 forThemeAttribute:@"track-width"];
[_brightnessSlider setValue:[CPColor colorWithPatternImage:[[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:[CPColorPicker class]] pathForResource:@"brightness_bar.png"]]] forThemeAttribute:@"track-color"];
var brightnessImage = [[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:[CPColorPicker class]] pathForResource:@"brightness_bar.png"] size:CGSizeMake(272, 20)];
[_brightnessSlider setValue:[CPColor colorWithPatternImage:brightnessImage] forThemeAttribute:@"track-color"];
[_brightnessSlider setMinValue:0.0];
[_brightnessSlider setMaxValue:100.0];
@@ -127,7 +136,7 @@
[_brightnessSlider setAction:@selector(brightnessSliderDidChange:)];
[_brightnessSlider setAutoresizingMask:CPViewWidthSizable | CPViewMinYMargin];
_hueSaturationView = [[__CPColorWheel alloc] initWithFrame:_CGRectMake(0, 0, aFrame.size.width, aFrame.size.height - 38)];
_hueSaturationView = [[__CPColorWheel alloc] initWithFrame:CGRectMake(0, 0, aFrame.size.width, aFrame.size.height - 38)];
[_hueSaturationView setDelegate:self];
[_hueSaturationView setAutoresizingMask:(CPViewWidthSizable | CPViewHeightSizable)];
@@ -152,12 +161,12 @@
brightness = [_brightnessSlider floatValue];
[_hueSaturationView setWheelBrightness:brightness / 100.0];
[_brightnessSlider setBackgroundColor:[CPColor colorWithHue:hue saturation:saturation brightness:100]];
[_brightnessSlider setBackgroundColor:[CPColor colorWithHue:hue / 360.0 saturation:saturation / 100.0 brightness:1]];
var colorPanel = [self colorPanel],
opacity = [colorPanel opacity];
_cachedColor = [CPColor colorWithHue:hue saturation:saturation brightness:brightness alpha:opacity];
_cachedColor = [CPColor colorWithHue:hue / 360.0 saturation:saturation / 100.0 brightness:brightness / 100.0 alpha:opacity];
[[self colorPanel] setColor:_cachedColor];
}
@@ -188,10 +197,10 @@
var hsb = [newColor hsbComponents];
[_hueSaturationView setPositionToColor:newColor];
[_brightnessSlider setFloatValue:hsb[2]];
[_hueSaturationView setWheelBrightness:hsb[2] / 100.0];
[_brightnessSlider setFloatValue:hsb[2] * 100.0];
[_hueSaturationView setWheelBrightness:hsb[2]];
[_brightnessSlider setBackgroundColor:[CPColor colorWithHue:hsb[0] saturation:hsb[1] brightness:100]];
[_brightnessSlider setBackgroundColor:[CPColor colorWithHue:hsb[0] saturation:hsb[1] brightness:1]];
}
- (CPImage)provideNewButtonImage
@@ -222,7 +231,7 @@
float _radius;
}
- (id)initWithFrame:(CPRect)aFrame
- (id)initWithFrame:(CGRect)aFrame
{
if (self = [super initWithFrame:aFrame])
{
@@ -238,7 +247,7 @@
_blackWheelImage = new Image();
_blackWheelImage.src = path;
_blackWheelImage.style.opacity = "0";
_blackWheelImage.style.filter = "alpha(opacity=0)"
_blackWheelImage.style.filter = "alpha(opacity=0)";
_blackWheelImage.style.position = "absolute";
_DOMElement.appendChild(_wheelImage);
@@ -269,13 +278,13 @@
#endif
}
- (void)setFrameSize:(CPSize)aSize
- (void)setFrameSize:(CGSize)aSize
{
[super setFrameSize:aSize];
[self setWheelSize:aSize];
}
- (void)setWheelSize:(CPSize)aSize
- (void)setWheelSize:(CGSize)aSize
{
var min = MIN(aSize.width, aSize.height);
@@ -353,15 +362,15 @@
_angle = [self radiansToDegrees:angle];
_distance = (distance / _radius) * 100.0;
[_crosshair setFrameOrigin:CPPointMake(COS(angle) * distance + midX - 2.0, SIN(angle) * distance + midY - 2.0)];
[_crosshair setFrameOrigin:CGPointMake(COS(angle) * distance + midX - 2.0, SIN(angle) * distance + midY - 2.0)];
}
- (void)setPositionToColor:(CPColor)aColor
{
var hsb = [aColor hsbComponents],
bounds = [self bounds],
angle = [self degreesToRadians:hsb[0]],
distance = (hsb[1] / 100.0) * _radius;
angle = [self degreesToRadians:hsb[0] * 360.0],
distance = hsb[1] * _radius;
[self setAngle:angle distance:distance];
}
+2
View File
@@ -20,6 +20,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import <Foundation/CPObject.j>
var sRGBColorSpace = nil;
/*!
+67 -37
View File
@@ -45,12 +45,12 @@ var _CPColorWellDidBecomeExclusiveNotification = @"_CPColorWellDidBecomeExclusiv
CPColor _color;
}
+ (Class)_binderClassForBinding:(CPString)theBinding
+ (Class)_binderClassForBinding:(CPString)aBinding
{
if (theBinding == CPValueBinding)
if (aBinding == CPValueBinding)
return [CPColorWellValueBinder class];
return [super _binderClassForBinding:theBinding];
return [super _binderClassForBinding:aBinding];
}
+ (CPString)defaultThemeClass
@@ -58,10 +58,15 @@ var _CPColorWellDidBecomeExclusiveNotification = @"_CPColorWellDidBecomeExclusiv
return @"colorwell";
}
+ (id)themeAttributes
+ (CPDictionary)themeAttributes
{
return [CPDictionary dictionaryWithObjects:[_CGInsetMakeZero(), [CPNull null], _CGInsetMake(3.0, 3.0, 3.0, 3.0), _CGInsetMakeZero(), [CPNull null]]
forKeys:[@"bezel-inset", @"bezel-color", @"content-inset", @"content-border-inset", @"content-border-color"]];
return @{
@"bezel-inset": CGInsetMakeZero(),
@"bezel-color": [CPNull null],
@"content-inset": CGInsetMake(3.0, 3.0, 3.0, 3.0),
@"content-border-inset": CGInsetMakeZero(),
@"content-border-color": [CPNull null],
};
}
- (void)_reverseSetBinding
@@ -81,14 +86,12 @@ var _CPColorWellDidBecomeExclusiveNotification = @"_CPColorWellDidBecomeExclusiv
_active = NO;
_color = [CPColor whiteColor];
[self setBordered:YES];
[self _registerForNotifications];
}
return self;
}
- (void)_registerForNotifications
- (void)_registerNotifications
{
var defaultCenter = [CPNotificationCenter defaultCenter];
@@ -105,6 +108,22 @@ var _CPColorWellDidBecomeExclusiveNotification = @"_CPColorWellDidBecomeExclusiv
object:[CPColorPanel sharedColorPanel]];
}
- (void)_removeNotifications
{
var defaultCenter = [CPNotificationCenter defaultCenter];
[defaultCenter
removeObserver:self
name:_CPColorWellDidBecomeExclusiveNotification
object:nil];
[defaultCenter
removeObserver:self
name:CPWindowWillCloseNotification
object:[CPColorPanel sharedColorPanel]];
}
/*!
Sets whether the color well is bordered.
*/
@@ -236,6 +255,8 @@ var _CPColorWellDidBecomeExclusiveNotification = @"_CPColorWellDidBecomeExclusiv
var colorPanel = [CPColorPanel sharedColorPanel];
[colorPanel setPlatformWindow:[[self window] platformWindow]];
[colorPanel setColor:_color];
[colorPanel orderFront:self];
}
@@ -244,21 +265,21 @@ var _CPColorWellDidBecomeExclusiveNotification = @"_CPColorWellDidBecomeExclusiv
{
var contentInset = [self currentValueForThemeAttribute:@"content-inset"];
return _CGRectInsetByInset(bounds, contentInset);
return CGRectInsetByInset(bounds, contentInset);
}
- (CGRect)bezelRectForBounds:(CGRect)bounds
{
var bezelInset = [self currentValueForThemeAttribute:@"bezel-inset"];
return _CGRectInsetByInset(bounds, bezelInset);
return CGRectInsetByInset(bounds, bezelInset);
}
- (CGRect)contentBorderRectForBounds:(CGRect)bounds
{
var contentBorderInset = [self currentValueForThemeAttribute:@"content-border-inset"];
return _CGRectInsetByInset(bounds, contentBorderInset);
return CGRectInsetByInset(bounds, contentBorderInset);
}
- (CGRect)rectForEphemeralSubviewNamed:(CPString)aName
@@ -278,7 +299,7 @@ var _CPColorWellDidBecomeExclusiveNotification = @"_CPColorWellDidBecomeExclusiv
- (CPView)createEphemeralSubviewNamed:(CPString)aName
{
var view = [[CPView alloc] initWithFrame:_CGRectMakeZero()];
var view = [[CPView alloc] initWithFrame:CGRectMakeZero()];
[view setHitTests:NO];
@@ -307,6 +328,28 @@ var _CPColorWellDidBecomeExclusiveNotification = @"_CPColorWellDidBecomeExclusiv
[contentBorderView setBackgroundColor:[self currentValueForThemeAttribute:@"content-border-color"]];
}
#pragma mark -
#pragma mark Observers method
- (void)_addObservers
{
if (_isObserving)
return;
[super _addObservers];
[self _registerNotifications];
}
- (void)_removeObservers
{
if (!_isObserving)
return;
[super _removeObservers];
[self _removeNotifications];
}
@end
@implementation CPColorWellValueBinder : CPBinder
@@ -315,7 +358,7 @@ var _CPColorWellDidBecomeExclusiveNotification = @"_CPColorWellDidBecomeExclusiv
- (void)_updatePlaceholdersWithOptions:(CPDictionary)options
{
var placeholderColor = [CPColor blueColor];
var placeholderColor = [CPColor blackColor];
[self _setPlaceholder:placeholderColor forMarker:CPMultipleValuesMarker isDefault:YES];
[self _setPlaceholder:placeholderColor forMarker:CPNoSelectionMarker isDefault:YES];
@@ -323,30 +366,19 @@ var _CPColorWellDidBecomeExclusiveNotification = @"_CPColorWellDidBecomeExclusiv
[self _setPlaceholder:placeholderColor forMarker:CPNullMarker isDefault:YES];
}
- (void)setValueFor:(CPString)theBinding
- (id)valueForBinding:(CPString)aBinding
{
var destination = [_info objectForKey:CPObservedObjectKey],
keyPath = [_info objectForKey:CPObservedKeyPathKey],
options = [_info objectForKey:CPOptionsKey],
newValue = [destination valueForKeyPath:keyPath],
isPlaceholder = CPIsControllerMarker(newValue);
return [_source color];
}
if (isPlaceholder)
{
if (newValue === CPNotApplicableMarker && [options objectForKey:CPRaisesForNotApplicableKeysBindingOption])
{
[CPException raise:CPGenericException
reason:@"can't transform non applicable key on: " + _source + " value: " + newValue];
}
- (void)setValue:(id)aValue forBinding:(CPString)theBinding
{
[_source setColor:aValue];
}
newValue = [self _placeholderForMarker:newValue];
}
else
{
newValue = [self transformValue:newValue withOptions:options];
}
[_source setColor:newValue];
- (void)setPlaceholderValue:(id)aValue withMarker:(CPString)aMarker forBinding:(CPString)aBinding
{
[_source setColor:aValue];
}
@end
@@ -369,8 +401,6 @@ var CPColorWellColorKey = "CPColorWellColorKey",
_active = NO;
_color = [aCoder decodeObjectForKey:CPColorWellColorKey];
[self setBordered:[aCoder decodeBoolForKey:CPColorWellBorderedKey]];
[self _registerForNotifications];
}
return self;
+200 -93
View File
@@ -20,10 +20,32 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "CPText.j"
@import "CPTextField.j"
@import "_CPPopUpList.j"
// TODO : should conform to protocol CPTextFieldDelegate
@protocol CPComboBoxDelegate <CPObject>
@optional
- (void)comboBoxSelectionIsChanging:(CPNotification)aNotification;
- (void)comboBoxSelectionDidChange:(CPNotification)aNotification;
- (void)comboBoxWillPopUp:(CPNotification)aNotification;
- (void)comboBoxWillDismiss:(CPNotification)aNotification;
@end
@protocol CPComboBoxDataSource <CPObject>
@optional
- (CPString)comboBox:(CPComboBox)aComboBox completedString:(CPString)uncompletedString;
- (id)comboBox:(CPComboBox)aComboBox objectValueForItemAtIndex:(int)index;
- (int)comboBox:(CPComboBox)aComboBox indexOfItemWithStringValue:(CPString)stringValue;
- (int)numberOfItemsInComboBox:(CPComboBox)aComboBox;
@end
CPComboBoxSelectionDidChangeNotification = @"CPComboBoxSelectionDidChangeNotification";
CPComboBoxSelectionIsChangingNotification = @"CPComboBoxSelectionIsChangingNotification";
CPComboBoxWillDismissNotification = @"CPComboBoxWillDismissNotification";
@@ -31,6 +53,11 @@ CPComboBoxWillPopUpNotification = @"CPComboBoxWillPopUpNotification";
CPComboBoxStateButtonBordered = CPThemeState("button-bordered");
var CPComboBoxDelegate_comboBoxSelectionIsChanging_ = 1 << 0,
CPComboBoxDelegate_comboBoxSelectionDidChange_ = 1 << 1,
CPComboBoxDelegate_comboBoxWillPopUp_ = 1 << 2,
CPComboBoxDelegate_comboBoxWillDismiss_ = 1 << 3;
var CPComboBoxTextSubview = @"text",
CPComboBoxButtonSubview = @"button",
CPComboBoxDefaultNumberOfVisibleItems = 5,
@@ -39,17 +66,20 @@ var CPComboBoxTextSubview = @"text",
@implementation CPComboBox : CPTextField
{
CPArray _items;
_CPPopUpList _listDelegate;
CPComboBoxDataSource _dataSource;
BOOL _usesDataSource;
BOOL _completes;
BOOL _canComplete;
int _numberOfVisibleItems;
BOOL _forceSelection;
BOOL _hasVerticalScroller;
CPString _selectedStringValue;
BOOL _popUpButtonCausedResign;
BOOL _canComplete;
BOOL _completes;
BOOL _forceSelection;
BOOL _hasVerticalScroller;
BOOL _popUpButtonCausedResign;
BOOL _usesDataSource;
CGSize _intercellSpacing;
CPArray _items;
id <CPComboBoxDataSource> _dataSource;
CPInteger _implementedDelegateComboBoxMethods;
CPString _selectedStringValue;
float _itemHeight;
int _numberOfVisibleItems;
_CPPopUpList _listDelegate;
}
+ (CPString)defaultThemeClass
@@ -57,17 +87,20 @@ var CPComboBoxTextSubview = @"text",
return "combobox";
}
+ (id)themeAttributes
+ (CPDictionary)themeAttributes
{
return [CPDictionary dictionaryWithObjectsAndKeys:_CGSizeMake(21.0, 29.0), @"popup-button-size", _CGInsetMake(3.0, 3.0, 3.0, 3.0), @"border-inset"];
return @{
@"popup-button-size": CGSizeMake(21.0, 29.0),
@"border-inset": CGInsetMake(3.0, 3.0, 3.0, 3.0),
};
}
+ (Class)_binderClassForBinding:(CPString)theBinding
+ (Class)_binderClassForBinding:(CPString)aBinding
{
if (theBinding === CPContentBinding || theBinding === CPContentValuesBinding)
if (aBinding === CPContentBinding || aBinding === CPContentValuesBinding)
return [_CPComboBoxContentBinder class];
return [super _binderClassForBinding:theBinding];
return [super _binderClassForBinding:aBinding];
}
- (id)initWithFrame:(CGRect)aFrame
@@ -83,7 +116,7 @@ var CPComboBoxTextSubview = @"text",
- (void)_initComboBox
{
_items = [CPArray array];
_listClass = [_CPPopUpList class];
// _listClass = [_CPPopUpList class];
_usesDataSource = NO;
_completes = NO;
_canComplete = NO;
@@ -115,7 +148,9 @@ var CPComboBoxTextSubview = @"text",
return;
_hasVerticalScroller = flag;
[[_listDelegate scrollView] setHasVerticalScroller:flag];
if (_listDelegate)
[[_listDelegate scrollView] setHasVerticalScroller:_hasVerticalScroller];
}
- (CGSize)intercellSpacing
@@ -125,7 +160,13 @@ var CPComboBoxTextSubview = @"text",
- (void)setIntercellSpacing:(CGSize)aSize
{
[[_listDelegate tableView] setIntercellSpacing:aSize];
if (_intercellSpacing && CGSizeEqualToSize(aSize, _intercellSpacing))
return;
_intercellSpacing = aSize;
if (_listDelegate)
[[_listDelegate tableView] setIntercellSpacing:_intercellSpacing];
}
- (BOOL)isButtonBordered
@@ -148,10 +189,18 @@ var CPComboBoxTextSubview = @"text",
- (void)setItemHeight:(float)itemHeight
{
[[_listDelegate tableView] setRowHeight:itemHeight];
if (itemHeight === _itemHeight)
return;
// FIXME: This shouldn't be necessary, but CPTableView does not tile after setRowHeight
[[_listDelegate tableView] reloadData];
_itemHeight = itemHeight;
if (_listDelegate)
{
[[_listDelegate tableView] setRowHeight:_itemHeight];
// FIXME: This shouldn't be necessary, but CPTableView does not tile after setRowHeight
[[_listDelegate tableView] reloadData];
}
}
- (int)numberOfVisibleItems
@@ -167,7 +216,7 @@ var CPComboBoxTextSubview = @"text",
#pragma mark Setting a Delegate
- (id < CPComboBoxDelegate >)delegate
- (id <CPComboBoxDelegate>)delegate
{
return [super delegate];
}
@@ -178,48 +227,28 @@ var CPComboBoxTextSubview = @"text",
protocol, in actual fact it doesn't. Also note that the same
delegate may conform to the NSTextFieldDelegate protocol.
*/
- (void)setDelegate:(id < CPComboBoxDelegate >)aDelegate
- (void)setDelegate:(id <CPComboBoxDelegate>)aDelegate
{
var delegate = [self delegate];
if (aDelegate === delegate)
return;
var defaultCenter = [CPNotificationCenter defaultCenter];
if (delegate)
{
[defaultCenter removeObserver:delegate name:CPComboBoxSelectionIsChangingNotification object:self];
[defaultCenter removeObserver:delegate name:CPComboBoxSelectionDidChangeNotification object:self];
[defaultCenter removeObserver:delegate name:CPComboBoxWillDismissNotification object:self];
[defaultCenter removeObserver:delegate name:CPComboBoxWillPopUpNotification object:self];
}
_implementedDelegateComboBoxMethods = 0;
if (aDelegate)
{
if ([aDelegate respondsToSelector:@selector(comboBoxSelectionIsChanging:)])
[defaultCenter addObserver:delegate
selector:@selector(comboBoxSelectionIsChanging:)
name:CPComboBoxSelectionIsChangingNotification
object:self];
_implementedDelegateComboBoxMethods |= CPComboBoxDelegate_comboBoxSelectionIsChanging_;
if ([aDelegate respondsToSelector:@selector(comboBoxSelectionDidChange:)])
[defaultCenter addObserver:delegate
selector:@selector(comboBoxSelectionDidChange:)
name:CPComboBoxSelectionDidChangeNotification
object:self];
_implementedDelegateComboBoxMethods |= CPComboBoxDelegate_comboBoxSelectionDidChange_;
if ([aDelegate respondsToSelector:@selector(comboBoxWillPopUp:)])
[defaultCenter addObserver:delegate
selector:@selector(comboBoxWillPopUp:)
name:CPComboBoxWillPopUpNotification
object:self];
_implementedDelegateComboBoxMethods |= CPComboBoxDelegate_comboBoxWillPopUp_;
if ([aDelegate respondsToSelector:@selector(comboBoxWillDismiss:)])
[defaultCenter addObserver:delegate
selector:@selector(comboBoxWillDissmis:)
name:CPComboBoxWillDismissNotification
object:self];
_implementedDelegateComboBoxMethods |= CPComboBoxDelegate_comboBoxWillDismiss_;
}
[super setDelegate:aDelegate];
@@ -227,7 +256,7 @@ var CPComboBoxTextSubview = @"text",
#pragma mark Setting a Data Source
- (id < CPComboBoxDataSource >)dataSource
- (id <CPComboBoxDataSource>)dataSource
{
if (!_usesDataSource)
[self _dataSourceWarningForMethod:_cmd condition:NO];
@@ -235,10 +264,12 @@ var CPComboBoxTextSubview = @"text",
return _dataSource;
}
- (void)setDataSource:(id < CPComboBoxDataSource >)aSource
- (void)setDataSource:(id <CPComboBoxDataSource>)aSource
{
if (!_usesDataSource)
{
[self _dataSourceWarningForMethod:_cmd condition:NO];
}
else if (_dataSource !== aSource)
{
if (![aSource respondsToSelector:@selector(numberOfItemsInComboBox:)] ||
@@ -247,7 +278,9 @@ var CPComboBoxTextSubview = @"text",
CPLog.warn("Illegal %s data source (%s). Must implement numberOfItemsInComboBox: and comboBox:objectValueForItemAtIndex:", [self className], [aSource description]);
}
else
{
_dataSource = aSource;
}
}
}
@@ -365,49 +398,57 @@ var CPComboBoxTextSubview = @"text",
if (_listDelegate === aDelegate)
return;
var defaultCenter = [CPNotificationCenter defaultCenter];
if (_listDelegate)
{
[defaultCenter removeObserver:self name:_CPPopUpListWillPopUpNotification object:_listDelegate];
[defaultCenter removeObserver:self name:_CPPopUpListWillDismissNotification object:_listDelegate];
[defaultCenter removeObserver:self name:_CPPopUpListDidDismissNotification object:_listDelegate];
[defaultCenter removeObserver:self name:_CPPopUpListItemWasClickedNotification object:_listDelegate];
var oldTableView = [_listDelegate tableView];
if (oldTableView)
{
[defaultCenter removeObserver:self name:CPTableViewSelectionIsChangingNotification object:oldTableView];
[defaultCenter removeObserver:self name:CPTableViewSelectionDidChangeNotification object:oldTableView];
}
}
[self _removeObserversForListDelegate:_listDelegate];
_listDelegate = aDelegate;
// We only add the observers if the CPComboBox is displayed
if ([self window])
[self _addObserversForListDelegate:_listDelegate]
// Apply our text style to the list
[_listDelegate setFont:[self font]];
[_listDelegate setAlignment:[self alignment]];
[[_listDelegate scrollView] setHasVerticalScroller:_hasVerticalScroller];
if (_intercellSpacing)
[[_listDelegate tableView] setIntercellSpacing:_intercellSpacing];
if (_itemHeight)
[[_listDelegate tableView] setRowHeight:_itemHeight];
}
- (void)_addObserversForListDelegate:(_CPPopUpList)aDelegate
{
if (!aDelegate)
return;
var defaultCenter = [CPNotificationCenter defaultCenter];
[defaultCenter addObserver:self
selector:@selector(comboBoxWillPopUp:)
name:_CPPopUpListWillPopUpNotification
object:_listDelegate];
object:aDelegate];
[defaultCenter addObserver:self
selector:@selector(comboBoxWillDismiss:)
name:_CPPopUpListWillDismissNotification
object:_listDelegate];
object:aDelegate];
[defaultCenter addObserver:self
selector:@selector(listDidDismiss:)
name:_CPPopUpListDidDismissNotification
object:_listDelegate];
object:aDelegate];
[defaultCenter addObserver:self
selector:@selector(itemWasClicked:)
name:_CPPopUpListItemWasClickedNotification
object:_listDelegate];
object:aDelegate];
[[_listDelegate scrollView] setHasVerticalScroller:_hasVerticalScroller];
[[aDelegate scrollView] setHasVerticalScroller:_hasVerticalScroller];
var tableView = [_listDelegate tableView];
var tableView = [aDelegate tableView];
[defaultCenter addObserver:self
selector:@selector(comboBoxSelectionIsChanging:)
@@ -418,10 +459,27 @@ var CPComboBoxTextSubview = @"text",
selector:@selector(comboBoxSelectionDidChange:)
name:CPTableViewSelectionDidChangeNotification
object:tableView];
}
// Apply our text style to the list
[_listDelegate setFont:[self font]];
[_listDelegate setAlignment:[self alignment]];
- (void)_removeObserversForListDelegate:(_CPPopUpList)aDelegate
{
if (!aDelegate)
return;
var defaultCenter = [CPNotificationCenter defaultCenter];
[defaultCenter removeObserver:self name:_CPPopUpListWillPopUpNotification object:aDelegate];
[defaultCenter removeObserver:self name:_CPPopUpListWillDismissNotification object:aDelegate];
[defaultCenter removeObserver:self name:_CPPopUpListDidDismissNotification object:aDelegate];
[defaultCenter removeObserver:self name:_CPPopUpListItemWasClickedNotification object:aDelegate];
var oldTableView = [aDelegate tableView];
if (oldTableView)
{
[defaultCenter removeObserver:self name:CPTableViewSelectionIsChangingNotification object:oldTableView];
[defaultCenter removeObserver:self name:CPTableViewSelectionDidChangeNotification object:oldTableView];
}
}
- (int)indexOfItemWithObjectValue:(id)anObject
@@ -466,8 +524,6 @@ var CPComboBoxTextSubview = @"text",
if (!_listDelegate)
[self setListDelegate:[[_CPPopUpList alloc] initWithDataSource:self]];
[self _selectMatchingItem];
// Note the offset here is 1 less than the focus ring width because the outer edge
// of the focus ring is very transparent and it looks better if the list is closer.
if (CPComboBoxFocusRingWidth < 0)
@@ -478,6 +534,7 @@ var CPComboBoxTextSubview = @"text",
}
[_listDelegate popUpRelativeToRect:[self _borderFrame] view:self offset:CPComboBoxFocusRingWidth - 1];
[self _selectMatchingItem];
}
/*! @ignore */
@@ -786,7 +843,17 @@ var CPComboBoxTextSubview = @"text",
// In FireFox this needs to be done in setTimeout, otherwise there is no caret
// We have to save the input element now, when we lose focus it will change.
var element = [self _inputElement];
window.setTimeout(function() { element.focus(); }, 0);
[[CPRunLoop mainRunLoop] performBlock:function()
{
// This will prevent to jump to the focused element
var previousScrollingOrigin = [self _scrollToVisibleRectAndReturnPreviousOrigin];
element.focus();
[self _restorePreviousScrollingOrigin:previousScrollingOrigin];
} argument:nil order:0 modes:[CPDefaultRunLoopMode]];
#endif
return NO;
@@ -813,13 +880,17 @@ var CPComboBoxTextSubview = @"text",
- (void)setFont:(CPFont)aFont
{
[super setFont:aFont];
[_listDelegate setFont:aFont];
if (_listDelegate)
[_listDelegate setFont:aFont];
}
- (void)setAlignment:(CPTextAlignment)alignment
{
[super setAlignment:alignment];
[_listDelegate setAlignment:alignment];
if (_listDelegate)
[_listDelegate setAlignment:alignment];
}
#pragma mark Pop Up Button Layout
@@ -850,7 +921,7 @@ var CPComboBoxTextSubview = @"text",
{
if (aName === "popup-button-view")
{
var view = [[_CPComboBoxPopUpButton alloc] initWithFrame:_CGRectMakeZero() comboBox:self];
var view = [[_CPComboBoxPopUpButton alloc] initWithFrame:CGRectMakeZero() comboBox:self];
return view;
}
@@ -890,7 +961,9 @@ var CPComboBoxTextSubview = @"text",
index = [_dataSource comboBox:self indexOfItemWithStringValue:stringValue]
}
else
{
index = [self indexOfItemWithObjectValue:stringValue];
}
[_listDelegate selectRow:index];
@@ -942,6 +1015,28 @@ var CPComboBoxTextSubview = @"text",
}
}
#pragma mark -
#pragma mark Observers method
- (void)_addObservers
{
if (_isObserving)
return;
[super _addObservers];
[self _addObserversForListDelegate:_listDelegate];
}
- (void)_removeObservers
{
if (!_isObserving)
return;
[super _removeObservers];
[self _removeObserversForListDelegate:_listDelegate];
}
@end
@implementation CPComboBox (CPComboBoxDelegate)
@@ -949,24 +1044,36 @@ var CPComboBoxTextSubview = @"text",
/*! @ignore */
- (void)comboBoxSelectionIsChanging:(CPNotification)aNotification
{
if (_implementedDelegateComboBoxMethods & CPComboBoxDelegate_comboBoxSelectionIsChanging_)
[_delegate comboBoxSelectionIsChanging:[[CPNotification alloc] initWithName:CPComboBoxSelectionIsChangingNotification object:self userInfo:nil]];
[[CPNotificationCenter defaultCenter] postNotificationName:CPComboBoxSelectionIsChangingNotification object:self];
}
/*! @ignore */
- (void)comboBoxSelectionDidChange:(CPNotification)aNotification
{
if (_implementedDelegateComboBoxMethods & CPComboBoxDelegate_comboBoxSelectionDidChange_)
[_delegate comboBoxSelectionDidChange:[[CPNotification alloc] initWithName:CPComboBoxSelectionDidChangeNotification object:self userInfo:nil]];
[[CPNotificationCenter defaultCenter] postNotificationName:CPComboBoxSelectionDidChangeNotification object:self];
}
/*! @ignore */
- (void)comboBoxWillPopUp:(CPNotification)aNotification
{
if (_implementedDelegateComboBoxMethods & CPComboBoxDelegate_comboBoxWillPopUp_)
[_delegate comboBoxWillPopUp:[[CPNotification alloc] initWithName:CPComboBoxWillPopUpNotification object:self userInfo:nil]];
[[CPNotificationCenter defaultCenter] postNotificationName:CPComboBoxWillPopUpNotification object:self];
}
/*! @ignore */
- (void)comboBoxWillDismiss:(CPNotification)aNotification
{
if (_implementedDelegateComboBoxMethods & CPComboBoxDelegate_comboBoxWillDismiss_)
[_delegate comboBoxWillDismiss:[[CPNotification alloc] initWithName:CPComboBoxWillDismissNotification object:self userInfo:nil]];
[[CPNotificationCenter defaultCenter] postNotificationName:CPComboBoxWillDismissNotification object:self];
}
@@ -1035,11 +1142,9 @@ var CPComboBoxTextSubview = @"text",
// Directly nuke _items, [_items removeAll] will trigger an extra call to setContent
_items = [];
var values = [];
[anArray enumerateObjectsUsingBlock:function(object)
var values = [anArray arrayByApplyingBlock:function(object)
{
values.push([object description]);
return [object description];
}];
[self addItemsWithObjectValues:values];
@@ -1110,7 +1215,7 @@ var CPComboBoxCompletionTest = function(object, index, context)
*/
@implementation _CPComboBoxContentBinder : CPBinder
- (void)setValueFor:(CPString)theBinding
- (void)setValueFor:(CPString)aBinding
{
var destination = [_info objectForKey:CPObservedObjectKey],
keyPath = [_info objectForKey:CPObservedKeyPathKey],
@@ -1152,13 +1257,15 @@ var CPComboBoxCompletionTest = function(object, index, context)
else
newValue = [self transformValue:newValue withOptions:options];
switch (theBinding)
switch (aBinding)
{
case CPContentBinding: [_source setContent:newValue];
break;
case CPContentBinding:
[_source setContent:newValue];
break;
case CPContentValuesBinding: [_source setContentValues:newValue];
break;
case CPContentValuesBinding:
[_source setContentValues:newValue];
break;
}
}
+182 -79
View File
@@ -20,17 +20,18 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "CPEvent.j"
@import "CPEvent_Constants.j"
@import "CPPlatform.j"
// Browser Engines
CPUnknownBrowserEngine = 0;
CPGeckoBrowserEngine = 1;
CPInternetExplorerBrowserEngine = 2;
CPKHTMLBrowserEngine = 3;
CPOperaBrowserEngine = 4;
CPWebKitBrowserEngine = 5;
CPGeckoBrowserEngine = 1 << 0;
CPInternetExplorerBrowserEngine = 1 << 1;
CPKHTMLBrowserEngine = 1 << 2;
CPOperaBrowserEngine = 1 << 3;
CPWebKitBrowserEngine = 1 << 4; // Safari + Chrome
CPBlinkBrowserEngine = 1 << 5; // Recent Chrome
// Operating Systems
CPMacOperatingSystem = 0;
@@ -38,58 +39,80 @@ CPWindowsOperatingSystem = 1;
CPOtherOperatingSystem = 2;
// Features
CPCSSRGBAFeature = 1 << 5;
CPCSSRGBAFeature = 5;
CPHTMLCanvasFeature = 1 << 6;
CPHTMLContentEditableFeature = 1 << 7;
CPHTMLDragAndDropFeature = 1 << 8;
CPHTMLCanvasFeature = 6;
CPHTMLContentEditableFeature = 7;
CPHTMLDragAndDropFeature = 8;
CPJavaScriptInnerTextFeature = 1 << 9;
CPJavaScriptTextContentFeature = 1 << 10;
CPJavaScriptClipboardEventsFeature = 1 << 11;
CPJavaScriptClipboardAccessFeature = 1 << 12;
CPJavaScriptCanvasDrawFeature = 1 << 13;
CPJavaScriptCanvasTransformFeature = 1 << 14;
CPJavaScriptInnerTextFeature = 9;
CPJavaScriptTextContentFeature = 10;
// In onpaste, oncopy and oncut events, the event has an event.clipboardData from which the current pasteboard contents can be read with event.clipboardData.getData.
CPJavaScriptClipboardEventsFeature = 11;
// window.clipboardData exists and can be read and written to at any time using window.clipboardData.getData/setData.
CPJavaScriptClipboardAccessFeature = 12;
CPJavaScriptCanvasDrawFeature = 13;
CPJavaScriptCanvasTransformFeature = 14;
CPVMLFeature = 1 << 15;
CPVMLFeature = 15;
CPJavaScriptRemedialKeySupport = 1 << 16;
CPJavaScriptShadowFeature = 1 << 20;
CPJavaScriptRemedialKeySupport = 16;
CPJavaScriptShadowFeature = 20;
CPJavaScriptNegativeMouseWheelValues = 1 << 22;
CPJavaScriptMouseWheelValues_8_15 = 1 << 23;
CPJavaScriptNegativeMouseWheelValues = 22;
CPJavaScriptMouseWheelValues_8_15 = 23;
CPOpacityRequiresFilterFeature = 1 << 24;
CPOpacityRequiresFilterFeature = 24;
//Internet explorer does not allow dynamically changing the type of an input element
CPInputTypeCanBeChangedFeature = 1 << 25;
CPHTML5DragAndDropSourceYOffBy1 = 1 << 26;
// Internet explorer does not allow dynamically changing the type of an input element
CPInputTypeCanBeChangedFeature = 25;
CPHTML5DragAndDropSourceYOffBy1 = 26;
CPSOPDisabledFromFileURLs = 1 << 27;
CPSOPDisabledFromFileURLs = 27;
// element.style.font can be set for an element not in the DOM.
CPInputSetFontOutsideOfDOM = 1 << 28;
CPInputSetFontOutsideOfDOM = 28;
// Input elements have 1 px of extra padding on the left regardless of padding setting.
CPInput1PxLeftPadding = 1 << 29;
CPInputOnInputEventFeature = 1 << 30;
CPInput1PxLeftPadding = 29;
CPInputOnInputEventFeature = 30;
// When an absolutely positioned div (CPView) with an absolutely positioned canvas in it (CPView with drawRect:) moves things on top of the canvas
// (subviews) don't redraw correctly. E.g. if you have a bunch of text fields in a CPBox in a sheet which animates in, some of the text fields might
// not be visible because the CPBox has a canvas at the bottom and the box moved form offscreen to onscreen.
// This bug is probably very related: https://bugs.webkit.org/show_bug.cgi?id=67203
CPFileAPIFeature = 31;
CPAltEnterTextAreaFeature = 32;
CPCSSAnimationFeature = 33;
/*
When an absolutely positioned div (CPView) with an absolutely positioned canvas in it (CPView with drawRect:) moves things on top of the canvas (subviews) don't redraw correctly. E.g. if you have a bunch of text fields in a CPBox in a sheet which animates in, some of the text fields might not be visible because the CPBox has a canvas at the bottom and the box moved form offscreen to onscreen. This bug is probably very related: https://bugs.webkit.org/show_bug.cgi?id=67203
*/
CPCanvasParentDrawErrorsOnMovementBug = 1 << 0;
// The paste event is only sent if an input or textarea has focus.
CPJavaScriptPasteRequiresEditableTarget = 1 << 1;
// Redirecting the focus of the browser on keydown to an input for Cmd-V or Ctrl-V makes the paste fail.
CPJavaScriptPasteCantRefocus = 1 << 2;
/*
Safari calculates incorrect text size unless you set the canvas font even if it is already set
You can see the bug after disabling the workaround and opening any panel while typing.
You can use the font panel in the manual test for CPTextView.
Look out for a displaced cursor, i.e. after typing letters of small width, such as the 'i'.
https://bugs.webkit.org/show_bug.cgi?id=150224
*/
CPTextSizingAlwaysNeedsSetFontBug = 1 << 3;
var USER_AGENT = "",
PLATFORM_ENGINE = CPUnknownBrowserEngine,
PLATFORM_FEATURES = 0,
PLATFORM_FEATURES = [],
PLATFORM_BUGS = 0,
PLATFORM_STYLE_JS_PROPERTIES = {};
// default these features to true
PLATFORM_FEATURES |= CPInputTypeCanBeChangedFeature;
PLATFORM_FEATURES |= CPInputSetFontOutsideOfDOM;
PLATFORM_FEATURES[CPInputTypeCanBeChangedFeature] = YES;
PLATFORM_FEATURES[CPInputSetFontOutsideOfDOM] = YES;
PLATFORM_FEATURES[CPAltEnterTextAreaFeature] = YES;
if (typeof window !== "undefined" && typeof window.navigator !== "undefined")
USER_AGENT = window.navigator.userAgent;
@@ -97,44 +120,44 @@ if (typeof window !== "undefined" && typeof window.navigator !== "undefined")
// Opera
if (typeof window !== "undefined" && window.opera)
{
PLATFORM_ENGINE = CPOperaBrowserEngine;
PLATFORM_ENGINE |= CPOperaBrowserEngine;
PLATFORM_FEATURES |= CPJavaScriptCanvasDrawFeature;
PLATFORM_FEATURES[CPJavaScriptCanvasDrawFeature] = YES;
}
// Internet Explorer
else if (typeof window !== "undefined" && window.attachEvent) // Must follow Opera check.
else if (typeof window !== "undefined" && (window.attachEvent || (!(window.ActiveXObject) && "ActiveXObject" in window))) // Must follow Opera check.
{
PLATFORM_ENGINE = CPInternetExplorerBrowserEngine;
PLATFORM_ENGINE |= CPInternetExplorerBrowserEngine;
// Features we can only be sure of with IE (no known independent tests)
PLATFORM_FEATURES |= CPVMLFeature;
PLATFORM_FEATURES |= CPJavaScriptRemedialKeySupport;
PLATFORM_FEATURES |= CPJavaScriptShadowFeature;
PLATFORM_FEATURES[CPVMLFeature] = YES;
PLATFORM_FEATURES[CPJavaScriptRemedialKeySupport] = YES;
PLATFORM_FEATURES[CPJavaScriptShadowFeature] = YES;
PLATFORM_FEATURES |= CPOpacityRequiresFilterFeature;
PLATFORM_FEATURES[CPOpacityRequiresFilterFeature] = YES;
PLATFORM_FEATURES &= ~CPInputTypeCanBeChangedFeature;
PLATFORM_FEATURES[CPInputTypeCanBeChangedFeature] = NO;
// Tested in Internet Explore 8 and 9.
PLATFORM_FEATURES &= ~CPInputSetFontOutsideOfDOM;
PLATFORM_FEATURES[CPInputSetFontOutsideOfDOM] = NO;
// IE allows free clipboard access.
PLATFORM_FEATURES[CPJavaScriptClipboardAccessFeature] = YES;
}
// WebKit
// Safari + Chrome (WebKit and Blink)
else if (USER_AGENT.indexOf("AppleWebKit/") != -1)
{
PLATFORM_ENGINE = CPWebKitBrowserEngine;
PLATFORM_ENGINE |= CPWebKitBrowserEngine;
// Features we can only be sure of with WebKit (no known independent tests)
PLATFORM_FEATURES |= CPCSSRGBAFeature;
PLATFORM_FEATURES |= CPHTMLContentEditableFeature;
PLATFORM_FEATURES[CPCSSRGBAFeature] = YES;
PLATFORM_FEATURES[CPHTMLContentEditableFeature] = YES;
if (USER_AGENT.indexOf("Chrome") === -1)
PLATFORM_FEATURES |= CPHTMLDragAndDropFeature;
PLATFORM_FEATURES |= CPJavaScriptClipboardEventsFeature;
PLATFORM_FEATURES |= CPJavaScriptClipboardAccessFeature;
PLATFORM_FEATURES |= CPJavaScriptShadowFeature;
PLATFORM_FEATURES[CPJavaScriptClipboardEventsFeature] = YES;
PLATFORM_FEATURES[CPJavaScriptClipboardAccessFeature] = NO;
PLATFORM_FEATURES[CPJavaScriptShadowFeature] = YES;
var versionStart = USER_AGENT.indexOf("AppleWebKit/") + "AppleWebKit/".length,
versionEnd = USER_AGENT.indexOf(" ", versionStart),
@@ -144,22 +167,32 @@ else if (USER_AGENT.indexOf("AppleWebKit/") != -1)
minorVersion = parseInt(versionString.substr(versionDivision + 1));
if ((USER_AGENT.indexOf("Safari") !== CPNotFound && (majorVersion > 525 || (majorVersion === 525 && minorVersion > 14))) || USER_AGENT.indexOf("Chrome") !== CPNotFound)
PLATFORM_FEATURES |= CPJavaScriptRemedialKeySupport;
PLATFORM_FEATURES[CPJavaScriptRemedialKeySupport] = YES;
// FIXME this is a terrible hack to get around this bug:
// https://bugs.webkit.org/show_bug.cgi?id=21548
if (![CPPlatform isBrowser])
PLATFORM_FEATURES |= CPJavaScriptRemedialKeySupport;
PLATFORM_FEATURES[CPJavaScriptRemedialKeySupport] = YES;
if (majorVersion < 532 || (majorVersion === 532 && minorVersion < 6))
PLATFORM_FEATURES |= CPHTML5DragAndDropSourceYOffBy1;
PLATFORM_FEATURES[CPHTML5DragAndDropSourceYOffBy1] = YES;
// This is supposedly fixed in webkit r123603. Seems to work in Chrome 21 but not Safari 6.0.
if (majorVersion < 537)
PLATFORM_FEATURES |= CPInput1PxLeftPadding;
PLATFORM_FEATURES[CPInput1PxLeftPadding] = YES;
if (USER_AGENT.indexOf("Chrome") === CPNotFound)
PLATFORM_FEATURES |= CPSOPDisabledFromFileURLs;
{
PLATFORM_FEATURES[CPSOPDisabledFromFileURLs] = YES;
PLATFORM_FEATURES[CPHTMLDragAndDropFeature] = YES;
// https://bugs.webkit.org/show_bug.cgi?id=75891
PLATFORM_BUGS |= CPJavaScriptPasteRequiresEditableTarget;
// https://bugs.webkit.org/show_bug.cgi?id=39689
PLATFORM_BUGS |= CPJavaScriptPasteCantRefocus;
PLATFORM_BUGS |= CPTextSizingAlwaysNeedsSetFontBug;
}
else if ((window.chrome || (window.Intl && Intl.v8BreakIterator)) && 'CSS' in window)
PLATFORM_ENGINE |= CPBlinkBrowserEngine;
// Assume this bug was introduced around Safari 5.1/Chrome 16. This could probably be tighter.
if (majorVersion > 533)
@@ -169,67 +202,94 @@ else if (USER_AGENT.indexOf("AppleWebKit/") != -1)
// KHTML
else if (USER_AGENT.indexOf("KHTML") != -1) // Must follow WebKit check.
{
PLATFORM_ENGINE = CPKHTMLBrowserEngine;
PLATFORM_ENGINE |= CPKHTMLBrowserEngine;
}
// Gecko
else if (USER_AGENT.indexOf("Gecko") !== -1) // Must follow KHTML check.
{
PLATFORM_ENGINE = CPGeckoBrowserEngine;
PLATFORM_ENGINE |= CPGeckoBrowserEngine;
PLATFORM_FEATURES |= CPJavaScriptCanvasDrawFeature;
PLATFORM_FEATURES[CPJavaScriptCanvasDrawFeature] = YES;
var index = USER_AGENT.indexOf("Firefox"),
version = (index === -1) ? 2.0 : parseFloat(USER_AGENT.substring(index + "Firefox".length + 1));
if (version >= 3.0)
PLATFORM_FEATURES |= CPCSSRGBAFeature;
PLATFORM_FEATURES[CPCSSRGBAFeature] = YES;
if (version < 3.0)
PLATFORM_FEATURES |= CPJavaScriptMouseWheelValues_8_15;
PLATFORM_FEATURES[CPJavaScriptMouseWheelValues_8_15] = YES;
// Some day this might be fixed and should be version prefixed. No known fixed version yet.
PLATFORM_FEATURES |= CPInput1PxLeftPadding;
PLATFORM_FEATURES[CPInput1PxLeftPadding] = YES;
PLATFORM_FEATURES[CPAltEnterTextAreaFeature] = NO;
// This was supposed to be added in Firefox 22, but when testing with the latest beta as of 2013-06-14
// it does not seem to work. It seems to exhibit the CPJavaScriptPasteRequiresEditableTarget problem,
// and in addition doesn't seem to work with our native copy code either.
/*if (version >= 22.0)
{
PLATFORM_FEATURES[CPJavaScriptClipboardEventsFeature] = YES;
// TODO File a bug at https://bugzilla.mozilla.org/. In other browsers, one can return "false" from the
// beforepaste event to indicate a paste should be enabled even that the DOMEvent.target is not editable.
PLATFORM_BUGS |= CPJavaScriptPasteRequiresEditableTarget;
}*/
}
// Feature Specific Checks
// Feature-specific checks
if (typeof document != "undefined")
{
var canvasElement = document.createElement("canvas");
// Detect Canvas Support
// Detect canvas support
if (canvasElement && canvasElement.getContext)
{
PLATFORM_FEATURES |= CPHTMLCanvasFeature;
PLATFORM_FEATURES[CPHTMLCanvasFeature] = YES;
// Detect Canvas setTransform/transform support
// Any browser that supports canvas supports CSS opacity
PLATFORM_FEATURES[CPOpacityRequiresFilterFeature] = NO;
// Detect canvas setTransform/transform support
var context = document.createElement("canvas").getContext("2d");
if (context && context.setTransform && context.transform)
PLATFORM_FEATURES |= CPJavaScriptCanvasTransformFeature;
PLATFORM_FEATURES[CPJavaScriptCanvasTransformFeature] = YES;
}
var DOMElement = document.createElement("div");
// Detect whether we have innerText or textContent (or neither)
if (DOMElement.innerText != undefined)
PLATFORM_FEATURES |= CPJavaScriptInnerTextFeature;
PLATFORM_FEATURES[CPJavaScriptInnerTextFeature] = YES;
else if (DOMElement.textContent != undefined)
PLATFORM_FEATURES |= CPJavaScriptTextContentFeature;
PLATFORM_FEATURES[CPJavaScriptTextContentFeature] = YES;
var DOMInputElement = document.createElement("input");
if ("oninput" in DOMInputElement)
PLATFORM_FEATURES |= CPInputOnInputEventFeature;
PLATFORM_FEATURES[CPInputOnInputEventFeature] = YES;
else if (typeof DOMInputElement.setAttribute === "function")
{
DOMInputElement.setAttribute("oninput", "return;");
if (typeof DOMInputElement.oninput === "function")
PLATFORM_FEATURES |= CPInputOnInputEventFeature;
PLATFORM_FEATURES[CPInputOnInputEventFeature] = YES;
}
// Detect FileAPI support
if (typeof DOMInputElement.setAttribute === "function")
{
DOMInputElement.setAttribute("type", "file");
PLATFORM_FEATURES[CPFileAPIFeature] = !!DOMInputElement["files"];
}
else
PLATFORM_FEATURES[CPFileAPIFeature] = NO;
}
function CPFeatureIsCompatible(aFeature)
{
return PLATFORM_FEATURES & aFeature;
return !!PLATFORM_FEATURES[aFeature];
}
function CPPlatformHasBug(aBug)
@@ -239,7 +299,7 @@ function CPPlatformHasBug(aBug)
function CPBrowserIsEngine(anEngine)
{
return PLATFORM_ENGINE === anEngine;
return PLATFORM_ENGINE & anEngine;
}
function CPBrowserIsOperatingSystem(anOperatingSystem)
@@ -275,6 +335,14 @@ else
CPRedoKeyEquivalentModifierMask = CPControlKeyMask;
}
/*!
Sets a feature with the given value.
*/
function CPSetPlatformFeature(aFeature, aBool)
{
PLATFORM_FEATURES[aFeature] = aBool;
}
/*!
Return the properly prefixed JS property for the given name. E.g. in a webkit browser,
CPBrowserStyleProperty('transition') -> WebkitTransition
@@ -308,6 +376,32 @@ function CPBrowserStyleProperty(aProperty)
r = candidates[PLATFORM_STYLE_JS_PROPERTIES['transition']] || nil;
break;
case 'transformorigin':
var candidates = {
'WebkitTransform' : 'WebkitTransformOrigin',
'MozTransform' : 'MozTransformOrigin',
'OTransform' : 'OTransformOrigin',
'msTransform' : 'MSTransformOrigin',
'transform' : 'transformOrigin'
};
r = candidates[PLATFORM_STYLE_JS_PROPERTIES['transform']] || nil;
break;
case 'animationend':
var candidates = {
'WebkitAnimation' : 'webkitAnimationEnd',
'MozAnimation' : 'animationend',
'OAnimation' : 'oAnimationEnd',
'msAnimation' : 'MSAnimationEnd',
'animation' : 'animationend'
};
r = candidates[PLATFORM_STYLE_JS_PROPERTIES['animation']] || nil;
break;
default:
var prefixes = ["Webkit", "Moz", "O", "ms"],
strippedProperty = aProperty.split('-').join(' '),
@@ -377,3 +471,12 @@ function CPBrowserCSSProperty(aProperty)
return browserProperty.toLowerCase();
}
function CPBrowserBackingStorePixelRatio(context)
{
return context.webkitBackingStorePixelRatio ||
context.mozBackingStorePixelRatio ||
context.msBackingStorePixelRatio ||
context.oBackingStorePixelRatio ||
context.backingStorePixelRatio || 1;
}
+269 -49
View File
@@ -20,24 +20,35 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#import "../Foundation/Ref.h"
@import <Foundation/CPFormatter.j>
@import <Foundation/CPTimer.j>
@import "../Foundation/CPFormatter.j"
@import "CPFont.j"
@import "CPShadow.j"
@import "CPView.j"
@import "CPText.j"
@import "CPKeyValueBinding.j"
@import "CPTrackingArea.j"
CPLeftTextAlignment = 0;
CPRightTextAlignment = 1;
CPCenterTextAlignment = 2;
CPJustifiedTextAlignment = 3;
CPNaturalTextAlignment = 4;
@global CPApp
@protocol CPControlTextEditingDelegate <CPObject>
@optional
- (void)controlTextDidBeginEditing:(CPNotification)aNotification;
- (void)controlTextDidChange:(CPNotification)aNotification;
- (void)controlTextDidEndEditing:(CPNotification)aNotification;
- (void)controlTextDidFocus:(CPNotification)aNotification;
- (void)controlTextDidBlur:(CPNotification)aNotification;
- (BOOL)control:(CPControl)control didFailToFormatString:(CPString)string errorDescription:(CPString)error;
@end
@typedef CPControlSize
CPRegularControlSize = 0;
CPSmallControlSize = 1;
CPMiniControlSize = 2;
@typedef CPLineBreakMode
CPLineBreakByWordWrapping = 0;
CPLineBreakByCharWrapping = 1;
CPLineBreakByClipping = 2;
@@ -45,11 +56,13 @@ CPLineBreakByTruncatingHead = 3;
CPLineBreakByTruncatingTail = 4;
CPLineBreakByTruncatingMiddle = 5;
@typedef CPVerticalTextAlignment
CPTopVerticalTextAlignment = 1;
CPCenterVerticalTextAlignment = 2;
CPBottomVerticalTextAlignment = 3;
// Deprecated for use with images, use the CPImageScale constants
@typedef CPImageScaling
CPScaleProportionally = 0;
CPScaleToFit = 1;
CPScaleNone = 2;
@@ -59,6 +72,7 @@ CPImageScaleAxesIndependently = 1;
CPImageScaleNone = 2;
CPImageScaleProportionallyUpOrDown = 3;
@typedef CPCellImagePosition
CPNoImage = 0;
CPImageOnly = 1;
CPImageLeft = 2;
@@ -104,32 +118,28 @@ var CPControlBlackColor = [CPColor blackColor];
BOOL _trackingWasWithinFrame;
unsigned _trackingMouseDownFlags;
CGPoint _previousTrackingLocation;
CPControlSize _controlSize;
CPWritingDirection _baseWritingDirection @accessors(property=baseWritingDirection);
}
+ (CPDictionary)themeAttributes
{
return [CPDictionary dictionaryWithObjects:[CPLeftTextAlignment,
CPTopVerticalTextAlignment,
CPLineBreakByClipping,
[CPColor blackColor],
[CPFont systemFontOfSize:CPFontCurrentSystemSize],
[CPNull null],
_CGSizeMakeZero(),
CPImageLeft,
CPScaleToFit,
_CGSizeMakeZero(),
_CGSizeMake(-1.0, -1.0)]
forKeys:[@"alignment",
@"vertical-alignment",
@"line-break-mode",
@"text-color",
@"font",
@"text-shadow-color",
@"text-shadow-offset",
@"image-position",
@"image-scaling",
@"min-size",
@"max-size"]];
return @{
@"alignment": CPLeftTextAlignment,
@"vertical-alignment": CPTopVerticalTextAlignment,
@"line-break-mode": CPLineBreakByClipping,
@"text-color": [CPColor blackColor],
@"font": [CPFont systemFontOfSize:CPFontCurrentSystemSize],
@"text-shadow-color": [CPNull null],
@"text-shadow-offset": CGSizeMakeZero(),
@"image-position": CPImageLeft,
@"image-scaling": CPScaleToFit,
@"min-size": CGSizeMakeZero(),
@"max-size": CGSizeMake(-1.0, -1.0),
@"nib2cib-adjustment-frame": CGRectMakeZero()
};
}
+ (void)initialize
@@ -148,16 +158,18 @@ var CPControlBlackColor = [CPColor blackColor];
[self exposeBinding:@"enabled"];
}
+ (Class)_binderClassForBinding:(CPString)theBinding
+ (Class)_binderClassForBinding:(CPString)aBinding
{
if (theBinding === CPValueBinding)
if (aBinding === CPValueBinding)
return [_CPValueBinder class];
else if ([aBinding hasPrefix:CPEnabledBinding])
return [CPMultipleValueAndBinding class];
return [super _binderClassForBinding:theBinding];
return [super _binderClassForBinding:aBinding];
}
/*!
Reverse set the binding iff the CPContinuouslyUpdatesValueBindingOption is set.
Reverse set the binding if the CPContinuouslyUpdatesValueBindingOption is set.
*/
- (void)_continuouslyReverseSetBinding
{
@@ -182,13 +194,94 @@ var CPControlBlackColor = [CPColor blackColor];
if (self)
{
_sendActionOn = CPLeftMouseUpMask;
_sendActionOn = CPLeftMouseUpMask;
_trackingMouseDownFlags = 0;
}
return self;
}
#pragma mark -
#pragma mark Control Size
/*!
Returns the control's control size
*/
- (CPControlSize)controlSize
{
return _controlSize;
}
/*!
Sets the control's size.
@param aControlSize the control's size
*/
- (void)setControlSize:(CPControlSize)aControlSize
{
if (_controlSize === aControlSize)
return;
[self unsetThemeState:[self _controlSizeThemeState]];
_controlSize = aControlSize;
[self setThemeState:[self _controlSizeThemeState]];
[self setNeedsLayout];
[self setNeedsDisplay:YES];
}
/*!
Gets the current theme state according to the current controlSize.
@return a CPThemeState
*/
- (ThemeState)_controlSizeThemeState
{
switch (_controlSize)
{
case CPSmallControlSize:
return CPThemeStateControlSizeSmall;
case CPMiniControlSize:
return CPThemeStateControlSizeMini;
case CPRegularControlSize:
default:
return CPThemeStateControlSizeRegular;
}
}
/*!
@ignore
Change frame size according to the theme control size theme constraints
Basically for height to min-size.
*/
- (void)_sizeToControlSize
{
var frameSize = [self frameSize],
minSize = [self currentValueForThemeAttribute:@"min-size"],
maxSize = [self currentValueForThemeAttribute:@"max-size"];
if (minSize.width > 0)
{
frameSize.width = MAX(minSize.width, frameSize.width);
if (maxSize.width > 0)
frameSize.width = MIN(maxSize.width, frameSize.width);
}
if (minSize.height > 0)
{
frameSize.height = MAX(minSize.height, frameSize.height);
if (maxSize.height > 0)
frameSize.height = MIN(maxSize.height, frameSize.height);
}
[self setFrameSize:frameSize];
}
#pragma mark -
/*!
Sets the receiver's target action.
@@ -235,6 +328,9 @@ var CPControlBlackColor = [CPColor blackColor];
{
[self _reverseSetBinding];
var binding = [CPBinder getBinding:CPTargetBinding forObject:self];
[binding invokeAction];
return [CPApp sendAction:anAction to:anObject from:self];
}
@@ -324,11 +420,11 @@ var CPControlBlackColor = [CPColor blackColor];
_previousTrackingLocation = currentLocation;
}
- (void)setState:(int)state
- (void)setState:(CPInteger)state
{
}
- (int)nextState
- (CPInteger)nextState
{
return 0;
}
@@ -397,6 +493,14 @@ var CPControlBlackColor = [CPColor blackColor];
[self highlight:YES];
}
/*!
Enabled controls accept first mouse by default.
*/
- (BOOL)acceptsFirstMouse:(CPEvent)anEvent
{
return [self isEnabled];
}
- (void)mouseDown:(CPEvent)anEvent
{
if (![self isEnabled])
@@ -524,7 +628,7 @@ var CPControlBlackColor = [CPColor blackColor];
return formattedValue;
}
return (_value === undefined || _value === nil) ? "" : String(_value);
return (_value === undefined || _value === nil) ? @"" : String(_value);
}
/*!
@@ -545,10 +649,10 @@ var CPControlBlackColor = [CPColor blackColor];
{
value = nil;
if ([_formatter getObjectValue:AT_REF(value) forString:aString errorDescription:nil] === NO)
if ([_formatter getObjectValue:@ref(value) forString:aString errorDescription:nil] === NO)
{
// If the given string is non-empty and doesn't work, Cocoa tries an empty string.
if (!aString || [_formatter getObjectValue:AT_REF(value) forString:@"" errorDescription:nil] === NO)
if (!aString || [_formatter getObjectValue:@ref(value) forString:@"" errorDescription:nil] === NO)
value = undefined; // Means the value is invalid
}
}
@@ -601,7 +705,7 @@ var CPControlBlackColor = [CPColor blackColor];
if ([note object] != self)
return;
[[CPNotificationCenter defaultCenter] postNotificationName:CPControlTextDidBeginEditingNotification object:self userInfo:[CPDictionary dictionaryWithObject:[note object] forKey:"CPFieldEditor"]];
[[CPNotificationCenter defaultCenter] postNotificationName:CPControlTextDidBeginEditingNotification object:self userInfo:@{"CPFieldEditor": [note object]}];
}
- (void)textDidChange:(CPNotification)note
@@ -610,7 +714,7 @@ var CPControlBlackColor = [CPColor blackColor];
if ([note object] != self)
return;
[[CPNotificationCenter defaultCenter] postNotificationName:CPControlTextDidChangeNotification object:self userInfo:[CPDictionary dictionaryWithObject:[note object] forKey:"CPFieldEditor"]];
[[CPNotificationCenter defaultCenter] postNotificationName:CPControlTextDidChangeNotification object:self userInfo:@{"CPFieldEditor": [note object]}];
}
- (void)textDidEndEditing:(CPNotification)note
@@ -621,7 +725,49 @@ var CPControlBlackColor = [CPColor blackColor];
[self _reverseSetBinding];
[[CPNotificationCenter defaultCenter] postNotificationName:CPControlTextDidEndEditingNotification object:self userInfo:[CPDictionary dictionaryWithObject:[note object] forKey:"CPFieldEditor"]];
[[CPNotificationCenter defaultCenter] postNotificationName:CPControlTextDidEndEditingNotification object:self userInfo:[note userInfo]];
}
/*!
@ignore
Return the currentTextMovement needed by the delegate textDidEndEditing
This is going to check the currentEvent of the CPApp
*/
- (unsigned)_currentTextMovement
{
var currentEvent = [CPApp currentEvent],
keyCode = [currentEvent keyCode],
modifierFlags = [currentEvent modifierFlags];
switch (keyCode)
{
case CPEscapeKeyCode:
return CPCancelTextMovement;
case CPLeftArrowKeyCode:
return CPLeftTextMovement;
case CPRightArrowKeyCode:
return CPRightTextMovement;
case CPUpArrowKeyCode:
return CPUpTextMovement;
case CPDownArrowKeyCode:
return CPDownTextMovement;
case CPReturnKeyCode:
return CPReturnTextMovement;
case CPTabKeyCode:
if (modifierFlags & CPShiftKeyMask)
return CPBacktabTextMovement;
return CPTabTextMovement;
default:
return CPOtherTextMovement;
}
}
/*!
@@ -807,7 +953,7 @@ var CPControlBlackColor = [CPColor blackColor];
/*!
Returns the image scaling of the control.
*/
- (CPImageScaling)imageScaling
- (CPUInteger)imageScaling
{
return [self valueForThemeAttribute:@"image-scaling"];
}
@@ -865,16 +1011,81 @@ var CPControlBlackColor = [CPColor blackColor];
return [self hasThemeState:CPThemeStateHighlighted];
}
#pragma mark -
#pragma mark Base writing direction
/*!
Sets the initial writing direction of the receiver
@param writingDirection - It could be CPWritingDirectionNatural, CPWritingDirectionLeftToRight, CPWritingDirectionRightToLeft
*/
- (void)setBaseWritingDirection:(CPWritingDirection)writingDirection
{
if (writingDirection == _baseWritingDirection)
return;
[self willChangeValueForKey:@"baseWritingDirection"];
_baseWritingDirection = writingDirection;
[self didChangeValueForKey:@"baseWritingDirection"];
#if PLATFORM(DOM)
var style;
switch (_baseWritingDirection)
{
case CPWritingDirectionNatural:
style = "initial";
break;
case CPWritingDirectionLeftToRight:
style = "ltr";
break;
case CPWritingDirectionRightToLeft:
style = "rtl";
break;
default:
style = "initial";
}
_DOMElement.style.direction = style;
#endif
}
@end
var CPControlValueKey = @"CPControlValueKey",
@implementation CPControl (CPTrackingArea)
{
CPTrackingArea _controlTrackingArea;
}
- (void)updateTrackingAreas
{
if (_controlTrackingArea)
[self removeTrackingArea:_controlTrackingArea];
_controlTrackingArea = [[CPTrackingArea alloc] initWithRect:CGRectMakeZero()
options:CPTrackingMouseEnteredAndExited | CPTrackingActiveInKeyWindow | CPTrackingInVisibleRect
owner:self
userInfo:nil];
[self addTrackingArea:_controlTrackingArea];
[super updateTrackingAreas];
}
@end
var CPControlActionKey = @"CPControlActionKey",
CPControlControlSizeKey = @"CPControlControlSizeKey",
CPControlControlStateKey = @"CPControlControlStateKey",
CPControlIsEnabledKey = @"CPControlIsEnabledKey",
CPControlTargetKey = @"CPControlTargetKey",
CPControlActionKey = @"CPControlActionKey",
CPControlSendActionOnKey = @"CPControlSendActionOnKey",
CPControlFormatterKey = @"CPControlFormatterKey",
CPControlIsEnabledKey = @"CPControlIsEnabledKey",
CPControlSendActionOnKey = @"CPControlSendActionOnKey",
CPControlSendsActionOnEndEditingKey = @"CPControlSendsActionOnEndEditingKey",
CPControlTargetKey = @"CPControlTargetKey",
CPControlValueKey = @"CPControlValueKey",
CPControlBaseWrittingDirectionKey = @"CPControlBaseWrittingDirectionKey";
__Deprecated__CPImageViewImageKey = @"CPImageViewImageKey";
@@ -901,6 +1112,10 @@ var CPControlValueKey = @"CPControlValueKey",
[self setSendsActionOnEndEditing:[aCoder decodeBoolForKey:CPControlSendsActionOnEndEditingKey]];
[self setFormatter:[aCoder decodeObjectForKey:CPControlFormatterKey]];
[self setControlSize:[aCoder decodeIntForKey:CPControlControlSizeKey]];
[self setBaseWritingDirection:[aCoder decodeIntForKey:CPControlBaseWrittingDirectionKey]];
}
return self;
@@ -933,6 +1148,11 @@ var CPControlValueKey = @"CPControlValueKey",
if (_formatter !== nil)
[aCoder encodeObject:_formatter forKey:CPControlFormatterKey];
[aCoder encodeInt:_controlSize forKey:CPControlControlSizeKey];
[aCoder encodeInt:_baseWritingDirection forKey:CPControlBaseWrittingDirectionKey];
}
@end
+1 -1
View File
@@ -64,7 +64,7 @@ var CPControllerDeclaredKeysKey = @"CPControllerDeclaredKeysKey";
count = _editors.length;
for (; index < count; ++index)
if (![[_editors objectAtIndex:i] commitEditing])
if (![[_editors objectAtIndex:index] commitEditing])
return NO;
return YES;
+16 -3
View File
@@ -22,6 +22,9 @@ Cursor support by browser:
*/
@import <Foundation/CPObject.j>
@import "CPImage.j"
@global CPApp
var currentCursor = nil,
cursorStack = [],
@@ -77,7 +80,7 @@ var currentCursor = nil,
*/
- (id)initWithImage:(CPImage)image foregroundColorHint:(CPColor)foregroundColor backgroundColorHint:(CPColor)backgroundColor hotSpot:(CGPoint)aHotSpot
{
return [self initWithImage:image hotSpot:hotSpot];
return [self initWithImage:image hotSpot:aHotSpot];
}
+ (void)hide
@@ -114,11 +117,15 @@ var currentCursor = nil,
- (void)push
{
currentCursor = cursorStack.push(self);
cursorStack.push(self);
currentCursor = self;
}
- (void)set
{
if (currentCursor === self)
return;
currentCursor = self;
#if PLATFORM(DOM)
@@ -159,7 +166,13 @@ var currentCursor = nil,
var cssString;
if (doesHaveImage)
cssString = [CPString stringWithFormat:@"url(%@/CPCursor/%@.cur), %@", [[CPBundle bundleForClass:self] resourcePath], cursorName, aString];
{
var themeResourcePath = [[[CPApp themeBlend] bundle] resourcePath],
extension = CPBrowserIsEngine(CPInternetExplorerBrowserEngine) ? @"cur" : @"png";
cssString = [CPString stringWithFormat:@"url(%@cursors/%@.%@), %@", themeResourcePath, cursorName, extension, aString];
}
else
{
// IE <= 8 does not support some cursors, map them to supported cursors
+738
View File
@@ -0,0 +1,738 @@
/* CPDatePicker.j
* AppKit
*
* Created by Alexandre Wilhelm
* Copyright 2012 <alexandre.wilhelmfr@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "CPControl.j"
@import "CPFont.j"
@import "CPTextField.j"
@import "_CPDatePickerTextField.j"
@import "_CPDatePickerCalendar.j"
@import <Foundation/CPArray.j>
@import <Foundation/CPObject.j>
@import <Foundation/CPDate.j>
@import <Foundation/CPLocale.j>
@import <Foundation/CPTimeZone.j>
@class CPStepper
@class CPApp
@global CPLocaleLanguageCode
@global CPDateFormatterShortStyle
var CPDatePicker_validateProposedDateValue_timeInterval = 1 << 1;
CPSingleDateMode = 0;
CPRangeDateMode = 1;
CPTextFieldAndStepperDatePickerStyle = 0;
CPClockAndCalendarDatePickerStyle = 1;
CPTextFieldDatePickerStyle = 2;
CPHourMinuteDatePickerElementFlag = 0x000c;
CPHourMinuteSecondDatePickerElementFlag = 0x000e;
CPTimeZoneDatePickerElementFlag = 0x0010;
CPYearMonthDatePickerElementFlag = 0x00c0;
CPYearMonthDayDatePickerElementFlag = 0x00e0;
CPEraDatePickerElementFlag = 0x0100;
/*!
@ingroup appkit
This control displays a datepicker in a Cappuccino application
*/
@implementation CPDatePicker : CPControl
{
BOOL _isBordered @accessors(getter=isBordered, setter=setBordered:);
BOOL _isBezeled @accessors(getter=isBezeled, setter=setBezeled:);
BOOL _drawsBackground @accessors(property=drawsBackground);
CPDate _dateValue @accessors(property=dateValue);
CPDate _minDate @accessors(property=minDate);
CPDate _maxDate @accessors(property=maxDate);
CPFont _textFont @accessors(property=textFont);
CPLocale _locale @accessors(property=locale);
//CPCalendar _calendar @accessors(property=calendar);
CPTimeZone _timeZone @accessors(property=timeZone);
id _delegate @accessors(property=delegate);
CPInteger _datePickerElements @accessors(property=datePickerElements);
CPInteger _datePickerMode @accessors(property=datePickerMode);
CPInteger _datePickerStyle @accessors(property=datePickerStyle);
CPInteger _timeInterval @accessors(property=timeInterval);
BOOL _invokedByUserEvent;
_CPDatePickerTextField _datePickerTextfield;
_CPDatePickerCalendar _datePickerCalendar;
unsigned _implementedCDatePickerDelegateMethods;
}
#pragma mark -
#pragma mark Theme methods
+ (CPString)defaultThemeClass
{
return @"datePicker";
}
+ (CPDictionary)themeAttributes
{
return @{
@"bezel-color": [CPColor clearColor],
@"border-width" : 1.0,
@"border-color": [CPColor clearColor],
@"content-inset": CGInsetMakeZero(),
@"bezel-inset": CGInsetMakeZero(),
@"datepicker-textfield-bezel-color": [CPColor clearColor],
@"min-size-datepicker-textfield": CGSizeMakeZero(),
@"content-inset-datepicker-textfield": CGInsetMakeZero(),
@"content-inset-datepicker-textfield-separator": CGInsetMakeZero(),
@"separator-content-inset": CGInsetMakeZero(),
@"date-hour-margin": 5.0,
@"stepper-margin": 5.0,
@"bezel-color-calendar": [CPColor clearColor],
@"title-text-color": [CPColor blackColor],
@"title-text-shadow-color": [CPColor clearColor],
@"title-text-shadow-offset": CGSizeMakeZero(),
@"title-font": [CPNull null],
@"weekday-text-color": [CPColor blackColor],
@"weekday-text-shadow-color": [CPColor clearColor],
@"weekday-text-shadow-offset": CGSizeMakeZero(),
@"weekday-font": [CPNull null],
@"arrow-image-left": [CPNull null],
@"arrow-image-right": [CPNull null],
@"arrow-image-left-highlighted": [CPNull null],
@"arrow-image-right-highlighted": [CPNull null],
@"arrow-inset": CGInsetMakeZero(),
@"circle-image": [CPNull null],
@"circle-image-highlighted": [CPNull null],
@"tile-text-color": [CPColor blackColor],
@"tile-text-shadow-color": [CPColor clearColor],
@"tile-text-shadow-offset": CGSizeMakeZero(),
@"tile-font": [CPNull null],
@"size-tile": CGSizeMakeZero(),
@"size-calendar": CGSizeMakeZero(),
@"size-header": CGSizeMakeZero(),
@"min-size-calendar": CGSizeMakeZero(),
@"max-size-calendar": CGSizeMakeZero(),
@"bezel-color-clock": [CPColor clearColor],
@"clock-text-color": [CPColor blackColor],
@"clock-text-shadow-color": [CPColor clearColor],
@"clock-text-shadow-offset": CGSizeMakeZero(),
@"clock-font": [CPNull null],
@"second-hand-image": [CPNull null],
@"hour-hand-image": [CPNull null],
@"middle-hand-image": [CPNull null],
@"minute-hand-image": [CPNull null],
@"size-clock": CGSizeMakeZero(),
@"second-hand-size": CGSizeMakeZero(),
@"hour-hand-size": CGSizeMakeZero(),
@"middle-hand-size": CGSizeMakeZero(),
@"minute-hand-size": CGSizeMakeZero(),
};
}
#pragma mark -
#pragma mark Binding methods
+ (Class)_binderClassForBinding:(CPString)theBinding
{
if (theBinding == CPValueBinding || theBinding == CPMinValueBinding || theBinding == CPMaxValueBinding)
return [_CPDatePickerValueBinder class];
return [super _binderClassForBinding:theBinding];
}
- (CPString)_replacementKeyPathForBinding:(CPString)aBinding
{
if (aBinding == CPValueBinding)
return @"dateValue";
if (aBinding == CPMinValueBinding)
return @"minDate";
if (aBinding == CPMaxValueBinding)
return @"maxDate";
return [super _replacementKeyPathForBinding:aBinding];
}
#pragma mark -
#pragma mark Init methods
- (id)initWithFrame:(CGRect)aFrame
{
if (self = [super initWithFrame:aFrame])
{
_drawsBackground = YES;
_datePickerStyle = CPTextFieldAndStepperDatePickerStyle;
_datePickerMode = CPSingleDateMode;
_datePickerElements = CPYearMonthDayDatePickerElementFlag | CPHourMinuteSecondDatePickerElementFlag;
_timeInterval = 0;
_implementedCDatePickerDelegateMethods = 0;
[self setObjectValue:[CPDate date]];
_minDate = [CPDate distantPast];
_maxDate = [CPDate distantFuture];
[self setBezeled:YES];
[self setBordered:YES];
[self _init];
}
return self
}
- (void)_init
{
if (!_locale)
_locale = [CPLocale currentLocale];
_datePickerTextfield = [[_CPDatePickerTextField alloc] initWithFrame:[self bounds] withDatePicker:self];
[_datePickerTextfield setDateValue:_dateValue];
_datePickerCalendar = [[_CPDatePickerCalendar alloc] initWithFrame:[self bounds] withDatePicker:self];
[_datePickerCalendar setDateValue:_dateValue];
// We might have been unarchived in a disabled state.
[_datePickerTextfield setEnabled:[self isEnabled]];
[self setNeedsDisplay:YES];
[self setNeedsLayout];
}
#pragma mark -
#pragma mark Control Size
- (void)setControlSize:(CPControlSize)aControlSize
{
[super setControlSize:aControlSize];
if ([self datePickerStyle] == CPTextFieldAndStepperDatePickerStyle || [self datePickerStyle] == CPTextFieldDatePickerStyle)
[self _sizeToControlSize];
}
#pragma mark -
#pragma mark Delegate methods
/*! Set the delegate of the datePicker
@param aDelegate delegate of the datePicker
*/
- (void)setDelegate:(id)aDelegate
{
_delegate = aDelegate;
_implementedCDatePickerDelegateMethods = 0;
// Look if the delegate implements or not the delegate methods
if ([_delegate respondsToSelector:@selector(datePicker:validateProposedDateValue:timeInterval:)])
_implementedCDatePickerDelegateMethods |= CPDatePicker_validateProposedDateValue_timeInterval;
}
#pragma mark -
#pragma mark Layout method
/*! Layout the subviews
*/
- (void)layoutSubviews
{
[super layoutSubviews];
if (_datePickerStyle == CPTextFieldAndStepperDatePickerStyle || _datePickerStyle == CPTextFieldDatePickerStyle)
{
if (![_datePickerTextfield superview])
[self addSubview:_datePickerTextfield];
if ([_datePickerCalendar superview])
[_datePickerCalendar removeFromSuperview];
[_datePickerTextfield setControlSize:[self controlSize]];
[_datePickerTextfield setNeedsLayout];
[_datePickerTextfield setNeedsDisplay:YES];
}
else
{
if (![_datePickerCalendar superview])
[self addSubview:_datePickerCalendar];
if ([_datePickerTextfield superview])
[_datePickerTextfield removeFromSuperview];
[_datePickerCalendar setNeedsLayout];
[_datePickerCalendar setNeedsDisplay:YES];
}
}
#pragma mark -
#pragma mark Setter
/*! Return the objectValue of the datePicker. The objectValue should take the timeZoneEffect
*/
- (id)objectValue
{
// TODO : add timeZone effect. How to do it because js ???
return _dateValue
}
/*! Set the objectValue of the datePicker. It has to be a CPDate
@param aDateValue the dateValue
*/
- (void)setObjectValue:(CPDate)aValue
{
if (![aValue isKindOfClass:[CPDate class]])
return;
[self setDateValue:aValue];
}
/* Set the dateValue of the datePicker
@param aDateValue the dateValue
*/
- (void)setDateValue:(CPDate)aDateValue
{
if (aDateValue == nil)
return;
_invokedByUserEvent = NO;
[self _setDateValue:aDateValue timeInterval:_timeInterval];
}
/*! Set the dateValue and the timeInterval. This method checks the min and max date of the datePicker also. It will call the delegate if possible.
@param aDateValue the dateValue
@param aTimeInterval the timeInterval
*/
- (void)_setDateValue:(CPDate)aDateValue timeInterval:(CPTimeInterval)aTimeInterval
{
// Make sure to have a valid date and avoid NaN values
if (!isFinite(aDateValue))
{
[CPException raise:CPInvalidArgumentException
reason:@"aDateValue is not valid"];
return;
}
if (_minDate)
aDateValue = new Date (MAX(aDateValue, _minDate));
if (_maxDate)
aDateValue = new Date (MIN(aDateValue, _maxDate));
aTimeInterval = MAX(MIN(aTimeInterval, [_maxDate timeIntervalSinceDate:aDateValue]), [_minDate timeIntervalSinceDate:aDateValue]);
if ([aDateValue isEqualToDate:_dateValue] && aTimeInterval == _timeInterval)
{
if (_datePickerStyle == CPTextFieldAndStepperDatePickerStyle || _datePickerStyle == CPTextFieldDatePickerStyle)
[_datePickerTextfield setDateValue:_dateValue];
else
[_datePickerCalendar setDateValue:_dateValue];
return;
}
if (_implementedCDatePickerDelegateMethods & CPDatePicker_validateProposedDateValue_timeInterval)
{
// constrain timeInterval also
var aStartDateRef = function(x){if (typeof x == 'undefined') return aDateValue; aDateValue = x;};
var aTimeIntervalRef = function(x){if (typeof x == 'undefined') return aTimeInterval; aTimeInterval = x;};
[_delegate datePicker:self validateProposedDateValue:aStartDateRef timeInterval:aTimeIntervalRef];
}
[self willChangeValueForKey:@"objectValue"];
[self willChangeValueForKey:@"dateValue"];
_dateValue = aDateValue;
[super setObjectValue:_dateValue];
[self didChangeValueForKey:@"objectValue"];
[self didChangeValueForKey:@"dateValue"];
[self willChangeValueForKey:@"timeInterval"];
_timeInterval = (_datePickerMode == CPSingleDateMode)? 0 : aTimeInterval;
[self didChangeValueForKey:@"timeInterval"];
if (_invokedByUserEvent)
[self sendAction:[self action] to:[self target]];
if (_datePickerStyle == CPTextFieldAndStepperDatePickerStyle || _datePickerStyle == CPTextFieldDatePickerStyle)
[_datePickerTextfield setDateValue:_dateValue];
else
[_datePickerCalendar setDateValue:_dateValue];
}
/*! Set the minDate of the datePicker
@param aMinDate the minDate
*/
- (void)setMinDate:(CPDate)aMinDate
{
[self willChangeValueForKey:@"minDate"];
_minDate = aMinDate;
[self didChangeValueForKey:@"minDate"];
[self _setDateValue:_dateValue timeInterval:_timeInterval];
}
/*! Set the maxDate of the datePicker
@param aMaxDate the maxDate
*/
- (void)setMaxDate:(CPDate)aMaxDate
{
[self willChangeValueForKey:@"maxDate"];
_maxDate = aMaxDate;
[self didChangeValueForKey:@"maxDate"];
[self _setDateValue:_dateValue timeInterval:_timeInterval];
}
/*! Set the syle of the datePicker
@param aDatePickerStyle the datePicker style
*/
- (void)setDatePickerStyle:(CPInteger)aDatePickerStyle
{
_datePickerStyle = aDatePickerStyle;
[self setControlSize:[self controlSize]];
[self setNeedsDisplay:YES];
[self setNeedsLayout];
}
/*! Set the elements of the datePicker
@param aDatePickerElements the datePicker elements
*/
- (void)setDatePickerElements:(CPInteger)aDatePickerElements
{
_datePickerElements = aDatePickerElements;
[self setNeedsDisplay:YES];
[self setNeedsLayout];
}
/*! Set the mode of the datePicker
@param aDatePickerMode the datePicker mode
*/
- (void)setDatePickerMode:(CPInteger)aDatePickerMode
{
_datePickerMode = aDatePickerMode;
if (_datePickerMode == CPSingleDateMode)
[self _setDateValue:[self dateValue] timeInterval:0];
[self setNeedsDisplay:YES];
[self setNeedsLayout];
}
/*! Set the timeInterval of the datePicker
@param aTimeInterval the timeInterval of the datePicker
*/
- (void)setTimeInterval:(CPInteger)aTimeInterval
{
if (_datePickerMode == CPSingleDateMode)
return;
[self _setDateValue:[self dateValue] timeInterval:aTimeInterval];
}
/*! Set the locale of the datePicker. This update laso the locale of the formatter.
@param aLocale the locale
*/
- (void)setLocale:(CPLocale)aLocale
{
_locale = aLocale;
if (_formatter)
{
[self willChangeValueForKey:@"locale"];
[_formatter setLocale:_locale];
[self didChangeValueForKey:@"locale"];
}
// This will update the textFields (usefull when changing with a date with pm and am)
[_datePickerTextfield setDateValue:_dateValue];
[self setNeedsDisplay:YES];
[self setNeedsLayout];
}
/*!
Sets whether the datepicker will have a bezeled border.
@param shouldBeBezeled \c YES means the datepicker will draw a bezeled border
*/
- (void)setBezeled:(BOOL)shouldBeBezeled
{
_isBezeled = shouldBeBezeled;
if (shouldBeBezeled)
[self setThemeState:CPThemeStateBezeled];
else
[self unsetThemeState:CPThemeStateBezeled];
}
/*!
Sets whether the datepicker will have a border drawn. (actually it does nothing)
@param shouldBeBordered \c YES makes the datepicker draw a border
*/
- (void)setBordered:(BOOL)shouldBeBordered
{
_isBordered = shouldBeBordered;
if (shouldBeBordered)
[self setThemeState:CPThemeStateBordered];
else
[self unsetThemeState:CPThemeStateBordered];
}
/*!
Sets the font of the control.
@param aFont
*/
- (void)setTextFont:(CPFont)aFont
{
[self setFont:aFont];
}
/*! Sets the enabled status of the control. Controls that are not enabled can not be used by the user and obtain the CPThemeStateDisabled theme state.
@param a boolean. YES if the control should be enabled, otherwise NO.
*/
- (void)setEnabled:(BOOL)aBoolean
{
[super setEnabled:aBoolean];
[_datePickerTextfield setEnabled:aBoolean];
[_datePickerCalendar setEnabled:aBoolean];
}
/*! Set the background color of the datePicker
@param aColor
*/
- (void)setBackgroundColor:(CPColor)aColor
{
_backgroundColor = aColor;
[self setNeedsLayout];
}
/*! Set the boolean drawsBackgroundColor
@param aBoolean
*/
- (void)setDrawsBackground:(BOOL)aBoolean
{
[self willChangeValueForKey:@"drawsBackground"];
_drawsBackground = aBoolean;
[self didChangeValueForKey:@"drawsBackground"];
[self setNeedsLayout];
}
/*! Set the timeZone
@param aTimeZone
*/
- (void)setTimeZone:(CPTimeZone)aTimeZone
{
[self willChangeValueForKey:@"timeZone"];
_timeZone = aTimeZone;
[self didChangeValueForKey:@"timeZone"];
[self setNeedsLayout];
if (_datePickerStyle == CPTextFieldAndStepperDatePickerStyle || _datePickerStyle == CPTextFieldDatePickerStyle)
[_datePickerTextfield setDateValue:_dateValue];
else
[_datePickerCalendar setDateValue:_dateValue];
}
#pragma mark -
#pragma mark First responder methods
/*! Return YES if style is set to CPTextFieldAndStepperDatePickerStyle or CPTextFieldDatePickerStyle
*/
- (BOOL)becomeFirstResponder
{
if (_datePickerStyle == CPTextFieldAndStepperDatePickerStyle || _datePickerStyle == CPTextFieldDatePickerStyle)
{
if (![super becomeFirstResponder])
return NO;
[_datePickerTextfield _selectTextFieldWithFlags:[[CPApp currentEvent] modifierFlags]];
return YES;
}
return NO;
}
/*! Return YES
*/
- (BOOL)acceptsFirstResponder
{
return YES;
}
/*! Return YES
*/
- (BOOL)resignFirstResponder
{
if (_datePickerStyle == CPTextFieldAndStepperDatePickerStyle || _datePickerStyle == CPTextFieldDatePickerStyle)
[_datePickerTextfield resignFirstResponder];
return YES;
}
#pragma mark -
#pragma mark getter
/*!
Returns \c YES if the textfield is bezeled.
*/
- (BOOL)isBezeled
{
return [self hasThemeState:CPThemeStateBezeled];
}
/*!
Returns \c YES if the textfield has a border.
*/
- (BOOL)isBordered
{
return [self hasThemeState:CPThemeStateBordered];
}
/*!
Returns the font of the control.
*/
- (CPFont)textFont
{
return [self font];
}
/*! Check if we are in the american format or not. Depending on the locale
*/
- (BOOL)_isAmericanFormat
{
return [[_locale objectForKey:CPLocaleCountryCode] isEqualToString:@"US"];
}
#pragma mark -
#pragma mark Key event
/*! Key down event
@param anEvent
*/
- (void)keyDown:(CPEvent)anEvent
{
if (_datePickerStyle == CPTextFieldAndStepperDatePickerStyle || _datePickerStyle == CPTextFieldDatePickerStyle)
[_datePickerTextfield keyDown:anEvent];
}
@end
var CPDatePickerModeKey = @"CPDatePickerModeKey",
CPIntervalKey = @"CPIntervalKey",
CPMinDateKey = @"CPMinDateKey",
CPMaxDateKey = @"CPMaxDateKey",
CPBackgroundColorKey = @"CPBackgroundColorKey",
CPDrawsBackgroundKey = @"CPDrawsBackgroundKey",
CPTextFontKey = @"CPTextFontKey",
CPDatePickerElementsKey = @"CPDatePickerElementsKey",
CPDatePickerStyleKey = @"CPDatePickerStyleKey",
CPLocaleKey = @"CPLocaleKey",
CPBorderedKey = @"CPBorderedKey",
CPDateValueKey = @"CPDateValueKey";
@implementation CPDatePicker (CPCoding)
- (id)initWithCoder:(CPCoder)aCoder
{
self = [super initWithCoder:aCoder];
if (self)
{
_textFont = [aCoder decodeObjectForKey:CPTextFontKey];
_minDate = [aCoder decodeObjectForKey:CPMinDateKey] || [CPDate distantPast];
_maxDate = [aCoder decodeObjectForKey:CPMaxDateKey] || [CPDate distantFuture];
_timeInterval = [aCoder decodeDoubleForKey:CPIntervalKey];
_datePickerMode = [aCoder decodeIntForKey:CPDatePickerModeKey];
_datePickerElements = [aCoder decodeIntForKey:CPDatePickerElementsKey];
[self setDatePickerStyle:[aCoder decodeIntForKey:CPDatePickerStyleKey]];
_locale = [aCoder decodeObjectForKey:CPLocaleKey];
_dateValue = [aCoder decodeObjectForKey:CPDateValueKey];
_backgroundColor = [aCoder decodeObjectForKey:CPBackgroundColorKey];
_drawsBackground = [aCoder decodeBoolForKey:CPDrawsBackgroundKey];
_isBordered = [aCoder decodeBoolForKey:CPBorderedKey];
[self _init];
}
return self
}
- (void)encodeWithCoder:(CPCoder)aCoder
{
// FIXME Do we need to encode _datePickerTextfield and _datePickerCalendar? As subviews they'll be encoded, but when we decode we recreate them anyhow.
[super encodeWithCoder:aCoder];
[aCoder encodeDouble:_timeInterval forKey:CPIntervalKey];
[aCoder encodeInt:_datePickerMode forKey:CPDatePickerModeKey];
[aCoder encodeInt:_datePickerStyle forKey:CPDatePickerStyleKey];
[aCoder encodeInt:_datePickerElements forKey:CPDatePickerElementsKey];
[aCoder encodeObject:_minDate forKey:CPMinDateKey];
[aCoder encodeObject:_maxDate forKey:CPMaxDateKey];
[aCoder encodeObject:_dateValue forKey:CPDateValueKey];;
[aCoder encodeObject:_textFont forKey:CPTextFontKey];
[aCoder encodeObject:_locale forKey:CPLocaleKey];
[aCoder encodeObject:_backgroundColor forKey:CPBackgroundColorKey];
[aCoder encodeObject:_drawsBackground forKey:CPDrawsBackgroundKey];
[aCoder encodeObject:_isBordered forKey:CPBorderedKey];
}
@end
@implementation _CPDatePickerValueBinder : CPBinder
{
}
@end
@implementation CPDate (CPDatePickerAdditions)
- (int)_daysInMonth
{
return 32 - new Date(self.getFullYear(), self.getMonth(), 32).getDate();
}
- (void)_resetToMidnight
{
self.setHours(0);
self.setMinutes(0);
self.setSeconds(0);
self.setMilliseconds(0);
}
- (void)_resetToLastSeconds
{
self.setHours(23);
self.setMinutes(59);
self.setSeconds(59);
self.setMilliseconds(99);
}
@end
File diff suppressed because it is too large Load Diff
+313
View File
@@ -0,0 +1,313 @@
/*
* _CPDatePickerClock.j
* AppKit
*
* Created by Alexandre Wilhelm
* Copyright 2012 <alexandre.wilhelmfr@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "CPView.j"
@import "CPTextField.j"
@import "CPImageView.j"
@import "CALayer.j"
@class _CPCibCustomResource
@class CPDatePicker
@global CPHourMinuteSecondDatePickerElementFlag
@global CPTextFieldAndStepperDatePickerStyle
@global CPTextFieldDatePickerStyle
var RADIANS = Math.PI / 180;
@implementation _CPDatePickerClock : CPView
{
BOOL _isEnabled;
CALayer _rootLayer;
CALayer _hourHandLayer;
CALayer _minuteHandLayer;
CALayer _secondHandLayer;
CALayer _middleHandLayer;
CPDatePicker _datePicker;
CPTextField _PMAMTextField;
}
#pragma mark -
#pragma mark Init methods
- (id)initWithFrame:(CGRect)aFrame datePicker:(CPDatePicker)aDatePicker
{
if (self = [super initWithFrame:aFrame])
{
_datePicker = aDatePicker;
_PMAMTextField = [[CPTextField alloc] initWithFrame:CGRectMakeZero()];
[_PMAMTextField setValue:[_datePicker valueForThemeAttribute:@"clock-font" inState:CPThemeStateNormal] forThemeAttribute:@"font" inState:CPThemeStateNormal];
[_PMAMTextField setValue:[_datePicker valueForThemeAttribute:@"clock-text-color" inState:CPThemeStateNormal] forThemeAttribute:@"text-color" inState:CPThemeStateNormal];
[_PMAMTextField setValue:[_datePicker valueForThemeAttribute:@"clock-text-shadow-color" inState:CPThemeStateNormal] forThemeAttribute:@"text-shadow-color" inState:CPThemeStateNormal];
[_PMAMTextField setValue:[_datePicker valueForThemeAttribute:@"clock-text-shadow-offset" inState:CPThemeStateNormal] forThemeAttribute:@"text-shadow-offset" inState:CPThemeStateNormal];
[_PMAMTextField setValue:[_datePicker valueForThemeAttribute:@"clock-font" inState:CPThemeStateDisabled] forThemeAttribute:@"font" inState:CPThemeStateDisabled];
[_PMAMTextField setValue:[_datePicker valueForThemeAttribute:@"clock-text-color" inState:CPThemeStateDisabled] forThemeAttribute:@"text-color" inState:CPThemeStateDisabled];
[_PMAMTextField setValue:[_datePicker valueForThemeAttribute:@"clock-text-shadow-color" inState:CPThemeStateDisabled] forThemeAttribute:@"text-shadow-color" inState:CPThemeStateDisabled];
[_PMAMTextField setValue:[_datePicker valueForThemeAttribute:@"clock-text-shadow-offset" inState:CPThemeStateDisabled] forThemeAttribute:@"text-shadow-offset" inState:CPThemeStateDisabled];
[self addSubview:_PMAMTextField];
var middleHandSize = [_datePicker valueForThemeAttribute:@"middle-hand-size"],
minuteHandSize = [_datePicker valueForThemeAttribute:@"minute-hand-size"],
hourHandSize = [_datePicker valueForThemeAttribute:@"hour-hand-size"],
secondHandSize = [_datePicker valueForThemeAttribute:@"second-hand-size"];
// We use layer to make the rotation possible
_hourHandLayer = [[HandLayer alloc] initWithSize:hourHandSize];
[_hourHandLayer setBounds:CGRectMake(0, 0, aFrame.size.width, aFrame.size.height)];
[_hourHandLayer setAnchorPoint:CGPointMakeZero()];
[_hourHandLayer setPosition:CGPointMake(0.0, 0.0)];
_minuteHandLayer = [[HandLayer alloc] initWithSize:minuteHandSize];
[_minuteHandLayer setBounds:CGRectMake(0, 0, aFrame.size.width, aFrame.size.height)];
[_minuteHandLayer setAnchorPoint:CGPointMakeZero()];
[_minuteHandLayer setPosition:CGPointMake(0.0, 0.0)];
_secondHandLayer = [[HandLayer alloc] initWithSize:secondHandSize];
[_secondHandLayer setBounds:CGRectMake(0, 0, aFrame.size.width, aFrame.size.height)];
[_secondHandLayer setAnchorPoint:CGPointMakeZero()];
[_secondHandLayer setPosition:CGPointMake(0.0, 0.0)];
_middleHandLayer = [[HandLayer alloc] initWithSize:middleHandSize];
[_middleHandLayer setBounds:CGRectMake(0, 0, aFrame.size.width, aFrame.size.height)];
[_middleHandLayer setAnchorPoint:CGPointMakeZero()];
[_middleHandLayer setPosition:CGPointMake(0.0, 0.0)];
_rootLayer = [CALayer layer];
[self setWantsLayer:YES];
[self setLayer:_rootLayer];
[_hourHandLayer setNeedsDisplay];
[_middleHandLayer setNeedsDisplay];
[_secondHandLayer setNeedsDisplay];
[_minuteHandLayer setNeedsDisplay];
[_rootLayer addSublayer:_hourHandLayer];
[_rootLayer addSublayer:_minuteHandLayer];
[_rootLayer addSublayer:_secondHandLayer];
[_rootLayer addSublayer:_middleHandLayer];
[_rootLayer setNeedsDisplay];
}
return self;
}
#pragma mark -
#pragma mark Layout methods
- (void)layoutSubviews
{
if ([_datePicker datePickerStyle] == CPTextFieldAndStepperDatePickerStyle || [_datePicker datePickerStyle] == CPTextFieldDatePickerStyle)
return;
[super layoutSubviews];
var bounds = [self bounds],
dateValue = [[_datePicker dateValue] copy];
[dateValue _dateWithTimeZone:[_datePicker timeZone]];
[self setBackgroundColor:[_datePicker currentValueForThemeAttribute:@"bezel-color-clock"]];
[_middleHandLayer setImage:[_datePicker currentValueForThemeAttribute:@"middle-hand-image"]];
[_hourHandLayer setImage:[_datePicker currentValueForThemeAttribute:@"hour-hand-image"]];
[_minuteHandLayer setImage:[_datePicker currentValueForThemeAttribute:@"minute-hand-image"]];
[_secondHandLayer setImage:[_datePicker currentValueForThemeAttribute:@"second-hand-image"]];
if ([_datePicker _isAmericanFormat])
{
if (dateValue.getHours() > 11)
[_PMAMTextField setStringValue:@"PM"];
else
[_PMAMTextField setStringValue:@"AM"];
[_PMAMTextField sizeToFit];
[_PMAMTextField setFrameOrigin:CGPointMake(bounds.size.width / 2 - [_PMAMTextField frameSize].width / 2, bounds.size.height / 2 + 15)];
[_PMAMTextField setHidden:NO];
}
else
{
[_PMAMTextField setHidden:YES];
}
[_hourHandLayer setRotationRadians:[self _hourPositionRadianForDate:dateValue]];
[_minuteHandLayer setRotationRadians:[self _minutePositionRadianForDate:dateValue]];
[_secondHandLayer setRotationRadians:[self _secondPositionRadianForDate:dateValue]];
[_PMAMTextField setEnabled:_isEnabled];
[_hourHandLayer setEnabled:_isEnabled];
[_middleHandLayer setEnabled:_isEnabled];
[_secondHandLayer setEnabled:_isEnabled];
[_minuteHandLayer setEnabled:_isEnabled];
// Check if we have to display the hand second
if (([_datePicker datePickerElements] & CPHourMinuteSecondDatePickerElementFlag) == CPHourMinuteSecondDatePickerElementFlag)
[_secondHandLayer setHidden:NO];
else
[_secondHandLayer setHidden:YES];
[_rootLayer setNeedsDisplay];
}
#pragma mark -
#pragma mark Accessors
- (float)_hourPositionRadianForDate:(CPDate)aDate
{
var hours = aDate.getHours() + aDate.getMinutes() / 60;
return (360 * hours / 12) * RADIANS;
}
- (float)_secondPositionRadianForDate:(CPDate)aDate
{
return (360 * aDate.getSeconds() / 60) * RADIANS;
}
- (float)_minutePositionRadianForDate:(CPDate)aDate
{
var minutes = aDate.getMinutes() + aDate.getSeconds() / 60;
return (360 * minutes / 60) * RADIANS;
}
- (void)setEnabled:(BOOL)shouldEnable
{
shouldEnable = !!shouldEnable;
if (shouldEnable === _isEnabled)
return;
_isEnabled = shouldEnable;
[self setNeedsLayout];
// FIXME: This is a workaround for an apparent bug in CALayer.
// Without pumping the event loop, the sublayers of _rootLayer
// (the hands) are not redrawn until an event occurs.
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
}
@end
@implementation HandLayer : CALayer
{
BOOL _isEnabled @accessors(setter=setEnabled:, getter=isEnabled);
CPImage _image;
CALayer _imageLayer;
float _rotationRadians;
}
#pragma mark -
#pragma mark Init methods
- (id)initWithSize:(CGSize)aSize
{
if (self = [super init])
{
_isEnabled = YES;
_imageLayer = [CALayer layer];
_rotationRadians = 0;
[_imageLayer setDelegate:self];
[_imageLayer setBounds:CGRectMake(0.0, 0.0, aSize.width, aSize.height)];
[self addSublayer:_imageLayer];
}
return self;
}
#pragma mark -
#pragma mark Setter Getter methods
/*!
Set the bounds of the layer. The imageLayer will be at the center of this bounds.
*/
- (void)setBounds:(CGRect)aRect
{
[super setBounds:aRect];
[_imageLayer setPosition:CGPointMake(CGRectGetMidX(aRect), CGRectGetMidY(aRect))];
}
- (void)setImage:(CPImage)anImage
{
if (_image === anImage)
return;
if ([anImage isKindOfClass:[_CPCibCustomResource class]])
_image = [anImage imageFromCoder:nil];
else
_image = anImage;
[_imageLayer setNeedsDisplay];
}
- (void)setRotationRadians:(float)radians
{
if (_rotationRadians === radians)
return;
_rotationRadians = radians;
[_imageLayer setAffineTransform:CGAffineTransformScale(
CGAffineTransformMakeRotation(_rotationRadians),
1.0, 1.0)];
}
- (void)setEnabled:(BOOL)shouldEnable
{
shouldEnable = !!shouldEnable;
if (_isEnabled === shouldEnable)
return;
_isEnabled = shouldEnable;
[self setNeedsDisplay];
[_imageLayer setNeedsDisplay];
}
- (void)imageDidLoad:(CPImage)anImage
{
[_imageLayer setNeedsDisplay];
}
- (void)drawLayer:(CALayer)aLayer inContext:(CGContext)aContext
{
if ([_image loadStatus] != CPImageLoadStatusCompleted)
[_image setDelegate:self];
else
CGContextDrawImage(aContext, [aLayer bounds], _image);
}
@end
File diff suppressed because it is too large Load Diff
+168
View File
@@ -0,0 +1,168 @@
/*
* CPDictionaryController.j
* AppKit
*
* Adapted from Cocotron, by Johannes Fortmann
*
* Created by Blair Duncan
* Copyright 2013, SGL Studio, BBDO Toronto All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "CPArrayController.j"
@implementation CPDictionaryController : CPArrayController
{
CPDictionary _contentDictionary;
CPArray _includedKeys @accessors(property=includedKeys);
CPArray _excludedKeys @accessors(property=excludedKeys);
CPString _initialKey @accessors(property=initialKey);
id _initialValue @accessors(property=initialValue);
}
- (id)init
{
self = [super init];
if (self)
{
_initialKey = @"key";
_initialValue = @"value";
}
return self;
}
- (id)newObject
{
var keys = [_contentDictionary allKeys],
newKey = _initialKey,
count = 0;
if ([keys containsObject:newKey])
while ([keys containsObject:newKey])
newKey = [CPString stringWithFormat:@"%@%i", _initialKey, ++count];
return [self _newObjectWithKey:newKey value:_initialValue];
}
- (id)_newObjectWithKey:(CPString)aKey value:(id)aValue
{
var aNewObject = [_CPDictionaryControllerKeyValuePair new];
aNewObject._dictionary = _contentDictionary;
aNewObject._controller = self;
aNewObject._key = aKey;
if (aValue !== nil)
[aNewObject setValue:aValue];
return aNewObject;
}
- (CPDictionary)contentDictionary
{
return _contentDictionary;
}
- (void)setContentDictionary:(CPDictionary)aDictionary
{
if (aDictionary == _contentDictionary)
return;
if ([aDictionary isKindOfClass:[CPDictionary class]])
_contentDictionary = aDictionary;
else
_contentDictionary = nil;
var array = [CPArray array],
allKeys = [_contentDictionary allKeys];
[allKeys addObjectsFromArray:_includedKeys];
var iter = [[CPSet setWithArray:allKeys] objectEnumerator],
obj;
while ((obj = [iter nextObject]) !== nil)
if (![_excludedKeys containsObject:obj])
[array addObject:[self _newObjectWithKey:obj value:nil]];
[super setContent:array];
}
@end
var CPIncludedKeys = @"CPIncludedKeys",
CPExcludedKeys = @"CPExcludedKeys";
@implementation CPDictionaryController (CPCoding)
- (id)initWithCoder:(CPCoder)aCoder
{
self = [super initWithCoder:aCoder];
if (self)
{
_includedKeys = [aCoder decodeObjectForKey:CPIncludedKeys];
_excludedKeys = [aCoder decodeObjectForKey:CPExcludedKeys];
_initialKey = @"key";
_initialValue = @"value";
}
return self;
}
- (void)encodeWithCoder:(CPCoder)aCoder
{
[super encodeWithCoder:aCoder];
[aCoder encodeObject:_includedKeys forKey:CPIncludedKeys];
[aCoder encodeObject:_excludedKeys forKey:CPExcludedKeys];
}
@end
@implementation _CPDictionaryControllerKeyValuePair : CPObject
{
CPString _key @accessors(property=key);
CPDictionary _dictionary @accessors(property=dictionary);
CPDictionaryController _controller @accessors(property=controller);
}
- (id)value
{
return [_dictionary objectForKey:_key];
}
- (void)setValue:(id)aValue
{
[_dictionary setObject:aValue forKey:_key];
}
- (BOOL)isExplicitlyIncluded
{
return [[_controller _includedKeys] containsObject:_key];
}
@end
+41 -42
View File
@@ -23,12 +23,16 @@
@import <Foundation/CPString.j>
@import <Foundation/CPArray.j>
@import "CPApplication.j"
@import "CPAlert.j"
@import "CPResponder.j"
@import "CPSavePanel.j"
@import "CPViewController.j"
@import "CPWindowController.j"
@class CPDocumentController
@global CPApp
/*
@global
@@ -125,7 +129,7 @@ var CPDocumentUntitledCount = 0;
if (self)
{
_windowControllers = [];
_viewControllersForWindowControllers = [CPDictionary dictionary];
_viewControllersForWindowControllers = @{};
_hasUndoManager = YES;
_changeCount = 0;
@@ -142,7 +146,7 @@ var CPDocumentUntitledCount = 0;
@param anError not used
@return the initialized document
*/
- (id)initWithType:(CPString)aType error:({CPError})anError
- (id)initWithType:(CPString)aType error:(/*{*/CPError/*}*/)anError
{
self = [self init];
@@ -211,7 +215,7 @@ var CPDocumentUntitledCount = 0;
@throws CPUnsupportedMethodException if this method hasn't been overridden by the subclass
@return the document data
*/
- (CPData)dataOfType:(CPString)aType error:({CPError})anError
- (CPData)dataOfType:(CPString)aType error:(/*{*/CPError/*}*/)anError
{
[CPException raise:CPUnsupportedMethodException
reason:"dataOfType:error: must be overridden by the document subclass."];
@@ -240,11 +244,6 @@ var CPDocumentUntitledCount = 0;
{
}
- (CPWindowController)firstEligibleExistingWindowController
{
return nil;
}
// Creating and managing window controllers
/*!
Creates the window controller for this document.
@@ -257,6 +256,7 @@ var CPDocumentUntitledCount = 0;
- (void)makeViewAndWindowControllers
{
var viewCibName = [self viewCibName],
windowCibName = [self windowCibName],
viewController = nil,
windowController = nil;
@@ -264,31 +264,21 @@ var CPDocumentUntitledCount = 0;
if ([viewCibName length])
viewController = [[CPViewController alloc] initWithCibName:viewCibName bundle:nil owner:self];
// If we have a view controller, check if we have a free window for it.
if (viewController)
windowController = [self firstEligibleExistingWindowController];
// From a cib if we have one.
if ([windowCibName length])
windowController = [[CPWindowController alloc] initWithWindowCibName:windowCibName owner:self];
// If not, create one.
if (!windowController)
// If not you get a standard window capable of displaying multiple documents and view
else if (viewController)
{
var windowCibName = [self windowCibName];
var view = [viewController view],
viewFrame = [view frame];
// From a cib if we have one.
if ([windowCibName length])
windowController = [[CPWindowController alloc] initWithWindowCibName:windowCibName owner:self];
viewFrame.origin = CGPointMake(50, 50);
// If not you get a standard window capable of displaying multiple documents and view
else if (viewController)
{
var view = [viewController view],
viewFrame = [view frame];
var theWindow = [[CPWindow alloc] initWithContentRect:viewFrame styleMask:CPTitledWindowMask | CPClosableWindowMask | CPMiniaturizableWindowMask | CPResizableWindowMask];
viewFrame.origin = CGPointMake(50, 50);
var theWindow = [[CPWindow alloc] initWithContentRect:viewFrame styleMask:CPTitledWindowMask | CPClosableWindowMask | CPMiniaturizableWindowMask | CPResizableWindowMask];
windowController = [[CPWindowController alloc] initWithWindow:theWindow];
}
windowController = [[CPWindowController alloc] initWithWindow:theWindow];
}
if (windowController && viewController)
@@ -525,7 +515,9 @@ var CPDocumentUntitledCount = 0;
alert("There was an error retrieving the document.");
objj_msgSend(session.delegate, session.didReadSelector, self, NO, session.contextInfo);
var theDelegate = session.delegate;
theDelegate.isa.objj_msgSend3(theDelegate, session.didReadSelector, self, NO, session.contextInfo);
}
else
{
@@ -550,7 +542,9 @@ var CPDocumentUntitledCount = 0;
_writeRequest = nil;
objj_msgSend(session.delegate, session.didSaveSelector, self, NO, session.contextInfo);
var theDelegate = session.delegate;
theDelegate.isa.objj_msgSend3(theDelegate, session.didSaveSelector, self, NO, session.contextInfo);
[self _sendDocumentSavedNotification:NO];
}
}
@@ -563,14 +557,15 @@ var CPDocumentUntitledCount = 0;
*/
- (void)connection:(CPURLConnection)aConnection didReceiveData:(CPString)aData
{
var session = aConnection.session;
var session = aConnection.session,
theDelegate = session.delegate;
// READ
if (aConnection == _readConnection)
{
[self readFromData:[CPData dataWithRawString:aData] ofType:session.fileType error:nil];
objj_msgSend(session.delegate, session.didReadSelector, self, YES, session.contextInfo);
theDelegate.isa.objj_msgSend3(theDelegate, session.didReadSelector, self, YES, session.contextInfo);
}
else
{
@@ -579,7 +574,7 @@ var CPDocumentUntitledCount = 0;
_writeRequest = nil;
objj_msgSend(session.delegate, session.didSaveSelector, self, YES, session.contextInfo);
theDelegate.isa.objj_msgSend3(theDelegate, session.didSaveSelector, self, YES, session.contextInfo);
[self _sendDocumentSavedNotification:YES];
}
}
@@ -590,10 +585,11 @@ var CPDocumentUntitledCount = 0;
*/
- (void)connection:(CPURLConnection)aConnection didFailWithError:(CPError)anError
{
var session = aConnection.session;
var session = aConnection.session,
theDelegate = session.delegate;
if (_readConnection == aConnection)
objj_msgSend(session.delegate, session.didReadSelector, self, NO, session.contextInfo);
theDelegate.isa.objj_msgSend3(theDelegate, session.didReadSelector, self, NO, session.contextInfo);
else
{
@@ -607,7 +603,7 @@ var CPDocumentUntitledCount = 0;
alert("There was an error saving the document.");
objj_msgSend(session.delegate, session.didSaveSelector, self, NO, session.contextInfo);
theDelegate.isa.objj_msgSend3(theDelegate, session.didSaveSelector, self, NO, session.contextInfo);
[self _sendDocumentSavedNotification:NO];
}
}
@@ -868,21 +864,24 @@ var CPDocumentUntitledCount = 0;
[self canCloseDocumentWithDelegate:self shouldCloseSelector:@selector(_document:shouldClose:context:) contextInfo:{delegate:delegate, selector:selector, context:info}];
else if ([delegate respondsToSelector:selector])
objj_msgSend(delegate, selector, self, YES, info);
delegate.isa.objj_msgSend3(delegate, selector, self, YES, info);
}
- (void)_document:(CPDocument)aDocument shouldClose:(BOOL)shouldClose context:(Object)context
{
var theDelegate = context.delegate;
if (aDocument === self && shouldClose)
[self close];
objj_msgSend(context.delegate, context.selector, aDocument, shouldClose, context.context);
if (theDelegate != null)
theDelegate.isa.objj_msgSend3(theDelegate, context.selector, aDocument, shouldClose, context.context);
}
- (void)canCloseDocumentWithDelegate:(id)aDelegate shouldCloseSelector:(SEL)aSelector contextInfo:(Object)context
{
if (![self isDocumentEdited])
return [aDelegate respondsToSelector:aSelector] && objj_msgSend(aDelegate, aSelector, self, YES, context);
return [aDelegate respondsToSelector:aSelector] && aDelegate.isa.objj_msgSend3(aDelegate, aSelector, self, YES, context);
_canCloseAlert = [[CPAlert alloc] init];
@@ -911,8 +910,8 @@ var CPDocumentUntitledCount = 0;
if (returnCode === 0)
[self saveDocumentWithDelegate:delegate didSaveSelector:selector contextInfo:context];
else
objj_msgSend(delegate, selector, self, returnCode === 2, context);
else if (delegate != null)
delegate.isa.objj_msgSend3(delegate, selector, self, returnCode === 2, context);
_canCloseAlert = nil;
}
+49 -8
View File
@@ -25,6 +25,10 @@
@import "CPDocument.j"
@import "CPOpenPanel.j"
@import "CPMenuItem.j"
@import "CPWindowController.j"
@global CPApp
var CPSharedDocumentController = nil;
@@ -124,7 +128,7 @@ var CPSharedDocumentController = nil;
@param anError not used
@return the created document
*/
- (CPDocument)makeUntitledDocumentOfType:(CPString)aType error:({CPError})anError
- (CPDocument)makeUntitledDocumentOfType:(CPString)aType error:(/*{*/CPError/*}*/)anError
{
return [[[self documentClassForType:aType] alloc] initWithType:aType error:anError];
}
@@ -144,7 +148,7 @@ var CPSharedDocumentController = nil;
{
var type = [self typeForContentsOfURL:anAbsoluteURL error:anError];
result = [self makeDocumentWithContentsOfURL:anAbsoluteURL ofType:type delegate:self didReadSelector:@selector(document:didRead:contextInfo:) contextInfo:[CPDictionary dictionaryWithObject:shouldDisplay forKey:@"shouldDisplay"]];
result = [self makeDocumentWithContentsOfURL:anAbsoluteURL ofType:type delegate:self didReadSelector:@selector(document:didRead:contextInfo:) contextInfo:@{ @"shouldDisplay": shouldDisplay }];
[self addDocument:result];
@@ -249,6 +253,14 @@ var CPSharedDocumentController = nil;
return _documents;
}
/*!
Returns the CPDocument object associated with the main window.
*/
- (CPDocument)currentDocument
{
return [[[CPApp mainWindow] windowController] document];
}
/*!
Adds \c aDocument under the control of the receiver.
@param aDocument the document to add
@@ -267,6 +279,33 @@ var CPSharedDocumentController = nil;
[_documents removeObjectIdenticalTo:aDocument];
}
/*!
Returns the document object whose window controller
owns a specified window.
*/
- (CPDocument)documentForWindow:(CPWindow)aWindow
{
return [[aWindow windowController] document];
}
/*!
Returns a Boolean value that indicates whether the receiver
has any documents with unsaved changes.
*/
- (BOOL)hasEditedDocuments
{
var iter = [_documents objectEnumerator],
obj;
while ((obj = [iter nextObject]) !== nil)
{
if ([obj isDocumentEdited])
return YES;
}
return NO;
}
- (CPString)defaultType
{
return [_documentTypes[0] objectForKey:@"CPBundleTypeName"];
@@ -339,10 +378,10 @@ var CPSharedDocumentController = nil;
- (void)closeAllDocumentsWithDelegate:(id)aDelegate didCloseAllSelector:(SEL)didCloseSelector contextInfo:(Object)info
{
var context = {
delegate: aDelegate,
selector: didCloseSelector,
context: info
};
delegate: aDelegate,
selector: didCloseSelector,
context: info
};
[self _closeDocumentsStartingWith:nil shouldClose:YES context:context];
}
@@ -363,8 +402,10 @@ var CPSharedDocumentController = nil;
}
}
if ([context.delegate respondsToSelector:context.selector])
objj_msgSend(context.delegate, context.selector, self, [[self documents] count] === 0, context.context);
var theDelegate = context.delegate;
if ([theDelegate respondsToSelector:context.selector])
theDelegate.isa.objj_msgSend3(theDelegate, context.selector, self, [[self documents] count] === 0, context.context);
}
@end
+37 -64
View File
@@ -20,22 +20,17 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "CPApplication.j"
@import "CPDragServer_Constants.j"
@import "CPEvent.j"
@import "CPImageView.j"
@import "CPPasteboard.j"
@import "CPView.j"
@import "CPWindow.j"
@import "CPWindow_Constants.j"
@class CPWindow // This file is imported by CPWindow.j
@class _CPDOMDataTransferPasteboard
CPDragOperationNone = 0;
CPDragOperationCopy = 1 << 1;
CPDragOperationLink = 1 << 1;
CPDragOperationGeneric = 1 << 2;
CPDragOperationPrivate = 1 << 3;
CPDragOperationMove = 1 << 4;
CPDragOperationDelete = 1 << 5;
CPDragOperationEvery = -1;
@global CPApp
#define DRAGGING_WINDOW(anObject) ([anObject isKindOfClass:[CPWindow class]] ? anObject : [anObject window])
@@ -72,7 +67,7 @@ var CPDragServerSource = nil,
- (unsigned)draggingSourceOperationMask
*/
- (CPPoint)draggingLocation
- (CGPoint)draggingLocation
{
return [[CPDragServer sharedDragServer] draggingLocation];
}
@@ -168,7 +163,7 @@ var CPDraggingSource_draggedImage_movedTo_ = 1 << 0,
if (self)
{
_draggedWindow = [[CPWindow alloc] initWithContentRect:_CGRectMakeZero() styleMask:CPBorderlessWindowMask];
_draggedWindow = [[CPWindow alloc] initWithContentRect:CGRectMakeZero() styleMask:CPBorderlessWindowMask];
[_draggedWindow setLevel:CPDraggingWindowLevel];
}
@@ -206,7 +201,12 @@ var CPDraggingSource_draggedImage_movedTo_ = 1 << 0,
- (void)draggingSourceUpdatedWithGlobalLocation:(CGPoint)aGlobalLocation
{
if (![CPPlatform supportsDragAndDrop])
[_draggedWindow setFrameOrigin:_CGPointMake(aGlobalLocation.x - _draggingOffset.width, aGlobalLocation.y - _draggingOffset.height)];
{
var frame = [_draggedWindow frame];
frame.origin.x = aGlobalLocation.x - _draggingOffset.width;
frame.origin.y = aGlobalLocation.y - _draggingOffset.height;
[_draggedWindow _setFrame:frame display:YES animate:NO constrainWidth:NO constrainHeight:NO];
}
if (_implementedDraggingSourceMethods & CPDraggingSource_draggedImage_movedTo_)
[_draggingSource draggedImage:[_draggedView image] movedTo:aGlobalLocation];
@@ -253,7 +253,7 @@ var CPDraggingSource_draggedImage_movedTo_ = 1 << 0,
_draggingUpdateTimer = [CPTimer scheduledTimerWithTimeInterval:CPDragServerPeriodicUpdateInterval
target:self
selector:@selector(_sendPeriodicDraggingUpdate:)
userInfo:[CPDictionary dictionaryWithJSObject:{platformWindow:aPlatformWindow, location:aLocation}]
userInfo:@{ "platformWindow":aPlatformWindow, "location":aLocation }
repeats:NO];
var scrollView = [_draggingDestination isKindOfClass:[CPView class]] ? [_draggingDestination enclosingScrollView] : nil;
@@ -270,10 +270,10 @@ var CPDraggingSource_draggedImage_movedTo_ = 1 << 0,
{
if ([scrollView hasVerticalScroller])
{
if (eventLocation.y < _CGRectGetMinY(insetBounds))
deltaY = _CGRectGetMinY(insetBounds) - eventLocation.y;
else if (eventLocation.y > _CGRectGetMaxY(insetBounds))
deltaY = _CGRectGetMaxY(insetBounds) - eventLocation.y;
if (eventLocation.y < CGRectGetMinY(insetBounds))
deltaY = CGRectGetMinY(insetBounds) - eventLocation.y;
else if (eventLocation.y > CGRectGetMaxY(insetBounds))
deltaY = CGRectGetMaxY(insetBounds) - eventLocation.y;
if (deltaY < -insetBounds.size.height)
deltaY = -insetBounds.size.height;
if (deltaY > insetBounds.size.height)
@@ -282,17 +282,17 @@ var CPDraggingSource_draggedImage_movedTo_ = 1 << 0,
if ([scrollView hasHorizontalScroller])
{
if (eventLocation.x < _CGRectGetMinX(insetBounds))
deltaX = _CGRectGetMinX(insetBounds) - eventLocation.x;
else if (eventLocation.x > _CGRectGetMaxX(insetBounds))
deltaX = _CGRectGetMaxX(insetBounds) - eventLocation.x;
if (eventLocation.x < CGRectGetMinX(insetBounds))
deltaX = CGRectGetMinX(insetBounds) - eventLocation.x;
else if (eventLocation.x > CGRectGetMaxX(insetBounds))
deltaX = CGRectGetMaxX(insetBounds) - eventLocation.x;
if (deltaX < -insetBounds.size.width)
deltaX = -insetBounds.size.width;
if (deltaX > insetBounds.size.width)
deltaX = insetBounds.size.width;
}
var scrollPoint = _CGPointMake(bounds.origin.x - deltaX, bounds.origin.y - deltaY);
var scrollPoint = CGPointMake(bounds.origin.x - deltaX, bounds.origin.y - deltaY);
[contentView scrollToPoint:scrollPoint];
[[scrollView _headerView] scrollPoint:scrollPoint];
@@ -370,22 +370,26 @@ var CPDraggingSource_draggedImage_movedTo_ = 1 << 0,
if (mouseDownWindow)
mouseDownEventLocation = [mouseDownWindow convertBaseToGlobal:mouseDownEventLocation];
_draggingOffset = _CGSizeMake(mouseDownEventLocation.x - viewLocation.x, mouseDownEventLocation.y - viewLocation.y);
_draggingOffset = CGSizeMake(mouseDownEventLocation.x - viewLocation.x, mouseDownEventLocation.y - viewLocation.y);
}
else
_draggingOffset = _CGSizeMakeZero();
_draggingOffset = CGSizeMakeZero();
if ([CPPlatform isBrowser])
[_draggedWindow setPlatformWindow:[aWindow platformWindow]];
[aView setFrameOrigin:_CGPointMakeZero()];
[aView setFrameOrigin:CGPointMakeZero()];
var mouseLocation = [CPEvent mouseLocation];
var mouseLocation = [CPEvent mouseLocation],
viewSize = [aView frameSize],
startDragLocationX = mouseLocation.x - _draggingOffset.width,
startDragLocationY = mouseLocation.y - _draggingOffset.height,
draggedWindowFrame = CGRectMake(startDragLocationX, startDragLocationY, viewSize.width, viewSize.height);
// Place it where the mouse pointer is.
_startDragLocation = _CGPointMake(mouseLocation.x - _draggingOffset.width, mouseLocation.y - _draggingOffset.height);
[_draggedWindow setFrameOrigin:_startDragLocation];
[_draggedWindow setFrameSize:[aView frame].size];
_startDragLocation = CGPointMake(startDragLocationX, startDragLocationY);
[_draggedWindow _setFrame:draggedWindowFrame display:YES animate:NO constrainWidth:NO constrainHeight:NO];
[[_draggedWindow contentView] addSubview:aView];
@@ -434,7 +438,7 @@ var CPDraggingSource_draggedImage_movedTo_ = 1 << 0,
var imageSize = [anImage size];
if (!_imageView)
_imageView = [[CPImageView alloc] initWithFrame:_CGRectMake(0.0, 0.0, imageSize.width, imageSize.height)];
_imageView = [[CPImageView alloc] initWithFrame:CGRectMake(0.0, 0.0, imageSize.width, imageSize.height)];
[_imageView setImage:anImage];
@@ -461,6 +465,7 @@ var CPDraggingSource_draggedImage_movedTo_ = 1 << 0,
else if (type === CPKeyDown)
{
var characters = [anEvent characters];
if (characters === CPEscapeFunctionKey)
{
_dragOperation = CPDragOperationNone;
@@ -477,39 +482,7 @@ var CPDraggingSource_draggedImage_movedTo_ = 1 << 0,
// If we're not a mouse up, then we're going to want to grab the next event.
[CPApp setTarget:self selector:@selector(trackDragging:)
forNextEventMatchingMask:CPMouseMovedMask | CPLeftMouseDraggedMask | CPLeftMouseUpMask | CPKeyDownMask
untilDate:nil inMode:0 dequeue:NO];
}
@end
@implementation CPWindow (CPDraggingAdditions)
/* @ignore */
- (id)_dragHitTest:(CGPoint)aPoint pasteboard:(CPPasteboard)aPasteboard
{
// If none of our views or ourselves has registered for drag events...
if (!_inclusiveRegisteredDraggedTypes)
return nil;
// We don't need to do this because the only place this gets called
// -_dragHitTest: in CPPlatformWindow does this already. Perhaps to
// be safe?
// if (![self containsPoint:aPoint])
// return nil;
var adjustedPoint = [self convertPlatformWindowToBase:aPoint],
hitView = [_windowView hitTest:adjustedPoint];
while (hitView && ![aPasteboard availableTypeFromArray:[hitView registeredDraggedTypes]])
hitView = [hitView superview];
if (hitView)
return hitView;
if ([aPasteboard availableTypeFromArray:[self registeredDraggedTypes]])
return self;
return nil;
untilDate:nil inMode:0 dequeue:YES];
}
@end
@@ -1,9 +1,9 @@
/*
* CPRange.h
* Foundation
* CPDragServer_Constants.j
* AppKit
*
* Created by Alexander Ljungberg.
* Copyright 2012, SlevenBits Ltd.
* Created by Francisco Tolmasky.
* Copyright 2008, 280 North, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -20,8 +20,12 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#define _CPMaxRange(aRange) ((aRange).location + (aRange).length)
#define _CPMakeRange(aLocation, aLength) { location:(aLocation), length:aLength }
#define _CPMakeRangeCopy(aRange) { location:(aRange).location, length:(aRange).length }
#define _CPEmptyRange(aRange) ((aRange).length === 0)
#define _CPLocationInRange(aLocation, aRange) (((aLocation) >= (aRange).location) && ((aLocation) < _CPMaxRange(aRange)))
@typedef CPDragOperation
CPDragOperationNone = 0;
CPDragOperationCopy = 1 << 1;
CPDragOperationLink = 1 << 1;
CPDragOperationGeneric = 1 << 2;
CPDragOperationPrivate = 1 << 3;
CPDragOperationMove = 1 << 4;
CPDragOperationDelete = 1 << 5;
CPDragOperationEvery = -1;
+144 -162
View File
@@ -20,162 +20,28 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "CPEvent_Constants.j"
@import <Foundation/CPObject.j>
@import "CPText.j"
@import <Foundation/CPObjJRuntime.j>
@import <Foundation/CPString.j>
@import "CPCompatibility.j"
@import "CGGeometry.j"
@import "CPTrackingArea.j"
CPLeftMouseDown = 1;
CPLeftMouseUp = 2;
CPRightMouseDown = 3;
CPRightMouseUp = 4;
CPMouseMoved = 5;
CPLeftMouseDragged = 6;
CPRightMouseDragged = 7;
CPMouseEntered = 8;
CPMouseExited = 9;
CPKeyDown = 10;
CPKeyUp = 11;
CPFlagsChanged = 12;
CPAppKitDefined = 13;
CPSystemDefined = 14;
CPApplicationDefined = 15;
CPPeriodic = 16;
CPCursorUpdate = 17;
CPScrollWheel = 22;
CPOtherMouseDown = 25;
CPOtherMouseUp = 26;
CPOtherMouseDragged = 27;
@class CPTextField
@class CPWindow
@class CPGraphicsContext
// iPhone Event Types
CPTouchStart = 28;
CPTouchMove = 29;
CPTouchEnd = 30;
CPTouchCancel = 31;
@global CPApp
@global CPNewlineCharacter
@global CPCarriageReturnCharacter
@global CPEnterCharacter
CPAlphaShiftKeyMask = 1 << 16;
CPShiftKeyMask = 1 << 17;
CPControlKeyMask = 1 << 18;
CPAlternateKeyMask = 1 << 19;
CPCommandKeyMask = 1 << 20;
CPNumericPadKeyMask = 1 << 21;
CPHelpKeyMask = 1 << 22;
CPFunctionKeyMask = 1 << 23;
CPDeviceIndependentModifierFlagsMask = 0xffff0000;
@typedef DOMEvent
@typedef CPEventType
CPLeftMouseDownMask = 1 << CPLeftMouseDown;
CPLeftMouseUpMask = 1 << CPLeftMouseUp;
CPRightMouseDownMask = 1 << CPRightMouseDown;
CPRightMouseUpMask = 1 << CPRightMouseUp;
CPOtherMouseDownMask = 1 << CPOtherMouseDown;
CPOtherMouseUpMask = 1 << CPOtherMouseUp;
CPMouseMovedMask = 1 << CPMouseMoved;
CPLeftMouseDraggedMask = 1 << CPLeftMouseDragged;
CPRightMouseDraggedMask = 1 << CPRightMouseDragged;
CPOtherMouseDragged = 1 << CPOtherMouseDragged;
CPMouseEnteredMask = 1 << CPMouseEntered;
CPMouseExitedMask = 1 << CPMouseExited;
CPCursorUpdateMask = 1 << CPCursorUpdate;
CPKeyDownMask = 1 << CPKeyDown;
CPKeyUpMask = 1 << CPKeyUp;
CPFlagsChangedMask = 1 << CPFlagsChanged;
CPAppKitDefinedMask = 1 << CPAppKitDefined;
CPSystemDefinedMask = 1 << CPSystemDefined;
CPApplicationDefinedMask = 1 << CPApplicationDefined;
CPPeriodicMask = 1 << CPPeriodic;
CPScrollWheelMask = 1 << CPScrollWheel;
CPAnyEventMask = 0xffffffff;
CPUpArrowFunctionKey = "\uF700";
CPDownArrowFunctionKey = "\uF701";
CPLeftArrowFunctionKey = "\uF702";
CPRightArrowFunctionKey = "\uF703";
CPF1FunctionKey = "\uF704";
CPF2FunctionKey = "\uF705";
CPF3FunctionKey = "\uF706";
CPF4FunctionKey = "\uF707";
CPF5FunctionKey = "\uF708";
CPF6FunctionKey = "\uF709";
CPF7FunctionKey = "\uF70A";
CPF8FunctionKey = "\uF70B";
CPF9FunctionKey = "\uF70C";
CPF10FunctionKey = "\uF70D";
CPF11FunctionKey = "\uF70E";
CPF12FunctionKey = "\uF70F";
CPF13FunctionKey = "\uF710";
CPF14FunctionKey = "\uF711";
CPF15FunctionKey = "\uF712";
CPF16FunctionKey = "\uF713";
CPF17FunctionKey = "\uF714";
CPF18FunctionKey = "\uF715";
CPF19FunctionKey = "\uF716";
CPF20FunctionKey = "\uF717";
CPF21FunctionKey = "\uF718";
CPF22FunctionKey = "\uF719";
CPF23FunctionKey = "\uF71A";
CPF24FunctionKey = "\uF71B";
CPF25FunctionKey = "\uF71C";
CPF26FunctionKey = "\uF71D";
CPF27FunctionKey = "\uF71E";
CPF28FunctionKey = "\uF71F";
CPF29FunctionKey = "\uF720";
CPF30FunctionKey = "\uF721";
CPF31FunctionKey = "\uF722";
CPF32FunctionKey = "\uF723";
CPF33FunctionKey = "\uF724";
CPF34FunctionKey = "\uF725";
CPF35FunctionKey = "\uF726";
CPInsertFunctionKey = "\uF727";
CPDeleteFunctionKey = "\uF728";
CPHomeFunctionKey = "\uF729";
CPBeginFunctionKey = "\uF72A";
CPEndFunctionKey = "\uF72B";
CPPageUpFunctionKey = "\uF72C";
CPPageDownFunctionKey = "\uF72D";
CPPrintScreenFunctionKey = "\uF72E";
CPScrollLockFunctionKey = "\uF72F";
CPPauseFunctionKey = "\uF730";
CPSysReqFunctionKey = "\uF731";
CPBreakFunctionKey = "\uF732";
CPResetFunctionKey = "\uF733";
CPStopFunctionKey = "\uF734";
CPMenuFunctionKey = "\uF735";
CPUserFunctionKey = "\uF736";
CPSystemFunctionKey = "\uF737";
CPPrintFunctionKey = "\uF738";
CPClearLineFunctionKey = "\uF739";
CPClearDisplayFunctionKey = "\uF73A";
CPInsertLineFunctionKey = "\uF73B";
CPDeleteLineFunctionKey = "\uF73C";
CPInsertCharFunctionKey = "\uF73D";
CPDeleteCharFunctionKey = "\uF73E";
CPPrevFunctionKey = "\uF73F";
CPNextFunctionKey = "\uF740";
CPSelectFunctionKey = "\uF741";
CPExecuteFunctionKey = "\uF742";
CPUndoFunctionKey = "\uF743";
CPRedoFunctionKey = "\uF744";
CPFindFunctionKey = "\uF745";
CPHelpFunctionKey = "\uF746";
CPModeSwitchFunctionKey = "\uF747";
CPEscapeFunctionKey = "\u001B";
CPSpaceFunctionKey = "\u0020";
CPDOMEventDoubleClick = "dblclick";
CPDOMEventMouseDown = "mousedown";
CPDOMEventMouseUp = "mouseup";
CPDOMEventMouseMoved = "mousemove";
CPDOMEventMouseDragged = "mousedrag";
CPDOMEventKeyUp = "keyup";
CPDOMEventKeyDown = "keydown";
CPDOMEventKeyPress = "keypress";
CPDOMEventCopy = "copy";
CPDOMEventPaste = "paste";
CPDOMEventScrollWheel = "mousewheel";
CPDOMEventTouchStart = "touchstart";
CPDOMEventTouchMove = "touchmove";
CPDOMEventTouchEnd = "touchend";
CPDOMEventTouchCancel = "touchcancel";
var _CPEventPeriodicEventPeriod = 0,
_CPEventPeriodicEventTimer = nil,
@@ -190,7 +56,7 @@ var _CPEventPeriodicEventPeriod = 0,
@implementation CPEvent : CPObject
{
CPEventType _type;
CPPoint _location;
CGPoint _location;
unsigned _modifierFlags;
CPTimeInterval _timestamp;
CPGraphicsContext _context;
@@ -200,16 +66,27 @@ var _CPEventPeriodicEventPeriod = 0,
CPWindow _window;
Number _windowNumber;
CPString _characters;
CPString _charactersIgnoringModifiers
CPString _charactersIgnoringModifiers;
BOOL _isARepeat;
unsigned _keyCode;
DOMEvent _DOMEvent;
int _data1;
int _data2;
short _subtype;
float _deltaX;
float _deltaY;
float _deltaZ;
float _scrollingDeltaX;
float _scrollingDeltaY;
BOOL _hasPreciseScrollingDeltas;
#if PLATFORM(DOM)
BOOL _suppressCappuccinoCut;
BOOL _suppressCappuccinoPaste;
#endif
CPTrackingArea _trackingArea;
}
/*!
@@ -269,6 +146,27 @@ var _CPEventPeriodicEventPeriod = 0,
timestamp:aTimestamp windowNumber:aWindowNumber context:aGraphicsContext eventNumber:anEventNumber clickCount:aClickCount pressure:aPressure];
}
/*!
Creates a new mouse tracking event.
@param anEventType the event type
@param aPoint the location of the cursor in the window specified by \c aWindowNumber
@param modifierFlags a bitwise combination of the modifiers specified in the CPEvent globals
@param aTimestamp the time the event occurred
@param aWindowNumber the number of the CPWindow where the event occurred
@param aGraphicsContext the graphics context where the event occurred
@param anEventNumber a number for this event
@param aTrackingArea the tracking area that triggered the event
@throws CPInternalInconsistencyException if an invalid event type is provided
@return the new mouse event
*/
+ (id)enterExitEventWithType:(CPEventType)anEventType location:(CGPoint)aPoint modifierFlags:(unsigned)modifierFlags
timestamp:(CPTimeInterval)aTimestamp windowNumber:(int)aWindowNumber context:(CPGraphicsContext)aGraphicsContext
eventNumber:(int)anEventNumber trackingArea:(CPTrackingArea)aTrackingArea
{
return [[self alloc] _initEnterExitEventWithType:anEventType location:aPoint modifierFlags:modifierFlags timestamp:aTimestamp windowNumber:aWindowNumber context:aGraphicsContext eventNumber:anEventNumber trackingArea:aTrackingArea];
}
/*!
Creates a new custom event.
@@ -300,7 +198,9 @@ var _CPEventPeriodicEventPeriod = 0,
// Make sure these are 0 rather than nil.
_deltaX = 0;
_scrollingDeltaX = 0;
_deltaY = 0;
_scrollingDeltaY = 0;
_deltaZ = 0;
}
@@ -308,13 +208,13 @@ var _CPEventPeriodicEventPeriod = 0,
}
/* @ignore */
- (id)_initMouseEventWithType:(CPEventType)anEventType location:(CPPoint)aPoint modifierFlags:(unsigned)modifierFlags
- (id)_initMouseEventWithType:(CPEventType)anEventType location:(CGPoint)aPoint modifierFlags:(unsigned)modifierFlags
timestamp:(CPTimeInterval)aTimestamp windowNumber:(int)aWindowNumber context:(CPGraphicsContext)aGraphicsContext
eventNumber:(int)anEventNumber clickCount:(int)aClickCount pressure:(float)aPressure
{
if (self = [self _initWithType:anEventType])
{
_location = CPPointCreateCopy(aPoint);
_location = CGPointCreateCopy(aPoint);
_modifierFlags = modifierFlags;
_timestamp = aTimestamp;
_context = aGraphicsContext;
@@ -328,13 +228,35 @@ var _CPEventPeriodicEventPeriod = 0,
}
/* @ignore */
- (id)_initKeyEventWithType:(CPEventType)anEventType location:(CPPoint)aPoint modifierFlags:(unsigned int)modifierFlags
- (id)_initEnterExitEventWithType:(CPEventType)anEventType location:(CGPoint)aPoint modifierFlags:(unsigned)modifierFlags
timestamp:(CPTimeInterval)aTimestamp windowNumber:(int)aWindowNumber context:(CPGraphicsContext)aGraphicsContext
eventNumber:(int)anEventNumber trackingArea:(CPTrackingArea)aTrackingArea
{
if ((anEventType != CPMouseEntered) && (anEventType != CPMouseExited) && (anEventType != CPCursorUpdate))
[CPException raise:CPInternalInconsistencyException reason:"Invalid event type"];
if (self = [self _initWithType:anEventType])
{
_location = CGPointCreateCopy(aPoint);
_modifierFlags = modifierFlags;
_timestamp = aTimestamp;
_context = aGraphicsContext;
_eventNumber = anEventNumber;
_trackingArea = aTrackingArea;
_window = [CPApp windowWithWindowNumber:aWindowNumber];
}
return self;
}
/* @ignore */
- (id)_initKeyEventWithType:(CPEventType)anEventType location:(CGPoint)aPoint modifierFlags:(unsigned int)modifierFlags
timestamp:(CPTimeInterval)aTimestamp windowNumber:(int)aWindowNumber context:(CPGraphicsContext)aGraphicsContext
characters:(CPString)characters charactersIgnoringModifiers:(CPString)unmodCharacters isARepeat:(BOOL)isARepeat keyCode:(unsigned short)code
{
if (self = [self _initWithType:anEventType])
{
_location = CPPointCreateCopy(aPoint);
_location = CGPointCreateCopy(aPoint);
_modifierFlags = modifierFlags;
_timestamp = aTimestamp;
_context = aGraphicsContext;
@@ -355,13 +277,14 @@ var _CPEventPeriodicEventPeriod = 0,
{
if (self = [self _initWithType:anEventType])
{
_location = CPPointCreateCopy(aPoint);
_location = CGPointCreateCopy(aPoint);
_modifierFlags = modifierFlags;
_timestamp = aTimestamp;
_context = aGraphicsContext;
_subtype = aSubtype;
_data1 = aData1;
_data2 = aData2;
_windowNumber = aWindowNumber;
}
return self;
@@ -377,7 +300,7 @@ var _CPEventPeriodicEventPeriod = 0,
*/
- (CGPoint)locationInWindow
{
return _CGPointMakeCopy(_location);
return CGPointMakeCopy(_location);
}
- (CGPoint)globalLocation
@@ -415,6 +338,14 @@ var _CPEventPeriodicEventPeriod = 0,
return _type;
}
/*!
Returns the subtype of the event.
*/
- (CPEventType)subtype
{
return _subtype;
}
/*!
Returns the event's associated window.
*/
@@ -554,6 +485,31 @@ var _CPEventPeriodicEventPeriod = 0,
return _deltaZ;
}
- (BOOL)hasPreciseScrollingDeltas
{
return !!_hasPreciseScrollingDeltas;
}
/*!
Returns the change in points on the x-axis for a mouse movement, unless hasPreciseScrollingDeltas is NO,
in which case the change is measured in number of "lines" or "rows" and needs to be multiplied as appropriate
to get change in pixels.
*/
- (float)scrollingDeltaX
{
return _scrollingDeltaX;
}
/*!
Returns the change in points on the y-axis for a mouse movement, unless hasPreciseScrollingDeltas is NO,
in which case the change is measured in number of "lines" or "columns" and needs to be multiplied as appropriate
to get change in pixels.
*/
- (float)scrollingDeltaY
{
return _scrollingDeltaY;
}
- (BOOL)_triggersKeyEquivalent:(CPString)aKeyEquivalent withModifierMask:aKeyEquivalentModifierMask
{
if (!aKeyEquivalent)
@@ -615,6 +571,24 @@ var _CPEventPeriodicEventPeriod = 0,
return !firstResponderIsText;
}
/*!
Return YES if this event is a part of processing a browser controlled cut or paste event
where the browser will go ahead and do the work of cutting or pasting within the input
element after processing of this event. The implication is that it should not be done by
the CPTextField (or whatever else is controlling the input) since this would result in
nothing being cut (because the field already cut the text out), or a double paste
(because the field pasted as well as the browser).
*/
- (BOOL)_platformIsEffectingCutOrPaste
{
#if PLATFORM(DOM)
return _suppressCappuccinoCut || _suppressCappuccinoPaste;
#else
return NO;
#endif
}
/*!
Generates periodic events every \c aPeriod seconds.
@@ -649,7 +623,7 @@ var _CPEventPeriodicEventPeriod = 0,
case CPKeyDown:
case CPKeyUp:
case CPFlagsChanged:
return [CPString stringWithFormat:@"CPEvent: type=%d loc=%@ time=%.1f flags=0x%X win=%@ winNum=%d ctxt=%@ chars=\"%@\" unmodchars=\"%@\" repeat=%d keyCode=%d", _type, CPStringFromPoint(_location), _timestamp, _modifierFlags, _window, _windowNumber, _context, _characters, _charactersIgnoringModifiers, _isARepeat, _keyCode];
return [CPString stringWithFormat:@"CPEvent: type=%d loc=%@ time=%.1f flags=0x%X win=%@ winNum=%d ctxt=%@ chars=\"%@\" unmodchars=\"%@\" repeat=%d keyCode=%d", _type, CGStringFromPoint(_location), _timestamp, _modifierFlags, _window, _windowNumber, _context, _characters, _charactersIgnoringModifiers, _isARepeat, _keyCode];
case CPLeftMouseDown:
case CPLeftMouseUp:
case CPRightMouseDown:
@@ -659,17 +633,25 @@ var _CPEventPeriodicEventPeriod = 0,
case CPRightMouseDragged:
case CPMouseEntered:
case CPMouseExited:
return [CPString stringWithFormat:@"CPEvent: type=%d loc=%@ time=%.1f flags=0x%X win=%@ winNum=%d ctxt=%@ evNum=%d click=%d buttonNumber=%d pressure=%f", _type, CPStringFromPoint(_location), _timestamp, _modifierFlags, _window, _windowNumber, _context, _eventNumber, _clickCount, [self buttonNumber], _pressure];
return [CPString stringWithFormat:@"CPEvent: type=%d loc=%@ time=%.1f flags=0x%X win=%@ winNum=%d ctxt=%@ evNum=%d click=%d buttonNumber=%d pressure=%f", _type, CGStringFromPoint(_location), _timestamp, _modifierFlags, _window, _windowNumber, _context, _eventNumber, _clickCount, [self buttonNumber], _pressure];
default:
return [CPString stringWithFormat:@"CPEvent: type=%d loc=%@ time=%.1f flags=0x%X win=%@ winNum=%d ctxt=%@ subtype=%d data1=%d data2=%d", _type, CPStringFromPoint(_location), _timestamp, _modifierFlags, _window, _windowNumber, _context, _subtype, _data1, _data2];
return [CPString stringWithFormat:@"CPEvent: type=%d loc=%@ time=%.1f flags=0x%X win=%@ winNum=%d ctxt=%@ subtype=%d data1=%d data2=%d", _type, CGStringFromPoint(_location), _timestamp, _modifierFlags, _window, _windowNumber, _context, _subtype, _data1, _data2];
}
}
- (CPTrackingArea)trackingArea
{
if ((_type !== CPMouseEntered) && (_type !== CPMouseExited) && (_type !== CPCursorUpdate))
[CPException raise:CPInternalInconsistencyException format:@"You can't call trackingArea for events of type %#x", _type];
return _trackingArea;
}
@end
function _CPEventFirePeriodEvent()
{
[CPApp sendEvent:[CPEvent otherEventWithType:CPPeriodic location:_CGPointMakeZero() modifierFlags:0 timestamp:[CPEvent currentTimestamp] windowNumber:0 context:nil subtype:0 data1:0 data2:0]];
[CPApp sendEvent:[CPEvent otherEventWithType:CPPeriodic location:CGPointMakeZero() modifierFlags:0 timestamp:[CPEvent currentTimestamp] windowNumber:0 context:nil subtype:0 data1:0 data2:0]];
}
var CPEventClass = [CPEvent class];
+174
View File
@@ -0,0 +1,174 @@
/*
* CPEvent_Constants.j
* AppKit
*
* Created by Francisco Tolmasky.
* Copyright 2008, 280 North, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
CPLeftMouseDown = 1;
CPLeftMouseUp = 2;
CPRightMouseDown = 3;
CPRightMouseUp = 4;
CPMouseMoved = 5;
CPLeftMouseDragged = 6;
CPRightMouseDragged = 7;
CPMouseEntered = 8;
CPMouseExited = 9;
CPKeyDown = 10;
CPKeyUp = 11;
CPFlagsChanged = 12;
CPAppKitDefined = 13;
CPSystemDefined = 14;
CPApplicationDefined = 15;
CPPeriodic = 16;
CPCursorUpdate = 17;
CPScrollWheel = 22;
CPOtherMouseDown = 25;
CPOtherMouseUp = 26;
CPOtherMouseDragged = 27;
// iPhone Event Types
CPTouchStart = 28;
CPTouchMove = 29;
CPTouchEnd = 30;
CPTouchCancel = 31;
CPAlphaShiftKeyMask = 1 << 16;
CPShiftKeyMask = 1 << 17;
CPControlKeyMask = 1 << 18;
CPAlternateKeyMask = 1 << 19;
CPCommandKeyMask = 1 << 20;
CPNumericPadKeyMask = 1 << 21;
CPHelpKeyMask = 1 << 22;
CPFunctionKeyMask = 1 << 23;
CPDeviceIndependentModifierFlagsMask = 0xffff0000;
CPLeftMouseDownMask = 1 << CPLeftMouseDown;
CPLeftMouseUpMask = 1 << CPLeftMouseUp;
CPRightMouseDownMask = 1 << CPRightMouseDown;
CPRightMouseUpMask = 1 << CPRightMouseUp;
CPOtherMouseDownMask = 1 << CPOtherMouseDown;
CPOtherMouseUpMask = 1 << CPOtherMouseUp;
CPMouseMovedMask = 1 << CPMouseMoved;
CPLeftMouseDraggedMask = 1 << CPLeftMouseDragged;
CPRightMouseDraggedMask = 1 << CPRightMouseDragged;
CPOtherMouseDragged = 1 << CPOtherMouseDragged;
CPMouseEnteredMask = 1 << CPMouseEntered;
CPMouseExitedMask = 1 << CPMouseExited;
CPCursorUpdateMask = 1 << CPCursorUpdate;
CPKeyDownMask = 1 << CPKeyDown;
CPKeyUpMask = 1 << CPKeyUp;
CPFlagsChangedMask = 1 << CPFlagsChanged;
CPAppKitDefinedMask = 1 << CPAppKitDefined;
CPSystemDefinedMask = 1 << CPSystemDefined;
CPApplicationDefinedMask = 1 << CPApplicationDefined;
CPPeriodicMask = 1 << CPPeriodic;
CPScrollWheelMask = 1 << CPScrollWheel;
CPAnyEventMask = 0xffffffff;
CPUpArrowFunctionKey = "\uF700";
CPDownArrowFunctionKey = "\uF701";
CPLeftArrowFunctionKey = "\uF702";
CPRightArrowFunctionKey = "\uF703";
CPF1FunctionKey = "\uF704";
CPF2FunctionKey = "\uF705";
CPF3FunctionKey = "\uF706";
CPF4FunctionKey = "\uF707";
CPF5FunctionKey = "\uF708";
CPF6FunctionKey = "\uF709";
CPF7FunctionKey = "\uF70A";
CPF8FunctionKey = "\uF70B";
CPF9FunctionKey = "\uF70C";
CPF10FunctionKey = "\uF70D";
CPF11FunctionKey = "\uF70E";
CPF12FunctionKey = "\uF70F";
CPF13FunctionKey = "\uF710";
CPF14FunctionKey = "\uF711";
CPF15FunctionKey = "\uF712";
CPF16FunctionKey = "\uF713";
CPF17FunctionKey = "\uF714";
CPF18FunctionKey = "\uF715";
CPF19FunctionKey = "\uF716";
CPF20FunctionKey = "\uF717";
CPF21FunctionKey = "\uF718";
CPF22FunctionKey = "\uF719";
CPF23FunctionKey = "\uF71A";
CPF24FunctionKey = "\uF71B";
CPF25FunctionKey = "\uF71C";
CPF26FunctionKey = "\uF71D";
CPF27FunctionKey = "\uF71E";
CPF28FunctionKey = "\uF71F";
CPF29FunctionKey = "\uF720";
CPF30FunctionKey = "\uF721";
CPF31FunctionKey = "\uF722";
CPF32FunctionKey = "\uF723";
CPF33FunctionKey = "\uF724";
CPF34FunctionKey = "\uF725";
CPF35FunctionKey = "\uF726";
CPInsertFunctionKey = "\uF727";
CPDeleteFunctionKey = "\uF728";
CPHomeFunctionKey = "\uF729";
CPBeginFunctionKey = "\uF72A";
CPEndFunctionKey = "\uF72B";
CPPageUpFunctionKey = "\uF72C";
CPPageDownFunctionKey = "\uF72D";
CPPrintScreenFunctionKey = "\uF72E";
CPScrollLockFunctionKey = "\uF72F";
CPPauseFunctionKey = "\uF730";
CPSysReqFunctionKey = "\uF731";
CPBreakFunctionKey = "\uF732";
CPResetFunctionKey = "\uF733";
CPStopFunctionKey = "\uF734";
CPMenuFunctionKey = "\uF735";
CPUserFunctionKey = "\uF736";
CPSystemFunctionKey = "\uF737";
CPPrintFunctionKey = "\uF738";
CPClearLineFunctionKey = "\uF739";
CPClearDisplayFunctionKey = "\uF73A";
CPInsertLineFunctionKey = "\uF73B";
CPDeleteLineFunctionKey = "\uF73C";
CPInsertCharFunctionKey = "\uF73D";
CPDeleteCharFunctionKey = "\uF73E";
CPPrevFunctionKey = "\uF73F";
CPNextFunctionKey = "\uF740";
CPSelectFunctionKey = "\uF741";
CPExecuteFunctionKey = "\uF742";
CPUndoFunctionKey = "\uF743";
CPRedoFunctionKey = "\uF744";
CPFindFunctionKey = "\uF745";
CPHelpFunctionKey = "\uF746";
CPModeSwitchFunctionKey = "\uF747";
CPEscapeFunctionKey = "\u001B";
CPSpaceFunctionKey = "\u0020";
CPDOMEventDoubleClick = "dblclick";
CPDOMEventMouseDown = "mousedown";
CPDOMEventMouseUp = "mouseup";
CPDOMEventMouseMoved = "mousemove";
CPDOMEventMouseDragged = "mousedrag";
CPDOMEventKeyUp = "keyup";
CPDOMEventKeyDown = "keydown";
CPDOMEventKeyPress = "keypress";
CPDOMEventCopy = "copy";
CPDOMEventPaste = "paste";
CPDOMEventScrollWheel = "mousewheel";
CPDOMEventTouchStart = "touchstart";
CPDOMEventTouchMove = "touchmove";
CPDOMEventTouchEnd = "touchend";
CPDOMEventTouchCancel = "touchcancel";
+22 -13
View File
@@ -38,12 +38,14 @@ var IEFlashCLSID = "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000";
#if PLATFORM(DOM)
DOMElement _DOMParamElement;
DOMElement _DOMObjectElement;
DOMElement _DOMInnerObjectElement;
#endif
}
- (id)initWithFrame:(CGRect)aFrame
{
CPLog.warn("CPFlashView is not supported by Cappuccino, this is now deprecated and it will be removed in the version 1.1 of Cappuccino");
self = [super initWithFrame:aFrame];
if (self)
@@ -52,22 +54,16 @@ var IEFlashCLSID = "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000";
if (!CPBrowserIsEngine(CPInternetExplorerBrowserEngine))
{
_DOMObjectElement = document.createElement(@"object");
_DOMObjectElement.id = [self elementID];
_DOMObjectElement.width = @"100%";
_DOMObjectElement.height = @"100%";
_DOMObjectElement.style.top = @"0px";
_DOMObjectElement.style.left = @"0px";
_DOMObjectElement.type = @"application/x-shockwave-flash";
_DOMObjectElement.setAttribute(@"classid", IEFlashCLSID);
_DOMParamElement = document.createElement(@"param");
_DOMParamElement.name = @"movie";
_DOMInnerObjectElement = document.createElement(@"object");
_DOMInnerObjectElement.width = @"100%";
_DOMInnerObjectElement.height = @"100%";
_DOMObjectElement.appendChild(_DOMParamElement);
_DOMObjectElement.appendChild(_DOMInnerObjectElement);
_DOMElement.appendChild(_DOMObjectElement);
}
@@ -89,7 +85,7 @@ var IEFlashCLSID = "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000";
if (!CPBrowserIsEngine(CPInternetExplorerBrowserEngine))
{
_DOMParamElement.value = [aFlashMovie filename];
_DOMInnerObjectElement.data = [aFlashMovie filename];
_DOMObjectElement.data = [aFlashMovie filename];
}
else
[self _rebuildIEObjects];
@@ -107,11 +103,14 @@ var IEFlashCLSID = "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000";
enumerator = [aDictionary keyEnumerator],
key;
while ((key = [enumerator nextObject]) !== nil)
if (key = [enumerator nextObject])
varString = [varString stringByAppendingFormat:@"%@=%@", key, [aDictionary objectForKey:key]];
while (key = [enumerator nextObject])
varString = [varString stringByAppendingFormat:@"&%@=%@", key, [aDictionary objectForKey:key]];
if (!_params)
_params = [CPDictionary dictionary];
_params = @{};
[_params setObject:varString forKey:@"flashvars"];
[self setParameters:_params];
@@ -141,7 +140,7 @@ var IEFlashCLSID = "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000";
#if PLATFORM(DOM)
if (!CPBrowserIsEngine(CPInternetExplorerBrowserEngine))
{
_paramElements = [CPDictionary dictionary];
_paramElements = @{};
var enumerator = [_params keyEnumerator],
key;
@@ -184,10 +183,20 @@ var IEFlashCLSID = "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000";
_DOMObjectElement = document.createElement(@"object");
_DOMElement.appendChild(_DOMObjectElement);
_DOMObjectElement.outerHTML = [CPString stringWithFormat:@"<object classid=%@ width=%@ height=%@>%@</object>", IEFlashCLSID, CGRectGetWidth([self bounds]), CGRectGetHeight([self bounds]), paramString];
_DOMObjectElement.outerHTML = [CPString stringWithFormat:@"<object id=%@ classid=%@ width=%@ height=%@>%@</object>", [self elementID], IEFlashCLSID, CGRectGetWidth([self bounds]), CGRectGetHeight([self bounds]), paramString];
}
#endif
- (CPString)elementID
{
return @"CPFV_" + [self UID];
}
- (void)mouseMoved:(CPEvent)sommit
{
[[[self window] platformWindow] _propagateCurrentDOMEvent:YES];
}
- (void)mouseDragged:(CPEvent)anEvent
{
[[[self window] platformWindow] _propagateCurrentDOMEvent:YES];
+54 -14
View File
@@ -24,6 +24,7 @@
@import <Foundation/CPBundle.j>
@import "CPView.j"
@import "CPFontDescriptor.j"
CPFontDefaultSystemFontFace = @"Arial, sans-serif";
CPFontDefaultSystemFontSize = 12;
@@ -37,12 +38,12 @@ CPFontCurrentSystemSize = -1;
// For internal use only by this class and subclasses
_CPFontSystemFacePlaceholder = "_CPFontSystemFacePlaceholder";
var _CPFontCache = {},
_CPSystemFontCache = {},
_CPFontSystemFontFace = CPFontDefaultSystemFontFace,
_CPFontSystemFontSize = 12,
_CPFontFallbackFaces = CPFontDefaultSystemFontFace.split(", "),
_CPFontStripRegExp = new RegExp("(^\\s*[\"']?|[\"']?\\s*$)", "g");
var _CPFontCache = {},
_CPSystemFontCache = {},
_CPFontSystemFontFace = CPFontDefaultSystemFontFace,
_CPFontSystemFontSize = 12,
_CPFontFallbackFaces = CPFontDefaultSystemFontFace.split(", "),
_CPFontStripRegExp = new RegExp("(^\\s*[\"']?|[\"']?\\s*$)", "g");
#define _CPRealFontSize(aSize) (aSize <= 0 ? _CPFontSystemFontSize : aSize)
@@ -162,7 +163,7 @@ following:
if (normalizedFaces === _CPFontSystemFontFace)
return;
[self _invalidateSystemFontCache]
[self _invalidateSystemFontCache];
_CPFontSystemFontFace = aFace;
}
@@ -174,18 +175,20 @@ following:
return _CPFontSystemFontSize;
}
+ (float)systemFontSizeForControlSize:(CPControlSize)aSize
+ (CPFont)systemFontForControlSize:(CPControlSize)aSize
{
// TODO These sizes should be themable or made less arbitrary in some other way.
switch (aSize)
{
case CPSmallControlSize:
return _CPFontSystemFontSize - 1;
return [self systemFontOfSize:_CPFontSystemFontSize - 1];
case CPMiniControlSize:
return _CPFontSystemFontSize - 2;
return [self systemFontOfSize:_CPFontSystemFontSize - 2];
case CPRegularControlSize:
default:
return _CPFontSystemFontSize;
return [self systemFontOfSize:_CPFontSystemFontSize];
}
}
@@ -206,7 +209,7 @@ following:
var systemSize = String(_CPFontSystemFontSize),
currentSize = String(CPFontCurrentSystemSize);
for (key in _CPSystemFontCache)
for (var key in _CPSystemFontCache)
{
if (_CPSystemFontCache.hasOwnProperty(key) &&
(key.indexOf(systemSize) === 0 || key.indexOf(currentSize) === 0))
@@ -281,7 +284,7 @@ following:
that dynamically tracks the current system font size.
@return the requested system font
*/
+ (CPFont)systemFontOfSize:(CPSize)aSize
+ (CPFont)systemFontOfSize:(CGSize)aSize
{
return _CPSystemFont(aSize === 0 ? _CPFontSystemFontSize : aSize, NO);
}
@@ -293,7 +296,7 @@ following:
that dynamically tracks the current system font size.
@return the requested bold system font
*/
+ (CPFont)boldSystemFontOfSize:(CPSize)aSize
+ (CPFont)boldSystemFontOfSize:(CGSize)aSize
{
return _CPSystemFont(aSize === 0 ? _CPFontSystemFontSize : aSize, YES);
}
@@ -431,6 +434,43 @@ following:
@end
@implementation CPFont(DescriptorAdditions)
- (id)_initWithFontDescriptor:(CPFontDescriptor)fontDescriptor
{
var aName = [fontDescriptor objectForKey: CPFontNameAttribute] ,
aSize = [fontDescriptor pointSize],
isBold = [fontDescriptor symbolicTraits] & CPFontBoldTrait,
isItalic = [fontDescriptor symbolicTraits] & CPFontItalicTrait;
return [self _initWithName:aName size:aSize bold:isBold italic:isItalic system:NO];
}
+ (CPFont)fontWithDescriptor:(CPFontDescriptor)fontDescriptor size:(float)aSize
{
var aName = [fontDescriptor objectForKey: CPFontNameAttribute],
isBold = [fontDescriptor symbolicTraits] & CPFontBoldTrait,
isItalic = [fontDescriptor symbolicTraits] & CPFontItalicTrait;
return [self _fontWithName:aName size:aSize || [fontDescriptor pointSize] bold:isBold italic:isItalic];
}
- (CPFontDescriptor)fontDescriptor
{
var traits = 0;
if ([self isBold])
traits |= CPFontBoldTrait;
if ([self isItalic])
traits |= CPFontItalicTrait;
return [[CPFontDescriptor fontDescriptorWithName:_name size:_size] fontDescriptorWithSymbolicTraits:traits];
}
@end
var CPFontNameKey = @"CPFontNameKey",
CPFontSizeKey = @"CPFontSizeKey",
CPFontIsBoldKey = @"CPFontIsBoldKey",
+214 -9
View File
@@ -22,7 +22,12 @@
@import <Foundation/CPObject.j>
@import "CPControl.j"
@import "CPFont.j"
@import "CPFontDescriptor.j"
@global CPApp
@class CPFontPanel
CPItalicFontMask = 1 << 0;
CPBoldFontMask = 1 << 1;
@@ -39,7 +44,20 @@ CPUnitalicFontMask = 1 << 24;
var CPSharedFontManager = nil,
CPFontManagerFactory = Nil;
CPFontManagerFactory = nil,
CPFontPanelFactory = nil;
/*
modifyFont: sender's tag
*/
CPNoFontChangeAction = 0;
CPViaPanelFontAction = 1;
CPAddTraitFontAction = 2;
CPSizeUpFontAction = 3;
CPSizeDownFontAction = 4;
CPHeavierFontAction = 5;
CPLighterFontAction = 6;
CPRemoveTraitFontAction = 7;
/*!
@ingroup appkit
@@ -54,9 +72,11 @@ var CPSharedFontManager = nil,
id _delegate @accessors(property=delegate);
CPFont _selectedFont;
BOOL _multiple @accessors;
BOOL _multiple @accessors(getter=isMultiple, setter=setMultiple:);
CPDictionary _activeChange;
unsigned _fontAction;
}
// Getting the Shared Font Manager
@@ -81,6 +101,15 @@ var CPSharedFontManager = nil,
{
CPFontManagerFactory = aClass;
}
/*!
Sets the class that will be used to create the application's
Font panel.
*/
+ (void)setFontPanelFactory:(Class)aClass
{
CPFontPanelFactory = aClass;
}
- (id)init
{
@@ -139,7 +168,7 @@ var CPSharedFontManager = nil,
- (void)setSelectedFont:(CPFont)aFont isMultiple:(BOOL)aFlag
{
_selectedFont = aFont;
_isMultiple = aFlag;
_multiple = aFlag;
// TODO Notify CPFontPanel when it exists.
}
@@ -149,11 +178,6 @@ var CPSharedFontManager = nil,
return _selectedFont;
}
- (BOOL)isMultiple
{
return _isMultiple;
}
- (int)weightOfFont:(CPFont)aFont
{
// TODO Weight 5 is a normal of book weight and 9 and above is bold, but it would be nice to be more
@@ -211,7 +235,9 @@ var CPSharedFontManager = nil,
- (@action)addFontTrait:(id)sender
{
_activeChange = [CPDictionary dictionaryWithObject:[sender tag] forKey:@"addTraits"];
var tag = [sender tag];
_activeChange = tag === nil ? @{} : @{ @"addTraits": tag };
_fontAction = CPAddTraitFontAction;
[self sendAction];
}
@@ -221,6 +247,185 @@ var CPSharedFontManager = nil,
return [CPApp sendAction:_action to:_target from:self];
}
/*!
This method open the font panel, create it if necessary.
@param sender The object that sent the message.
*/
- (CPFontPanel)fontPanel:(BOOL)createIt
{
var panel = nil,
panelExists = [CPFontPanelFactory sharedFontPanelExists];
if ((panelExists) || (!panelExists && createIt))
panel = [CPFontPanelFactory sharedFontPanel];
return panel;
}
/*!
Convert a font to have the specified Font traits. The font is unchanged expect for the specified Font traits.
Using CPUnboldFontMask or CPUnitalicFontMask will respectively remove Bold and Italic traits.
@param aFont The font to convert.
@param fontTrait The new font traits mask.
@result The converted font or \c aFont if the conversion failed.
*/
- (CPFont)convertFont:(CPFont)aFont toHaveTrait:(CPFontTraitMask)fontTrait
{
var attributes = [[[aFont fontDescriptor] fontAttributes] copy],
symbolicTrait = [[aFont fontDescriptor] symbolicTraits];
if (fontTrait & CPBoldFontMask)
symbolicTrait |= CPFontBoldTrait;
if (fontTrait & CPItalicFontMask)
symbolicTrait |= CPFontItalicTrait;
if (fontTrait & CPUnboldFontMask) /* FIXME: this only change CPFontSymbolicTrait what about CPFontWeightTrait */
symbolicTrait &= ~CPFontBoldTrait;
if (fontTrait & CPUnitalicFontMask)
symbolicTrait &= ~CPFontItalicTrait;
if (fontTrait & CPExpandedFontMask)
symbolicTrait |= CPFontExpandedTrait;
if (fontTrait & CPSmallCapsFontMask)
symbolicTrait |= CPFontSmallCapsTrait;
if (![attributes containsKey:CPFontTraitsAttribute])
[attributes setObject:[CPDictionary dictionaryWithObject:[CPNumber numberWithUnsignedInt:symbolicTrait]
forKey:CPFontSymbolicTrait]
forKey:CPFontTraitsAttribute];
else
[[attributes objectForKey:CPFontTraitsAttribute] setObject:[CPNumber numberWithUnsignedInt:symbolicTrait]
forKey:CPFontSymbolicTrait];
return [[aFont class] fontWithDescriptor:[CPFontDescriptor fontDescriptorWithFontAttributes:attributes] size:0.0];
}
/*!
Convert a font to not have the specified Font traits. The font is unchanged expect for the specified Font traits.
@param aFont The font to convert.
@param fontTrait The font traits mask to remove.
@result The converted font or \c aFont if the conversion failed.
*/
- (CPFont)convertFont:(CPFont)aFont toNotHaveTrait:(CPFontTraitMask)fontTrait
{
var attributes = [[[aFont fontDescriptor] fontAttributes] copy],
symbolicTrait = [[aFont fontDescriptor] symbolicTraits];
if ((fontTrait & CPBoldFontMask) || (fontTrait & CPUnboldFontMask)) /* FIXME: see convertFont:toHaveTrait: about CPFontWeightTrait */
symbolicTrait &= ~CPFontBoldTrait;
if ((fontTrait & CPItalicFontMask) || (fontTrait & CPUnitalicFontMask))
symbolicTrait &= ~CPFontItalicTrait;
if (fontTrait & CPExpandedFontMask)
symbolicTrait &= ~CPFontExpandedTrait;
if (fontTrait & CPSmallCapsFontMask)
symbolicTrait &= ~CPFontSmallCapsTrait;
if (![attributes containsKey:CPFontTraitsAttribute])
[attributes setObject:[CPDictionary dictionaryWithObject:[CPNumber numberWithUnsignedInt:symbolicTrait]
forKey:CPFontSymbolicTrait]
forKey:CPFontTraitsAttribute];
else
[[attributes objectForKey:CPFontTraitsAttribute] setObject:[CPNumber numberWithUnsignedInt:symbolicTrait]
forKey:CPFontSymbolicTrait];
return [[aFont class] fontWithDescriptor:[CPFontDescriptor fontDescriptorWithFontAttributes:attributes] size:0.0];
}
/*!
Convert a font to have specified size. The font is unchanged expect for the specified size.
@param aFont The font to convert.
@param aSize The new font size.
@result The converted font or \c aFont if the conversion failed.
*/
- (CPFont)convertFont:(CPFont)aFont toSize:(float)aSize
{
var descriptor = [aFont fontDescriptor];
return [[aFont class] fontWithDescriptor: descriptor size:aSize]
}
- (void)orderFrontFontPanel:(id)sender
{
[[self fontPanel:YES] orderFront:sender];
}
- (void)modifyFont:(id)sender
{
_fontAction = [sender tag];
[self sendAction];
if (_selectedFont)
[self setSelectedFont:[self convertFont:_selectedFont] isMultiple:NO];
}
/*!
This method causes the receiver to send its action message.
@param sender The object that sent the message. (a Font panel)
*/
- (void)modifyFontViaPanel:(id)sender
{
_fontAction = CPViaPanelFontAction;
if (_selectedFont)
[self setSelectedFont:[self convertFont:_selectedFont] isMultiple:NO];
[self sendAction];
}
/*!
Convert a font according to current font changes, provided by the object that initiated the font change.
@param aFont The font to convert.
@result The converted font or \c aFont if the conversion failed.
*/
- (CPFont)convertFont:(CPFont)aFont
{
var newFont = nil;
switch (_fontAction)
{
case CPNoFontChangeAction:
newFont = aFont;
break;
case CPViaPanelFontAction:
newFont = [[self fontPanel:NO] panelConvertFont:aFont];
break;
case CPAddTraitFontAction:
newFont = aFont;
if (!_activeChange)
break;
var addTraits = [_activeChange valueForKey:@"addTraits"];
if (addTraits)
newFont = [self convertFont:aFont toHaveTrait:addTraits];
break;
case CPSizeUpFontAction:
newFont = [self convertFont:aFont toSize:[aFont size] + 1.0]; /* any limit ? */
break;
case CPSizeDownFontAction:
if ([aFont size] > 1)
newFont = [self convertFont:aFont toSize:[aFont size] - 1.0];
/* else CPBeep() :-p */
break;
default:
CPLog.trace(@"-[" + [self className] + " " + _cmd + "] unsupported font action: " + _fontAction + " aFont unchanged");
newFont = aFont;
break;
}
return newFont;
}
@end
var _CPFontDetectSpan,
+59 -13
View File
@@ -20,6 +20,16 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import <Foundation/CPObject.j>
@import <Foundation/CPException.j>
@import <Foundation/CPMutableArray.j>
@import "CGColor.j"
@import "CGColorSpace.j"
@import "CGGradient.j"
@import "CPBezierPath.j"
@import "CPGraphicsContext.j"
CPGradientDrawsBeforeStartingLocation = kCGGradientDrawsBeforeStartLocation;
CPGradientDrawsAfterEndingLocation = kCGGradientDrawsAfterEndLocation;
@@ -31,6 +41,11 @@ CPGradientDrawsAfterEndingLocation = kCGGradientDrawsAfterEndLocation;
CGGradient _gradient;
}
- (id)initWithStartingColor:(CPColor)startingColor endingColor:(CPColor)endingColor
{
return [self initWithColors:[startingColor, endingColor]];
}
- (id)initWithColors:(CPArray)someColors
{
var count = [someColors count];
@@ -55,11 +70,12 @@ CPGradientDrawsAfterEndingLocation = kCGGradientDrawsAfterEndLocation;
{
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]));
var colorSpace = [aColorSpace CGColorSpace] || CGColorSpaceCreateDeviceRGB,
cgColors = [someColors arrayByApplyingBlock:function(color)
{
return CGColorCreate(colorSpace, [color components])
}];
_gradient = CGGradientCreateWithColors(colorSpace, cgColors, someLocations);
}
@@ -74,20 +90,32 @@ CPGradientDrawsAfterEndingLocation = kCGGradientDrawsAfterEndLocation;
CGContextClipToRect(ctx, rect);
CGContextAddRect(ctx, rect);
var startPoint,
[self _drawInRect:rect atAngle:angle];
CGContextRestoreGState(ctx);
}
/*!
@ignore like draw in rect but apply no clipping.
*/
- (void)_drawInRect:(CGRect)rect atAngle:(float)angle
{
var ctx = [[CPGraphicsContext currentContext] graphicsPort],
startPoint,
endPoint;
// Modulo of negative values doesn't work as expected in JS.
angle = ((angle % 360.0) + 360.0) % 360.0;
if (angle < 90.0)
startPoint = _CGPointMake(_CGRectGetMinX(rect), _CGRectGetMinY(rect));
startPoint = CGPointMake(CGRectGetMinX(rect), CGRectGetMinY(rect));
else if (angle < 180.0)
startPoint = _CGPointMake(_CGRectGetMaxX(rect), _CGRectGetMinY(rect));
startPoint = CGPointMake(CGRectGetMaxX(rect), CGRectGetMinY(rect));
else if (angle < 270.0)
startPoint = _CGPointMake(_CGRectGetMaxX(rect), _CGRectGetMaxY(rect));
startPoint = CGPointMake(CGRectGetMaxX(rect), CGRectGetMaxY(rect));
else
startPoint = _CGPointMake(_CGRectGetMinX(rect), _CGRectGetMaxY(rect));
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
@@ -102,13 +130,31 @@ CPGradientDrawsAfterEndingLocation = kCGGradientDrawsAfterEndLocation;
// 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));
length = ABS(CGRectGetWidth(rect) * COS(radians)) + ABS(CGRectGetHeight(rect) * SIN(radians));
endPoint = _CGPointMake(startPoint.x + length * COS(radians),
endPoint = CGPointMake(startPoint.x + length * COS(radians),
startPoint.y + length * SIN(radians));
[self drawFromPoint:startPoint toPoint:endPoint options:CPGradientDrawsBeforeStartingLocation | CPGradientDrawsAfterEndingLocation];
CGContextRestoreGState(ctx);
}
- (void)drawInBezierPath:(CPBezierPath)aPath angle:(float)anAngle
{
[CPGraphicsContext saveGraphicsState];
var ctx = [[CPGraphicsContext currentContext] graphicsPort];
// Nail down the path which CGContextDrawLinearGradient will cause to be filled.
// Note we don't do this by clipping to the path and then calling drawInRect:atAngle:
// as this would cut off any antialias of the drawing, plus any active context shadow.
CGContextBeginPath(ctx);
CGContextAddPath(ctx, aPath._path);
CGContextSetLineWidth(ctx, [aPath lineWidth]);
CGContextClosePath(ctx);
[self _drawInRect:[aPath bounds] atAngle:anAngle];
[CPGraphicsContext restoreGraphicsState];
}
- (void)drawFromPoint:(NSPoint)startingPoint toPoint:(NSPoint)endingPoint options:(NSGradientDrawingOptions)options
+16 -16
View File
@@ -43,10 +43,10 @@ function CPDrawTiledRects(
if (sides.length != grays.length)
[CPException raise:CPInvalidArgumentException reason:@"sides (length: " + sides.length + ") and grays (length: " + grays.length + ") must have the same length."];
var colors = [];
for (var i = 0; i < grays.length; ++i)
colors.push([CPColor colorWithCalibratedWhite:grays[i] alpha:1.0]);
var colors = [grays arrayByApplyingBlock:function(gray)
{
return [CPColor colorWithCalibratedWhite:gray alpha:1.0];
}];
return CPDrawColorTiledRects(boundsRect, clipRect, sides, colors);
}
@@ -60,9 +60,9 @@ function CPDrawColorTiledRects(
if (sides.length != colors.length)
[CPException raise:CPInvalidArgumentException reason:@"sides (length: " + sides.length + ") and colors (length: " + colors.length + ") must have the same length."];
var resultRect = _CGRectMakeCopy(boundsRect),
slice = _CGRectMakeZero(),
remainder = _CGRectMakeZero(),
var resultRect = CGRectMakeCopy(boundsRect),
slice = CGRectMakeZero(),
remainder = CGRectMakeZero(),
context = [[CPGraphicsContext currentContext] graphicsPort];
CGContextSaveGState(context);
@@ -77,7 +77,7 @@ function CPDrawColorTiledRects(
slice = CGRectIntersection(slice, clipRect);
// Cocoa docs say that only slices that are within the clipRect are actually drawn
if (_CGRectIsEmpty(slice))
if (CGRectIsEmpty(slice))
continue;
var minX,
@@ -88,23 +88,23 @@ function CPDrawColorTiledRects(
if (side == CPMinXEdge || side == CPMaxXEdge)
{
// Make sure we have at least 1 pixel to draw a line
if (_CGRectGetWidth(slice) < 1.0)
if (CGRectGetWidth(slice) < 1.0)
continue;
minX = _CGRectGetMinX(slice) + 0.5;
minX = CGRectGetMinX(slice) + 0.5;
maxX = minX;
minY = _CGRectGetMinY(slice);
maxY = _CGRectGetMaxY(slice);
minY = CGRectGetMinY(slice);
maxY = CGRectGetMaxY(slice);
}
else // CPMinYEdge || CPMaxYEdge
{
// Make sure we have at least 1 pixel to draw a line
if (_CGRectGetHeight(slice) < 1.0)
if (CGRectGetHeight(slice) < 1.0)
continue;
minX = _CGRectGetMinX(slice);
maxX = _CGRectGetMaxX(slice);
minY = _CGRectGetMinY(slice) + 0.5;
minX = CGRectGetMinX(slice);
maxX = CGRectGetMaxX(slice);
minY = CGRectGetMinY(slice) + 0.5;
maxY = minY;
}
+1
View File
@@ -68,6 +68,7 @@ var CPGraphicsContextCurrent = nil,
+ (void)restoreGraphicsState
{
var lastContext = [CPGraphicsContextThreadStack lastObject];
if (lastContext)
{
[lastContext restoreGraphicsState];
+327 -23
View File
@@ -21,12 +21,28 @@
*/
@import <Foundation/CPBundle.j>
@import <Foundation/CPGeometry.j>
@import <Foundation/CPNotificationCenter.j>
@import <Foundation/CPObject.j>
@import <Foundation/CPRunLoop.j>
@import <Foundation/CPString.j>
@import <Foundation/CPData.j>
@import "CGGeometry.j"
@import "CPCompatibility.j"
@protocol CPImageDelegate <CPObject>
@optional
- (void)imageDidLoad:(CPImage)anImage;
- (void)imageDidError:(CPImage)anImage;
- (void)imageDidAbort:(CPImage)anImage;
@end
var CPImageDelegate_imageDidLoad_ = 1 << 1,
CPImageDelegate_imageDidError_ = 1 << 2,
CPImageDelegate_imageDidAbort_ = 1 << 3;
CPImageLoadStatusInitialized = 0;
CPImageLoadStatusLoading = 1;
@@ -49,15 +65,44 @@ var imagesForNames = { },
AppKitImageForNames[CPImageNameColorPanel] = CGSizeMake(26.0, 29.0);
AppKitImageForNames[CPImageNameColorPanelHighlighted] = CGSizeMake(26.0, 29.0);
function CPImageInBundle(aFilename, aSize, aBundle)
/*!
Returns a resource image with a relative path and size
in a bundle.
@param filename A filename or relative path to a resource image.
@param width Width of the image. May be omitted.
@param height Height of the image. May be omitted if width is omitted.
@param size Instead of passing width/height, a CGSize may be passed.
@param bundle Bundle in which the image resource can be found.
If omitted, defaults to the main bundle.
@return CPImage
*/
function CPImageInBundle()
{
if (!aBundle)
aBundle = [CPBundle mainBundle];
var filename = arguments[0],
size = nil,
bundle = nil;
if (aSize)
return [[CPImage alloc] initWithContentsOfFile:[aBundle pathForResource:aFilename] size:aSize];
if (typeof(arguments[1]) === "number")
{
if (arguments[1] !== nil && arguments[1] !== undefined)
size = CGSizeMake(arguments[1], arguments[2]);
return [[CPImage alloc] initWithContentsOfFile:[aBundle pathForResource:aFilename]];
bundle = arguments[3];
}
else if (typeof(arguments[1]) === "object")
{
size = arguments[1];
bundle = arguments[2];
}
if (!bundle)
bundle = [CPBundle mainBundle];
if (size)
return [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:filename] size:size];
return [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:filename]];
}
function CPAppKitImage(aFilename, aSize)
@@ -88,14 +133,15 @@ function CPAppKitImage(aFilename, aSize)
*/
@implementation CPImage : CPObject
{
CGSize _size;
CPString _filename;
CPString _name;
CGSize _size;
CPString _filename;
CPString _name;
id _delegate;
unsigned _loadStatus;
id <CPImageDelegate> _delegate;
unsigned _loadStatus;
unsigned _implementedDelegateMethods;
Image _image;
Image _image;
}
- (id)init
@@ -105,19 +151,24 @@ function CPAppKitImage(aFilename, aSize)
/*!
Initializes the image, by associating it with a filename. The image
denoted in \c aFilename is not actually loaded. It will
be loaded once needed.
denoted in \c aFilename is not actually loaded. It will be loaded
once needed.
@param aFilename the file containing the image
@param aSize the image's size
@return the initialized image
*/
- (id)initByReferencingFile:(CPString)aFilename size:(CGSize)aSize
{
// Quietly return nil like in Cocoa, rather than crashing later.
if (aFilename === undefined || aFilename === nil)
return nil;
self = [super init];
if (self)
{
_size = CPSizeCreateCopy(aSize);
_size = CGSizeMakeCopy(aSize);
_filename = aFilename;
_loadStatus = CPImageLoadStatusInitialized;
}
@@ -195,7 +246,7 @@ function CPAppKitImage(aFilename, aSize)
var canvas = document.createElement("canvas"),
ctx = canvas.getContext("2d");
canvas.width = _image.width,
canvas.width = _image.width;
canvas.height = _image.height;
ctx.drawImage(_image, 0, 0);
@@ -224,7 +275,7 @@ function CPAppKitImage(aFilename, aSize)
*/
- (CGSize)size
{
return _size;
return CGSizeMakeCopy(_size);
}
+ (id)imageNamed:(CPString)aName
@@ -271,13 +322,34 @@ function CPAppKitImage(aFilename, aSize)
return _name;
}
/*!
Returns the underlying Image element for a single image.
*/
- (Image)image
{
return _image;
}
/*!
Sets the receiver's delegate.
@param the delegate
*/
- (void)setDelegate:(id)aDelegate
- (void)setDelegate:(id <CPImageDelegate>)aDelegate
{
if (_delegate === aDelegate)
return;
_delegate = aDelegate;
_implementedDelegateMethods = 0;
if ([_delegate respondsToSelector:@selector(imageDidLoad:)])
_implementedDelegateMethods |= CPImageDelegate_imageDidLoad_;
if ([_delegate respondsToSelector:@selector(imageDidError:)])
_implementedDelegateMethods |= CPImageDelegate_imageDidError_;
if ([_delegate respondsToSelector:@selector(imageDidAbort:)])
_implementedDelegateMethods |= CPImageDelegate_imageDidAbort_;
}
/*!
@@ -359,6 +431,11 @@ function CPAppKitImage(aFilename, aSize)
#endif
}
- (BOOL)isSingleImage
{
return YES;
}
- (BOOL)isThreePartImage
{
return NO;
@@ -408,7 +485,7 @@ function CPAppKitImage(aFilename, aSize)
postNotificationName:CPImageDidLoadNotification
object:self];
if ([_delegate respondsToSelector:@selector(imageDidLoad:)])
if (_implementedDelegateMethods & CPImageDelegate_imageDidLoad_)
[_delegate imageDidLoad:self];
}
@@ -417,7 +494,7 @@ function CPAppKitImage(aFilename, aSize)
{
_loadStatus = CPImageLoadStatusReadError;
if ([_delegate respondsToSelector:@selector(imageDidError:)])
if (_implementedDelegateMethods & CPImageDelegate_imageDidError_)
[_delegate imageDidError:self];
}
@@ -426,12 +503,218 @@ function CPAppKitImage(aFilename, aSize)
{
_loadStatus = CPImageLoadStatusCancelled;
if ([_delegate respondsToSelector:@selector(imageDidAbort:)])
if (_implementedDelegateMethods & CPImageDelegate_imageDidAbort_)
[_delegate imageDidAbort:self];
}
@end
#pragma mark -
#pragma mark CSS Theming
// The code below adds support for CSS theming with 100% compatibility with current theming system.
// The idea is to extend CPImage (and CPColor) with CSS components and adapt low level UI components to
// support this new kind of CPColor/CPImage. See CPImageView, CPView and _CPImageAndTextView.
//
// To create a CPImage that uses CSS, simply use the new class method :
// + (CPImage)imageWithCSSDictionary:(CPDictionary)aDictionary beforeDictionary:(CPDictionary)beforeDictionary afterDictionary:(CPDictionary)afterDictionary size:(CGSize)aSize
// where beforeDictionary & afterDictionary are related to ::before & ::after pseudo-elements.
// If you don't need them, just use the simplified class method :
// + (CPImage)imageWithCSSDictionary:(CPDictionary)aDictionary size:(CGSize)aSize
//
// Examples :
// regularImageNormal = [CPImage imageWithCSSDictionary:@{
// @"border-color": A3ColorActiveBorder,
// @"border-style": @"solid",
// @"border-width": @"1px",
// @"border-radius": @"50%",
// @"box-sizing": @"border-box",
// @"background-color": A3ColorBackgroundWhite,
// @"transition-duration": @"0.35s",
// @"transition-property": @"all",
// @"transition-timing-function": @"ease"
// }
// size:CGSizeMake(16,16)];
//
// imageSearch = [CPImage imageWithCSSDictionary:@{
// @"background-image": @"url(%%packed.png)",
// @"background-position": @"-16px -32px",
// @"background-repeat": @"no-repeat",
// @"background-size": @"100px 400px"
// }
// size:CGSizeMake(16,16)];
//
// Remark : Please note the special URL of the background image used in this example : url(%%packed.png)
// During theme loading, "%%" will be replaced by the path to the theme blend resources folder.
// Typically, a CSS theme will use some (rare) images all packed together in a single image resource (see packed.png in Aristo3 theme)
//
// Also, please note that if you don't use one of the CSS components, you can either set it to nil (best solution) or to an empty dictionary, like :
// aCssImage = [CPImage imageWithCSSDictionary:@{} beforeDictionary:nil afterDictionary:@{ ... }];
//
// You can use -(BOOL)isCSSBased to determine how to cope with it in your code.
// -(BOOL)hasCSSDictionary, -(BOOL)hasCSSBeforeDictionary and -(BOOL)hasCSSAfterDictionary are convience methods you can use.
//
// Remark : -(DOMElement)applyCSSImageForView is meant to be used by low level UI widgets (like CPImageView and _CPImageAndTextView) to implement CSS theme support.
//
// In some circumstances, you may have to clear a CSS image. You can do this easily by replacing your current image with the special dummy empty CSS image :
// [CPImage dummyCSSImageOfSize:CGSizeMake(someWidth, someHeight)]
@implementation CPImage (CSSTheming)
{
CPDictionary _cssDictionary @accessors(property=cssDictionary);
CPDictionary _cssBeforeDictionary @accessors(property=cssBeforeDictionary);
CPDictionary _cssAfterDictionary @accessors(property=cssAfterDictionary);
}
+ (CPImage)imageWithCSSDictionary:(CPDictionary)aDictionary size:(CGSize)aSize
{
return [[CPImage alloc] initWithCSSDictionary:aDictionary beforeDictionary:nil afterDictionary:nil size:aSize];
}
+ (CPImage)imageWithCSSDictionary:(CPDictionary)aDictionary beforeDictionary:(CPDictionary)beforeDictionary afterDictionary:(CPDictionary)afterDictionary size:(CGSize)aSize
{
return [[CPImage alloc] initWithCSSDictionary:aDictionary beforeDictionary:beforeDictionary afterDictionary:afterDictionary size:aSize];
}
+ (CPImage)dummyCSSImageOfSize:(CGSize)aSize
{
// This is used to clear a previous CSS image
return [[CPImage alloc] initWithCSSDictionary:@{} beforeDictionary:nil afterDictionary:nil size:aSize];
}
- (id)initWithCSSDictionary:(CPDictionary)aDictionary beforeDictionary:(CPDictionary)beforeDictionary afterDictionary:(CPDictionary)afterDictionary size:(CGSize)aSize
{
self = [super init];
if (self)
{
_size = CGSizeMakeCopy(aSize);
_filename = @"CSS image";
_loadStatus = CPImageLoadStatusCompleted;
_cssDictionary = aDictionary;
_cssBeforeDictionary = beforeDictionary;
_cssAfterDictionary = afterDictionary;
}
return self;
}
- (BOOL)isCSSBased
{
return !!(_cssDictionary || _cssBeforeDictionary || _cssAfterDictionary);
}
- (BOOL)hasCSSDictionary
{
return ([_cssDictionary count] > 0);
}
- (BOOL)hasCSSBeforeDictionary
{
return ([_cssBeforeDictionary count] > 0);
}
- (BOOL)hasCSSAfterDictionary
{
return ([_cssAfterDictionary count] > 0);
}
- (DOMElement)applyCSSImageForView:(CPView)aView onDOMElement:(DOMElement)aDOMElement styleNode:(DOMElement)aStyleNode previousState:(CPArrayRef)aPreviousStateRef
{
#if PLATFORM(DOM)
// First, restore previous CSS styling before applying the new one
var aPreviousState = @deref(aPreviousStateRef);
for (var i = 0, count = aPreviousState.length; i < count; i++)
aDOMElement.style[aPreviousState[i][0]] = aPreviousState[i][1];
aPreviousState = @[];
// Then apply new CSS styling
[_cssDictionary enumerateKeysAndObjectsUsingBlock:function(aKey, anObject, stop)
{
[aPreviousState addObject:@[aKey, aDOMElement.style[aKey]]];
aDOMElement.style[aKey] = anObject;
}];
if (_cssBeforeDictionary || _cssAfterDictionary)
{
// We need to create a unique class name
var styleClassName = @".CP" + [aView UID],
styleContent = @"";
if (_cssBeforeDictionary)
{
styleContent += styleClassName + @"::before { ";
[_cssBeforeDictionary enumerateKeysAndObjectsUsingBlock:function(aKey, anObject, stop)
{
styleContent += aKey + ": " + anObject + "; ";
}];
styleContent += "} ";
}
if (_cssAfterDictionary)
{
styleContent += styleClassName + @"::after { ";
[_cssAfterDictionary enumerateKeysAndObjectsUsingBlock:function(aKey, anObject, stop)
{
styleContent += aKey + ": " + anObject + "; ";
}];
styleContent += "} ";
}
var styleDescription = document.createTextNode(styleContent);
if (!aStyleNode)
{
aStyleNode = document.createElement("style");
aView._DOMElement.insertBefore(aStyleNode, aView._DOMElement.firstChild);
aStyleNode.appendChild(styleDescription);
}
else
{
aStyleNode.replaceChild(styleDescription, aStyleNode.firstChild);
}
[aView setDOMClassName:@"CP"+[aView UID]];
}
else
{
// no before/after so remove aStyleNode if existing
if (aStyleNode)
{
aView._DOMElement.removeChild(aStyleNode);
aStyleNode = nil;
}
}
// Return actualised values
@deref(aPreviousStateRef) = aPreviousState;
return aStyleNode;
#endif
}
@end
var CPImageCSSDictionaryKey = @"CPImageCSSDictionaryKey",
CPImageCSSBeforeDictionaryKey = @"CPImageCSSBeforeDictionaryKey",
CPImageCSSAfterDictionaryKey = @"CPImageCSSAfterDictionaryKey";
#pragma mark -
@implementation CPImage (CPCoding)
/*!
@@ -441,7 +724,10 @@ function CPAppKitImage(aFilename, aSize)
*/
- (id)initWithCoder:(CPCoder)aCoder
{
return [self initWithContentsOfFile:[aCoder decodeObjectForKey:@"CPFilename"] size:[aCoder decodeSizeForKey:@"CPSize"]];
if ([aCoder containsValueForKey:CPImageCSSDictionaryKey])
return [self initWithCSSDictionary:[aCoder decodeObjectForKey:CPImageCSSDictionaryKey] beforeDictionary:[aCoder decodeObjectForKey:CPImageCSSBeforeDictionaryKey] afterDictionary:[aCoder decodeObjectForKey:CPImageCSSAfterDictionaryKey] size:[aCoder decodeSizeForKey:@"CPSize"]];
else
return [self initWithContentsOfFile:[aCoder decodeObjectForKey:@"CPFilename"] size:[aCoder decodeSizeForKey:@"CPSize"]];
}
/*!
@@ -452,6 +738,14 @@ function CPAppKitImage(aFilename, aSize)
{
[aCoder encodeObject:_filename forKey:@"CPFilename"];
[aCoder encodeSize:_size forKey:@"CPSize"];
// CSS Styling
if ([self isCSSBased])
{
[aCoder encodeObject:_cssDictionary forKey:CPImageCSSDictionaryKey];
[aCoder encodeObject:_cssBeforeDictionary forKey:CPImageCSSBeforeDictionaryKey];
[aCoder encodeObject:_cssAfterDictionary forKey:CPImageCSSAfterDictionaryKey];
}
}
@end
@@ -490,6 +784,11 @@ function CPAppKitImage(aFilename, aSize)
return _isVertical;
}
- (BOOL)isSingleImage
{
return NO;
}
- (BOOL)isThreePartImage
{
return YES;
@@ -554,6 +853,11 @@ var CPThreePartImageImageSlicesKey = @"CPThreePartImageImageSlicesKey",
return _imageSlices;
}
- (BOOL)isSingleImage
{
return NO;
}
- (BOOL)isThreePartImage
{
return NO;
+108 -49
View File
@@ -26,6 +26,10 @@
@import "CPImage.j"
@import "CPShadowView.j"
@global CPImagesPboardType
@global appkit_tag_dom_elements
@typedef CPImageAlignment
CPImageAlignCenter = 0;
CPImageAlignTop = 1;
CPImageAlignTopLeft = 2;
@@ -67,12 +71,14 @@ var CPImageViewEmptyPlaceholderImage = nil;
CPImageViewEmptyPlaceholderImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"empty.png"]];
}
+ (Class)_binderClassForBinding:(CPString)theBinding
+ (Class)_binderClassForBinding:(CPString)aBinding
{
if (theBinding === CPValueBinding || theBinding === CPValueURLBinding || theBinding === CPValuePathBinding || theBinding === CPDataBinding)
if (aBinding === CPValueBinding || aBinding === CPValueURLBinding || aBinding === CPValuePathBinding || aBinding === CPDataBinding)
return [CPImageViewValueBinder class];
else if ([aBinding hasPrefix:CPEditableBinding])
return [CPMultipleValueAndBinding class];
return [super _binderClassForBinding:theBinding];
return [super _binderClassForBinding:aBinding];
}
- (id)initWithFrame:(CGRect)aFrame
@@ -82,26 +88,59 @@ var CPImageViewEmptyPlaceholderImage = nil;
if (self)
{
#if PLATFORM(DOM)
_DOMImageElement = document.createElement("img");
_DOMImageElement.style.position = "absolute";
_DOMImageElement.style.left = "0px";
_DOMImageElement.style.top = "0px";
if ([CPPlatform supportsDragAndDrop])
{
_DOMImageElement.setAttribute("draggable", "true");
_DOMImageElement.style["-khtml-user-drag"] = "element";
}
CPDOMDisplayServerAppendChild(_DOMElement, _DOMImageElement);
_DOMImageElement.style.visibility = "hidden";
[self _createDOMImageElement];
#endif
}
return self;
}
- (void)_createDOMImageElement
{
#if PLATFORM(DOM)
var image = [self objectValue],
isCSSBasedImage = [image isCSSBased],
isIMGImageElement = _DOMImageElement && (_DOMImageElement.nodeName == "IMG");
// First, check if we need to destroy a current DOM image element. This is the case if :
// - we have one but not the right one (that is a DIV but needing an IMG, and vice versa)
if (_DOMImageElement)
{
if ((isIMGImageElement && isCSSBasedImage) || (!isIMGImageElement && !isCSSBasedImage))
{
// OK, destroy it
_DOMElement.removeChild(_DOMImageElement);
_DOMImageElement = nil;
// CSS styling cleaning
_cssStylePreviousState = @[];
_cssStyleNode = nil;
}
else
return;
}
_DOMImageElement = document.createElement(isCSSBasedImage ? "div" : "img");
_DOMImageElement.style.position = "absolute";
_DOMImageElement.style.left = "0px";
_DOMImageElement.style.top = "0px";
if ([CPPlatform supportsDragAndDrop])
{
_DOMImageElement.setAttribute("draggable", "true");
_DOMImageElement.style["-khtml-user-drag"] = "element";
}
_DOMImageElement.style.visibility = "hidden";
AppKitTagDOMElement(self, _DOMImageElement);
CPDOMDisplayServerAppendChild(_DOMElement, _DOMImageElement);
#endif
}
/*!
Returns the view's image.
*/
@@ -133,7 +172,15 @@ var CPImageViewEmptyPlaceholderImage = nil;
var newImage = [self objectValue];
#if PLATFORM(DOM)
_DOMImageElement.src = newImage ? [newImage filename] : [CPImageViewEmptyPlaceholderImage filename];
[self _createDOMImageElement];
if ([newImage isCSSBased])
_cssStyleNode = [newImage applyCSSImageForView:self
onDOMElement:_DOMImageElement
styleNode:_cssStyleNode
previousState:@ref(_cssStylePreviousState)];
else
_DOMImageElement.src = newImage ? [newImage filename] : [CPImageViewEmptyPlaceholderImage filename];
#endif
var size = [newImage size];
@@ -159,6 +206,7 @@ var CPImageViewEmptyPlaceholderImage = nil;
- (void)imageDidLoad:(CPNotification)aNotification
{
[[CPNotificationCenter defaultCenter] removeObserver:self name:CPImageDidLoadNotification object:[self objectValue]];
[self hideOrDisplayContents];
[self setNeedsLayout];
@@ -248,7 +296,7 @@ var CPImageViewEmptyPlaceholderImage = nil;
[self setNeedsDisplay:YES];
}
- (unsigned)imageScaling
- (CPUInteger)imageScaling
{
return [self currentValueForThemeAttribute:@"image-scaling"];
}
@@ -297,8 +345,8 @@ var CPImageViewEmptyPlaceholderImage = nil;
y = 0.0,
insetWidth = (_hasShadow ? [_shadowView horizontalInset] : 0.0),
insetHeight = (_hasShadow ? [_shadowView verticalInset] : 0.0),
boundsWidth = _CGRectGetWidth(bounds),
boundsHeight = _CGRectGetHeight(bounds),
boundsWidth = CGRectGetWidth(bounds),
boundsHeight = CGRectGetHeight(bounds),
width = boundsWidth - insetWidth,
height = boundsHeight - insetHeight;
@@ -396,10 +444,10 @@ var CPImageViewEmptyPlaceholderImage = nil;
#endif
}
_imageRect = _CGRectMake(x, y, width, height);
_imageRect = CGRectMake(x, y, width, height);
if (_hasShadow)
[_shadowView setFrame:_CGRectMake(x - [_shadowView leftInset], y - [_shadowView topInset], width + insetWidth, height + insetHeight)];
[_shadowView setFrame:CGRectMake(x - [_shadowView leftInset], y - [_shadowView topInset], width + insetWidth, height + insetHeight)];
}
- (void)mouseDown:(CPEvent)anEvent
@@ -471,16 +519,30 @@ var CPImageViewEmptyPlaceholderImage = nil;
{
var image;
if (aBinding === CPDataBinding)
if (aValue == nil)
image = nil;
else if (aBinding === CPDataBinding)
image = [[CPImage alloc] initWithData:aValue];
else if (aBinding === CPValueURLBinding || aBinding === CPValuePathBinding)
image = [[CPImage alloc] initWithContentsOfFile:aValue];
image = [CPImage cachedImageWithContentsOfFile:aValue];
else if (aBinding === CPValueBinding)
image = aValue;
[_source setImage:image];
}
- (id)valueForBinding:(CPString)aBinding
{
var image = [_source image];
if (aBinding === CPDataBinding)
return [image data];
else if (aBinding === CPValueURLBinding || aBinding === CPValuePathBinding)
return [image filename];
else if (aBinding === CPValueBinding)
return image;
}
@end
var CPImageViewImageKey = @"CPImageViewImageKey",
@@ -498,28 +560,12 @@ var CPImageViewImageKey = @"CPImageViewImageKey",
*/
- (id)initWithCoder:(CPCoder)aCoder
{
#if PLATFORM(DOM)
_DOMImageElement = document.createElement("img");
_DOMImageElement.style.position = "absolute";
_DOMImageElement.style.left = "0px";
_DOMImageElement.style.top = "0px";
_DOMImageElement.style.visibility = "hidden";
if ([CPPlatform supportsDragAndDrop])
{
_DOMImageElement.setAttribute("draggable", "true");
_DOMImageElement.style["-khtml-user-drag"] = "element";
}
if (typeof(appkit_tag_dom_elements) !== "undefined" && !!appkit_tag_dom_elements)
_DOMImageElement.setAttribute("data-cappuccino-view", [self className]);
#endif
self = [super initWithCoder:aCoder];
if (self)
{
#if PLATFORM(DOM)
_DOMElement.appendChild(_DOMImageElement);
[self _createDOMImageElement];
#endif
[self setHasShadow:[aCoder decodeBoolForKey:CPImageViewHasShadowKey]];
@@ -545,17 +591,12 @@ var CPImageViewImageKey = @"CPImageViewImageKey",
// We do this in order to avoid encoding the _shadowView, which
// should just automatically be created programmatically as needed.
if (_shadowView)
{
var actualSubviews = _subviews;
_subviews = [_subviews copy];
[_subviews removeObjectIdenticalTo:_shadowView];
}
[_shadowView removeFromSuperview];
[super encodeWithCoder:aCoder];
if (_shadowView)
_subviews = actualSubviews;
[self addSubview:_shadowView];
[aCoder encodeBool:_hasShadow forKey:CPImageViewHasShadowKey];
[aCoder encodeInt:_imageAlignment forKey:CPImageViewImageAlignmentKey];
@@ -565,3 +606,21 @@ var CPImageViewImageKey = @"CPImageViewImageKey",
}
@end
@implementation CPImage (CachedImage)
+ (CPImage)cachedImageWithContentsOfFile:(CPString)aFile
{
var cached_name = [CPString stringWithFormat:@"%@_%d", [self class], [aFile hash]],
image = [CPImage imageNamed:cached_name];
if (!image)
{
image = [[CPImage alloc] initWithContentsOfFile:aFile];
[image setName:cached_name];
}
return image;
}
@end
+3 -2
View File
@@ -21,9 +21,10 @@
*/
@import <Foundation/CPObject.j>
@import <Foundation/CPArray.j>
@import "CPEvent.j"
@import "CPEvent_Constants.j"
@import "CPText.j"
CPStandardKeyBindings = {
@"@.": @"cancelOperation:",
+430 -95
View File
@@ -26,19 +26,23 @@
@import <Foundation/CPObject.j>
@import <Foundation/CPArray.j>
@import <Foundation/CPDictionary.j>
@import <Foundation/CPInvocation.j>
@import <Foundation/CPValueTransformer.j>
@import <Foundation/CPKeyValueObserving.j>
@class CPButton
var exposedBindingsMap = [CPDictionary new],
bindingsMap = [CPDictionary new];
var exposedBindingsMap = @{},
bindingsMap = @{};
@typedef CPBindingOperationKind
var CPBindingOperationAnd = 0,
CPBindingOperationOr = 1;
@implementation CPBinder : CPObject
{
CPDictionary _info;
id _source;
id _source @accessors(getter=source);
JSObject _suppressedNotifications;
JSObject _placeholderForMarker;
@@ -67,6 +71,20 @@ var CPBindingOperationAnd = 0,
return [[bindingsMap objectForKey:[anObject UID]] objectForKey:aBinding];
}
+ (void)_reverseSetValueFromExclusiveBinderForObject:(id)anObject
{
var bindersByBindingName = [bindingsMap objectForKey:[anObject UID]];
[bindersByBindingName enumerateKeysAndObjectsUsingBlock:function(binding, binder, stop)
{
if ([binder isKindOfClass:[self class]])
{
[binder reverseSetValueFor:binding];
stop(YES);
}
}];
}
+ (CPDictionary)infoForBinding:(CPString)aBinding forObject:(id)anObject
{
var theBinding = [self getBinding:aBinding forObject:anObject];
@@ -94,9 +112,9 @@ var CPBindingOperationAnd = 0,
if (!theBinding)
return;
var infoDictionary = theBinding._info,
observedObject = [infoDictionary objectForKey:CPObservedObjectKey],
keyPath = [infoDictionary objectForKey:CPObservedKeyPathKey];
var info = theBinding._info,
observedObject = [info objectForKey:CPObservedObjectKey],
keyPath = [info objectForKey:CPObservedKeyPathKey];
[observedObject removeObserver:theBinding forKeyPath:keyPath];
[bindings removeObjectForKey:aBinding];
@@ -105,6 +123,7 @@ var CPBindingOperationAnd = 0,
+ (void)unbindAllForObject:(id)anObject
{
var bindings = [bindingsMap objectForKey:[anObject UID]];
if (!bindings)
return;
@@ -112,19 +131,24 @@ var CPBindingOperationAnd = 0,
count = allKeys.length;
while (count--)
[anObject unbind:[bindings objectForKey:allKeys[count]]];
[anObject unbind:allKeys[count]];
[bindingsMap removeObjectForKey:[anObject UID]];
}
- (id)initWithBinding:(CPString)aBinding name:(CPString)aName to:(id)aDestination keyPath:(CPString)aKeyPath options:(CPDictionary)options from:(id)aSource
{
self = [super init];
// We use [self init] here because subclasses override init. We can't override this method
// because their initialization has to occur before this method in this class is executed.
self = [self init];
if (self)
{
_source = aSource;
_info = [CPDictionary dictionaryWithObjects:[aDestination, aKeyPath] forKeys:[CPObservedObjectKey, CPObservedKeyPathKey]];
_info = @{
CPObservedObjectKey: aDestination,
CPObservedKeyPathKey: aKeyPath,
};
_suppressedNotifications = {};
_placeholderForMarker = {};
@@ -133,12 +157,13 @@ var CPBindingOperationAnd = 0,
[self _updatePlaceholdersWithOptions:options forBinding:aName];
[aDestination addObserver:self forKeyPath:aKeyPath options:CPKeyValueObservingOptionNew context:aBinding];
[aDestination addObserver:self forKeyPath:aKeyPath options:0 context:aBinding];
var bindings = [bindingsMap objectForKey:[_source UID]];
if (!bindings)
{
bindings = [CPDictionary new];
bindings = @{};
[bindingsMap setObject:bindings forKey:[_source UID]];
}
@@ -149,21 +174,43 @@ var CPBindingOperationAnd = 0,
return self;
}
+ (BOOL)isBindingAllowed:(CPString)aBinding forObject:(id)anObject
{
if ([[anObject class] isBindingExclusive:aBinding])
{
var bindingsForObject = [bindingsMap objectForKey:[anObject UID]],
allBindings = [bindingsForObject allKeys],
count = [allBindings count];
while (count--)
{
if ([[anObject class] isBindingExclusive:allBindings[count]])
return NO;
}
}
return YES;
}
- (void)raiseIfNotApplicable:(id)aValue forKeyPath:(CPString)keyPath options:(CPDictionary)options
{
if (aValue === CPNotApplicableMarker && [options objectForKey:CPRaisesForNotApplicableKeysBindingOption])
{
[CPException raise:CPGenericException
reason:@"Cannot transform non-applicable key on: " + _source + " key path: " + keyPath + " value: " + aValue];
}
}
- (void)setValueFor:(CPString)theBinding
{
var destination = [_info objectForKey:CPObservedObjectKey],
keyPath = [_info objectForKey:CPObservedKeyPathKey],
options = [_info objectForKey:CPOptionsKey],
newValue = [destination valueForKeyPath:keyPath],
isPlaceholder = CPIsControllerMarker(newValue);
newValue = [destination valueForKeyPath:keyPath];
if (isPlaceholder)
if (CPIsControllerMarker(newValue))
{
if (newValue === CPNotApplicableMarker && [options objectForKey:CPRaisesForNotApplicableKeysBindingOption])
{
[CPException raise:CPGenericException
reason:@"Cannot transform non-applicable key on: " + _source + " key path: " + keyPath + " value: " + newValue];
}
[self raiseIfNotApplicable:newValue forKeyPath:keyPath options:options];
var value = [self _placeholderForMarker:newValue];
[self setPlaceholderValue:value withMarker:newValue forBinding:theBinding];
@@ -210,6 +257,7 @@ var CPBindingOperationAnd = 0,
return;
var objectSuppressions = _suppressedNotifications[[anObject UID]];
if (objectSuppressions && objectSuppressions[aKeyPath])
return;
@@ -228,6 +276,7 @@ var CPBindingOperationAnd = 0,
if (!valueTransformer)
{
var valueTransformerClass = CPClassFromString(valueTransformerName);
if (valueTransformerClass)
{
valueTransformer = [[valueTransformerClass alloc] init];
@@ -241,7 +290,11 @@ var CPBindingOperationAnd = 0,
if (valueTransformer)
aValue = [valueTransformer transformedValue:aValue];
if (aValue === undefined || aValue === nil || aValue === [CPNull null])
// If the value is nil AND the source doesn't respond to setPlaceholderString: then
// we set the value to the placeholder. Otherwise, we do not want to short cut the process
// of setting the placeholder that is based on the fact that the value is nil.
if ((aValue === undefined || aValue === nil || aValue === [CPNull null])
&& ![_source respondsToSelector:@selector(setPlaceholderString:)])
aValue = [options objectForKey:CPNullPlaceholderBindingOption] || nil;
return aValue;
@@ -285,6 +338,7 @@ var CPBindingOperationAnd = 0,
var uid = [anObject UID],
objectSuppressions = _suppressedNotifications[uid];
if (!objectSuppressions)
_suppressedNotifications[uid] = objectSuppressions = {};
@@ -301,6 +355,7 @@ var CPBindingOperationAnd = 0,
var uid = [anObject UID],
objectSuppressions = _suppressedNotifications[uid];
if (!objectSuppressions)
return;
@@ -317,6 +372,7 @@ var CPBindingOperationAnd = 0,
optionName = CPBinderPlaceholderOptions[count],
isExplicit = [options containsKey:optionName],
placeholder = isExplicit ? [options objectForKey:optionName] : nil;
[self _setPlaceholder:placeholder forMarker:marker isDefault:!isExplicit];
}
}
@@ -326,11 +382,13 @@ var CPBindingOperationAnd = 0,
[self _updatePlaceholdersWithOptions:options];
}
- (void)_placeholderForMarker:aMarker
- (JSObject)_placeholderForMarker:(id)aMarker
{
var placeholder = _placeholderForMarker[aMarker];
var placeholder = _placeholderForMarker[[aMarker UID]];
if (placeholder)
return placeholder['value'];
return placeholder.value;
return nil;
}
@@ -338,14 +396,14 @@ var CPBindingOperationAnd = 0,
{
if (isDefault)
{
var existingPlaceholder = _placeholderForMarker[aMarker];
var existingPlaceholder = _placeholderForMarker[[aMarker UID]];
// Don't overwrite an explicitly set placeholder with a default.
if (existingPlaceholder && !existingPlaceholder['isDefault'])
if (existingPlaceholder && !existingPlaceholder.isDefault)
return;
}
_placeholderForMarker[aMarker] = { 'isDefault': isDefault, 'value': aPlaceholder };
_placeholderForMarker[[aMarker UID]] = { 'isDefault': isDefault, 'value': aPlaceholder };
}
@end
@@ -357,11 +415,16 @@ var CPBindingOperationAnd = 0,
[CPBinder exposeBinding:aBinding forClass:[self class]];
}
+ (Class)_binderClassForBinding:(CPString)theBinding
+ (Class)_binderClassForBinding:(CPString)aBinding
{
return [CPBinder class];
}
+ (BOOL)isBindingExclusive:(CPString)aBinding
{
return NO;
}
- (CPArray)exposedBindings
{
var exposedBindings = [],
@@ -390,6 +453,11 @@ var CPBindingOperationAnd = 0,
if (!anObject || !aKeyPath)
return CPLog.error("Invalid object or path on " + self + " for " + aBinding);
if (![CPBinder isBindingAllowed:aBinding forObject:self])
{
CPLog.warn([self description] + " : cannot bind " + aBinding + " because another binding with the same functionality is already in use.");
return;
}
//if (![[self exposedBindings] containsObject:aBinding])
// CPLog.warn("No binding exposed on " + self + " for " + aBinding);
@@ -410,7 +478,7 @@ var CPBindingOperationAnd = 0,
[binderClass unbind:aBinding forObject:self];
}
- (id)_replacementKeyPathForBinding:(CPString)binding
- (CPString)_replacementKeyPathForBinding:(CPString)binding
{
return binding;
}
@@ -419,13 +487,13 @@ var CPBindingOperationAnd = 0,
/*!
@ignore
Provides stub implementations that simply call super for the "objectValue" binding
This class should not be necessary but assures backwards compliance with our old way of doing bindings
Every class with a value binding should implement a subclass to handle it's specific value binding logic
Provides stub implementations that simply calls super for the "objectValue" binding.
This class should not be necessary but assures backwards compliance with our old way of doing bindings.
IMPORTANT!
Every class with a value binding should implement a subclass to handle its specific value binding logic.
*/
@implementation _CPValueBinder : CPBinder
{
}
- (void)setValueFor:(CPString)theBinding
{
@@ -439,8 +507,9 @@ var CPBindingOperationAnd = 0,
@end
@implementation _CPKeyValueOrBinding : CPBinder
@implementation _CPMultipleValueBooleanBinding : CPBinder
{
CPBindingOperationKind _operation;
}
- (void)setValueFor:(CPString)aBinding
@@ -450,7 +519,14 @@ var CPBindingOperationAnd = 0,
if (!bindings)
return;
[_source setValue:resolveMultipleValues(aBinding, bindings, CPBindingOperationOr) forKey:aBinding];
var baseBinding = aBinding.replace(/\d$/, "");
[_source setValue:[self resolveMultipleValuesForBinding:baseBinding bindings:bindings booleanOperation:_operation] forKey:baseBinding];
}
- (void)reverseSetValueFor:(CPString)theBinding
{
// read-only
}
- (void)observeValueForKeyPath:(CPString)aKeyPath ofObject:(id)anObject change:(CPDictionary)changes context:(id)context
@@ -458,61 +534,146 @@ var CPBindingOperationAnd = 0,
[self setValueFor:context];
}
@end
@implementation _CPKeyValueAndBinding : CPBinder
- (BOOL)resolveMultipleValuesForBinding:(CPString)aBinding bindings:(CPDictionary)bindings booleanOperation:(CPBindingOperationKind)operation
{
}
- (void)setValueFor:(CPString)aBinding
{
var bindings = [bindingsMap objectForKey:[_source UID]];
if (!bindings)
return;
[_source setValue:resolveMultipleValues(aBinding, bindings, CPBindingOperationAnd) forKey:aBinding];
}
- (void)observeValueForKeyPath:(CPString)aKeyPath ofObject:(id)anObejct change:(CPDictionary)changes context:(id)context
{
[self setValueFor:context];
}
@end
var resolveMultipleValues = function(/*CPString*/key, /*CPDictionary*/bindings, /*GSBindingOperationKind*/operation)
{
var bindingName = key,
var bindingName = aBinding,
theBinding,
count = 1;
count = 2;
while (theBinding = [bindings objectForKey:bindingName])
{
var infoDictionary = theBinding._info,
object = [infoDictionary objectForKey:CPObservedObjectKey],
keyPath = [infoDictionary objectForKey:CPObservedKeyPathKey],
options = [infoDictionary objectForKey:CPOptionsKey];
var info = theBinding._info,
object = [info objectForKey:CPObservedObjectKey],
keyPath = [info objectForKey:CPObservedKeyPathKey],
options = [info objectForKey:CPOptionsKey],
value = [object valueForKeyPath:keyPath];
var value = [theBinding transformValue:[object valueForKeyPath:keyPath] withOptions:options];
if (CPIsControllerMarker(value))
{
[self raiseIfNotApplicable:value forKeyPath:keyPath options:options];
value = [theBinding _placeholderForMarker:value];
}
else
value = [theBinding transformValue:value withOptions:options];
if (value == operation)
return operation;
if (operation === CPBindingOperationOr)
{
// Any true condition means true for OR
if (value)
return YES;
}
bindingName = [CPString stringWithFormat:@"%@%i", key, ++count];
// Any false condition means false for AND
else if (!value)
return NO;
bindingName = aBinding + (count++);
}
return !operation;
};
// If we get here, all OR conditions were false or all AND conditions were true
return operation === CPBindingOperationOr ? NO : YES;
}
var invokeAction = function(/*CPString*/targetKey, /*CPString*/argumentKey, /*CPDictionary*/bindings)
@end
@implementation CPMultipleValueAndBinding : _CPMultipleValueBooleanBinding
- (id)init
{
var theBinding = [bindings objectForKey:targetKey],
infoDictionary = theBinding._info,
if (self = [super init])
_operation = CPBindingOperationAnd;
object = [infoDictionary objectForKey:CPObservedObjectKey],
keyPath = [infoDictionary objectForKey:CPObservedKeyPathKey],
options = [infoDictionary objectForKey:CPOptionsKey],
return self;
}
@end
@implementation CPMultipleValueOrBinding : _CPMultipleValueBooleanBinding
- (id)init
{
if (self = [super init])
_operation = CPBindingOperationOr;
return self;
}
@end
@implementation _CPMultipleValueActionBinding : CPBinder
{
CPString _argumentBinding;
CPString _targetBinding;
}
- (void)setValueFor:(CPString)theBinding
{
// Called when the binding is first created
[self checkForNullBinding:theBinding initializing:YES];
}
- (void)reverseSetValueFor:(CPString)theBinding
{
// no-op
}
- (void)observeValueForKeyPath:(CPString)aKeyPath ofObject:(id)anObject change:(CPDictionary)changes context:(id)context
{
// context is the binding name
[self checkForNullBinding:context initializing:NO];
}
/*!
@ignore
When the value of a multiple-value argument binding changes,
if the binding is marked not to allow null arguments, we have to check
if the binding's value is nil and disable the button if it is.
Otherwise the button is enabled.
*/
- (void)checkForNullBinding:(CPString)theBinding initializing:(BOOL)isInitializing
{
// Only done for buttons
if (![_source isKindOfClass:CPButton])
return;
// We start with the button enabled for the first argument during init,
// and subsequent checks can disable it.
if (isInitializing && theBinding === CPArgumentBinding)
[_source setEnabled:YES];
var bindings = [bindingsMap valueForKey:[_source UID]],
binding = [bindings objectForKey:theBinding],
info = binding._info,
options = [info objectForKey:CPOptionsKey];
if (![options valueForKey:CPAllowsNullArgumentBindingOption])
{
var object = [info objectForKey:CPObservedObjectKey],
keyPath = [info objectForKey:CPObservedKeyPathKey],
value = [object valueForKeyPath:keyPath];
if (value === nil || value === undefined)
{
[_source setEnabled:NO];
return;
}
}
// If a binding value changed and did not fail the null test, enable the button
if (!isInitializing)
[_source setEnabled:YES];
}
- (void)invokeAction
{
var bindings = [bindingsMap valueForKey:[_source UID]],
theBinding = [bindings objectForKey:CPTargetBinding],
info = theBinding._info,
object = [info objectForKey:CPObservedObjectKey],
keyPath = [info objectForKey:CPObservedKeyPathKey],
options = [info objectForKey:CPOptionsKey],
target = [object valueForKeyPath:keyPath],
selector = [options objectForKey:CPSelectorNameBindingOption];
@@ -520,27 +681,194 @@ var invokeAction = function(/*CPString*/targetKey, /*CPString*/argumentKey, /*CP
if (!target || !selector)
return;
var invocation = [CPInvocation invocationWithMethodSignature:[target methodSignatureForSelector:selector]];
[invocation setSelector:selector];
var bindingName = argumentKey,
var invocation = [CPInvocation invocationWithMethodSignature:[target methodSignatureForSelector:selector]],
bindingName = CPArgumentBinding,
count = 1;
while (theBinding = [bindings objectForKey:bindingName])
{
infoDictionary = theBinding._info;
info = theBinding._info;
object = [info objectForKey:CPObservedObjectKey];
keyPath = [info objectForKey:CPObservedKeyPathKey];
keyPath = [infoDictionary objectForKey:CPObserverKeyPathKey];
object = [[infoDictionary objectForKey:CPObservedObjectKey] valueForKeyPath:keyPath];
[invocation setArgument:[object valueForKeyPath:keyPath] atIndex:++count];
if (object)
[invocation setArgument:object atIndex:++count];
bindingName = [CPString stringWithFormat:@"%@%i", argumentKey, count];
bindingName = CPArgumentBinding + count;
}
[invocation invoke];
};
[invocation setSelector:selector];
[invocation invokeWithTarget:target];
}
@end
@implementation CPActionBinding : _CPMultipleValueActionBinding
- (id)init
{
if (self = [super init])
{
_argumentBinding = CPArgumentBinding;
_targetBinding = CPTargetBinding;
}
return self;
}
@end
@implementation CPDoubleClickActionBinding : _CPMultipleValueActionBinding
- (id)init
{
if (self = [super init])
{
_argumentBinding = CPArgumentBinding;
_targetBinding = CPTargetBinding;
}
return self;
}
@end
/*!
Abstract superclass for CPValueWithPatternBinding and CPTitleWithPatternBinding.
*/
@implementation _CPPatternBinding : CPBinder
{
CPString _bindingKey;
CPString _patternPlaceholder;
}
- (void)setValueFor:(CPString)aBinding
{
var bindings = [bindingsMap valueForKey:[_source UID]];
if (!bindings)
return;
// Strip off any trailing number from the binding name
var baseBinding = aBinding.replace(/\d$/, ""),
result = [self resolveMultipleValuesForBindings:bindings];
if (result.isPlaceholder)
[self setPlaceholderValue:result.value withMarker:result.marker forBinding:baseBinding];
else
[self setValue:result.value forBinding:baseBinding];
}
- (void)reverseSetValueFor:(CPString)theBinding
{
// read-only
}
- (void)observeValueForKeyPath:(CPString)aKeyPath ofObject:(id)anObject change:(CPDictionary)changes context:(id)context
{
[self setValueFor:context];
}
- (JSObject)resolveMultipleValuesForBindings:(CPDictionary)bindings
{
var theBinding,
result = { value:@"", isPlaceholder:NO, marker:nil };
for (var count = 1; theBinding = [bindings objectForKey:_bindingKey + count]; ++count)
{
var info = theBinding._info,
object = [info objectForKey:CPObservedObjectKey],
keyPath = [info objectForKey:CPObservedKeyPathKey],
options = [info objectForKey:CPOptionsKey],
value = [object valueForKeyPath:keyPath];
if (count === 1)
result.value = [options objectForKey:CPDisplayPatternBindingOption];
if (CPIsControllerMarker(value))
{
[self raiseIfNotApplicable:value forKeyPath:keyPath options:options];
result.isPlaceholder = YES;
result.marker = value;
value = [theBinding _placeholderForMarker:value];
}
else
value = [theBinding transformValue:value withOptions:options];
if (value === nil || value === undefined)
value = @"";
result.value = result.value.replace("%{" + _patternPlaceholder + count + "}@", [value description]);
}
return result;
}
@end
/*!
Users of this class must override setValue:forKey: and if the
key is CPDisplayPatternValueBinding, set the appropriate value
for the control class. For example, CPTextField uses setObjectValue.
*/
@implementation CPValueWithPatternBinding : _CPPatternBinding
- (id)init
{
if (self = [super init])
{
_bindingKey = CPDisplayPatternValueBinding;
_patternPlaceholder = @"value";
}
return self;
}
@end
/*!
Users of this class must override setValue:forKey: and if the
key is CPDisplayPatternTitleBinding, set the appropriate value
for the control class. For example, CPBox uses setTitle.
*/
@implementation CPTitleWithPatternBinding : _CPPatternBinding
- (id)init
{
if (self = [super init])
{
_bindingKey = CPDisplayPatternTitleBinding;
_patternPlaceholder = @"title";
}
return self;
}
@end
@implementation _CPStateMarker : CPObject
{
CPString _name;
}
- (id)initWithName:(CPString)aName
{
if (self = [super init])
_name = aName;
return self;
}
- (CPString)description
{
return "<" + _name + ">";
}
@end
// Keys in options dictionary
@@ -550,18 +878,23 @@ CPObservedKeyPathKey = @"CPObservedKeyPathKey";
CPOptionsKey = @"CPOptionsKey";
// special markers
CPMultipleValuesMarker = @"CPMultipleValuesMarker";
CPNoSelectionMarker = @"CPNoSelectionMarker";
CPNotApplicableMarker = @"CPNotApplicableMarker";
CPNullMarker = @"CPNullMarker";
CPNoSelectionMarker = [[_CPStateMarker alloc] initWithName:@"NO SELECTION MARKER"];
CPMultipleValuesMarker = [[_CPStateMarker alloc] initWithName:@"MULTIPLE VALUES MARKER"];
CPNotApplicableMarker = [[_CPStateMarker alloc] initWithName:@"NOT APPLICABLE MARKER"];
CPNullMarker = [[_CPStateMarker alloc] initWithName:@"NULL MARKER"];
// Binding name constants
CPAlignmentBinding = @"alignment";
CPArgumentBinding = @"argument";
CPContentArrayBinding = @"contentArray";
CPContentBinding = @"content";
CPContentObjectBinding = @"contentObject";
CPContentObjectsBinding = @"contentObjects";
CPContentValuesBinding = @"contentValues";
CPDisplayPatternTitleBinding = @"displayPatternTitle";
CPDisplayPatternValueBinding = @"displayPatternValue";
CPDoubleClickArgumentBinding = @"doubleClickArgument";
CPDoubleClickTargetBinding = @"doubleClickTarget";
CPEditableBinding = @"editable";
CPEnabledBinding = @"enabled";
CPFontBinding = @"font";
@@ -580,15 +913,17 @@ CPSelectedTagBinding = @"selectedTag";
CPSelectedValueBinding = @"selectedValue";
CPSelectedValuesBinding = @"selectedValues";
CPSelectionIndexesBinding = @"selectionIndexes";
CPTargetBinding = @"target";
CPTextColorBinding = @"textColor";
CPTitleBinding = @"title";
CPToolTipBinding = @"toolTip";
CPValueBinding = @"value";
CPAttributedStringBinding = @"attributedString";
CPValueURLBinding = @"valueURL";
CPValuePathBinding = @"valuePath";
CPDataBinding = @"data";
//Binding options constants
// Binding options constants
CPAllowsEditingMultipleValuesSelectionBindingOption = @"CPAllowsEditingMultipleValuesSelection";
CPAllowsNullArgumentBindingOption = @"CPAllowsNullArgument";
CPConditionallySetsEditableBindingOption = @"CPConditionallySetsEditable";
+48 -83
View File
@@ -21,25 +21,22 @@
*/
@import "CPControl.j"
@import "CPWindow_Constants.j"
@global CPApp
@typedef CPTickMarkPosition
CPTickMarkBelow = 0;
CPTickMarkAbove = 1;
CPTickMarkLeft = CPTickMarkAbove;
CPTickMarkRight = CPTickMarkBelow;
@typedef CPLevelIndicatorStyle
CPRelevancyLevelIndicatorStyle = 0;
CPContinuousCapacityLevelIndicatorStyle = 1;
CPDiscreteCapacityLevelIndicatorStyle = 2;
CPRatingLevelIndicatorStyle = 3;
var _CPLevelIndicatorBezelColor = nil,
_CPLevelIndicatorSegmentEmptyColor = nil,
_CPLevelIndicatorSegmentNormalColor = nil,
_CPLevelIndicatorSegmentWarningColor = nil,
_CPLevelIndicatorSegmentCriticalColor = nil,
_CPLevelIndicatorSpacing = 1;
/*!
@ingroup appkit
@class CPLevelIndicator
@@ -62,57 +59,21 @@ var _CPLevelIndicatorBezelColor = nil,
BOOL _isTracking;
}
+ (void)initialize
+ (CPString)defaultThemeClass
{
if (self !== [CPLevelIndicator class])
return;
return "level-indicator";
}
var bundle = [CPBundle bundleForClass:CPLevelIndicator];
_CPLevelIndicatorBezelColor = [CPColor colorWithPatternImage:[[CPThreePartImage alloc] initWithImageSlices:
[
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPLevelIndicator/level-indicator-bezel-left.png"] size:CGSizeMake(3.0, 18.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPLevelIndicator/level-indicator-bezel-center.png"] size:CGSizeMake(1.0, 18.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPLevelIndicator/level-indicator-bezel-right.png"] size:CGSizeMake(3.0, 18.0)]
]
isVertical:NO
]];
_CPLevelIndicatorSegmentEmptyColor = [CPColor colorWithPatternImage:[[CPThreePartImage alloc] initWithImageSlices:
[
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPLevelIndicator/level-indicator-segment-empty-left.png"] size:CGSizeMake(3.0, 17.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPLevelIndicator/level-indicator-segment-empty-center.png"] size:CGSizeMake(1.0, 17.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPLevelIndicator/level-indicator-segment-empty-right.png"] size:CGSizeMake(3.0, 17.0)]
]
isVertical:NO
]];
_CPLevelIndicatorSegmentNormalColor = [CPColor colorWithPatternImage:[[CPThreePartImage alloc] initWithImageSlices:
[
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPLevelIndicator/level-indicator-segment-normal-left.png"] size:CGSizeMake(3.0, 17.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPLevelIndicator/level-indicator-segment-normal-center.png"] size:CGSizeMake(1.0, 17.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPLevelIndicator/level-indicator-segment-normal-right.png"] size:CGSizeMake(3.0, 17.0)]
]
isVertical:NO
]];
_CPLevelIndicatorSegmentWarningColor = [CPColor colorWithPatternImage:[[CPThreePartImage alloc] initWithImageSlices:
[
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPLevelIndicator/level-indicator-segment-warning-left.png"] size:CGSizeMake(3.0, 17.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPLevelIndicator/level-indicator-segment-warning-center.png"] size:CGSizeMake(1.0, 17.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPLevelIndicator/level-indicator-segment-warning-right.png"] size:CGSizeMake(3.0, 17.0)]
]
isVertical:NO
]];
_CPLevelIndicatorSegmentCriticalColor = [CPColor colorWithPatternImage:[[CPThreePartImage alloc] initWithImageSlices:
[
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPLevelIndicator/level-indicator-segment-critical-left.png"] size:CGSizeMake(3.0, 17.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPLevelIndicator/level-indicator-segment-critical-center.png"] size:CGSizeMake(1.0, 17.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPLevelIndicator/level-indicator-segment-critical-right.png"] size:CGSizeMake(3.0, 17.0)]
]
isVertical:NO
]];
+ (CPDictionary)themeAttributes
{
return @{
@"bezel-color": [CPNull null],
@"color-empty": [CPNull null],
@"color-normal": [CPNull null],
@"color-warning": [CPNull null],
@"color-critical": [CPNull null],
@"spacing": 1.0,
};
}
- (id)initWithFrame:(CGRect)aFrame
@@ -125,37 +86,42 @@ var _CPLevelIndicatorBezelColor = nil,
_maxValue = 2;
_warningValue = 2;
_criticalValue = 2;
[self _init];
}
return self;
}
- (void)_init
{
}
- (void)layoutSubviews
{
var bezelView = [self layoutEphemeralSubviewNamed:"bezel"
positioned:CPWindowBelow
relativeToEphemeralSubviewNamed:nil];
// TODO Make themable.
[bezelView setBackgroundColor:_CPLevelIndicatorBezelColor];
[bezelView setBackgroundColor:[self valueForThemeAttribute:@"bezel-color"]];
var segmentCount = _maxValue - _minValue;
if (segmentCount <= 0)
return;
var filledColor = _CPLevelIndicatorSegmentNormalColor,
var filledColor = [self valueForThemeAttribute:@"color-normal"],
value = [self doubleValue];
if (value <= _criticalValue)
filledColor = _CPLevelIndicatorSegmentCriticalColor;
else if (value <= _warningValue)
filledColor = _CPLevelIndicatorSegmentWarningColor;
if (_warningValue < _criticalValue)
{
if (value >= _criticalValue)
filledColor = [self valueForThemeAttribute:@"color-critical"];
else if (value >= _warningValue)
filledColor = [self valueForThemeAttribute:@"color-warning"];
}
else
{
if (value <= _criticalValue)
filledColor = [self valueForThemeAttribute:@"color-critical"];
else if (value <= _warningValue)
filledColor = [self valueForThemeAttribute:@"color-warning"];
}
for (var i = 0; i < segmentCount; i++)
{
@@ -163,13 +129,13 @@ var _CPLevelIndicatorBezelColor = nil,
positioned:CPWindowAbove
relativeToEphemeralSubviewNamed:bezelView];
[segmentView setBackgroundColor:(_minValue + i) < value ? filledColor : _CPLevelIndicatorSegmentEmptyColor];
[segmentView setBackgroundColor:(_minValue + i) < value ? filledColor : [self valueForThemeAttribute:@"color-empty"]];
}
}
- (CPView)createEphemeralSubviewNamed:(CPString)aName
{
return [[CPView alloc] initWithFrame:_CGRectMakeZero()];
return [[CPView alloc] initWithFrame:CGRectMakeZero()];
}
- (CGRect)rectForEphemeralSubviewNamed:(CPString)aViewName
@@ -177,11 +143,11 @@ var _CPLevelIndicatorBezelColor = nil,
// TODO Put into theme attributes.
var bezelHeight = 18,
segmentHeight = 17,
bounds = _CGRectCreateCopy([self bounds]);
bounds = CGRectCreateCopy([self bounds]);
if (aViewName == "bezel")
{
bounds.origin.y = (_CGRectGetHeight(bounds) - bezelHeight) / 2.0;
bounds.origin.y = (CGRectGetHeight(bounds) - bezelHeight) / 2.0;
bounds.size.height = bezelHeight;
return bounds;
}
@@ -191,20 +157,21 @@ var _CPLevelIndicatorBezelColor = nil,
segmentCount = _maxValue - _minValue;
if (segment >= segmentCount)
return _CGRectMakeZero();
return CGRectMakeZero();
var basicSegmentWidth = bounds.size.width / segmentCount,
segmentFrame = CGRectCreateCopy([self bounds]);
segmentFrame = CGRectCreateCopy([self bounds]),
spacing = [self valueForThemeAttribute:@"spacing"];
segmentFrame.origin.y = (_CGRectGetHeight(bounds) - bezelHeight) / 2.0;
segmentFrame.origin.y = (CGRectGetHeight(bounds) - bezelHeight) / 2.0;
segmentFrame.origin.x = FLOOR(segment * basicSegmentWidth);
segmentFrame.size.width = (segment == segmentCount - 1) ? bounds.size.width - segmentFrame.origin.x : FLOOR(((segment + 1) * basicSegmentWidth)) - FLOOR((segment * basicSegmentWidth)) - _CPLevelIndicatorSpacing;
segmentFrame.size.width = (segment == segmentCount - 1) ? bounds.size.width - segmentFrame.origin.x : FLOOR(((segment + 1) * basicSegmentWidth)) - FLOOR((segment * basicSegmentWidth)) - spacing;
segmentFrame.size.height = segmentHeight;
return segmentFrame;
}
return _CGRectMakeZero();
return CGRectMakeZero();
}
/*!
@@ -226,7 +193,7 @@ var _CPLevelIndicatorBezelColor = nil,
return _isEditable;
}
- (CPView)hitTest:(CPPoint)aPoint
- (CPView)hitTest:(CGPoint)aPoint
{
// Don't swallow clicks when displayed in a table.
if (![self isEditable])
@@ -325,7 +292,7 @@ var _CPLevelIndicatorBezelColor = nil,
[self setNeedsLayout];
}
- (void)setWarningValue:(double)warningValue;
- (void)setWarningValue:(double)warningValue
{
if (_warningValue === warningValue)
return;
@@ -334,7 +301,7 @@ var _CPLevelIndicatorBezelColor = nil,
[self setNeedsLayout];
}
- (void)setCriticalValue:(double)criticalValue;
- (void)setCriticalValue:(double)criticalValue
{
if (_criticalValue === criticalValue)
return;
@@ -388,8 +355,6 @@ var CPLevelIndicatorStyleKey = "CPLevelIndicatorStyleKey",
_isEditable = [aCoder decodeBoolForKey:CPLevelIndicatorIsEditableKey];
[self _init];
[self setNeedsLayout];
[self setNeedsDisplay:YES];
}
+171 -59
View File
@@ -25,12 +25,21 @@
@import <Foundation/CPNotificationCenter.j>
@import <Foundation/CPString.j>
@import "_CPMenuManager.j"
@import "CPApplication.j"
@import "CPClipView.j"
@import "CPKeyValueBinding.j"
@import "CPMenuItem.j"
@import "CPPanel.j"
@global CPApp
@protocol CPMenuDelegate <CPObject>
@optional
- (void)menuWillOpen:(CPMenu)aMenu;
- (void)menuDidClose:(CPMenu)aMenu;
@end
var CPMenuDelegate_menuWillOpen_ = 1 << 1,
CPMenuDelegate_menuDidClose_ = 1 << 2;
CPMenuDidAddItemNotification = @"CPMenuDidAddItemNotification";
CPMenuDidChangeItemNotification = @"CPMenuDidChangeItemNotification";
@@ -38,12 +47,8 @@ CPMenuDidRemoveItemNotification = @"CPMenuDidRemoveItemNotification";
CPMenuDidEndTrackingNotification = @"CPMenuDidEndTrackingNotification";
var MENUBAR_HEIGHT = 28.0;
var _CPMenuBarVisible = NO,
_CPMenuBarTitle = @"",
_CPMenuBarIconImage = nil,
_CPMenuBarIconImageAlphaValue = 1.0,
_CPMenuBarAttributes = nil,
_CPMenuBarSharedWindow = nil;
@@ -56,24 +61,27 @@ var _CPMenuBarVisible = NO,
*/
@implementation CPMenu : CPObject
{
CPMenu _supermenu;
CPMenu _supermenu;
CPString _title;
CPString _name;
CPString _title;
CPString _name;
CPFont _font;
CPFont _font;
float _minimumWidth;
float _minimumWidth;
CPMutableArray _items;
CPMutableArray _items;
BOOL _autoenablesItems;
BOOL _showsStateColumn;
BOOL _autoenablesItems;
BOOL _showsStateColumn;
id _delegate;
id <CPMenuDelegate> _delegate;
unsigned _implementedDelegateMethods;
int _highlightedIndex;
_CPMenuWindow _menuWindow;
int _highlightedIndex;
_CPMenuWindow _menuWindow;
CPEvent _lastCloseEvent;
}
// Managing the Menu Bar
@@ -83,7 +91,7 @@ var _CPMenuBarVisible = NO,
if (self !== [CPMenu class])
return;
[[self class] setMenuBarAttributes:[CPDictionary dictionary]];
[[self class] setMenuBarAttributes:@{}];
}
+ (BOOL)menuBarVisible
@@ -109,8 +117,8 @@ var _CPMenuBarVisible = NO,
[_CPMenuBarSharedWindow setMenu:[CPApp mainMenu]];
[_CPMenuBarSharedWindow setTitle:_CPMenuBarTitle];
[_CPMenuBarSharedWindow setIconImage:_CPMenuBarIconImage];
[_CPMenuBarSharedWindow setIconImageAlphaValue:_CPMenuBarIconImageAlphaValue];
[_CPMenuBarSharedWindow setIconImage:[[CPTheme defaultTheme] valueForAttributeWithName:@"menu-bar-icon-image" forClass:_CPMenuView]];
[_CPMenuBarSharedWindow setIconImageAlphaValue:[[CPTheme defaultTheme] valueForAttributeWithName:@"menu-bar-icon-image-alpha-value" forClass:_CPMenuView]];
[_CPMenuBarSharedWindow setColor:[_CPMenuBarAttributes objectForKey:@"CPMenuBarBackgroundColor"]];
[_CPMenuBarSharedWindow setTextColor:[_CPMenuBarAttributes objectForKey:@"CPMenuBarTextColor"]];
@@ -154,6 +162,13 @@ var _CPMenuBarVisible = NO,
return _CPMenuBarImage;
}
+ (void)_setOrRemoveMenuBarAttribute:(id)aValue forKey:(id)aKey
{
if (aValue === nil)
[_CPMenuBarAttributes removeObjectForKey:aKey];
else
[_CPMenuBarAttributes setObject:aValue forKey:aKey];
}
+ (void)setMenuBarAttributes:(CPDictionary)attributes
{
@@ -178,8 +193,8 @@ var _CPMenuBarVisible = NO,
else if (!textColor && !titleColor)
{
[_CPMenuBarAttributes setObject:[CPColor colorWithRed:0.051 green:0.2 blue:0.275 alpha:1.0] forKey:@"CPMenuBarTextColor"];
[_CPMenuBarAttributes setObject:[CPColor colorWithRed:0.051 green:0.2 blue:0.275 alpha:1.0] forKey:@"CPMenuBarTitleColor"];
[self _setOrRemoveMenuBarAttribute:[[CPTheme defaultTheme] valueForAttributeWithName:@"menu-bar-text-color" forClass:_CPMenuView] forKey:@"CPMenuBarTextColor"];
[self _setOrRemoveMenuBarAttribute:[[CPTheme defaultTheme] valueForAttributeWithName:@"menu-bar-title-color" forClass:_CPMenuView] forKey:@"CPMenuBarTitleColor"];
}
if (!textShadowColor && titleShadowColor)
@@ -190,18 +205,18 @@ var _CPMenuBarVisible = NO,
else if (!textShadowColor && !titleShadowColor)
{
[_CPMenuBarAttributes setObject:[CPColor whiteColor] forKey:@"CPMenuBarTextShadowColor"];
[_CPMenuBarAttributes setObject:[CPColor whiteColor] forKey:@"CPMenuBarTitleShadowColor"];
[self _setOrRemoveMenuBarAttribute:[[CPTheme defaultTheme] valueForAttributeWithName:@"menu-bar-text-shadow-color" forClass:_CPMenuView] forKey:@"CPMenuBarTextShadowColor"];
[self _setOrRemoveMenuBarAttribute:[[CPTheme defaultTheme] valueForAttributeWithName:@"menu-bar-title-shadow-color" forClass:_CPMenuView] forKey:@"CPMenuBarTitleShadowColor"];
}
if (!highlightColor)
[_CPMenuBarAttributes setObject:[CPColor colorWithCalibratedRed:94.0 / 255.0 green:130.0 / 255.0 blue:186.0 / 255.0 alpha:1.0] forKey:@"CPMenuBarHighlightColor"];
[self _setOrRemoveMenuBarAttribute:[[CPTheme defaultTheme] valueForAttributeWithName:@"menu-bar-highlight-color" forClass:_CPMenuView] forKey:@"CPMenuBarHighlightColor"];
if (!highlightTextColor)
[_CPMenuBarAttributes setObject:[CPColor whiteColor] forKey:@"CPMenuBarHighlightTextColor"];
[self _setOrRemoveMenuBarAttribute:[[CPTheme defaultTheme] valueForAttributeWithName:@"menu-bar-highlight-text-color" forClass:_CPMenuView] forKey:@"CPMenuBarHighlightTextColor"];
if (!highlightTextShadowColor)
[_CPMenuBarAttributes setObject:[CPColor blackColor] forKey:@"CPMenuBarHighlightTextShadowColor"];
[self _setOrRemoveMenuBarAttribute:[[CPTheme defaultTheme] valueForAttributeWithName:@"menu-bar-highlight-text-shadow-color" forClass:_CPMenuView] forKey:@"CPMenuBarHighlightTextShadowColor"];
if (_CPMenuBarSharedWindow)
{
@@ -230,14 +245,14 @@ var _CPMenuBarVisible = NO,
- (float)menuBarHeight
{
if (self === [CPApp mainMenu])
return MENUBAR_HEIGHT;
return [CPMenu menuBarHeight];
return 0.0;
}
+ (float)menuBarHeight
{
return MENUBAR_HEIGHT;
return [[CPTheme defaultTheme] valueForAttributeWithName:@"menu-bar-height" forClass:_CPMenuView];
}
// Creating a CPMenu Object
@@ -275,7 +290,7 @@ var _CPMenuBarVisible = NO,
@param aMenuItem the item to insert
@param anIndex the index in the menu to insert the item.
*/
- (void)insertItem:(CPMenuItem)aMenuItem atIndex:(unsigned)anIndex
- (void)insertItem:(CPMenuItem)aMenuItem atIndex:(CPUInteger)anIndex
{
[self insertObject:aMenuItem inItemsAtIndex:anIndex];
}
@@ -288,7 +303,7 @@ var _CPMenuBarVisible = NO,
@param anIndex the index location in the menu for the new item
@return the new menu item
*/
- (CPMenuItem)insertItemWithTitle:(CPString)aTitle action:(SEL)anAction keyEquivalent:(CPString)aKeyEquivalent atIndex:(unsigned)anIndex
- (CPMenuItem)insertItemWithTitle:(CPString)aTitle action:(SEL)anAction keyEquivalent:(CPString)aKeyEquivalent atIndex:(CPUInteger)anIndex
{
var item = [[CPMenuItem alloc] initWithTitle:aTitle action:anAction keyEquivalent:aKeyEquivalent];
@@ -332,7 +347,7 @@ var _CPMenuBarVisible = NO,
Removes the item at the specified index from the menu
@param anIndex the index of the item to remove
*/
- (void)removeItemAtIndex:(unsigned)anIndex
- (void)removeItemAtIndex:(CPUInteger)anIndex
{
[self removeObjectFromItemsAtIndex:anIndex];
}
@@ -352,7 +367,7 @@ var _CPMenuBarVisible = NO,
while (count--)
[_items[count] setMenu:nil];
_highlightedIndex = CPNotFound;
[self _highlightItemAtIndex:CPNotFound];
// Because we are changing _items directly, be sure to notify KVO
[self willChangeValueForKey:@"items"];
@@ -366,7 +381,12 @@ var _CPMenuBarVisible = NO,
*/
- (void)itemChanged:(CPMenuItem)aMenuItem
{
if ([aMenuItem menu] !== self)
/*
During cib unarchiving, menu items will have a reference to their menu,
but of course the items are still being unarchived and the menu's _items
have not yet been instantiated. In that case we will not do anything here.
*/
if ([aMenuItem menu] !== self || !_items)
return;
[aMenuItem setValue:[aMenuItem valueForKey:@"changeCount"] + 1 forKey:@"changeCount"];
@@ -374,7 +394,7 @@ var _CPMenuBarVisible = NO,
[[CPNotificationCenter defaultCenter]
postNotificationName:CPMenuDidChangeItemNotification
object:self
userInfo:[CPDictionary dictionaryWithObject:[_items indexOfObjectIdenticalTo:aMenuItem] forKey:@"CPMenuItemIndex"]];
userInfo:@{ @"CPMenuItemIndex": [_items indexOfObjectIdenticalTo:aMenuItem] }];
}
// Finding Menu Items
@@ -607,15 +627,17 @@ var _CPMenuBarVisible = NO,
/*!
Enables or disables the receivers menu items.
If the target does not implement the menu item's action method the item is disabled.
If the target responsds to selector validateMenuItem: or validateUserInterfaceItem: (in that order) the return value is used.
If the item has no target, an action binding is checked. If the target does not implement
the menu item's action method or the binding's selector, the item is disabled.
If the target responds to selector validateMenuItem: or validateUserInterfaceItem: (in that order) the return value is used.
*/
- (void)update
{
if (![self autoenablesItems])
if (!_autoenablesItems)
return;
var items = [self itemArray];
for (var i = 0; i < [items count]; i++)
{
var item = [items objectAtIndex:i];
@@ -623,14 +645,51 @@ var _CPMenuBarVisible = NO,
if ([item hasSubmenu])
continue;
var validator = [CPApp targetForAction:[item action] to:[item target] from:item];
// If there are enabled bindings for the item, they override anything else
var binder = [CPBinder getBinding:CPEnabledBinding forObject:item];
if (!validator || ![validator respondsToSelector:[item action]])
[item setEnabled:NO];
if (binder)
{
[binder setValueFor:CPEnabledBinding];
[[_menuWindow _menuView] tile];
return;
}
var validator = [CPApp targetForAction:[item action] to:[item target] from:item],
shouldBeEnabled = YES;
if (!validator)
{
// If targetForAction: returns nil, it could be that there is no action.
// If there is an action and nil is returned, no valid target could be found.
if ([item action] || [item target])
shouldBeEnabled = NO;
else
{
// Check to see if there is a target binding with an invalid selector
var info = [CPBinder infoForBinding:CPTargetBinding forObject:item];
if (info)
{
var object = [info objectForKey:CPObservedObjectKey],
keyPath = [info objectForKey:CPObservedKeyPathKey],
options = [info objectForKey:CPOptionsKey],
target = [object valueForKeyPath:keyPath],
selector = [options valueForKey:CPSelectorNameBindingOption];
if (target && selector && ![target respondsToSelector:CPSelectorFromString(selector)])
shouldBeEnabled = NO;
}
}
}
else if (![validator respondsToSelector:[item action]])
shouldBeEnabled = NO;
else if ([validator respondsToSelector:@selector(validateMenuItem:)])
[item setEnabled:[validator validateMenuItem:item]];
shouldBeEnabled = [validator validateMenuItem:item];
else if ([validator respondsToSelector:@selector(validateUserInterfaceItem:)])
[item setEnabled:[validator validateUserInterfaceItem:item]];
shouldBeEnabled = [validator validateUserInterfaceItem:item];
[item setEnabled:shouldBeEnabled];
}
[[_menuWindow _menuView] tile];
@@ -675,7 +734,13 @@ var _CPMenuBarVisible = NO,
// highlightedItem is always enabled. Do there exist edge cases: disabling on closing a menu,
// etc.? Requires further investigation and tests.
if (highlightedItem && [highlightedItem isEnabled])
{
// Perform any action binding
var binding = [CPBinder getBinding:CPTargetBinding forObject:highlightedItem];
[binding invokeAction];
[CPApp sendAction:[highlightedItem action] to:[highlightedItem target] from:highlightedItem];
}
}
//
@@ -803,6 +868,9 @@ var _CPMenuBarVisible = NO,
+ (void)popUpContextMenu:(CPMenu)aMenu withEvent:(CPEvent)anEvent forView:(CPView)aView withFont:(CPFont)aFont
{
// This is needed when we are making several rights click
[[_CPMenuManager sharedMenuManager] cancelActiveMenu];
[aMenu _menuWillOpen];
if (!aFont)
@@ -886,9 +954,19 @@ var _CPMenuBarVisible = NO,
// Managing the Delegate
- (void)setDelegate:(id)aDelegate
- (void)setDelegate:(id <CPMenuDelegate>)aDelegate
{
if (_delegate === aDelegate)
return;
_delegate = aDelegate;
_implementedDelegateMethods = 0;
if ([_delegate respondsToSelector:@selector(menuWillOpen:)])
_implementedDelegateMethods |= CPMenuDelegate_menuWillOpen_;
if ([_delegate respondsToSelector:@selector(menuDidClose:)])
_implementedDelegateMethods |= CPMenuDelegate_menuDidClose_;
}
- (id)delegate
@@ -898,18 +976,16 @@ var _CPMenuBarVisible = NO,
- (void)_menuWillOpen
{
var delegate = [self delegate];
if ([delegate respondsToSelector:@selector(menuWillOpen:)])
[delegate menuWillOpen:self];
[self _sendDelegateMenuWillOpen];
}
- (void)_menuDidClose
{
var delegate = [self delegate];
// Remember which event caused this menu to close, if any. CPPopUpButton uses this to detect
// when a click on the button itself caused the menu to close.
_lastCloseEvent = [CPApp currentEvent];
if ([delegate respondsToSelector:@selector(menuDidClose:)])
[delegate menuDidClose:self];
[self _sendDelegateMenuDidClose];
}
// Handling Tracking
@@ -925,7 +1001,7 @@ var _CPMenuBarVisible = NO,
{
[CPApp sendEvent:[CPEvent
otherEventWithType:CPAppKitDefined
location:_CGPointMakeZero()
location:CGPointMakeZero()
modifierFlags:0
timestamp:0
windowNumber:0
@@ -1002,7 +1078,7 @@ var _CPMenuBarVisible = NO,
Sends the action of the menu item at the specified index.
@param anIndex the index of the item
*/
- (void)performActionForItemAtIndex:(unsigned)anIndex
- (void)performActionForItemAtIndex:(CPUInteger)anIndex
{
var item = _items[anIndex];
@@ -1073,6 +1149,36 @@ var _CPMenuBarVisible = NO,
@end
@implementation CPMenu (CPMenuDelegate)
/*!
@ignore
Call delegate menuWillOpen
*/
- (void)_sendDelegateMenuWillOpen
{
if (!(_implementedDelegateMethods & CPMenuDelegate_menuWillOpen_))
return;
[_delegate menuWillOpen:self];
}
/*!
@ignore
Call delegate menuDidClose
*/
- (void)_sendDelegateMenuDidClose
{
if (!(_implementedDelegateMethods & CPMenuDelegate_menuDidClose_))
return;
[_delegate menuDidClose:self];
}
@end
@implementation CPMenu (CPKeyValueCoding)
- (CPUInteger)countOfItems
@@ -1105,12 +1211,13 @@ var _CPMenuBarVisible = NO,
return;
[aMenuItem setMenu:self];
[self _highlightItemAtIndex:CPNotFound];
[_items insertObject:aMenuItem atIndex:anIndex];
[[CPNotificationCenter defaultCenter]
postNotificationName:CPMenuDidAddItemNotification
object:self
userInfo:[CPDictionary dictionaryWithObject:anIndex forKey:@"CPMenuItemIndex"]];
userInfo:@{ @"CPMenuItemIndex": anIndex }];
}
- (void)removeObjectFromItemsAtIndex:(CPUInteger)anIndex
@@ -1119,12 +1226,13 @@ var _CPMenuBarVisible = NO,
return;
[[_items objectAtIndex:anIndex] setMenu:nil];
[self _highlightItemAtIndex:CPNotFound];
[_items removeObjectAtIndex:anIndex];
[[CPNotificationCenter defaultCenter]
postNotificationName:CPMenuDidRemoveItemNotification
object:self
userInfo:[CPDictionary dictionaryWithObject:anIndex forKey:@"CPMenuItemIndex"]];
userInfo:@{ @"CPMenuItemIndex": anIndex }];
}
@end
@@ -1132,7 +1240,8 @@ var _CPMenuBarVisible = NO,
var CPMenuTitleKey = @"CPMenuTitleKey",
CPMenuNameKey = @"CPMenuNameKey",
CPMenuItemsKey = @"CPMenuItemsKey",
CPMenuShowsStateColumnKey = @"CPMenuShowsStateColumnKey";
CPMenuShowsStateColumnKey = @"CPMenuShowsStateColumnKey",
CPMenuAutoEnablesItemsKey = @"CPMenuAutoEnablesItemsKey";
@implementation CPMenu (CPCoding)
@@ -1154,7 +1263,7 @@ var CPMenuTitleKey = @"CPMenuTitleKey",
_showsStateColumn = ![aCoder containsValueForKey:CPMenuShowsStateColumnKey] || [aCoder decodeBoolForKey:CPMenuShowsStateColumnKey];
_autoenablesItems = YES;
_autoenablesItems = ![aCoder containsValueForKey:CPMenuAutoEnablesItemsKey] || [aCoder decodeBoolForKey:CPMenuAutoEnablesItemsKey];
[self setMinimumWidth:0];
}
@@ -1177,6 +1286,9 @@ var CPMenuTitleKey = @"CPMenuTitleKey",
if (!_showsStateColumn)
[aCoder encodeBool:_showsStateColumn forKey:CPMenuShowsStateColumnKey];
if (!_autoenablesItems)
[aCoder encodeBool:_autoenablesItems forKey:CPMenuAutoEnablesItemsKey];
}
@end
+49 -133
View File
@@ -1,18 +1,37 @@
/*
* _CPMenuBarWindow.j
* AppKit
*
* Created by Francisco Tolmasky.
* Copyright 2009, 280 North, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "CPPanel.j"
@import "_CPMenuWindow.j"
@import "_CPMenuManager.j"
@class _CPMenuView
@class CPMenu
var MENUBAR_HEIGHT = 28.0,
MENUBAR_MARGIN = 10.0,
MENUBAR_LEFT_MARGIN = 10.0,
MENUBAR_RIGHT_MARGIN = 10.0;
var _CPMenuBarWindowBackgroundColor = nil,
_CPMenuBarWindowFont = nil;
@global CPMenuDidAddItemNotification
@global CPMenuDidChangeItemNotification
@global CPMenuDidRemoveItemNotification
@implementation _CPMenuBarWindow : CPPanel
{
CPMenu _menu;
CPView _highlightView;
CPArray _menuItemViews;
@@ -32,19 +51,9 @@ var _CPMenuBarWindowBackgroundColor = nil,
CPColor _highlightTextShadowColor;
}
+ (void)initialize
{
if (self !== [_CPMenuBarWindow class])
return;
var bundle = [CPBundle bundleForClass:self];
_CPMenuBarWindowFont = [CPFont boldSystemFontOfSize:[CPFont systemFontSize]];
}
+ (CPFont)font
{
return _CPMenuBarWindowFont;
return [[CPTheme defaultTheme] valueForAttributeWithName:@"menu-bar-window-font" forClass:_CPMenuView];
}
- (id)init
@@ -52,12 +61,14 @@ var _CPMenuBarWindowBackgroundColor = nil,
// This only shows up in browser land, so don't bother calculating metrics in desktop.
var contentRect = [[CPPlatformWindow primaryPlatformWindow] contentBounds];
contentRect.size.height = MENUBAR_HEIGHT;
contentRect.size.height = [[CPTheme defaultTheme] valueForAttributeWithName:@"menu-bar-window-height" forClass:_CPMenuView];
self = [super initWithContentRect:contentRect styleMask:CPBorderlessWindowMask];
if (self)
{
_constrainsToUsableScreen = NO;
[self setLevel:CPMainMenuWindowLevel];
[self setAutoresizingMask:CPWindowWidthSizable];
@@ -119,12 +130,7 @@ var _CPMenuBarWindowBackgroundColor = nil,
- (void)setColor:(CPColor)aColor
{
if (!aColor)
{
if (!_CPMenuBarWindowBackgroundColor)
_CPMenuBarWindowBackgroundColor = [CPColor colorWithPatternImage:[[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:[_CPMenuBarWindow class]] pathForResource:@"_CPMenuBarWindow/_CPMenuBarWindowBackground.png"] size:CGSizeMake(1.0, 28.0)]];
[[self contentView] setBackgroundColor:_CPMenuBarWindowBackgroundColor];
}
[[self contentView] setBackgroundColor:[[CPTheme defaultTheme] valueForAttributeWithName:@"menu-bar-window-background-color" forClass:_CPMenuView]];
else
[[self contentView] setBackgroundColor:aColor];
}
@@ -137,6 +143,7 @@ var _CPMenuBarWindowBackgroundColor = nil,
_textColor = aColor;
[_menuItemViews makeObjectsPerformSelector:@selector(setTextColor:) withObject:_textColor];
[_menuItemViews makeObjectsPerformSelector:@selector(setParentMenuTextColor:) withObject:_textColor];
}
- (void)setTitleColor:(CPColor)aColor
@@ -157,6 +164,7 @@ var _CPMenuBarWindowBackgroundColor = nil,
_textShadowColor = aColor;
[_menuItemViews makeObjectsPerformSelector:@selector(setTextShadowColor:) withObject:_textShadowColor];
[_menuItemViews makeObjectsPerformSelector:@selector(setParentMenuTextShadowColor:) withObject:_textShadowColor];
}
- (void)setTitleShadowColor:(CPColor)aColor
@@ -175,6 +183,8 @@ var _CPMenuBarWindowBackgroundColor = nil,
return;
_highlightColor = aColor;
[_menuItemViews makeObjectsPerformSelector:@selector(setParentMenuHighlightColor:) withObject:_highlightColor];
}
- (void)setHighlightTextColor:(CPColor)aColor
@@ -184,7 +194,7 @@ var _CPMenuBarWindowBackgroundColor = nil,
_highlightTextColor = aColor;
// [_menuItemViews makeObjectsPerformSelector:@selector(setActivateColor:) withObject:_highlightTextColor];
[_menuItemViews makeObjectsPerformSelector:@selector(setParentMenuHighlightTextColor:) withObject:_highlightTextColor];
}
- (void)setHighlightTextShadowColor:(CPColor)aColor
@@ -194,7 +204,7 @@ var _CPMenuBarWindowBackgroundColor = nil,
_highlightTextShadowColor = aColor;
// [_menuItemViews makeObjectsPerformSelector:@selector(setActivateShadowColor:) withObject:_highlightTextShadowColor];
[_menuItemViews makeObjectsPerformSelector:@selector(setParentMenuHighlightTextShadowColor:) withObject:_highlightTextShadowColor];
}
- (void)setMenu:(CPMenu)aMenu
@@ -316,6 +326,11 @@ var _CPMenuBarWindowBackgroundColor = nil,
[self tile];
}
- (BOOL)acceptsFirstMouse:(CPEvent)anEvent
{
return YES;
}
- (void)mouseDown:(CPEvent)anEvent
{
var constraintRect = CGRectInset([[self platformWindow] visibleFrame], 5.0, 0.0);
@@ -344,7 +359,7 @@ var _CPMenuBarWindowBackgroundColor = nil,
index = 0,
count = items.length,
x = MENUBAR_LEFT_MARGIN,
x = [[CPTheme defaultTheme] valueForAttributeWithName:@"menu-bar-window-left-margin" forClass:_CPMenuView],
y = 0.0,
isLeftAligned = YES;
@@ -354,7 +369,7 @@ var _CPMenuBarWindowBackgroundColor = nil,
if ([item isSeparatorItem])
{
x = CGRectGetWidth([self frame]) - MENUBAR_RIGHT_MARGIN;
x = CGRectGetWidth([self frame]) - [[CPTheme defaultTheme] valueForAttributeWithName:@"menu-bar-window-right-margin" forClass:_CPMenuView];
isLeftAligned = NO;
continue;
@@ -368,13 +383,13 @@ var _CPMenuBarWindowBackgroundColor = nil,
if (isLeftAligned)
{
[menuItemView setFrame:CGRectMake(x, 0.0, CGRectGetWidth(frame), MENUBAR_HEIGHT)];
[menuItemView setFrame:CGRectMake(x, 0.0, CGRectGetWidth(frame), [[CPTheme defaultTheme] valueForAttributeWithName:@"menu-bar-window-height" forClass:_CPMenuView])];
x += CGRectGetWidth([menuItemView frame]);
}
else
{
[menuItemView setFrame:CGRectMake(x - CGRectGetWidth(frame), 0.0, CGRectGetWidth(frame), MENUBAR_HEIGHT)];
[menuItemView setFrame:CGRectMake(x - CGRectGetWidth(frame), 0.0, CGRectGetWidth(frame), [[CPTheme defaultTheme] valueForAttributeWithName:@"menu-bar-window-height" forClass:_CPMenuView])];
x = CGRectGetMinX([menuItemView frame]);
}
@@ -402,7 +417,7 @@ var _CPMenuBarWindowBackgroundColor = nil,
[super setFrame:aRect display:shouldDisplay animate:shouldAnimate];
if (!_CGSizeEqualToSize(size, aRect.size))
if (!CGSizeEqualToSize(size, aRect.size))
[self tile];
}
@@ -452,102 +467,3 @@ var _CPMenuBarWindowBackgroundColor = nil,
}
@end
@implementation _CPMenuBarView : _CPMenuView
{
}
- (CGRect)rectForItemAtIndex:(int)anIndex
{
return [_menuItemViews[anIndex === CPNotFound ? 0 : anIndex] frame];
}
- (int)itemIndexAtPoint:(CGPoint)aPoint
{
var bounds = [self bounds];
if (!CGRectContainsPoint(bounds, aPoint))
return CPNotFound;
var x = aPoint.x,
low = 0,
high = _visibleMenuItemInfos.length - 1;
while (low <= high)
{
var middle = FLOOR(low + (high - low) / 2),
info = _visibleMenuItemInfos[middle],
frame = [info.view frame];
if (x < CGRectGetMinX(frame))
high = middle - 1;
else if (x > CGRectGetMaxX(frame))
low = middle + 1;
else
return info.index;
}
return CPNotFound;
}
- (void)tile
{
var items = [_menu itemArray],
index = 0,
count = items.length,
x = MENUBAR_LEFT_MARGIN,
y = 0.0,
isLeftAligned = YES;
for (; index < count; ++index)
{
var item = items[index];
if ([item isSeparatorItem])
{
x = CGRectGetWidth([self frame]) - MENUBAR_RIGHT_MARGIN;
isLeftAligned = NO;
continue;
}
if ([item isHidden])
continue;
var menuItemView = [item _menuItemView],
frame = [menuItemView frame];
if (isLeftAligned)
{
[menuItemView setFrameOrigin:CGPointMake(x, (MENUBAR_HEIGHT - 1.0 - CGRectGetHeight(frame)) / 2.0)];
x += CGRectGetWidth([menuItemView frame]) + MENUBAR_MARGIN;
}
else
{
[menuItemView setFrameOrigin:CGPointMake(x - CGRectGetWidth(frame), (MENUBAR_HEIGHT - 1.0 - CGRectGetHeight(frame)) / 2.0)];
x = CGRectGetMinX([menuItemView frame]) - MENUBAR_MARGIN;
}
}
var bounds = [[self contentView] bounds],
titleFrame = [_titleField frame];
if ([_iconImageView isHidden])
[_titleField setFrameOrigin:CGPointMake((CGRectGetWidth(bounds) - CGRectGetWidth(titleFrame)) / 2.0, (CGRectGetHeight(bounds) - CGRectGetHeight(titleFrame)) / 2.0)];
else
{
var iconFrame = [_iconImageView frame],
iconWidth = CGRectGetWidth(iconFrame),
totalWidth = iconWidth + CGRectGetWidth(titleFrame);
[_iconImageView setFrameOrigin:CGPointMake((CGRectGetWidth(bounds) - totalWidth) / 2.0, (CGRectGetHeight(bounds) - CGRectGetHeight(iconFrame)) / 2.0)];
[_titleField setFrameOrigin:CGPointMake((CGRectGetWidth(bounds) - totalWidth) / 2.0 + iconWidth, (CGRectGetHeight(bounds) - CGRectGetHeight(titleFrame)) / 2.0)];
}
}
@end
+107 -32
View File
@@ -1,16 +1,51 @@
@import <Foundation/CPObject.j>
/*
* _CPMenuManager.j
* AppKit
*
* Created by Francisco Tolmasky.
* Copyright 2009, 280 North, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import <Foundation/CPObject.j>
@import <Foundation/CPNotificationCenter.j>
@import "CPEvent.j"
@import "CPKeyBinding.j"
@class CPWindow
@class _CPMenuWindow
@global CPApp
@global CPMenuDidEndTrackingNotification
@global _CPMenuWindowMenuBarBackgroundStyle
@global _CPMenuWindowPopUpBackgroundStyle
_CPMenuManagerScrollingStateUp = -1;
_CPMenuManagerScrollingStateDown = 1;
_CPMenuManagerScrollingStateNone = 0;
var STICKY_TIME_INTERVAL = 0.5,
var STICKY_TIME_INTERVAL = 0.4,
SharedMenuManager = nil;
@implementation _CPMenuManager: CPObject
{
CPTimeInterval _startTime;
CPEvent _openEvent;
BOOL _mouseWasDragged;
int _scrollingState;
CGPoint _lastGlobalLocation;
@@ -26,6 +61,8 @@ var STICKY_TIME_INTERVAL = 0.5,
CPMenuItem _previousActiveItem;
int _showTimerID;
int _menuBarButtonItemIndex;
}
+ (_CPMenuManager)sharedMenuManager
@@ -67,6 +104,7 @@ var STICKY_TIME_INTERVAL = 0.5,
CPApp._activeMenu = menu;
_startTime = [anEvent timestamp];
_openEvent = anEvent;
_scrollingState = _CPMenuManagerScrollingStateNone;
_constraintRect = aRect;
@@ -85,7 +123,7 @@ var STICKY_TIME_INTERVAL = 0.5,
activeItem = activeItemIndex !== CPNotFound ? [menu itemAtIndex:activeItemIndex] : nil;
_menuBarButtonItemIndex = activeItemIndex;
_menuBarButtonMenuContainer = aMenuContainer;
// _menuBarButtonMenuContainer = aMenuContainer;
if ([activeItem _isMenuBarButton])
return [self trackMenuBarButtonEvent:anEvent];
@@ -96,6 +134,11 @@ var STICKY_TIME_INTERVAL = 0.5,
[self trackEvent:anEvent];
}
- (void)_trackAgain
{
[CPApp setTarget:self selector:@selector(trackEvent:) forNextEventMatchingMask:CPKeyDownMask | CPPeriodicMask | CPMouseMovedMask | CPLeftMouseDraggedMask | CPLeftMouseDownMask | CPLeftMouseUpMask | CPRightMouseUpMask | CPAppKitDefinedMask | CPScrollWheelMask untilDate:nil inMode:nil dequeue:YES];
}
- (void)trackEvent:(CPEvent)anEvent
{
var type = [anEvent type],
@@ -105,8 +148,6 @@ var STICKY_TIME_INTERVAL = 0.5,
if (type === CPAppKitDefined)
return [self completeTracking];
[CPApp setTarget:self selector:@selector(trackEvent:) forNextEventMatchingMask:CPKeyDownMask | CPPeriodicMask | CPMouseMovedMask | CPLeftMouseDraggedMask | CPLeftMouseUpMask | CPRightMouseUpMask | CPAppKitDefinedMask | CPScrollWheelMask untilDate:nil inMode:nil dequeue:YES];
if (type === CPKeyDown)
{
var menu = trackingMenu,
@@ -122,23 +163,18 @@ var STICKY_TIME_INTERVAL = 0.5,
if ([menu numberOfItems])
[self interpretKeyEvent:anEvent forMenu:menu];
[self _trackAgain];
return;
}
if (_keyBuffer)
{
if (([anEvent timestamp] - _startTime) > (STICKY_TIME_INTERVAL + [activeMenu numberOfItems] / 2))
[self selectNextItemBeginningWith:_keyBuffer inMenu:menu clearBuffer:YES];
if (type === CPPeriodic)
return;
}
// Periodic events don't have a valid location.
var globalLocation = type === CPPeriodic ? _lastGlobalLocation : [anEvent globalLocation];
if (!globalLocation)
{
[self _trackAgain];
return;
}
// Find which menu window the mouse is currently on top of
var activeMenuContainer = [self menuContainerForPoint:globalLocation],
@@ -149,6 +185,35 @@ var STICKY_TIME_INTERVAL = 0.5,
activeItemIndex = activeMenuContainer ? [activeMenuContainer itemIndexAtPoint:menuLocation] : CPNotFound,
activeItem = activeItemIndex !== CPNotFound ? [activeMenu itemAtIndex:activeItemIndex] : nil;
/*
Click outside the menu structure?
The event which caused the menu to open is not considered even if it's
technically a click outside of an open menu, since this would mean the same
click which opened the menu could also close it. This is actually common.
E.g. you click on a button and it opens a menu below itself.
*/
if (type === CPLeftMouseDown && _openEvent !== anEvent && (!activeMenuContainer || !CGRectContainsPoint([activeMenuContainer globalFrame], globalLocation)))
{
[self completeTracking];
/*
You can close and interact with a control in a single click. E.g. you can have a menu open,
click on a button outside of it and have the menu immediately close and the button activate,
without having to click once to close the menu and once to activate the button.
Since we normally dequeue the event after tracking it, we'll have to put it back on the stack
in this special case. Note that it's important the event is executed /right now/, since certain
controls such as HTML upload buttons need a native click event at the top of the stack trace
to activate - it's not something we can fake later.
*/
[CPApp sendEvent:anEvent];
return;
}
[self _trackAgain];
// unhighlight when mouse is moved off the menu
if (_lastGlobalLocation && CGRectContainsPoint([activeMenuContainer globalFrame], _lastGlobalLocation)
&& !CGRectContainsPoint([activeMenuContainer globalFrame], globalLocation))
@@ -185,9 +250,9 @@ var STICKY_TIME_INTERVAL = 0.5,
if (_lastMouseOverMenuView != mouseOverMenuView)
{
[mouseOverMenuView mouseExited:anEvent];
[_lastMouseOverMenuView mouseExited:anEvent];
// FIXME: Possibly multiple of these?
[_lastMouseOverMenuView mouseEntered:anEvent];
[mouseOverMenuView mouseEntered:anEvent];
_lastMouseOverMenuView = mouseOverMenuView;
}
@@ -216,7 +281,7 @@ var STICKY_TIME_INTERVAL = 0.5,
_lastMouseOverMenuView = nil;
}
if (activeItemIndex != CPNotFound)
if (activeItemIndex !== CPNotFound)
[activeMenu _highlightItemAtIndex:activeItemIndex];
if (type === CPMouseMoved || type === CPLeftMouseDragged || type === CPLeftMouseDown || type === CPPeriodic)
@@ -342,6 +407,15 @@ var STICKY_TIME_INTERVAL = 0.5,
[menu cancelTracking];
}
- (void)cancelActiveMenu
{
if (CPApp._activeMenu)
{
[self completeTracking];
_menuContainerStack = [];
}
}
- (void)completeTracking
{
var trackingMenu = [self trackingMenu];
@@ -392,8 +466,8 @@ var STICKY_TIME_INTERVAL = 0.5,
{
var menuContainer = _menuContainerStack[index],
menuContainerFrame = [menuContainer globalFrame],
menuContainerMinX = _CGRectGetMinX(menuContainerFrame),
menuContainerMaxX = _CGRectGetMaxX(menuContainerFrame);
menuContainerMinX = CGRectGetMinX(menuContainerFrame),
menuContainerMaxX = CGRectGetMaxX(menuContainerFrame);
// If within the x bounds of this menu container, return it.
if (x < menuContainerMaxX && x >= menuContainerMinX)
@@ -489,6 +563,9 @@ var STICKY_TIME_INTERVAL = 0.5,
}
else if (!(modifierFlags & (CPCommandKeyMask | CPControlKeyMask)))
{
if (([anEvent timestamp] - _startTime) > STICKY_TIME_INTERVAL)
_keyBuffer = nil;
if (!_keyBuffer)
{
_startTime = [anEvent timestamp];
@@ -500,12 +577,12 @@ var STICKY_TIME_INTERVAL = 0.5,
else
_keyBuffer += character;
[self selectNextItemBeginningWith:_keyBuffer inMenu:menu clearBuffer:NO];
_lastGlobalLocation = Nil;
[self selectNextItemBeginningWith:_keyBuffer inMenu:menu];
_lastGlobalLocation = nil;
}
}
- (void)selectNextItemBeginningWith:(CPString)characters inMenu:(CPMenu)menu clearBuffer:(BOOL)shouldClear
- (void)selectNextItemBeginningWith:(CPString)characters inMenu:(CPMenu)menu
{
var iter = [[menu itemArray] objectEnumerator],
obj;
@@ -522,13 +599,7 @@ var STICKY_TIME_INTERVAL = 0.5,
}
}
if (shouldClear)
{
[CPEvent stopPeriodicEvents];
_keyBuffer = Nil;
}
else
_startTime = [CPEvent currentTimestamp];
_startTime = [CPEvent currentTimestamp];
}
- (void)scrollToBeginningOfDocument:(CPMenu)menu
@@ -556,7 +627,7 @@ var STICKY_TIME_INTERVAL = 0.5,
return;
}
next = current + (last - first);
var next = current + (last - first);
if (next < [menu numberOfItems])
[menu _highlightItemAtIndex:next];
@@ -584,7 +655,7 @@ var STICKY_TIME_INTERVAL = 0.5,
return;
}
next = current - (last - first);
var next = current - (last - first);
if (next < 0)
[menu _highlightItemAtIndex:0];
@@ -665,6 +736,8 @@ var STICKY_TIME_INTERVAL = 0.5,
if ([item isSeparatorItem] || [item isHidden] || ![item isEnabled])
[self moveDown:menu];
}
else if (menu == [CPApp mainMenu])
[menu _highlightItemAtIndex:0];
}
- (void)moveUp:(CPMenu)menu
@@ -673,10 +746,12 @@ var STICKY_TIME_INTERVAL = 0.5,
if (index < 0)
{
if (index != CPNotFound)
if (index != CPNotFound || menu == [CPApp mainMenu])
[menu _highlightItemAtIndex:[menu numberOfItems] - 1];
return;
}
[menu _highlightItemAtIndex:index];
var item = [menu highlightedItem];
+106 -82
View File
@@ -1,5 +1,31 @@
@import "CPWindow.j"
/*
* _CPMenuWindow.j
* AppKit
*
* Created by Francisco Tolmasky.
* Copyright 2009, 280 North, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "CPClipView.j"
@import "CPImageView.j"
@import "CPWindow.j"
@import "_CPMenuManager.j"
@class _CPMenuView
var _CPMenuWindowPool = [],
_CPMenuWindowPoolCapacity = 5,
@@ -10,15 +36,6 @@ _CPMenuWindowMenuBarBackgroundStyle = 0;
_CPMenuWindowPopUpBackgroundStyle = 1;
_CPMenuWindowAttachedMenuBackgroundStyle = 2;
var STICKY_TIME_INTERVAL = 500,
TOP_MARGIN = 5.0,
LEFT_MARGIN = 1.0,
RIGHT_MARGIN = 1.0,
BOTTOM_MARGIN = 5.0,
SCROLL_INDICATOR_HEIGHT = 16.0;
/*
@ignore
*/
@@ -57,32 +74,24 @@ var STICKY_TIME_INTERVAL = 500,
+ (void)poolMenuWindow:(_CPMenuWindow)aMenuWindow
{
if (!aMenuWindow || _CPMenuWindowPool.length >= _CPMenuWindowPoolCapacity)
// FIXME :the poolMenuWindow is called too many times somewhere....
if (!aMenuWindow || _CPMenuWindowPool.length >= _CPMenuWindowPoolCapacity || [_CPMenuWindowPool containsObject:aMenuWindow])
return;
_CPMenuWindowPool.push(aMenuWindow);
}
+ (void)initialize
{
if (self !== [_CPMenuWindow class])
return;
var bundle = [CPBundle bundleForClass:self];
_CPMenuWindowMoreAboveImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuWindow/_CPMenuWindowMoreAbove.png"] size:CGSizeMake(38.0, 18.0)];
_CPMenuWindowMoreBelowImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuWindow/_CPMenuWindowMoreBelow.png"] size:CGSizeMake(38.0, 18.0)];
}
- (id)initWithContentRect:(CGRect)aRect styleMask:(unsigned)aStyleMask
{
_constraintRect = _CGRectMakeZero();
_unconstrainedFrame = _CGRectMakeZero();
_constraintRect = CGRectMakeZero();
_unconstrainedFrame = CGRectMakeZero();
self = [super initWithContentRect:aRect styleMask:CPBorderlessWindowMask];
if (self)
{
_constrainsToUsableScreen = NO;
[self setLevel:CPPopUpMenuWindowLevel];
[self setHasShadow:YES];
[self setShadowStyle:CPMenuWindowShadowStyle];
@@ -92,22 +101,22 @@ var STICKY_TIME_INTERVAL = 500,
_menuView = [[_CPMenuView alloc] initWithFrame:CGRectMakeZero()];
_menuClipView = [[CPClipView alloc] initWithFrame:CGRectMake(LEFT_MARGIN, TOP_MARGIN, 0.0, 0.0)];
_menuClipView = [[CPClipView alloc] initWithFrame:CGRectMake([_menuView valueForThemeAttribute:@"menu-window-margin-inset"].left, [_menuView valueForThemeAttribute:@"menu-window-margin-inset"].top, 0.0, 0.0)];
[_menuClipView setDocumentView:_menuView];
[contentView addSubview:_menuClipView];
_moreAboveView = [[CPImageView alloc] initWithFrame:CGRectMakeZero()];
[_moreAboveView setImage:_CPMenuWindowMoreAboveImage];
[_moreAboveView setFrameSize:[_CPMenuWindowMoreAboveImage size]];
[_moreAboveView setImage:[_menuView valueForThemeAttribute:@"menu-window-more-above-image"]];
[_moreAboveView setFrameSize:[[_menuView valueForThemeAttribute:@"menu-window-more-above-image"] size]];
[contentView addSubview:_moreAboveView];
_moreBelowView = [[CPImageView alloc] initWithFrame:CGRectMakeZero()];
[_moreBelowView setImage:_CPMenuWindowMoreBelowImage];
[_moreBelowView setFrameSize:[_CPMenuWindowMoreBelowImage size]];
[_moreBelowView setImage:[_menuView valueForThemeAttribute:@"menu-window-more-below-image"]];
[_moreBelowView setFrameSize:[[_menuView valueForThemeAttribute:@"menu-window-more-below-image"] size]];
[contentView addSubview:_moreBelowView];
}
@@ -117,7 +126,7 @@ var STICKY_TIME_INTERVAL = 500,
+ (float)_standardLeftMargin
{
return LEFT_MARGIN;
return [[CPTheme defaultTheme] valueForAttributeWithName:@"menu-window-margin-inset" forClass:_CPMenuView].left;
}
- (void)setFont:(CPFont)aFont
@@ -139,36 +148,10 @@ var STICKY_TIME_INTERVAL = 500,
var bundle = [CPBundle bundleForClass:[self class]];
if (aBackgroundStyle == _CPMenuWindowPopUpBackgroundStyle)
color = [CPColor colorWithPatternImage:[[CPNinePartImage alloc] initWithImageSlices:
[
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuWindow/_CPMenuWindowRounded0.png"] size:CGSizeMake(4.0, 4.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuWindow/_CPMenuWindow1.png"] size:CGSizeMake(1.0, 4.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuWindow/_CPMenuWindowRounded2.png"] size:CGSizeMake(4.0, 4.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuWindow/_CPMenuWindow3.png"] size:CGSizeMake(4.0, 1.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuWindow/_CPMenuWindow4.png"] size:CGSizeMake(1.0, 1.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuWindow/_CPMenuWindow5.png"] size:CGSizeMake(4.0, 1.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuWindow/_CPMenuWindowRounded6.png"] size:CGSizeMake(4.0, 4.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuWindow/_CPMenuWindow7.png"] size:CGSizeMake(1.0, 4.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuWindow/_CPMenuWindowRounded8.png"] size:CGSizeMake(4.0, 4.0)]
]]];
color = [[CPTheme defaultTheme] valueForAttributeWithName:@"menu-window-pop-up-background-style-color" forClass:_CPMenuView];
else if (aBackgroundStyle == _CPMenuWindowMenuBarBackgroundStyle)
color = [CPColor colorWithPatternImage:[[CPNinePartImage alloc] initWithImageSlices:
[
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuWindow/_CPMenuWindow3.png"] size:CGSizeMake(4.0, 0.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuWindow/_CPMenuWindow4.png"] size:CGSizeMake(1.0, 0.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuWindow/_CPMenuWindow5.png"] size:CGSizeMake(4.0, 0.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuWindow/_CPMenuWindow3.png"] size:CGSizeMake(4.0, 1.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuWindow/_CPMenuWindow4.png"] size:CGSizeMake(1.0, 1.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuWindow/_CPMenuWindow5.png"] size:CGSizeMake(4.0, 1.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuWindow/_CPMenuWindowRounded6.png"] size:CGSizeMake(4.0, 4.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuWindow/_CPMenuWindow7.png"] size:CGSizeMake(1.0, 4.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuWindow/_CPMenuWindowRounded8.png"] size:CGSizeMake(4.0, 4.0)]
]]];
color = [[CPTheme defaultTheme] valueForAttributeWithName:@"menu-window-menu-bar-background-style-color" forClass:_CPMenuView];
_CPMenuWindowBackgroundColors[aBackgroundStyle] = color;
}
@@ -186,12 +169,13 @@ var STICKY_TIME_INTERVAL = 500,
[aMenu _setMenuWindow:self];
[_menuView setMenu:aMenu];
var menuViewSize = [_menuView frame].size;
var menuViewSize = [_menuView frame].size,
marginInset = [_menuView valueForThemeAttribute:@"menu-window-margin-inset"];
[self setFrameSize:CGSizeMake(LEFT_MARGIN + menuViewSize.width + RIGHT_MARGIN, TOP_MARGIN + menuViewSize.height + BOTTOM_MARGIN)];
[self setFrameSize:CGSizeMake(marginInset.left + menuViewSize.width + marginInset.right, marginInset.top + menuViewSize.height + marginInset.bottom)];
[_menuView scrollPoint:CGPointMake(0.0, 0.0)];
[_menuClipView setFrame:CGRectMake(LEFT_MARGIN, TOP_MARGIN, menuViewSize.width, menuViewSize.height)];
[_menuClipView setFrame:CGRectMake(marginInset.left, marginInset.top, menuViewSize.width, menuViewSize.height)];
}
- (void)setMinWidth:(float)aWidth
@@ -228,28 +212,30 @@ var STICKY_TIME_INTERVAL = 500,
- (CGRect)unconstrainedFrame
{
return _CGRectMakeCopy(_unconstrainedFrame);
return CGRectMakeCopy(_unconstrainedFrame);
}
// We need this because if not this will call setFrame: with -frame instead of -unconstrainedFrame, turning
// the constrained frame into the unconstrained frame.
- (void)setFrameOrigin:(CGPoint)aPoint
{
[super setFrame:_CGRectMake(aPoint.x, aPoint.y, _CGRectGetWidth(_unconstrainedFrame), _CGRectGetHeight(_unconstrainedFrame))];
[super setFrame:CGRectMake(aPoint.x, aPoint.y, CGRectGetWidth(_unconstrainedFrame), CGRectGetHeight(_unconstrainedFrame))];
}
- (void)setFrameSize:(CGSize)aSize
{
[super setFrame:_CGRectMake(_CGRectGetMinX(_unconstrainedFrame), _CGRectGetMinY(_unconstrainedFrame), aSize.width, aSize.height)];
[super setFrame:CGRectMake(CGRectGetMinX(_unconstrainedFrame), CGRectGetMinY(_unconstrainedFrame), aSize.width, aSize.height)];
}
- (void)setFrame:(CGRect)aFrame display:(BOOL)shouldDisplay animate:(BOOL)shouldAnimate
{
// FIXME: There are integral window issues with platform windows.
// FIXME: This gets called far too often.
_unconstrainedFrame = _CGRectMakeCopy(aFrame);
_unconstrainedFrame = CGRectMakeCopy(aFrame);
var constrainedFrame = CGRectIntersection(_unconstrainedFrame, _constraintRect);
var constrainedFrame = CGRectIntersection(_unconstrainedFrame, _constraintRect),
marginInset = [_menuView valueForThemeAttribute:@"menu-window-margin-inset"],
scrollIndicatorHeight = [_menuView valueForThemeAttribute:@"menu-window-scroll-indicator-height"];
// We don't want to simply intersect the visible frame and the unconstrained frame.
// We should be allowing as much of the width to fit as possible (pushing back and forward).
@@ -268,41 +254,41 @@ var STICKY_TIME_INTERVAL = 500,
[super setFrame:constrainedFrame display:shouldDisplay animate:shouldAnimate];
// This needs to happen before changing the frame.
var menuViewOrigin = CGPointMake(CGRectGetMinX(aFrame) + LEFT_MARGIN, CGRectGetMinY(aFrame) + TOP_MARGIN),
moreAbove = menuViewOrigin.y < CGRectGetMinY(constrainedFrame) + TOP_MARGIN,
moreBelow = menuViewOrigin.y + CGRectGetHeight([_menuView frame]) > CGRectGetMaxY(constrainedFrame) - BOTTOM_MARGIN,
var menuViewOrigin = CGPointMake(CGRectGetMinX(aFrame) + marginInset.left, CGRectGetMinY(aFrame) + marginInset.top),
moreAbove = menuViewOrigin.y < CGRectGetMinY(constrainedFrame) + marginInset.top,
moreBelow = menuViewOrigin.y + CGRectGetHeight([_menuView frame]) > CGRectGetMaxY(constrainedFrame) - marginInset.bottom,
topMargin = TOP_MARGIN,
bottomMargin = BOTTOM_MARGIN,
topMargin = marginInset.top,
bottomMargin = marginInset.bottom,
contentView = [self contentView],
bounds = [contentView bounds];
if (moreAbove)
{
topMargin += SCROLL_INDICATOR_HEIGHT;
topMargin += scrollIndicatorHeight;
var frame = [_moreAboveView frame];
[_moreAboveView setFrameOrigin:CGPointMake((CGRectGetWidth(bounds) - CGRectGetWidth(frame)) / 2.0, (TOP_MARGIN + SCROLL_INDICATOR_HEIGHT - CGRectGetHeight(frame)) / 2.0)];
[_moreAboveView setFrameOrigin:CGPointMake((CGRectGetWidth(bounds) - CGRectGetWidth(frame)) / 2.0, (marginInset.top + scrollIndicatorHeight - CGRectGetHeight(frame)) / 2.0)];
}
[_moreAboveView setHidden:!moreAbove];
if (moreBelow)
{
bottomMargin += SCROLL_INDICATOR_HEIGHT;
bottomMargin += scrollIndicatorHeight;
[_moreBelowView setFrameOrigin:CGPointMake((CGRectGetWidth(bounds) - CGRectGetWidth([_moreBelowView frame])) / 2.0, CGRectGetHeight(bounds) - SCROLL_INDICATOR_HEIGHT - BOTTOM_MARGIN)];
[_moreBelowView setFrameOrigin:CGPointMake((CGRectGetWidth(bounds) - CGRectGetWidth([_moreBelowView frame])) / 2.0, CGRectGetHeight(bounds) - scrollIndicatorHeight - marginInset.bottom)];
}
[_moreBelowView setHidden:!moreBelow];
var clipFrame = CGRectMakeZero();
clipFrame.origin.x = LEFT_MARGIN;
clipFrame.origin.x = marginInset.left;
clipFrame.origin.y = topMargin;
clipFrame.size.width = CGRectGetWidth(constrainedFrame) - LEFT_MARGIN - RIGHT_MARGIN;
clipFrame.size.width = CGRectGetWidth(constrainedFrame) - marginInset.left - marginInset.right;
clipFrame.size.height = CGRectGetHeight(constrainedFrame) - topMargin - bottomMargin;
[_menuClipView setFrame:clipFrame];
@@ -398,15 +384,15 @@ var STICKY_TIME_INTERVAL = 500,
- (_CPManagerScrollingState)scrollingStateForPoint:(CGPoint)aGlobalLocation
{
var frame = [self frame];
if (!CPRectContainsPoint(frame,aGlobalLocation) || ![self canScroll])
if (!CGRectContainsPoint(frame,aGlobalLocation) || ![self canScroll])
return _CPMenuManagerScrollingStateNone;
// If we're at or above of the top scroll indicator...
if (aGlobalLocation.y < CGRectGetMinY(frame) + TOP_MARGIN + SCROLL_INDICATOR_HEIGHT && ![_moreAboveView isHidden])
if (aGlobalLocation.y < CGRectGetMinY(frame) + [_menuView valueForThemeAttribute:@"menu-window-margin-inset"].top + [_menuView valueForThemeAttribute:@"menu-window-scroll-indicator-height"] && ![_moreAboveView isHidden])
return _CPMenuManagerScrollingStateUp;
// If we're at or below the bottom scroll indicator...
if (aGlobalLocation.y > CGRectGetMaxY(frame) - BOTTOM_MARGIN - SCROLL_INDICATOR_HEIGHT && ![_moreBelowView isHidden])
if (aGlobalLocation.y > CGRectGetMaxY(frame) - [_menuView valueForThemeAttribute:@"menu-window-margin-inset"].bottom - [_menuView valueForThemeAttribute:@"menu-window-scroll-indicator-height"] && ![_moreBelowView isHidden])
return _CPMenuManagerScrollingStateDown;
return _CPMenuManagerScrollingStateNone;
@@ -414,7 +400,7 @@ var STICKY_TIME_INTERVAL = 500,
- (float)deltaYForItemAtIndex:(int)anIndex
{
return TOP_MARGIN + CGRectGetMinY([_menuView rectForItemAtIndex:anIndex]);
return [_menuView valueForThemeAttribute:@"menu-window-margin-inset"].top + CGRectGetMinY([_menuView rectForItemAtIndex:anIndex]);
}
- (CGPoint)rectForItemAtIndex:(int)anIndex
@@ -426,7 +412,7 @@ var STICKY_TIME_INTERVAL = 500,
{
// Don't return indexes of items that aren't visible.
if (!CGRectContainsPoint([_menuClipView bounds], [_menuClipView convertPoint:aPoint fromView:nil]))
return NO;
return CPNotFound;
return [_menuView itemIndexAtPoint:[_menuView convertPoint:aPoint fromView:nil]];
}
@@ -445,6 +431,44 @@ var STICKY_TIME_INTERVAL = 500,
CPFont _font @accessors(property=font);
}
+ (CPString)defaultThemeClass
{
return "menu-view";
}
+ (CPDictionary)themeAttributes
{
return @{
@"menu-window-more-above-image": [CPNull null],
@"menu-window-more-below-image": [CPNull null],
@"menu-window-pop-up-background-style-color": [CPNull null],
@"menu-window-menu-bar-background-style-color": [CPNull null],
@"menu-window-margin-inset": CGInsetMake(5.0, 1.0, 1.0, 5.0),
@"menu-window-scroll-indicator-height": 16.0,
@"menu-bar-window-background-color": [CPNull null],
@"menu-bar-window-background-selected-color": [CPNull null],
@"menu-bar-window-font": [CPNull null],
@"menu-bar-window-height": 30.0,
@"menu-bar-window-margin": 10.0,
@"menu-bar-window-left-margin": 10.0,
@"menu-bar-window-right-margin": 10.0,
@"menu-bar-text-color": [CPNull null],
@"menu-bar-title-color": [CPNull null],
@"menu-bar-text-shadow-color": [CPNull null],
@"menu-bar-title-shadow-color": [CPNull null],
@"menu-bar-highlight-color": [CPNull null],
@"menu-bar-highlight-text-color": [CPNull null],
@"menu-bar-highlight-text-shadow-color": [CPNull null],
@"menu-bar-height": 28.0,
@"menu-bar-icon-image": [CPNull null],
@"menu-bar-icon-image-alpha-value": 1.0,
@"menu-general-icon-new": [CPNull null],
@"menu-general-icon-save": [CPNull null],
@"menu-general-icon-open": [CPNull null],
};
}
- (unsigned)numberOfUnhiddenItems
{
return _visibleMenuItemInfos.length;
+38 -21
View File
@@ -25,29 +25,33 @@
@import <Foundation/CPString.j>
@import "CPImage.j"
@import "CPMenu.j"
@import "CPText.j"
@import "CPView.j"
@import "_CPMenuItemView.j"
@class CPMenu
var CPMenuItemStringRepresentationDictionary = [CPDictionary dictionary];
[CPMenuItemStringRepresentationDictionary setObject:"\u238B" forKey:CPEscapeFunctionKey];
[CPMenuItemStringRepresentationDictionary setObject:"\u21E5" forKey:CPTabCharacter];
[CPMenuItemStringRepresentationDictionary setObject:"\u21E4" forKey:CPBackTabCharacter];
[CPMenuItemStringRepresentationDictionary setObject:"\u2423" forKey:CPSpaceFunctionKey];
[CPMenuItemStringRepresentationDictionary setObject:"\u23CE" forKey:CPCarriageReturnCharacter];
[CPMenuItemStringRepresentationDictionary setObject:"\u232B" forKey:CPBackspaceCharacter];
[CPMenuItemStringRepresentationDictionary setObject:"\u232B" forKey:CPDeleteFunctionKey];
[CPMenuItemStringRepresentationDictionary setObject:"\u2326" forKey:CPDeleteCharacter];
[CPMenuItemStringRepresentationDictionary setObject:"\u21F1" forKey:CPHomeFunctionKey];
[CPMenuItemStringRepresentationDictionary setObject:"\u21F2" forKey:CPEndFunctionKey];
[CPMenuItemStringRepresentationDictionary setObject:"\u21DE" forKey:CPPageUpFunctionKey];
[CPMenuItemStringRepresentationDictionary setObject:"\u21DF" forKey:CPPageDownFunctionKey];
[CPMenuItemStringRepresentationDictionary setObject:"\u2191" forKey:CPUpArrowFunctionKey];
[CPMenuItemStringRepresentationDictionary setObject:"\u2193" forKey:CPDownArrowFunctionKey];
[CPMenuItemStringRepresentationDictionary setObject:"\u2190" forKey:CPLeftArrowFunctionKey];
[CPMenuItemStringRepresentationDictionary setObject:"\u2192" forKey:CPRightArrowFunctionKey];
[CPMenuItemStringRepresentationDictionary setObject:"\u2327" forKey:CPClearDisplayFunctionKey];
@global CPApp
var CPMenuItemStringRepresentationDictionary = @{
CPEscapeFunctionKey: "\u238B",
CPTabCharacter: "\u21E5",
CPBackTabCharacter: "\u21E4",
CPSpaceFunctionKey: "\u2423",
CPCarriageReturnCharacter: "\u23CE",
CPBackspaceCharacter: "\u232B",
CPDeleteFunctionKey: "\u232B",
CPDeleteCharacter: "\u2326",
CPHomeFunctionKey: "\u21F1",
CPEndFunctionKey: "\u21F2",
CPPageUpFunctionKey: "\u21DE",
CPPageDownFunctionKey: "\u21DF",
CPUpArrowFunctionKey: "\u2191",
CPDownArrowFunctionKey: "\u2193",
CPLeftArrowFunctionKey: "\u2190",
CPRightArrowFunctionKey: "\u2192",
CPClearDisplayFunctionKey: "\u2327",
};
/*!
@ingroup appkit
@@ -101,6 +105,16 @@ var CPMenuItemStringRepresentationDictionary = [CPDictionary dictionary];
_CPMenuItemView _menuItemView;
}
+ (Class)_binderClassForBinding:(CPString)aBinding
{
if ([aBinding hasPrefix:CPEnabledBinding])
return [CPMultipleValueAndBinding class];
else if (aBinding === CPTargetBinding || [aBinding hasPrefix:CPArgumentBinding])
return [CPActionBinding class];
return [super _binderClassForBinding:aBinding];
}
- (id)init
{
return [self initWithTitle:@"" action:nil keyEquivalent:nil];
@@ -152,6 +166,9 @@ var CPMenuItemStringRepresentationDictionary = [CPDictionary dictionary];
if (_isEnabled === isEnabled)
return;
if (!isEnabled && [self isHighlighted])
[_menu _highlightItemAtIndex:CPNotFound];
_isEnabled = !!isEnabled;
[_menuItemView setDirty];
@@ -488,7 +505,7 @@ CPOffState
if (_submenu)
{
[_submenu setSupermenu:_menu];
[_submenu setTitle:[self title]]
[_submenu setTitle:[self title]];
[self setTarget:_menu];
[self setAction:@selector(submenuAction:)];
@@ -826,7 +843,7 @@ CPControlKeyMask
[item setTarget:_target];
[item setAction:_action];
[item setEnabled:_isEnabled];
[item setHidden:_isHidden]
[item setHidden:_isHidden];
[item setTag:_tag];
[item setState:_state];
[item setImage:_image];
+108 -138
View File
@@ -1,54 +1,62 @@
@import "CPView.j"
/*
* _CPMenuItemMenuBarView.j
* AppKit
*
* Created by Francisco Tolmasky.
* Copyright 2009, 280 North, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "CPControl.j"
@import "_CPImageAndTextView.j"
var HORIZONTAL_MARGIN = 8.0,
SUBMENU_INDICATOR_MARGIN = 3.0,
VERTICAL_MARGIN = 4.0;
var SelectionColor = nil,
SUBMENU_INDICATOR_COLOR = nil,
_CPMenuItemSelectionColor = nil,
_CPMenuItemTextShadowColor = nil,
_CPMenuItemDefaultStateImages = [],
_CPMenuItemDefaultStateHighlightedImages = [];
@class _CPMenuBarWindow
@class _CPMenuView
@class CPMenuItem
@implementation _CPMenuItemMenuBarView : CPView
{
CPColor _highlightColor @accessors(property=highlightColor);
CPColor _textColor @accessors(property=textColor);
CPColor _textShadowColor @accessors(property=textShadowColor);
CPColor _highlightTextColor @accessors(property=highlightTextColor);
CPColor _highlightTextShadowColor @accessors(property=highlightTextShadowColor);
CPMenuItem _menuItem @accessors(property=menuItem);
CPFont _font;
CPColor _textColor;
CPColor _textShadowColor;
BOOL _isDirty;
BOOL _shouldHighlight;
_CPImageAndTextView _imageAndTextView;
CPView _submenuIndicatorView;
}
+ (void)initialize
+ (CPString)defaultThemeClass
{
if (self !== [_CPMenuItemMenuBarView class])
return;
return "menu-item-bar-view";
}
var bundle = [CPBundle bundleForClass:self];
SelectionColor = [CPColor colorWithPatternImage:[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuBarWindow/_CPMenuBarWindowBackgroundSelected.png"] size:CGSizeMake(1.0, 28.0)]];
SUBMENU_INDICATOR_COLOR = [CPColor grayColor];
_CPMenuItemSelectionColor = [CPColor colorWithCalibratedRed:95.0 / 255.0 green:131.0 / 255.0 blue:185.0 / 255.0 alpha:1.0];
_CPMenuItemTextShadowColor = [CPColor colorWithCalibratedRed:26.0 / 255.0 green: 73.0 / 255.0 blue:109.0 / 255.0 alpha:1.0];
_CPMenuItemDefaultStateImages[CPOffState] = nil;
_CPMenuItemDefaultStateHighlightedImages[CPOffState] = nil;
_CPMenuItemDefaultStateImages[CPOnState] = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPMenuItem/CPMenuItemOnState.png"] size:CGSizeMake(14.0, 14.0)];
_CPMenuItemDefaultStateHighlightedImages[CPOnState] = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPMenuItem/CPMenuItemOnStateHighlighted.png"] size:CGSizeMake(14.0, 14.0)];
_CPMenuItemDefaultStateImages[CPMixedState] = nil;
_CPMenuItemDefaultStateHighlightedImages[CPMixedState] = nil;
+ (CPDictionary)themeAttributes
{
return @{
@"horizontal-margin": 9.0,
@"submenu-indicator-margin": 3.0,
@"vertical-margin": 4.0,
};
}
+ (id)view
@@ -62,7 +70,7 @@ var SelectionColor = nil,
if (self)
{
_imageAndTextView = [[_CPImageAndTextView alloc] initWithFrame:CGRectMake(HORIZONTAL_MARGIN, 0.0, 0.0, 0.0)];
_imageAndTextView = [[_CPImageAndTextView alloc] initWithFrame:CGRectMake([self valueForThemeAttribute:@"horizontal-margin"], 0.0, 0.0, 0.0)];
[_imageAndTextView setImagePosition:CPImageLeft];
[_imageAndTextView setImageOffset:3.0];
@@ -71,86 +79,98 @@ var SelectionColor = nil,
[self addSubview:_imageAndTextView];
_submenuIndicatorView = [[_CPMenuItemMenuBarSubmenuIndicatorView alloc] initWithFrame:CGRectMake(0.0, 0.0, 9.0, 6.0)];
[_submenuIndicatorView setAutoresizingMask:CPViewMinYMargin | CPViewMaxYMargin];
[self addSubview:_submenuIndicatorView];
[self setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
}
return self;
}
- (void)setTextColor:(CPColor)aColor
{
_textColor = aColor;
[self setNeedsLayout];
}
- (void)setTextShadowColor:(CPColor)aColor
{
_textShadowColor = aColor;
[self setNeedsLayout];
}
- (void)setHighlightTextColor:(CPColor)aColor
{
_highlightTextColor = aColor;
[self setNeedsLayout];
}
- (void)setHighlightTextShadowColor:(CPColor)aColor
{
_highlightTextShadowColor = aColor;
[self setNeedsLayout];
}
- (CPColor)textColor
{
if (![_menuItem isEnabled])
return [CPColor lightGrayColor];
return _textColor || [CPColor colorWithCalibratedRed:70.0 / 255.0 green:69.0 / 255.0 blue:69.0 / 255.0 alpha:1.0];
return _textColor || [[CPTheme defaultTheme] valueForAttributeWithName:@"menu-bar-text-color" forClass:_CPMenuView];
}
- (CPColor)textShadowColor
{
if (![_menuItem isEnabled])
return [CPColor colorWithWhite:0.8 alpha:0.8];
return [CPColor clearColor];
return _textShadowColor || [CPColor colorWithWhite:1.0 alpha:0.8];
return _textShadowColor || [[CPTheme defaultTheme] valueForAttributeWithName:@"menu-bar-text-shadow-color" forClass:_CPMenuView];
}
- (CPColor)highlightTextColor
{
if (![_menuItem isEnabled])
return [CPColor lightGrayColor];
return _highlightTextColor || [[CPTheme defaultTheme] valueForAttributeWithName:@"menu-bar-highlight-text-color" forClass:_CPMenuView];
}
- (CPColor)highlightTextShadowColor
{
if (![_menuItem isEnabled])
return [CPColor clearColor];
return _highlightTextShadowColor || [[CPTheme defaultTheme] valueForAttributeWithName:@"menu-bar-highlight-text-shadow-color" forClass:_CPMenuView];
}
- (CPColor)highlightColor
{
return _highlightColor || [[CPTheme defaultTheme] valueForAttributeWithName:@"menu-bar-window-background-selected-color" forClass:_CPMenuView];
}
- (void)update
{
var x = HORIZONTAL_MARGIN,
var x = [self valueForThemeAttribute:@"horizontal-margin"],
height = 0.0;
[_imageAndTextView setText:[_menuItem title]];
[_imageAndTextView setFont:[_menuItem font] || [_CPMenuBarWindow font]];
[_imageAndTextView setVerticalAlignment:CPCenterVerticalTextAlignment];
[_imageAndTextView setImage:[_menuItem image]];
[_imageAndTextView setText:[_menuItem title]];
[_imageAndTextView setTextColor:[self textColor]];
[_imageAndTextView setTextShadowColor:[self textShadowColor]];
[_imageAndTextView setTextShadowOffset:CGSizeMake(0.0, 1.0)];
[_imageAndTextView setImage:[_menuItem image]];
[_imageAndTextView sizeToFit];
var imageAndTextViewFrame = [_imageAndTextView frame];
imageAndTextViewFrame.origin.x = x;
x += CGRectGetWidth(imageAndTextViewFrame);
height = MAX(height, CGRectGetHeight(imageAndTextViewFrame));
var hasSubmenuIndicator = [_menuItem hasSubmenu] && [_menuItem action];
if (hasSubmenuIndicator)
{
[_submenuIndicatorView setHidden:NO];
[_submenuIndicatorView setColor:[self textColor]];
[_submenuIndicatorView setShadowColor:[self textShadowColor]];
var submenuViewFrame = [_submenuIndicatorView frame];
submenuViewFrame.origin.x = x + SUBMENU_INDICATOR_MARGIN;
x = CGRectGetMaxX(submenuViewFrame);
height = MAX(height, CGRectGetHeight(submenuViewFrame));
}
else
[_submenuIndicatorView setHidden:YES];
height += 2.0 * VERTICAL_MARGIN;
height = MAX(height, CGRectGetHeight(imageAndTextViewFrame)) + 2.0 * [self valueForThemeAttribute:@"vertical-margin"];
imageAndTextViewFrame.origin.y = FLOOR((height - CGRectGetHeight(imageAndTextViewFrame)) / 2.0);
[_imageAndTextView setFrame:imageAndTextViewFrame];
if (hasSubmenuIndicator)
{
submenuViewFrame.origin.y = FLOOR((height - CGRectGetHeight(submenuViewFrame)) / 2.0) + 1.0;
[_submenuIndicatorView setFrame:submenuViewFrame];
}
[self setAutoresizesSubviews:NO];
[self setFrameSize:CGSizeMake(x + HORIZONTAL_MARGIN, height)];
[self setFrameSize:CGSizeMake(x + [self valueForThemeAttribute:@"horizontal-margin"], height)];
[self setAutoresizesSubviews:YES];
[self setNeedsLayout];
}
- (void)highlight:(BOOL)shouldHighlight
@@ -159,17 +179,20 @@ var SelectionColor = nil,
if (![_menuItem isEnabled])
shouldHighlight = NO;
if (shouldHighlight)
_shouldHighlight = shouldHighlight;
[self setNeedsLayout];
}
- (void)layoutSubviews
{
if (_shouldHighlight)
{
if (![_menuItem _isMenuBarButton])
[self setBackgroundColor:SelectionColor];
[self setBackgroundColor:[self highlightColor]];
[_imageAndTextView setImage:[_menuItem alternateImage] || [_menuItem image]];
[_imageAndTextView setTextColor:[CPColor whiteColor]];
[_imageAndTextView setTextShadowColor:_CPMenuItemTextShadowColor];
[_submenuIndicatorView setColor:[CPColor whiteColor]];
[_submenuIndicatorView setShadowColor:[CPColor colorWithWhite:0.1 alpha:0.7]];
[_imageAndTextView setTextColor:[self highlightTextColor]];
[_imageAndTextView setTextShadowColor:[self highlightTextShadowColor]];
}
else
{
@@ -178,60 +201,7 @@ var SelectionColor = nil,
[_imageAndTextView setImage:[_menuItem image]];
[_imageAndTextView setTextColor:[self textColor]];
[_imageAndTextView setTextShadowColor:[self textShadowColor]];
[_submenuIndicatorView setColor:[self textColor]];
[_submenuIndicatorView setShadowColor:[self textShadowColor]];
}
}
@end
@implementation _CPMenuItemMenuBarSubmenuIndicatorView : CPView
{
CPColor _color;
CPColor _shadowColor;
}
- (void)setColor:(CPColor)aColor
{
if (_color === aColor)
return;
_color = aColor;
[self setNeedsDisplay:YES];
}
- (void)setShadowColor:(CPColor)aColor
{
if (_shadowColor === aColor)
return;
_shadowColor = aColor;
[self setNeedsDisplay:YES];
}
- (void)drawRect:(CGRect)aRect
{
var context = [[CPGraphicsContext currentContext] graphicsPort],
bounds = [self bounds];
bounds.size.height -= 1.0;
bounds.size.width -= 2.0;
bounds.origin.x += 1.0;
CGContextBeginPath(context);
CGContextMoveToPoint(context, CGRectGetMinX(bounds), CGRectGetMinY(bounds));
CGContextAddLineToPoint(context, CGRectGetMaxX(bounds), CGRectGetMinY(bounds));
CGContextAddLineToPoint(context, CGRectGetMidX(bounds), CGRectGetMaxY(bounds));
CGContextClosePath(context);
CGContextSetShadowWithColor(context, CGSizeMake(0.0, 1.0), 1.1, _shadowColor || [CPColor whiteColor]);
CGContextSetFillColor(context, _color || [CPColor blackColor]);
CGContextFillPath(context);
}
@end
+25 -2
View File
@@ -1,6 +1,29 @@
/*
* _CPMenuItemSeparatorView.j
* AppKit
*
* Created by Francisco Tolmasky.
* Copyright 2009, 280 North, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "CPView.j"
@class _CPMenuItemStandardView
@implementation _CPMenuItemSeparatorView : CPView
{
@@ -31,8 +54,8 @@
CGContextMoveToPoint(context, CGRectGetMinX(bounds), FLOOR(CGRectGetMidY(bounds)) - 0.5);
CGContextAddLineToPoint(context, CGRectGetMaxX(bounds), FLOOR(CGRectGetMidY(bounds)) - 0.5);
CGContextSetStrokeColor(context, [CPColor lightGrayColor]);
CGContextSetStrokeColor(context, [[CPTheme defaultTheme] valueForAttributeWithName:@"menu-item-separator-color" forClass:_CPMenuItemStandardView]);
CGContextStrokePath(context);
}
@end
@end
+142 -66
View File
@@ -1,32 +1,41 @@
/*
* _CPMenuItemStandardView.j
* AppKit
*
* Created by Francisco Tolmasky.
* Copyright 2009, 280 North, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "CPControl.j"
@import "CPImageView.j"
@import "_CPImageAndTextView.j"
@class CPMenuItem
var LEFT_MARGIN = 3.0,
RIGHT_MARGIN = 14.0 + 3.0,
STATE_COLUMN_WIDTH = 14.0,
INDENTATION_WIDTH = 17.0,
VERTICAL_MARGIN = 4.0,
RIGHT_COLUMNS_MARGIN = 30.0,
KEY_EQUIVALENT_MARGIN = 10.0;
var SUBMENU_INDICATOR_COLOR = nil,
_CPMenuItemSelectionColor = nil,
_CPMenuItemTextShadowColor = nil,
_CPMenuItemDefaultStateImages = [],
_CPMenuItemDefaultStateHighlightedImages = [];
@implementation _CPMenuItemStandardView : CPView
{
CPMenuItem _menuItem @accessors(property=menuItem);
CPFont _font;
CPColor _textColor;
CPColor _textShadowColor;
CGSize _minSize @accessors(readonly, property=minSize);
BOOL _isDirty;
BOOL _highlighted;
CPImageView _stateView;
_CPImageAndTextView _imageAndTextView;
@@ -34,26 +43,33 @@ var SUBMENU_INDICATOR_COLOR = nil,
CPView _submenuIndicatorView;
}
+ (void)initialize
+ (CPString)defaultThemeClass
{
if (self !== [_CPMenuItemStandardView class])
return;
return "menu-item-standard-view";
}
SUBMENU_INDICATOR_COLOR = [CPColor grayColor];
_CPMenuItemSelectionColor = [CPColor colorWithCalibratedRed:95.0 / 255.0 green:131.0 / 255.0 blue:185.0 / 255.0 alpha:1.0];
_CPMenuItemTextShadowColor = [CPColor colorWithCalibratedRed:26.0 / 255.0 green: 73.0 / 255.0 blue:109.0 / 255.0 alpha:1.0];
var bundle = [CPBundle bundleForClass:self];
_CPMenuItemDefaultStateImages[CPOffState] = nil;
_CPMenuItemDefaultStateHighlightedImages[CPOffState] = nil;
_CPMenuItemDefaultStateImages[CPOnState] = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPMenuItem/CPMenuItemOnState.png"] size:CGSizeMake(14.0, 14.0)];
_CPMenuItemDefaultStateHighlightedImages[CPOnState] = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPMenuItem/CPMenuItemOnStateHighlighted.png"] size:CGSizeMake(14.0, 14.0)];
_CPMenuItemDefaultStateImages[CPMixedState] = nil;
_CPMenuItemDefaultStateHighlightedImages[CPMixedState] = nil;
+ (CPDictionary)themeAttributes
{
return @{
@"submenu-indicator-color": [CPNull null],
@"menu-item-selection-color": [CPNull null],
@"menu-item-text-shadow-color": [CPNull null],
@"menu-item-text-color": [CPNull null],
@"menu-item-disabled-text-color": [CPColor lightGrayColor],
@"menu-item-default-off-state-image": [CPNull null],
@"menu-item-default-off-state-highlighted-image": [CPNull null],
@"menu-item-default-on-state-image": [CPNull null],
@"menu-item-default-on-state-highlighted-image": [CPNull null],
@"menu-item-default-mixed-state-image": [CPNull null],
@"menu-item-default-mixed-state-highlighted-image": [CPNull null],
@"menu-item-separator-color": [CPNull null],
@"left-margin": 3.0,
@"right-margin": 17.0,
@"state-column-width": 14.0,
@"indentation-width": 17.0,
@"vertical-margin": 4.0,
@"right-columns-margin": 30.0,
};
}
+ (id)view
@@ -63,7 +79,7 @@ var SUBMENU_INDICATOR_COLOR = nil,
+ (float)_standardLeftMargin
{
return LEFT_MARGIN + STATE_COLUMN_WIDTH;
return [[CPTheme defaultTheme] valueForAttributeWithName:@"left-margin" forClass:[self class]] + [[CPTheme defaultTheme] valueForAttributeWithName:@"state-column-width" forClass:[self class]];
}
- (id)initWithFrame:(CGRect)aFrame
@@ -95,7 +111,7 @@ var SUBMENU_INDICATOR_COLOR = nil,
_submenuIndicatorView = [[_CPMenuItemSubmenuIndicatorView alloc] initWithFrame:CGRectMake(0.0, 0.0, 8.0, 10.0)];
[_submenuIndicatorView setColor:SUBMENU_INDICATOR_COLOR];
[_submenuIndicatorView setColor:[self valueForThemeAttribute:@"submenu-indicator-color"]];
[_submenuIndicatorView setAutoresizingMask:CPViewMinXMargin];
[self addSubview:_submenuIndicatorView];
@@ -109,9 +125,12 @@ var SUBMENU_INDICATOR_COLOR = nil,
- (CPColor)textColor
{
if (![_menuItem isEnabled])
return [CPColor lightGrayColor];
return [self valueForThemeAttribute:@"menu-item-disabled-text-color"];
return _textColor || [CPColor colorWithCalibratedRed:70.0 / 255.0 green:69.0 / 255.0 blue:69.0 / 255.0 alpha:1.0];
if (_highlighted)
return [CPColor whiteColor];
return [self valueForThemeAttribute:@"menu-item-text-color"];
}
- (CPColor)textShadowColor
@@ -119,7 +138,10 @@ var SUBMENU_INDICATOR_COLOR = nil,
if (![_menuItem isEnabled])
return nil;
return _textShadowColor || [CPColor colorWithWhite:1.0 alpha:0.8];
if (_highlighted)
return nil;
return [self valueForThemeAttribute:@"menu-item-text-shadow-color"];
}
- (void)setFont:(CPFont)aFont
@@ -129,16 +151,34 @@ var SUBMENU_INDICATOR_COLOR = nil,
- (void)update
{
var x = LEFT_MARGIN + [_menuItem indentationLevel] * INDENTATION_WIDTH,
var x = [self valueForThemeAttribute:@"left-margin"] + [_menuItem indentationLevel] * [self valueForThemeAttribute:@"indentation-width"],
height = 0.0,
hasStateColumn = [[_menuItem menu] showsStateColumn];
if (hasStateColumn)
{
[_stateView setHidden:NO];
[_stateView setImage:_CPMenuItemDefaultStateImages[[_menuItem state]] || nil];
//[_stateView setImage:_CPMenuItemDefaultStateImages[[_menuItem state]] || nil];
x += STATE_COLUMN_WIDTH;
switch ([_menuItem state])
{
case CPOnState:
[_stateView setImage:[self valueForThemeAttribute:@"menu-item-default-on-state-image"]];
break;
case CPOffState:
[_stateView setImage:[self valueForThemeAttribute:@"menu-item-default-off-state-image"]];
break;
case CPMixedState:
[_stateView setImage:[self valueForThemeAttribute:@"menu-item-default-mixed-state-image"]];
break;
default:
break;
}
x += [self valueForThemeAttribute:@"state-column-width"];
}
else
[_stateView setHidden:YES];
@@ -162,7 +202,7 @@ var SUBMENU_INDICATOR_COLOR = nil,
hasSubmenu = [_menuItem hasSubmenu];
if (hasKeyEquivalent || hasSubmenu)
x += RIGHT_COLUMNS_MARGIN;
x += [self valueForThemeAttribute:@"right-columns-margin"];
if (hasKeyEquivalent)
{
@@ -173,7 +213,7 @@ var SUBMENU_INDICATOR_COLOR = nil,
[_keyEquivalentView setTextColor:[self textColor]];
[_keyEquivalentView setTextShadowColor:[self textShadowColor]];
[_keyEquivalentView setTextShadowOffset:CGSizeMake(0, 1)];
[_keyEquivalentView setFrameOrigin:CGPointMake(x, VERTICAL_MARGIN)];
[_keyEquivalentView setFrameOrigin:CGPointMake(x, [self valueForThemeAttribute:@"vertical-margin"])];
[_keyEquivalentView sizeToFit];
var keyEquivalentViewFrame = [_keyEquivalentView frame];
@@ -183,7 +223,7 @@ var SUBMENU_INDICATOR_COLOR = nil,
height = MAX(height, CGRectGetHeight(keyEquivalentViewFrame));
if (hasSubmenu)
x += RIGHT_COLUMNS_MARGIN;
x += [self valueForThemeAttribute:@"right-columns-margin"];
}
else
[_keyEquivalentView setHidden:YES];
@@ -202,13 +242,13 @@ var SUBMENU_INDICATOR_COLOR = nil,
else
[_submenuIndicatorView setHidden:YES];
height += 2.0 * VERTICAL_MARGIN;
height += 2.0 * [self valueForThemeAttribute:@"vertical-margin"];
imageAndTextViewFrame.origin.y = FLOOR((height - CGRectGetHeight(imageAndTextViewFrame)) / 2.0);
[_imageAndTextView setFrame:imageAndTextViewFrame];
if (hasStateColumn)
[_stateView setFrameSize:CGSizeMake(STATE_COLUMN_WIDTH, height)];
[_stateView setFrameSize:CGSizeMake([self valueForThemeAttribute:@"state-column-width"], height)];
if (hasKeyEquivalent)
{
@@ -222,7 +262,7 @@ var SUBMENU_INDICATOR_COLOR = nil,
[_submenuIndicatorView setFrame:submenuViewFrame];
}
_minSize = CGSizeMake(x + RIGHT_MARGIN, height);
_minSize = CGSizeMake(x + [self valueForThemeAttribute:@"right-margin"], height);
[self setAutoresizesSubviews:NO];
[self setFrameSize:_minSize];
@@ -235,40 +275,76 @@ var SUBMENU_INDICATOR_COLOR = nil,
if (![_menuItem isEnabled])
return;
_highlighted = shouldHighlight;
[_imageAndTextView setTextColor:[self textColor]];
[_keyEquivalentView setTextColor:[self textColor]];
[_imageAndTextView setTextShadowColor:[self textShadowColor]];
[_keyEquivalentView setTextShadowColor:[self textShadowColor]];
if (shouldHighlight)
{
[self setBackgroundColor:_CPMenuItemSelectionColor];
[self setBackgroundColor:[self valueForThemeAttribute:@"menu-item-selection-color"]];
[_imageAndTextView setImage:[_menuItem alternateImage] || [_menuItem image]];
[_imageAndTextView setTextColor:[CPColor whiteColor]];
[_keyEquivalentView setTextColor:[CPColor whiteColor]];
[_submenuIndicatorView setColor:[CPColor whiteColor]];
[_imageAndTextView setTextShadowColor:_CPMenuItemTextShadowColor];
[_keyEquivalentView setTextShadowColor:_CPMenuItemTextShadowColor];
[_submenuIndicatorView setColor:[self textColor]];
}
else
{
[self setBackgroundColor:nil];
[_imageAndTextView setImage:[_menuItem image]];
[_imageAndTextView setTextColor:[self textColor]];
[_keyEquivalentView setTextColor:[self textColor]];
[_submenuIndicatorView setColor:SUBMENU_INDICATOR_COLOR];
[_imageAndTextView setTextShadowColor:[self textShadowColor]];
[_keyEquivalentView setTextShadowColor:[self textShadowColor]];
[_submenuIndicatorView setColor:[self valueForThemeAttribute:@"submenu-indicator-color"]];
}
if ([[_menuItem menu] showsStateColumn])
{
if (shouldHighlight)
[_stateView setImage:_CPMenuItemDefaultStateHighlightedImages[[_menuItem state]] || nil];
{
switch ([_menuItem state])
{
case CPOnState:
[_stateView setImage:[self valueForThemeAttribute:@"menu-item-default-on-state-highlighted-image"]];
break;
case CPOffState:
[_stateView setImage:[self valueForThemeAttribute:@"menu-item-default-off-state-highlighted-image"]];
break;
case CPMixedState:
[_stateView setImage:[self valueForThemeAttribute:@"menu-item-default-mixed-state-highlighted-image"]];
break;
default:
break;
}
}
else
[_stateView setImage:_CPMenuItemDefaultStateImages[[_menuItem state]] || nil];
{
switch ([_menuItem state])
{
case CPOnState:
[_stateView setImage:[self valueForThemeAttribute:@"menu-item-default-on-state-image"]];
break;
case CPOffState:
[_stateView setImage:[self valueForThemeAttribute:@"menu-item-default-off-state-image"]];
break;
case CPMixedState:
[_stateView setImage:[self valueForThemeAttribute:@"menu-item-default-mixed-state-image"]];
break;
default:
break;
}
}
}
}
- (BOOL)isHighlighted
{
return _highlighted;
}
@end
@implementation _CPMenuItemSubmenuIndicatorView : CPView
+65 -36
View File
@@ -1,22 +1,33 @@
/*
* _CPMenuItemView.j
* AppKit
*
* Created by Francisco Tolmasky.
* Copyright 2009, 280 North, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import <AppKit/CPControl.j>
@import "CPControl.j"
@import "_CPMenuItemSeparatorView.j"
@import "_CPMenuItemStandardView.j"
@import "_CPMenuItemMenuBarView.j"
var LEFT_MARGIN = 3.0,
RIGHT_MARGIN = 16.0,
STATE_COLUMN_WIDTH = 14.0,
INDENTATION_WIDTH = 17.0,
VERTICAL_MARGIN = 4.0;
var _CPMenuItemSelectionColor = nil,
_CPMenuItemTextShadowColor = nil,
_CPMenuItemDefaultStateImages = [],
_CPMenuItemDefaultStateHighlightedImages = [];
@class CPMenuItem
@global CPApp
/*
@ignore
@@ -24,7 +35,7 @@ var _CPMenuItemSelectionColor = nil,
@implementation _CPMenuItemView : CPView
{
CPMenuItem _menuItem;
CPView _view;
CPView _view @accessors(property=view, readonly);
CPFont _font;
CPColor _textColor;
@@ -38,31 +49,22 @@ var _CPMenuItemSelectionColor = nil,
CPView _submenuView;
}
+ (void)initialize
+ (CPString)defaultThemeClass
{
if (self !== [_CPMenuItemView class])
return;
_CPMenuItemSelectionColor = [CPColor colorWithCalibratedRed:95.0 / 255.0 green:131.0 / 255.0 blue:185.0 / 255.0 alpha:1.0];
_CPMenuItemTextShadowColor = [CPColor colorWithCalibratedRed:26.0 / 255.0 green: 73.0 / 255.0 blue:109.0 / 255.0 alpha:1.0];
var bundle = [CPBundle bundleForClass:self];
_CPMenuItemDefaultStateImages[CPOffState] = nil;
_CPMenuItemDefaultStateHighlightedImages[CPOffState] = nil;
_CPMenuItemDefaultStateImages[CPOnState] = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPMenuItem/CPMenuItemOnState.png"] size:CGSizeMake(14.0, 14.0)];
_CPMenuItemDefaultStateHighlightedImages[CPOnState] = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPMenuItem/CPMenuItemOnStateHighlighted.png"] size:CGSizeMake(14.0, 14.0)];
_CPMenuItemDefaultStateImages[CPMixedState] = nil;
_CPMenuItemDefaultStateHighlightedImages[CPMixedState] = nil;
return "menu-item-view";
}
+ (float)leftMargin
+ (CPDictionary)themeAttributes
{
return LEFT_MARGIN + STATE_COLUMN_WIDTH;
return @{};
}
// Not used in the Appkit
// + (float)leftMargin
// {
// return LEFT_MARGIN + STATE_COLUMN_WIDTH;
// }
- (id)initWithFrame:(CGRect)aFrame forMenuItem:(CPMenuItem)aMenuItem
{
self = [super initWithFrame:aFrame];
@@ -111,7 +113,6 @@ var _CPMenuItemSelectionColor = nil,
_view = menuItemView;
}
}
else if ([_menuItem menu] == [CPApp mainMenu])
{
if (![_view isKindOfClass:[_CPMenuItemMenuBarView class]])
@@ -219,6 +220,36 @@ var _CPMenuItemSelectionColor = nil,
return [_menuItem isEnabled] ? (_textShadowColor ? _textShadowColor : [CPColor colorWithWhite:1.0 alpha:0.8]) : [CPColor colorWithWhite:0.8 alpha:0.8];
}
- (void)setParentMenuHighlightColor:(CPColor)aColor
{
if ([_view respondsToSelector:@selector(setHighlightColor:)])
[_view setHighlightColor:aColor];
}
- (void)setParentMenuHighlightTextColor:(CPColor)aColor
{
if ([_view respondsToSelector:@selector(setHighlightTextColor:)])
[_view setHighlightTextColor:aColor];
}
- (void)setParentMenuHighlightTextShadowColor:(CPColor)aColor
{
if ([_view respondsToSelector:@selector(setHighlightTextShadowColor:)])
[_view setHighlightTextShadowColor:aColor];
}
- (void)setParentMenuTextColor:(CPColor)aColor
{
if ([_view respondsToSelector:@selector(setTextColor:)])
[_view setTextColor:aColor];
}
- (void)setParentMenuTextShadowColor:(CPColor)aColor
{
if ([_view respondsToSelector:@selector(setTextShadowColor:)])
[_view setTextShadowColor:aColor];
}
@end
@implementation _CPMenuItemArrowView : CPView
@@ -245,8 +276,6 @@ var _CPMenuItemSelectionColor = nil,
CGContextMoveToPoint(context, 1.0, 4.0);
CGContextAddLineToPoint(context, 9.0, 4.0);
CGContextAddLineToPoint(context, 5.0, 8.0);
CGContextAddLineToPoint(context, 1.0, 4.0);
CGContextClosePath(context);
CGContextSetFillColor(context, _color);
+157 -32
View File
@@ -22,8 +22,13 @@
@import <Foundation/CPDictionary.j>
@import <Foundation/CPCountedSet.j>
@import <Foundation/_CPCollectionKVCOperators.j>
@import "CPController.j"
@import "CPKeyValueBinding.j"
@class _CPManagedProxy
@class CPPredicate;
/*!
@class
@@ -45,11 +50,14 @@
BOOL _isEditable;
BOOL _automaticallyPreparesContent;
BOOL _usesLazyFetching @accessors(getter=usesLazyFetching, setter=setUsesLazyFetching:);
BOOL _isUsingManagedProxy;
_CPManagedProxy _managedProxy;
CPCountedSet _observedKeys;
}
+ (id)initialize
+ (void)initialize
{
if (self !== [CPObjectController class])
return;
@@ -104,11 +112,13 @@
{
if (self = [super init])
{
[self setContent:aContent];
[self setEditable:YES];
[self setObjectClass:[CPMutableDictionary class]];
_observedKeys = [[CPCountedSet alloc] init];
_selection = [[CPControllerSelectionProxy alloc] initWithController:self];
[self setContent:aContent];
}
return self;
@@ -175,6 +185,52 @@
return _automaticallyPreparesContent;
}
/*!
Sets the entity name the controller handles.
@param CPString newEntityName - The new entity name.
*/
- (void)setEntityName:(CPString)newEntityName
{
if (!_managedProxy)
{
_managedProxy = [[_CPManagedProxy alloc] init];
_isUsingManagedProxy = YES;
}
[_managedProxy setEntityName:newEntityName];
}
/*!
Returns the entity name.
@return CPString - The name of the entity.
*/
- (CPString)entityName
{
return [_managedProxy entityName];
}
/*!
Sets the predicate used to fetch content.
@param CPPredicate newPredicate - The fetch predicate.
*/
- (void)setFetchPredicate:(CPPredicate)newPredicate
{
[_managedProxy setFetchPredicate:newPredicate];
}
/*!
Returns the fetch predicate.
@return CPPredicate - The predicate used to fetch content.
*/
- (CPPredicate)fetchPredicate
{
return [_managedProxy fetchPredicate];
}
/*!
Overridden by a subclass that require control over the creation of new objects.
*/
@@ -185,6 +241,7 @@
/*!
Sets the object class when creating new objects.
@param Class - the class of new objects that will be created.
*/
- (void)setObjectClass:(Class)aClass
@@ -359,7 +416,10 @@
var CPObjectControllerContentKey = @"CPObjectControllerContentKey",
CPObjectControllerObjectClassNameKey = @"CPObjectControllerObjectClassNameKey",
CPObjectControllerIsEditableKey = @"CPObjectControllerIsEditableKey",
CPObjectControllerAutomaticallyPreparesContentKey = @"CPObjectControllerAutomaticallyPreparesContentKey";
CPObjectControllerAutomaticallyPreparesContentKey = @"CPObjectControllerAutomaticallyPreparesContentKey",
CPObjectControllerUsesLazyFetchingKey = @"CPObjectControllerUsesLazyFetchingKey",
CPObjectControllerIsUsingManagedProxyKey = @"CPObjectControllerIsUsingManagedProxyKey",
CPObjectControllerManagedProxyKey = @"CPObjectControllerManagedProxyKey";
@implementation CPObjectController (CPCoding)
@@ -370,12 +430,18 @@ var CPObjectControllerContentKey = @"CPObjectControllerCo
if (self)
{
var objectClassName = [aCoder decodeObjectForKey:CPObjectControllerObjectClassNameKey],
objectClass = CPClassFromString(objectClassName);
objectClass = CPClassFromString(objectClassName),
content = [aCoder decodeObjectForKey:CPObjectControllerContentKey];
[self setObjectClass:objectClass || [CPMutableDictionary class]];
[self setEditable:[aCoder decodeBoolForKey:CPObjectControllerIsEditableKey]];
[self setAutomaticallyPreparesContent:[aCoder decodeBoolForKey:CPObjectControllerAutomaticallyPreparesContentKey]];
[self setContent:[aCoder decodeObjectForKey:CPObjectControllerContentKey]];
[self setUsesLazyFetching:[aCoder decodeBoolForKey:CPObjectControllerUsesLazyFetchingKey]];
_isUsingManagedProxy = [aCoder decodeBoolForKey:CPObjectControllerIsUsingManagedProxyKey];
_managedProxy = [aCoder decodeObjectForKey:CPObjectControllerManagedProxyKey];
if (content != nil)
[self setContent:content];
_observedKeys = [[CPCountedSet alloc] init];
}
@@ -394,6 +460,11 @@ var CPObjectControllerContentKey = @"CPObjectControllerCo
[aCoder encodeBool:[self isEditable] forKey:CPObjectControllerIsEditableKey];
[aCoder encodeBool:[self automaticallyPreparesContent] forKey:CPObjectControllerAutomaticallyPreparesContentKey];
[aCoder encodeBool:[self usesLazyFetching] forKey:CPObjectControllerUsesLazyFetchingKey];
[aCoder encodeBool:_isUsingManagedProxy forKey:CPObjectControllerIsUsingManagedProxyKey];
if (_managedProxy)
[aCoder encodeObject:_managedProxy forKey:CPObjectControllerManagedProxyKey];
}
- (void)awakeFromCib
@@ -455,13 +526,13 @@ var CPObjectControllerContentKey = @"CPObjectControllerCo
- (BOOL)isEqual:(id)anObject
{
if ([anObject class] === [self class])
{
if (anObject._observer === _observer && [anObject._keyPath isEqual:_keyPath] && [anObject._object isEqual:_object])
return YES;
}
if (self === anObject)
return YES;
return NO;
if (!anObject || [anObject class] !== [self class] || anObject._observer !== _observer || anObject._keyPath !== _keyPath || anObject._object !== _object)
return NO;
return YES;
}
- (void)observeValueForKeyPath:(CPString)aKeyPath ofObject:(id)anObject change:(CPDictionary)change context:(id)context
@@ -516,8 +587,12 @@ var CPObjectControllerContentKey = @"CPObjectControllerCo
- (void)addObserver:(id)anObserver forKeyPath:(CPString)aKeyPath options:(CPKeyValueObservingOptions)options context:(id)context
{
if (aKeyPath.indexOf("@") === 0)
if (aKeyPath.charAt(0) === "@")
{
// Simple collection operators are scalar and can't be proxied
if ([_CPCollectionKVCOperator isSimpleCollectionOperator:aKeyPath])
return;
var proxy = [[_CPObservationProxy alloc] initWithKeyPath:aKeyPath observer:anObserver object:self];
proxy._options = options;
@@ -540,8 +615,12 @@ var CPObjectControllerContentKey = @"CPObjectControllerCo
- (void)removeObserver:(id)anObserver forKeyPath:(CPString)aKeyPath
{
if (aKeyPath.indexOf("@") === 0)
if (aKeyPath.charAt(0) === "@")
{
// Simple collection operators are scalar and can't be proxied
if ([_CPCollectionKVCOperator isSimpleCollectionOperator:aKeyPath])
return;
var proxy = [[_CPObservationProxy alloc] initWithKeyPath:aKeyPath observer:anObserver object:self],
index = [_observationProxies indexOfObject:proxy];
@@ -560,13 +639,13 @@ var CPObjectControllerContentKey = @"CPObjectControllerCo
}
}
- (void)insertObject:(id)anObject atIndex:(unsigned)anIndex
- (void)insertObject:(id)anObject atIndex:(CPUInteger)anIndex
{
for (var i = 0, count = [_observationProxies count]; i < count; i++)
{
var proxy = [_observationProxies objectAtIndex:i],
keyPath = [proxy keyPath],
operator = keyPath.indexOf(".") === 0;
operator = keyPath.charAt(0) === ".";
if (operator)
[self willChangeValueForKey:keyPath];
@@ -580,7 +659,7 @@ var CPObjectControllerContentKey = @"CPObjectControllerCo
[super insertObject:anObject atIndex:anIndex];
}
- (void)removeObjectAtIndex:(unsigned)anIndex
- (void)removeObjectAtIndex:(CPUInteger)anIndex
{
var currentObject = [self objectAtIndex:anIndex];
@@ -588,7 +667,7 @@ var CPObjectControllerContentKey = @"CPObjectControllerCo
{
var proxy = [_observationProxies objectAtIndex:i],
keyPath = [proxy keyPath],
operator = keyPath.indexOf(".") === 0;
operator = keyPath.charAt(0) === ".";
if (operator)
[self willChangeValueForKey:keyPath];
@@ -602,7 +681,7 @@ var CPObjectControllerContentKey = @"CPObjectControllerCo
[super removeObjectAtIndex:anIndex];
}
- (_CPObservableArray)objectsAtIndexes:(CPIndexSet)theIndexes
- (CPArray)objectsAtIndexes:(CPIndexSet)theIndexes
{
return [_CPObservableArray arrayWithArray:[super objectsAtIndexes:theIndexes]];
}
@@ -617,7 +696,7 @@ var CPObjectControllerContentKey = @"CPObjectControllerCo
[self removeObjectAtIndex:[self count]];
}
- (void)replaceObjectAtIndex:(unsigned)anIndex withObject:(id)anObject
- (void)replaceObjectAtIndex:(CPUInteger)anIndex withObject:(id)anObject
{
var currentObject = [self objectAtIndex:anIndex];
@@ -625,7 +704,7 @@ var CPObjectControllerContentKey = @"CPObjectControllerCo
{
var proxy = [_observationProxies objectAtIndex:i],
keyPath = [proxy keyPath],
operator = keyPath.indexOf(".") === 0;
operator = keyPath.charAt(0) === ".";
if (operator)
[self willChangeValueForKey:keyPath];
@@ -657,7 +736,7 @@ var CPObjectControllerContentKey = @"CPObjectControllerCo
{
if (self = [super init])
{
_cachedValues = [CPDictionary dictionary];
_cachedValues = @{};
_observationProxies = [CPArray array];
_controller = aController;
_observedObjectsByKeyPath = {};
@@ -699,12 +778,18 @@ var CPObjectControllerContentKey = @"CPObjectControllerCo
- (id)valueForKeyPath:(CPString)theKeyPath
{
var values = [[_controller selectedObjects] valueForKeyPath:theKeyPath],
value = [self _controllerMarkerForValues:values];
var values = [[_controller selectedObjects] valueForKeyPath:theKeyPath];
[_cachedValues setObject:value forKey:theKeyPath];
// Simple collection operators like @count return a scalar value, not an array or set
if ([values isKindOfClass:CPArray] || [values isKindOfClass:CPSet])
{
var value = [self _controllerMarkerForValues:values];
[_cachedValues setObject:value forKey:theKeyPath];
return value;
return value;
}
else
return values;
}
- (id)valueForKey:(CPString)theKeyPath
@@ -731,7 +816,7 @@ var CPObjectControllerContentKey = @"CPObjectControllerCo
- (void)setValue:(id)theValue forKey:(CPString)theKeyPath
{
[self setValue:theKeyPath forKeyPath:theKeyPath];
[self setValue:theValue forKeyPath:theKeyPath];
}
- (unsigned)count
@@ -790,15 +875,55 @@ var CPObjectControllerContentKey = @"CPObjectControllerCo
- (void)removeObserver:(id)anObject forKeyPath:(CPString)aKeyPath
{
var proxy = [[_CPObservationProxy alloc] initWithKeyPath:aKeyPath observer:anObject object:self],
index = [_observationProxies indexOfObject:proxy];
[_observationProxies enumerateObjectsUsingBlock:function(aProxy, idx, stop)
{
if (aProxy._object === self && aProxy._keyPath == aKeyPath && aProxy._observer === anObject)
{
var observedObjects = _observedObjectsByKeyPath[aKeyPath];
var observedObjects = _observedObjectsByKeyPath[aKeyPath];
[observedObjects removeObserver:[_observationProxies objectAtIndex:index] forKeyPath:aKeyPath];
[observedObjects removeObserver:aProxy forKeyPath:aKeyPath];
[_observationProxies removeObjectAtIndex:idx];
[_observationProxies removeObjectAtIndex:index];
_observedObjectsByKeyPath[aKeyPath] = nil;
_observedObjects = nil;
stop(YES);
}
}];
}
@end
@implementation _CPManagedProxy : CPObject
{
CPString _entityName @accessors(getter=entityName, setter=setEntityName:);
CPPredicate _fetchPredicate @accessors(getter=fetchPredicate, setter=setFetchPredicate:);
}
@end
var CPManagedProxyEntityNameKey = @"CPManagedProxyEntityNameKey",
CPManagedProxyFetchPredicateKey = @"CPManagedProxyFetchPredicateKey";
@implementation _CPManagedProxy (CPCoding)
- (id)initWithCoder:(CPCoder)aCoder
{
self = [super init];
if (self)
{
[self setEntityName:[aCoder decodeObjectForKey:CPManagedProxyEntityNameKey]];
[self setFetchPredicate:[aCoder decodeObjectForKey:CPManagedProxyFetchPredicateKey]];
}
return self;
}
- (void)encodeWithCoder:(CPCoder)aCoder
{
[aCoder encodeObject:[self entityName] forKey:CPManagedProxyEntityNameKey];
[aCoder encodeObject:[self fetchPredicate] forKey:CPManagedProxyFetchPredicateKey];
}
@end
+2 -2
View File
@@ -47,9 +47,9 @@
var options = { directoryURL: [self directoryURL],
canChooseFiles: [self canChooseFiles],
canChooseDirectories: [self canChooseDirectories],
allowsMultipleSelection: [self allowsMultipleSelection] };
allowsMultipleSelection: [self allowsMultipleSelection] },
var result = window.cpOpenPanel(options);
result = window.cpOpenPanel(options);
_URLs = result.URLs;
+595 -381
View File
File diff suppressed because it is too large Load Diff
+24 -3
View File
@@ -22,10 +22,13 @@
@import "CPWindow.j"
@global CPApp
CPOKButton = 1;
CPCancelButton = 0;
CPDocModalWindowMask = 1 << 6;
/*!
@ingroup appkit
@class CPPanel
@@ -51,8 +54,6 @@ CPCancelButton = 0;
@global
@class CPWindow
*/
CPDocModalWindowMask = 1 << 6;
@implementation CPPanel : CPWindow
{
BOOL _becomesKeyOnlyIfNeeded;
@@ -116,7 +117,27 @@ CPDocModalWindowMask = 1 << 6;
- (BOOL)canBecomeKeyWindow
{
return YES;
return YES;
}
#pragma mark -
#pragma mark Overrides
/*!
@ignore
*/
- (void)cancelOperation:(id)sender
{
if ([[CPApp currentEvent] _couldBeKeyEquivalent] && [self performKeyEquivalent:[CPApp currentEvent]])
return;
[[self firstResponder] tryToPerform:@selector(cancel:) with:self];
}
- (void)cancel:(id)sender
{
[self performClose:sender];
}
@end
+24 -79
View File
@@ -22,9 +22,13 @@
@import <Foundation/CPObject.j>
@import <Foundation/CPArray.j>
@import <Foundation/CPData.j>
@import <Foundation/CPDictionary.j>
@import <Foundation/CPPropertyListSerialization.j>
@class CPWebScriptObject
@typedef DataTransfer
CPGeneralPboard = @"CPGeneralPboard";
CPFontPboard = @"CPFontPboard";
@@ -40,6 +44,8 @@ CPStringPboardType = @"CPStringPboardType";
CPURLPboardType = @"CPURLPboardType";
CPImagesPboardType = @"CPImagesPboardType";
CPVideosPboardType = @"CPVideosPboardType";
CPRTFPboardType = @"CPRTFPboardType";
_CPSmartPboardType = @"_CPSmartPboardType";
UTF8PboardType = @"public.utf8-plain-text";
@@ -47,8 +53,7 @@ UTF8PboardType = @"public.utf8-plain-text";
CPImagePboardType = @"CPImagePboardType";
var CPPasteboards = nil,
supportsNativePasteboard = NO;
var CPPasteboards = nil;
/*!
@ingroup appkit
@@ -64,8 +69,6 @@ var CPPasteboards = nil,
unsigned _changeCount;
CPString _stateUID;
WebScriptObject _nativePasteboard;
}
/*
@@ -78,10 +81,7 @@ var CPPasteboards = nil,
[self setVersion:1.0];
CPPasteboards = [CPDictionary dictionary];
if (typeof window.cpPasteboardWithName !== "undefined")
supportsNativePasteboard = YES;
CPPasteboards = @{};
}
/*!
@@ -117,19 +117,13 @@ var CPPasteboards = nil,
if (self)
{
_name = aName;
// _name = aName;
_types = [];
_owners = [CPDictionary dictionary];
_provided = [CPDictionary dictionary];
_owners = @{};
_provided = @{};
_changeCount = 0;
if (supportsNativePasteboard)
{
_nativePasteboard = window.cpPasteboardWithName(aName);
[self _synchronizePasteboard];
}
}
return self;
@@ -159,15 +153,6 @@ var CPPasteboards = nil,
[_owners setObject:anOwner forKey:type];
}
if (_nativePasteboard)
{
var nativeTypes = [types copy];
if ([types containsObject:CPStringPboardType])
nativeTypes.push(UTF8PboardType);
_nativePasteboard.addTypes_(nativeTypes);
}
return ++_changeCount;
}
@@ -178,32 +163,19 @@ var CPPasteboards = nil,
@return the pasteboard's change count
*/
- (unsigned)declareTypes:(CPArray)types owner:(id)anOwner
{
[self _declareTypes:types owner:anOwner updateNativePasteboard:YES];
}
/*! @ignore */
- (unsigned)_declareTypes:(CPArray)types owner:(id)anOwner updateNativePasteboard:(BOOL)shouldUpdate
{
[_types setArray:types];
_owners = [CPDictionary dictionary];
_provided = [CPDictionary dictionary];
_owners = @{};
_provided = @{};
var count = _types.length;
while (count--)
[_owners setObject:anOwner forKey:_types[count]];
if (_nativePasteboard && shouldUpdate)
if (anOwner)
{
var nativeTypes = [types copy];
if ([types containsObject:CPStringPboardType])
nativeTypes.push(UTF8PboardType);
_nativePasteboard.declareTypes_(nativeTypes);
_changeCount = _nativePasteboard.changeCount();
var count = _types.length;
while (count--)
[_owners setObject:anOwner forKey:_types[count]];
}
return ++_changeCount;
}
@@ -242,19 +214,23 @@ var CPPasteboards = nil,
*/
- (void)setString:(CPString)aString forType:(CPString)aType
{
// Putting a non-string on the string pasteboard can lead to strange crashes.
if (aString && aString.isa && ![aString isKindOfClass:CPString])
[CPException raise:CPInvalidArgumentException reason:"CPPasteboard setString:forType: must be called with a string."];
[self setPropertyList:aString forType:aType];
}
// Determining Types
/*!
Checks the pasteboard's types for a match with the types listen in the specified array. The array should
Checks the pasteboard's types for a match with the types listed in the specified array. The array should
be ordered by the requestor's most preferred data type first.
@param anArray an array of requested types ordered by preference
@return the highest match with the pasteboard's supported types or \c nil if no match was found
*/
- (CPString)availableTypeFromArray:(CPArray)anArray
{
return [[self types] firstObjectCommonWithArray:anArray];
return [anArray firstObjectCommonWithArray:[self types]];
}
/*!
@@ -262,7 +238,6 @@ var CPPasteboards = nil,
*/
- (CPArray)types
{
[self _synchronizePasteboard];
return _types;
}
@@ -301,36 +276,6 @@ var CPPasteboards = nil,
return nil;
}
- (void)_synchronizePasteboard
{
if (_nativePasteboard && _nativePasteboard.changeCount() > _changeCount)
{
var nativeTypes = [_nativePasteboard.types() copy];
if ([nativeTypes containsObject:UTF8PboardType])
nativeTypes.push(CPStringPboardType);
[self _declareTypes:nativeTypes owner:self updateNativePasteboard:NO];
_changeCount = _nativePasteboard.changeCount();
}
}
/*! @ignore
method provided for integration with native pasteboard
*/
- (void)pasteboard:(CPPasteboard)aPasteboard provideDataForType:(CPString)aType
{
if (aType === CPStringPboardType)
{
var string = _nativePasteboard.stringForType_(UTF8PboardType);
[self setString:string forType:CPStringPboardType];
[self setString:string forType:UTF8PboardType];
}
else
[self setString:_nativePasteboard.stringForType_(aType) forType:aType];
}
/*!
Returns the property list for the specified data type
@param aType the requested data type
+55 -53
View File
@@ -20,15 +20,12 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import <Foundation/CPGeometry.j>
@import "CGGeometry.j"
@import "CPButton.j"
@import "CPKeyValueBinding.j"
@import "CPMenu.j"
@import "CPMenuItem.j"
var VISIBLE_MARGIN = 7.0;
CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
/*!
@@ -280,7 +277,7 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
Selects the item at the specified index
@param anIndex the index of the item to select
*/
- (void)setObjectValue:(int)anIndex
- (void)setObjectValue:(id)anIndex
{
var indexOfSelectedItem = [self objectValue];
@@ -345,7 +342,7 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
Returns the item at the specified index or \c nil if the item does not exist.
@param anIndex the index of the item to obtain
*/
- (CPMenuItem)itemAtIndex:(unsigned)anIndex
- (CPMenuItem)itemAtIndex:(CPUInteger)anIndex
{
return [[self menu] itemAtIndex:anIndex];
}
@@ -354,7 +351,7 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
Returns the title of the item at the specified index or \c nil if no item exists.
@param anIndex the index of the item
*/
- (CPString)itemTitleAtIndex:(unsigned)anIndex
- (CPString)itemTitleAtIndex:(CPUInteger)anIndex
{
return [[[self menu] itemAtIndex:anIndex] title];
}
@@ -364,15 +361,10 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
*/
- (CPArray)itemTitles
{
var titles = [],
items = [self itemArray],
index = 0,
count = [items count];
for (; index < count; ++index)
titles.push([items[index] title]);
return titles;
return [[self itemArray] arrayByApplyingBlock:function(item)
{
return [item title];
}];
}
/*!
@@ -668,10 +660,15 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
if (![self isEnabled] || ![self numberOfItems])
return;
var menu = [self menu];
// Don't reopen the menu based on the same click which caused it to close, e.g. a click on this button.
if (menu._lastCloseEvent === anEvent)
return;
[self highlight:YES];
var menu = [self menu],
bounds = [self bounds],
var bounds = [self bounds],
minimumWidth = CGRectGetWidth(bounds);
// FIXME: setFont: should set the font on the menu.
@@ -680,7 +677,7 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
if ([self pullsDown])
{
var positionedItem = nil,
location = CGPointMake(0.0, CGRectGetMaxY(bounds));
location = CGPointMake(0.0, CGRectGetMaxY(bounds) - 1);
}
else
{
@@ -769,13 +766,6 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
[[self selectedItem] setState:CPOffState];
}
- (void)_reverseSetBinding
{
[_CPPopUpButtonSelectionBinder reverseSetValueForObject:self];
[super _reverseSetBinding];
}
@end
@implementation CPPopUpButton (BindingSupport)
@@ -798,6 +788,20 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
return [super _binderClassForBinding:aBinding];
}
+ (BOOL)isBindingExclusive:(CPString)aBinding
{
return (aBinding == CPSelectedIndexBinding ||
aBinding == CPSelectedTagBinding ||
aBinding == CPSelectedValueBinding);
}
- (void)_reverseSetBinding
{
[_CPPopUpButtonSelectionBinder _reverseSetValueFromExclusiveBinderForObject:self];
[super _reverseSetBinding];
}
@end
@implementation _CPPopUpButtonContentBinder : CPBinder
@@ -834,7 +838,7 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
[self _setContentValuesIfNeeded:contentArray];
}
- (void)valueForBinding:(CPString)aBinding
- (id)valueForBinding:(CPString)aBinding
{
return [self _content];
}
@@ -843,7 +847,17 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
{
var count = [aValue count],
options = [_info objectForKey:CPOptionsKey],
offset = [self _getInsertNullOffset];
offset = [self _getInsertNullOffset],
selectedBindingInfo = [_source infoForBinding:CPSelectedObjectBinding],
selectedObject = nil;
if (selectedBindingInfo)
{
var destination = [selectedBindingInfo objectForKey:CPObservedObjectKey],
keyPath = [selectedBindingInfo objectForKey:CPObservedKeyPathKey];
selectedObject = [destination valueForKeyPath:keyPath];
}
if (count + offset != [_source numberOfItems])
{
@@ -854,9 +868,19 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
for (var i = 0; i < count; i++)
{
var item = [[CPMenuItem alloc] initWithTitle:@"" action:NULL keyEquivalent:nil];
[self _setValue:[aValue objectAtIndex:i] forItem:item withOptions:options];
var item = [[CPMenuItem alloc] initWithTitle:@"" action:NULL keyEquivalent:nil],
itemValue = [aValue objectAtIndex:i];
[self _setValue:itemValue forItem:item withOptions:options];
[_source addItem:item];
// Select this item if it is the one selected by the selected object binding
// This is needed if the selected object binding is set before the items
// from the content binding
if (itemValue === selectedObject)
{
[_source setSelectedIndex:[_source numberOfItems] - 1];
}
}
}
else
@@ -906,7 +930,7 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
{
}
- (void)setValue:(id)aValue forBinding:(CPString)aBinding
- (void)setValue:(CPArray)aValue forBinding:(CPString)aBinding
{
[super _setContent:aValue];
}
@@ -927,30 +951,8 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
@end
var binderForObject = {};
@implementation _CPPopUpButtonSelectionBinder : CPBinder
{
CPString _selectionBinding @accessors;
}
- (id)initWithBinding:(CPString)aBinding name:(CPString)aName to:(id)aDestination keyPath:(CPString)aKeyPath options:(CPDictionary)options from:(id)aSource
{
self = [super initWithBinding:aBinding name:aName to:aDestination keyPath:aKeyPath options:options from:aSource];
if (self)
{
binderForObject[[aSource UID]] = self;
_selectionBinding = aName;
}
return self;
}
+ (void)reverseSetValueForObject:(id)aSource
{
var binder = binderForObject[[aSource UID]];
[binder reverseSetValueFor:[binder _selectionBinding]];
}
- (void)setPlaceholderValue:(id)aValue withMarker:(CPString)aMarker forBinding:(CPString)aBinding
+105 -70
View File
@@ -28,8 +28,19 @@
@import "CPImageView.j"
@import "CPResponder.j"
@import "CPView.j"
@import "_CPAttachedWindow.j"
@import "CPViewController.j"
@import "_CPPopoverWindow.j"
@protocol CPPopoverDelegate <CPObject>
@optional
- (BOOL)popoverShouldClose:(CPPopover)aPopover;
- (void)popoverWillClose:(CPPopover)aPopover;
- (void)popoverDidClose:(CPPopover)aPopover;
- (void)popoverWillShow:(CPPopover)aPopover;
- (void)popoverDidShow:(CPPopover)aPopover;
@end
CPPopoverBehaviorApplicationDefined = 0;
CPPopoverBehaviorTransient = 1;
@@ -45,7 +56,7 @@ var CPPopoverDelegate_popover_willShow_ = 1 << 0,
/*! @ingroup appkit
@class CPPopover
This class represent a widget that displays a attached
This class represent a widget that displays a popover
view relative to another one.
Delegate can implement:
@@ -60,15 +71,16 @@ var CPPopoverDelegate_popover_willShow_ = 1 << 0,
*/
@implementation CPPopover : CPResponder
{
@outlet CPViewController _contentViewController @accessors(property=contentViewController);
@outlet id _delegate @accessors(getter=delegate);
@outlet CPViewController _contentViewController @accessors(property=contentViewController);
@outlet id <CPPopoverDelegate> _delegate @accessors(getter=delegate);
BOOL _animates @accessors(property=animates);
int _appearance @accessors(property=appearance);
int _behavior @accessors(getter=behavior);
BOOL _animates @accessors(getter=animates);
int _appearance @accessors(property=appearance);
int _behavior @accessors(getter=behavior);
_CPAttachedWindow _attachedWindow;
int _implementedDelegateMethods;
_CPPopoverWindow _popoverWindow;
CPView _positioningView;
int _implementedDelegateMethods;
}
@@ -103,9 +115,10 @@ var CPPopoverDelegate_popover_willShow_ = 1 << 0,
*/
- (CGRect)positioningRect
{
if (![_attachedWindow isVisible])
if (![_popoverWindow isVisible])
return CGRectMakeZero();
return [_attachedWindow frame];
return [_popoverWindow frame];
}
/*! Sets the frame of the popover
@@ -113,9 +126,10 @@ var CPPopoverDelegate_popover_willShow_ = 1 << 0,
*/
- (void)setPositioningRect:(CGRect)aRect
{
if (![_attachedWindow isVisible])
if (![_popoverWindow isVisible])
return;
[_attachedWindow setFrame:aRect];
[_popoverWindow setFrame:aRect];
}
/*!
@@ -125,8 +139,6 @@ var CPPopoverDelegate_popover_willShow_ = 1 << 0,
*/
- (CGSize)contentSize
{
if (![_attachedWindow isVisible])
return CGRectMakeZero();
return [[_contentViewController view] frameSize];
}
@@ -135,9 +147,12 @@ var CPPopoverDelegate_popover_willShow_ = 1 << 0,
@param aSize the desired size
*/
- (void)setContentSize:(CPSize)aSize
- (void)setContentSize:(CGSize)aSize
{
[[_contentViewController view] setFrameSize:aSize];
if (!_popoverWindow)
[[_contentViewController view] setFrameSize:aSize];
else
[_popoverWindow updateFrameWithSize:aSize];
}
/*!
@@ -147,7 +162,21 @@ var CPPopoverDelegate_popover_willShow_ = 1 << 0,
*/
- (BOOL)isShown
{
return [_attachedWindow isVisible];
return [_popoverWindow isVisible];
}
/*!
Set if the popover should animate for open/close actions.
@param shouldAnimate if YES, the popover will be animated.
*/
- (void)setAnimates:(BOOL)shouldAnimate
{
if (_animates == shouldAnimate)
return;
_animates = shouldAnimate;
[_popoverWindow setAnimates:_animates];
}
/*!
@@ -164,10 +193,10 @@ Set the behavior of the CPPopover. It can be:
return;
_behavior = aBehavior;
[_attachedWindow setStyleMask:[self styleMaskForBehavior]];
[_popoverWindow setStyleMask:[self _styleMaskForBehavior]];
}
- (void)setDelegate:(id)aDelegate
- (void)setDelegate:(id <CPPopoverDelegate>)aDelegate
{
if (_delegate === aDelegate)
return;
@@ -209,38 +238,38 @@ Set the behavior of the CPPopover. It can be:
if (!_contentViewController)
[CPException raise:CPInternalInconsistencyException reason:@"contentViewController must not be nil"];
// If the popover is currently closing, do nothing. That is what Cocoa does.
if ([_attachedWindow isClosing])
// If the popover is currently closing or opening, do nothing. That is what Cocoa does.
if ([_popoverWindow isClosing] || [_popoverWindow isOpening])
return;
if (_implementedDelegateMethods & CPPopoverDelegate_popover_willShow_)
[_delegate popoverWillShow:self];
_positioningView = positioningView;
if (!_attachedWindow)
{
_attachedWindow = [[_CPAttachedWindow alloc] initWithContentRect:CGRectMakeZero() styleMask:[self styleMaskForBehavior]];
if (!_popoverWindow)
_popoverWindow = [[_CPPopoverWindow alloc] initWithContentRect:CGRectMakeZero() styleMask:[self _styleMaskForBehavior]];
var parentWindow = [positioningView window];
[_popoverWindow setPlatformWindow:[[positioningView window] platformWindow]];
[_popoverWindow setAppearance:_appearance];
[_popoverWindow setAnimates:_animates];
[_popoverWindow setDelegate:self];
[_popoverWindow setMovableByWindowBackground:NO];
[_popoverWindow setFrame:[_popoverWindow frameRectForContentRect:[[_contentViewController view] frame]]];
[_popoverWindow setContentView:[_contentViewController view]];
if (![parentWindow isKindOfClass:_CPAttachedWindow])
[[CPNotificationCenter defaultCenter] addObserver:self selector:@selector(parentWindowWillClose:) name:CPWindowWillCloseNotification object:parentWindow];
}
if (![self isShown])
[self _popoverWillShow];
[_attachedWindow setAppearance:_appearance];
[_attachedWindow setAnimates:_animates];
[_attachedWindow setDelegate:self];
[_attachedWindow setMovableByWindowBackground:NO];
[_attachedWindow setFrame:[_attachedWindow frameRectForContentRect:[[_contentViewController view] frame]]];
[_attachedWindow setContentView:[_contentViewController view]];
[_attachedWindow positionRelativeToRect:positioningRect ofView:positioningView preferredEdge:preferredEdge];
[_popoverWindow positionRelativeToRect:positioningRect ofView:positioningView preferredEdge:preferredEdge];
if (!_animates && _implementedDelegateMethods & CPPopoverDelegate_popover_didShow_)
[_delegate popoverDidShow:self];
if (![self isShown])
[self _popoverWindowDidShow];
}
- (unsigned)styleMaskForBehavior
- (unsigned)_styleMaskForBehavior
{
return (_behavior == CPPopoverBehaviorTransient) ? CPClosableOnBlurWindowMask : 0;
if (_behavior == CPPopoverBehaviorApplicationDefined)
return 0;
return CPClosableOnBlurWindowMask
}
/*!
@@ -256,16 +285,16 @@ Set the behavior of the CPPopover. It can be:
*/
- (void)_close
{
if ([_attachedWindow isClosing] || ![self isShown])
if ([_popoverWindow isClosing] || ![self isShown])
return;
if (_implementedDelegateMethods & CPPopoverDelegate_popover_willClose_)
[_delegate popoverWillClose:self];
[self _popoverWillClose];
[_attachedWindow close];
_positioningView = nil;
[_popoverWindow close];
// popoverDidClose will be sent from attachedWindowDidClose, since
// the attached window will close asynchronously when animating.
// popoverDidClose will be sent from popoverWindowDidClose, since
// the popover window will close asynchronously when animating.
}
@@ -279,12 +308,11 @@ Set the behavior of the CPPopover. It can be:
*/
- (IBAction)performClose:(id)sender
{
if ([_attachedWindow isClosing])
if ([_popoverWindow isClosing])
return;
if (_implementedDelegateMethods & CPPopoverDelegate_popover_shouldClose_)
if (![_delegate popoverShouldClose:self])
return;
if (![self _popoverShouldClose])
return;
[self _close];
}
@@ -294,44 +322,51 @@ Set the behavior of the CPPopover. It can be:
#pragma mark Delegates
/*! @ignore */
- (BOOL)attachedWindowShouldClose:(_CPAttachedWindow)anAttachedWindow
- (BOOL)_popoverWindowShouldClose
{
[self performClose:self];
// We return NO, because we want the CPPopover to determine
// if the attached window can be closed and to give us a chance
// if the popover window can be closed and to give us a chance
// to send delegate messages.
return NO;
}
/*! @ignore */
- (void)attachedWindowDidClose:(_CPAttachedWindow)anAttachedWindow
- (void)_popoverWindowDidClose
{
if (_implementedDelegateMethods & CPPopoverDelegate_popover_didClose_)
[_delegate popoverDidClose:self];
}
/*! @ignore */
- (void)attachedWindowDidShow:(_CPAttachedWindow)anAttachedWindow
- (void)_popoverWindowDidShow
{
if (_implementedDelegateMethods & CPPopoverDelegate_popover_didShow_)
[_delegate popoverDidShow:self];
}
#pragma mark -
#pragma mark Notifications
/*!
@ignore
This method is called only when a non-popover parent window
is closing. In that case popovers should order out.
*/
- (void)parentWindowWillClose:(CPNotification)aNotification
/*! @ignore */
- (BOOL)_popoverShouldClose
{
[_attachedWindow orderOut:nil];
[self performClose:nil];
if (_implementedDelegateMethods & CPPopoverDelegate_popover_shouldClose_)
return [_delegate popoverShouldClose:self];
return YES;
}
/*! @ignore */
- (void)_popoverWillClose
{
if (_implementedDelegateMethods & CPPopoverDelegate_popover_willClose_)
[_delegate popoverWillClose:self];
}
/*! @ignore */
- (void)_popoverWillShow
{
if (_implementedDelegateMethods & CPPopoverDelegate_popover_willShow_)
[_delegate popoverWillShow:self];
}
@end
@@ -347,7 +382,7 @@ Set the behavior of the CPPopover. It can be:
@end
var CPPopoverNeedsNewAttachedWindowKey = @"CPPopoverNeedsNewAttachedWindowKey",
var CPPopoverNeedsNewPopoverWindowKey = @"CPPopoverNeedsNewPopoverWindowKey",
CPPopoverAppearanceKey = @"CPPopoverAppearanceKey",
CPPopoverAnimatesKey = @"CPPopoverAnimatesKey",
CPPopoverContentViewControllerKey = @"CPPopoverContentViewControllerKey",
+170 -101
View File
@@ -23,29 +23,27 @@
@import "CGGeometry.j"
@import "CPImageView.j"
@import "CPView.j"
@import "CPWindow_Constants.j"
@typedef CPProgressIndicatorStyle
/*
@global
@group CPProgressIndicatorStyle
*/
CPProgressIndicatorBarStyle = 0;
CPProgressIndicatorBarStyle = 0;
/*
@global
@group CPProgressIndicatorStyle
*/
CPProgressIndicatorSpinningStyle = 1;
CPProgressIndicatorSpinningStyle = 1;
/*
@global
@group CPProgressIndicatorStyle
*/
CPProgressIndicatorHUDBarStyle = 2;
CPProgressIndicatorHUDBarStyle = 2;
var CPProgressIndicatorSpinningStyleColors = nil,
CPProgressIndicatorClassName = nil,
CPProgressIndicatorStyleIdentifiers = nil,
CPProgressIndicatorStyleSizes = nil;
var CPProgressIndicatorSpinningStyleColors = [];
/*!
@ingroup appkit
@@ -64,7 +62,7 @@ var CPProgressIndicatorSpinningStyleColors = nil,
CPControlSize _controlSize;
BOOL _isIndeterminate;
BOOL _indeterminate;
CPProgressIndicatorStyle _style;
BOOL _isAnimating;
@@ -73,66 +71,33 @@ var CPProgressIndicatorSpinningStyleColors = nil,
BOOL _isDisplayedWhenStopped;
}
/*
@ignore
*/
+ (void)initialize
+ (CPString)defaultThemeClass
{
if (self !== [CPProgressIndicator class])
return;
return @"progress-indicator";
}
var bundle = [CPBundle bundleForClass:self];
+ (CPDictionary)themeAttributes
{
return @{
@"indeterminate-bar-color": [CPNull null],
@"bar-color": [CPNull null],
@"default-height": 20,
@"bezel-color": [CPNull null],
@"spinning-mini-gif": [CPNull null],
@"spinning-small-gif": [CPNull null],
@"spinning-regular-gif": [CPNull null],
@"circular-border-color": [CPNull null],
@"circular-border-size": 1,
@"circular-color": [CPNull null]
};
}
CPProgressIndicatorSpinningStyleColors = [];
+ (Class)_binderClassForBinding:(CPString)aBinding
{
if (aBinding === CPValueBinding || aBinding === @"isIndeterminate")
return [_CPProgressIndicatorBinder class];
CPProgressIndicatorSpinningStyleColors[CPMiniControlSize] = [CPColor colorWithPatternImage:[[CPImage alloc] initWithContentsOfFile:
[bundle pathForResource:@"CPProgressIndicator/CPProgressIndicatorSpinningStyleMini.gif"] size:CGSizeMake(16.0, 16.0)]];
CPProgressIndicatorSpinningStyleColors[CPSmallControlSize] = [CPColor colorWithPatternImage:[[CPImage alloc] initWithContentsOfFile:
[bundle pathForResource:@"CPProgressIndicator/CPProgressIndicatorSpinningStyleSmall.gif"] size:CGSizeMake(32.0, 32.0)]];
CPProgressIndicatorSpinningStyleColors[CPRegularControlSize] = [CPColor colorWithPatternImage:[[CPImage alloc] initWithContentsOfFile:
[bundle pathForResource:@"CPProgressIndicator/CPProgressIndicatorSpinningStyleRegular.gif"] size:CGSizeMake(64.0, 64.0)]];
CPProgressIndicatorBezelBorderViewPool = [];
var start = CPProgressIndicatorBarStyle,
end = CPProgressIndicatorHUDBarStyle;
for (; start <= end; ++start)
{
CPProgressIndicatorBezelBorderViewPool[start] = [];
CPProgressIndicatorBezelBorderViewPool[start][CPMiniControlSize] = [];
CPProgressIndicatorBezelBorderViewPool[start][CPSmallControlSize] = [];
CPProgressIndicatorBezelBorderViewPool[start][CPRegularControlSize] = [];
}
CPProgressIndicatorClassName = [self className];
CPProgressIndicatorStyleIdentifiers = [];
CPProgressIndicatorStyleIdentifiers[CPProgressIndicatorBarStyle] = @"Bar";
CPProgressIndicatorStyleIdentifiers[CPProgressIndicatorSpinningStyle] = @"Spinny";
CPProgressIndicatorStyleIdentifiers[CPProgressIndicatorHUDBarStyle] = @"HUDBar";
var regularIdentifier = _CPControlIdentifierForControlSize(CPRegularControlSize),
smallIdentifier = _CPControlIdentifierForControlSize(CPSmallControlSize),
miniIdentifier = _CPControlIdentifierForControlSize(CPMiniControlSize);
CPProgressIndicatorStyleSizes = [];
// Bar Style
var prefixes = [
CPProgressIndicatorClassName + @"BezelBorder" + CPProgressIndicatorStyleIdentifiers[CPProgressIndicatorBarStyle],
CPProgressIndicatorClassName + @"Bar" + CPProgressIndicatorStyleIdentifiers[CPProgressIndicatorBarStyle],
CPProgressIndicatorClassName + @"BezelBorder" + CPProgressIndicatorStyleIdentifiers[CPProgressIndicatorHUDBarStyle],
CPProgressIndicatorClassName + @"Bar" + CPProgressIndicatorStyleIdentifiers[CPProgressIndicatorHUDBarStyle]
];
for (var i = 0, count = prefixes.length; i < count; i++)
{
var prefix = prefixes[i];
CPProgressIndicatorStyleSizes[prefix + regularIdentifier] = [_CGSizeMake(3.0, 16.0), _CGSizeMake(1.0, 16.0), _CGSizeMake(3.0, 16.0)];
CPProgressIndicatorStyleSizes[prefix + smallIdentifier] = [_CGSizeMake(3.0, 16.0), _CGSizeMake(1.0, 16.0), _CGSizeMake(3.0, 16.0)];
CPProgressIndicatorStyleSizes[prefix + miniIdentifier] = [_CGSizeMake(3.0, 16.0), _CGSizeMake(1.0, 16.0), _CGSizeMake(3.0, 16.0)];
}
return [super _binderClassForBinding:aBinding];
}
- (id)initWithFrame:(CGRect)aFrame
@@ -151,8 +116,7 @@ var CPProgressIndicatorSpinningStyleColors = nil,
_controlSize = CPRegularControlSize;
[self updateBackgroundColor];
[self drawBar];
[self setNeedsLayout];
}
return self;
@@ -314,12 +278,12 @@ var CPProgressIndicatorSpinningStyleColors = nil,
Specifies whether this progress indicator should be indeterminate or display progress based on it's max and min.
@param isDeterminate \c YES makes the indicator indeterminate
*/
- (void)setIndeterminate:(BOOL)isIndeterminate
- (void)setIndeterminate:(BOOL)indeterminate
{
if (_isIndeterminate == isIndeterminate)
if (_indeterminate == indeterminate)
return;
_isIndeterminate = isIndeterminate;
_indeterminate = indeterminate;
[self updateBackgroundColor];
}
@@ -329,7 +293,7 @@ var CPProgressIndicatorSpinningStyleColors = nil,
*/
- (BOOL)isIndeterminate
{
return _isIndeterminate;
return _indeterminate;
}
/*!
@@ -343,6 +307,8 @@ var CPProgressIndicatorSpinningStyleColors = nil,
_style = aStyle;
[self setTheme:(_style === CPProgressIndicatorHUDBarStyle) ? [CPTheme defaultHudTheme] : [CPTheme defaultTheme]];
[self updateBackgroundColor];
}
@@ -354,8 +320,7 @@ var CPProgressIndicatorSpinningStyleColors = nil,
if (_style == CPProgressIndicatorSpinningStyle)
[self setFrameSize:[[CPProgressIndicatorSpinningStyleColors[_controlSize] patternImage] size]];
else
[self setFrameSize:CGSizeMake(CGRectGetWidth([self frame]), CPProgressIndicatorStyleSizes[
CPProgressIndicatorClassName + @"BezelBorder" + CPProgressIndicatorStyleIdentifiers[CPProgressIndicatorBarStyle] + _CPControlIdentifierForControlSize(_controlSize)][0].height)];
[self setFrameSize:CGSizeMake(CGRectGetWidth([self frame]), [self valueForThemeAttribute:@"default-height"])];
}
/*!
@@ -405,25 +370,13 @@ var CPProgressIndicatorSpinningStyleColors = nil,
/* @ignore */
- (void)drawBar
{
if (_style == CPProgressIndicatorSpinningStyle)
return;
var barView = [self layoutEphemeralSubviewNamed:"bar-view"
positioned:CPWindowBelow
relativeToEphemeralSubviewNamed:nil];
[barView setBackgroundColor:_CPControlThreePartImagePattern(
NO,
CPProgressIndicatorStyleSizes,
CPProgressIndicatorClassName,
@"Bar",
CPProgressIndicatorStyleIdentifiers[_style],
_CPControlIdentifierForControlSize(_controlSize))];
[self setNeedsLayout];
[self setNeedsDisplay:YES];
}
- (CPView)createEphemeralSubviewNamed:(CPString)aName
{
return [[CPView alloc] initWithFrame:_CGRectMakeZero()];
return [[CPView alloc] initWithFrame:CGRectMakeZero()];
}
- (CGRect)rectForEphemeralSubviewNamed:(CPString)aViewName
@@ -436,7 +389,10 @@ var CPProgressIndicatorSpinningStyleColors = nil,
if (barWidth > 0.0 && barWidth < 4.0)
barWidth = 4.0;
return _CGRectMake(0, 0, barWidth, 16.0);
if (_indeterminate)
barWidth = width;
return CGRectMake(0, 0, barWidth, [self valueForThemeAttribute:@"default-height"]);
}
return nil;
@@ -444,11 +400,26 @@ var CPProgressIndicatorSpinningStyleColors = nil,
/* @ignore */
- (void)updateBackgroundColor
{
if ([CPProgressIndicatorSpinningStyleColors count] === 0)
{
CPProgressIndicatorSpinningStyleColors[CPMiniControlSize] = [self valueForThemeAttribute:@"spinning-mini-gif"];
CPProgressIndicatorSpinningStyleColors[CPSmallControlSize] = [self valueForThemeAttribute:@"spinning-small-gif"];
CPProgressIndicatorSpinningStyleColors[CPRegularControlSize] = [self valueForThemeAttribute:@"spinning-regular-gif"];
}
[self setNeedsLayout];
}
- (void)layoutSubviews
{
if (YES)//_isBezeled)
{
if (_style == CPProgressIndicatorSpinningStyle)
{
if (!_indeterminate)
return;
// This will cause the bar view to go away due to having a nil rect when _style == CPProgressIndicatorSpinningStyle.
[self layoutEphemeralSubviewNamed:"bar-view"
positioned:CPWindowBelow
@@ -458,21 +429,70 @@ var CPProgressIndicatorSpinningStyleColors = nil,
}
else
{
[self setBackgroundColor:_CPControlThreePartImagePattern(
NO,
CPProgressIndicatorStyleSizes,
CPProgressIndicatorClassName,
@"BezelBorder",
CPProgressIndicatorStyleIdentifiers[_style],
_CPControlIdentifierForControlSize(_controlSize))];
[self setBackgroundColor:[self currentValueForThemeAttribute:@"bezel-color"]];
[self drawBar];
var barView = [self layoutEphemeralSubviewNamed:"bar-view"
positioned:CPWindowBelow
relativeToEphemeralSubviewNamed:nil];
if (_indeterminate)
[barView setBackgroundColor:[self currentValueForThemeAttribute:@"indeterminate-bar-color"]];
else
[barView setBackgroundColor:[self currentValueForThemeAttribute:@"bar-color"]];
}
}
else
[self setBackgroundColor:nil];
}
- (void)drawRect:(CGRect)aRect
{
if (_style == CPProgressIndicatorSpinningStyle && !_indeterminate)
{
var context = [[CPGraphicsContext currentContext] graphicsPort],
rect = CGRectMakeCopy(aRect),
borderSize = [self currentValueForThemeAttribute:@"circular-border-size"];
rect.origin.x += borderSize;
rect.origin.y += borderSize;
rect.size.width = rect.size.width - borderSize * 2;
rect.size.height = rect.size.height - borderSize * 2;
if ([self doubleValue] > [self minValue] && [self doubleValue] < [self maxValue])
{
var midX = CGRectGetMidX(rect),
midY = CGRectGetMidY(rect),
endAngle = Math.PI * 2 * (([self doubleValue] - [self minValue]) / ([self maxValue] - [self minValue])) - Math.PI / 2,
radius = MIN(rect.size.width / 2, rect.size.height / 2);
CGContextBeginPath(context);
CGContextSetLineWidth(context, borderSize);
CGContextSetFillColor(context, [self currentValueForThemeAttribute:@"circular-color"]);
CGContextMoveToPoint(context, midX, midY);
CGContextAddArc(context, midX, midY, radius, 3 * Math.PI / 2, endAngle, YES);
CGContextAddLineToPoint(context, midX, midY);
CGContextClosePath(context);
CGContextFillPath(context);
CGContextStrokePath(context);
}
else if ([self doubleValue] == [self maxValue])
{
CGContextBeginPath(context);
CGContextSetFillColor(context, [self currentValueForThemeAttribute:@"circular-color"]);
CGContextAddEllipseInRect(context, rect);
CGContextClosePath(context);
CGContextFillPath(context);
}
CGContextBeginPath(context);
CGContextSetStrokeColor(context , [self currentValueForThemeAttribute:@"circular-border-color"]);
CGContextSetLineWidth(context, borderSize);
CGContextAddEllipseInRect(context, rect);
CGContextClosePath(context);
CGContextStrokePath(context);
}
}
@end
@@ -486,7 +506,7 @@ var CPProgressIndicatorSpinningStyleColors = nil,
_maxValue = [aCoder decodeObjectForKey:@"_maxValue"];
_doubleValue = [aCoder decodeObjectForKey:@"_doubleValue"];
_controlSize = [aCoder decodeObjectForKey:@"_controlSize"];
_isIndeterminate = [aCoder decodeObjectForKey:@"_isIndeterminate"];
_indeterminate = [aCoder decodeObjectForKey:@"_indeterminate"];
_style = [aCoder decodeIntForKey:@"_style"];
_isAnimating = [aCoder decodeObjectForKey:@"_isAnimating"];
_isDisplayedWhenStoppedSet = [aCoder decodeObjectForKey:@"_isDisplayedWhenStoppedSet"];
@@ -500,8 +520,8 @@ var CPProgressIndicatorSpinningStyleColors = nil,
- (void)encodeWithCoder:(CPCoder)aCoder
{
// Don't encode the background colour. It can be recreated based on the flags and if encoded causes hardcoded
// image paths in the cib while just wasting space.
// Don't encode the background colour. It can be recreated based on the flags
// and if encoded causes hardcoded image paths in the cib while just wasting space.
var backgroundColor = [self backgroundColor];
[self setBackgroundColor:nil];
[super encodeWithCoder:aCoder];
@@ -511,7 +531,7 @@ var CPProgressIndicatorSpinningStyleColors = nil,
[aCoder encodeObject:_maxValue forKey:@"_maxValue"];
[aCoder encodeObject:_doubleValue forKey:@"_doubleValue"];
[aCoder encodeObject:_controlSize forKey:@"_controlSize"];
[aCoder encodeObject:_isIndeterminate forKey:@"_isIndeterminate"];
[aCoder encodeObject:_indeterminate forKey:@"_indeterminate"];
[aCoder encodeInt:_style forKey:@"_style"];
[aCoder encodeObject:_isAnimating forKey:@"_isAnimating"];
[aCoder encodeObject:_isDisplayedWhenStoppedSet forKey:@"_isDisplayedWhenStoppedSet"];
@@ -519,3 +539,52 @@ var CPProgressIndicatorSpinningStyleColors = nil,
}
@end
@implementation _CPProgressIndicatorBinder : CPBinder
- (void)_updatePlaceholdersWithOptions:(CPDictionary)options forBinding:(CPString)aBinding
{
var value = aBinding === CPValueBinding ? 0.0 : YES;
[self _setPlaceholder:value forMarker:CPMultipleValuesMarker isDefault:YES];
[self _setPlaceholder:value forMarker:CPNoSelectionMarker isDefault:YES];
[self _setPlaceholder:value forMarker:CPNotApplicableMarker isDefault:YES];
[self _setPlaceholder:value forMarker:CPNullMarker isDefault:YES];
}
- (id)valueForBinding:(CPString)aBinding
{
if (aBinding === CPValueBinding)
return [_source doubleValue];
else if (aBinding === @"isIndeterminate")
[_source isIndeterminate];
else
return [super valueForBinding:aBinding];
}
- (BOOL)_setValue:(id)aValue forBinding:(CPString)aBinding
{
if (aBinding === CPValueBinding)
[_source setDoubleValue:aValue];
else if (aBinding === @"isIndeterminate")
[_source setIndeterminate:aValue];
else
return NO;
return YES;
}
- (void)setValue:(id)aValue forBinding:(CPString)aBinding
{
if (![self _setValue:aValue forBinding:aBinding])
[super setValue:aValue forBinding:aBinding];
}
- (void)setPlaceholderValue:(id)aValue withMarker:(CPString)aMarker forBinding:(CPString)aBinding
{
if (![self _setValue:aValue forBinding:aBinding])
[super setPlaceholderValue:aValue withMarker:aMarker forBinding:aBinding];
}
@end
+201 -17
View File
@@ -25,6 +25,11 @@
@import "CPButton.j"
@class CPRadioGroup
@global CPApp
CPRadioImageOffset = 4.0;
/*!
@ingroup appkit
@@ -63,9 +68,6 @@
option.
*/
CPRadioImageOffset = 4.0;
@implementation CPRadio : CPButton
{
CPRadioGroup _radioGroup;
@@ -150,7 +152,7 @@ CPRadioImageOffset = 4.0;
[_radioGroup _setSelectedRadio:self];
}
- (void)sendAction:(SEL)anAction to:(id)anObject
- (BOOL)sendAction:(SEL)anAction to:(id)anObject
{
[super sendAction:anAction to:anObject];
@@ -202,29 +204,122 @@ var CPRadioRadioGroupKey = @"CPRadioRadioGroupKey";
@implementation CPRadioGroup : CPObject
{
CPSet _radios;
CPArray _radios;
CPRadio _selectedRadio;
BOOL _enabled @accessors(getter=enabled);
BOOL _hidden @accessors(getter=hidden);
id _target @accessors(property=target);
SEL _action @accessors(property=action);
}
+ (void)initialize
{
if (self !== [CPRadioGroup class])
return;
[self exposeBinding:CPSelectedValueBinding];
[self exposeBinding:CPSelectedTagBinding];
[self exposeBinding:CPSelectedIndexBinding];
[self exposeBinding:CPEnabledBinding];
[self exposeBinding:CPHiddenBinding];
}
- (id)init
{
self = [super init];
if (self)
{
_radios = [CPSet set];
_radios = [];
_selectedRadio = nil;
_enabled = YES;
_hidden = NO;
}
return self;
}
/*!
Selects the radio button at the given index within the group.
If index is -1, all of the radio buttons are turned off.
*/
- (void)selectRadioAtIndex:(int)index
{
if (index === -1)
[self _setSelectedRadio:nil];
else
{
var radio = [_radios objectAtIndex:index];
[self _setSelectedRadio:radio];
[radio setState:CPOnState];
}
}
/*!
Selects the first radio button within the group with the given tag.
If a radio button with the given tag is found, selects it
and returns YES. Otherwise returns NO.
*/
- (BOOL)selectRadioWithTag:(int)tag
{
var index = [_radios indexOfObjectPassingTest:function(radio)
{
return [radio tag] === tag;
}];
if (index !== CPNotFound)
{
[self selectRadioAtIndex:index];
return YES;
}
else
return NO;
}
/*!
Returns the CPRadio that is currently selected within the group,
or nil if none are selected.
*/
- (CPRadio)selectedRadio
{
return _selectedRadio;
}
/*!
Returns the index of the selected radio within the array of radio buttons.
Buttons are numbered going left to right and top to bottom. Returns -1
if no radio within the group is selected.
*/
- (int)selectedRadioIndex
{
return [_radios indexOfObject:_selectedRadio];
}
- (CPArray)radios
{
return _radios;
}
- (void)setEnabled:(BOOL)enabled
{
[_radios makeObjectsPerformSelector:@selector(setEnabled:) withObject:enabled];
}
- (void)setHidden:(BOOL)hidden
{
[_radios makeObjectsPerformSelector:@selector(setHidden:) withObject:hidden];
}
#pragma mark Private
- (void)_addRadio:(CPRadio)aRadio
{
[_radios addObject:aRadio];
if ([_radios indexOfObject:aRadio] === CPNotFound)
[_radios addObject:aRadio];
if ([aRadio state] === CPOnState)
[self _setSelectedRadio:aRadio];
@@ -238,23 +333,30 @@ var CPRadioRadioGroupKey = @"CPRadioRadioGroupKey";
[_radios removeObject:aRadio];
}
/*!
Selects the first radio button within the group with the given tag.
If a radio button with the given tag is found, selects it
and returns YES. Otherwise returns NO.
*/
- (void)_selectRadioWithTitle:(CPString)aTitle
{
var index = [_radios indexOfObjectPassingTest:function(radio)
{
return [radio title] === aTitle;
}];
[self selectRadioAtIndex:index];
}
- (void)_setSelectedRadio:(CPRadio)aRadio
{
if (_selectedRadio === aRadio)
return;
[_selectedRadio setState:CPOffState];
_selectedRadio = aRadio;
}
- (CPRadio)selectedRadio
{
return _selectedRadio;
}
- (CPArray)radios
{
return [_radios allObjects];
[_CPRadioGroupSelectionBinder _reverseSetValueFromExclusiveBinderForObject:self];
}
@end
@@ -284,3 +386,85 @@ var CPRadioGroupRadiosKey = @"CPRadioGroupRadiosKey",
}
@end
@implementation CPRadioGroup (BindingSupport)
+ (Class)_binderClassForBinding:(CPString)aBinding
{
if (aBinding === CPSelectedValueBinding ||
aBinding === CPSelectedTagBinding ||
aBinding === CPSelectedIndexBinding)
{
var capitalizedBinding = aBinding.charAt(0).toUpperCase() + aBinding.substr(1);
return [CPClassFromString(@"_CPRadioGroup" + capitalizedBinding + "Binder") class];
}
else if ([aBinding hasPrefix:CPEnabledBinding])
return [CPMultipleValueAndBinding class];
else if ([aBinding hasPrefix:CPHiddenBinding])
return [CPMultipleValueOrBinding class];
return [super _binderClassForBinding:aBinding];
}
+ (BOOL)isBindingExclusive:(CPString)aBinding
{
return (aBinding == CPSelectedIndexBinding ||
aBinding == CPSelectedTagBinding ||
aBinding == CPSelectedValueBinding);
}
@end
@implementation _CPRadioGroupSelectionBinder : CPBinder
{
}
- (void)setPlaceholderValue:(id)aValue withMarker:(CPString)aMarker forBinding:(CPString)aBinding
{
[self setValue:aValue forBinding:aBinding];
}
@end
@implementation _CPRadioGroupSelectedIndexBinder : _CPRadioGroupSelectionBinder
- (void)setValue:(id)aValue forBinding:(CPString)aBinding
{
[_source selectRadioAtIndex:aValue];
}
- (id)valueForBinding:(CPString)aBinding
{
return [_source selectedRadioIndex];
}
@end
@implementation _CPRadioGroupSelectedTagBinder : _CPRadioGroupSelectionBinder
- (void)setValue:(id)aValue forBinding:(CPString)aBinding
{
[_source selectRadioWithTag:aValue];
}
- (id)valueForBinding:(CPString)aBinding
{
return [[_source selectedRadio] tag];
}
@end
@implementation _CPRadioGroupSelectedValueBinder : _CPRadioGroupSelectionBinder
- (void)setValue:(id)aValue forBinding:(CPString)aBinding
{
[_source _selectRadioWithTitle:aValue];
}
- (id)valueForBinding:(CPString)aBinding
{
return [[_source selectedRadio] title];
}
@end
+19 -1
View File
@@ -21,7 +21,13 @@
*/
@import <Foundation/CPObject.j>
@import <Foundation/CPObjJRuntime.j>
@import "CPEvent.j"
@import "CPCursor.j"
@class CPKeyBinding
@class CPMenu
CPDeleteKeyCode = 8;
CPTabKeyCode = 9;
@@ -195,6 +201,18 @@ CPDeleteForwardKeyCode = 46;
[_nextResponder performSelector:_cmd withObject:anEvent];
}
/*!
Notifies the receiver that the mouse entered the receiver's area and that it can adapt the cursor.
@param anEvent contains information about the exit
*/
- (void)cursorUpdate:(CPEvent)anEvent
{
if (_nextResponder)
[_nextResponder performSelector:_cmd withObject:anEvent];
else
[[CPCursor arrowCursor] set];
}
/*!
Notifies the receiver that the mouse scroll wheel has moved.
@param anEvent information about the scroll
@@ -352,7 +370,7 @@ CPDeleteForwardKeyCode = 46;
var CPResponderNextResponderKey = @"CPResponderNextResponderKey",
CPResponderMenuKey = @"CPResponderMenuKey";
@implementation CPResponder (CPCoding)
@implementation CPResponder (CPCoding) <CPCoding>
/*!
Initializes the responder with data from a coder.
+15 -11
View File
@@ -82,15 +82,15 @@
}
/*! @cond */
+ (Class)_binderClassForBinding:(CPString)theBinding
+ (Class)_binderClassForBinding:(CPString)aBinding
{
if (theBinding == CPValueBinding)
if (aBinding == CPValueBinding)
return [CPPredicateEditorValueBinder class];
return [super _binderClassForBinding:theBinding];
return [super _binderClassForBinding:aBinding];
}
- (id)_replacementKeyPathForBinding:(CPString)aBinding
- (CPString)_replacementKeyPathForBinding:(CPString)aBinding
{
if (aBinding == CPValueBinding)
return @"predicate";
@@ -220,7 +220,7 @@
var children = [CPArray array],
itemsCount = 0,
menuIndex = -1,
itemsArray,
itemArray,
templateView = [templateViews objectAtIndex:count],
isPopup = [templateView isKindOfClass:[CPPopUpButton class]];
@@ -360,7 +360,11 @@
rootItems = [treeChild children];
}
var row = [CPDictionary dictionaryWithObjectsAndKeys:criteria, @"criteria", values, @"displayValues", rowType, @"rowType"];
var row = @{
@"criteria": criteria,
@"displayValues": values,
@"rowType": rowType,
};
return row;
}
@@ -480,7 +484,7 @@
#pragma mark RuleEditor delegate methods
- (int)_queryNumberOfChildrenOfItem:(id)rowItem withRowType:(int)type
- (int)_queryNumberOfChildrenOfItem:(id)rowItem withRowType:(CPRuleEditorRowType)type
{
if (rowItem == nil)
{
@@ -490,7 +494,7 @@
return [[rowItem children] count];
}
- (id)_queryChild:(int)childIndex ofItem:(id)rowItem withRowType:(int)type
- (id)_queryChild:(int)childIndex ofItem:(id)rowItem withRowType:(CPRuleEditorRowType)type
{
if (rowItem == nil)
{
@@ -501,7 +505,7 @@
return [[rowItem children] objectAtIndex:childIndex];
}
- (id)_queryValueForItem:(id)rowItem inRow:(int)rowIndex
- (id)_queryValueForItem:(id)rowItem inRow:(CPInteger)rowIndex
{
return [rowItem displayValue];
}
@@ -512,7 +516,7 @@ var CPPredicateTemplatesKey = @"CPPredicateTemplates";
@implementation CPPredicateEditor (CPCoding)
- (id)initWithCoder:(id)aCoder
- (id)initWithCoder:(CPCoder)aCoder
{
self = [super initWithCoder:aCoder];
@@ -527,7 +531,7 @@ var CPPredicateTemplatesKey = @"CPPredicateTemplates";
return self;
}
- (void)encodeWithCoder:(id)aCoder
- (void)encodeWithCoder:(CPCoder)aCoder
{
[super encodeWithCoder:aCoder];
[aCoder encodeObject:_allTemplates forKey:CPPredicateTemplatesKey];
@@ -20,6 +20,16 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import <Foundation/CPPredicate.j>
@import "CPCheckBox.j"
@import "CPPopUpButton.j"
@import "CPMenuItem.j"
@import "CPTextField.j"
@import "CPDatePicker.j"
CPUndefinedAttributeType = 0;
CPInteger16AttributeType = 100;
CPInteger32AttributeType = 200;
@@ -461,9 +471,11 @@ CPTransformableAttributeType = 1800;
var value;
if (attributeType >= CPInteger16AttributeType && attributeType <= CPFloatAttributeType)
value = [aView intValue];
value = [aView floatValue];
else if (attributeType == CPBooleanAttributeType)
value = [aView state];
else if (attributeType == CPDateAttributeType)
value = [aView dateValue];
else
value = [aView stringValue];
@@ -477,7 +489,36 @@ CPTransformableAttributeType = 1800;
- (id)copy
{
return [CPKeyedUnarchiver unarchiveObjectWithData:[CPKeyedArchiver archivedDataWithRootObject:self]];
var views = [CPArray array],
copy = [[[self class] alloc] init];
[copy _setTemplateType:_templateType];
[copy _setOptions:_predicateOptions];
[copy _setModifier:_predicateModifier];
[copy _setLeftAttributeType:_leftAttributeType];
[copy _setRightAttributeType:_rightAttributeType];
[copy setLeftIsWildcard:_leftIsWildcard];
[copy setRightIsWildcard:_rightIsWildcard];
[_views enumerateObjectsUsingBlock:function(aView, idx, stop)
{
var vcopy;
if ([aView implementsSelector:@selector(copy)])
{
vcopy = [aView copy];
}
else
{
vcopy = [CPKeyedUnarchiver unarchiveObjectWithData:[CPKeyedArchiver archivedDataWithRootObject:aView]];
}
[views addObject:vcopy];
}];
[copy setTemplateViews:views];
return copy;
}
+ (id)_operatorsForAttributeType:(CPAttributeType)attributeType
@@ -583,7 +624,7 @@ CPTransformableAttributeType = 1800;
- (CPPopUpButton)_viewFromExpressions:(CPArray)expressions
{
var popup = [[CPPopUpButton alloc] initWithFrame:CPMakeRect(0, 0, 100, 18)],
var popup = [[CPPopUpButton alloc] initWithFrame:CGRectMake(0, 0, 100, 18)],
count = [expressions count];
for (var i = 0; i < count; i++)
@@ -669,7 +710,10 @@ CPTransformableAttributeType = 1800;
view = [[CPCheckBox alloc] initWithFrame:CGRectMake(0, 0, 50, 26)];
}
else if (attributeType == CPDateAttributeType)
view = [[CPDatePicker alloc] initWithFrame:CGRectMake(0, 0, 150, 26)];
{
view = [[CPDatePicker alloc] initWithFrame:CGRectMake(0, 0, 180, 26)];
[view setDatePickerElements:CPYearMonthDayDatePickerElementFlag];
}
else
return nil;
@@ -691,12 +735,12 @@ CPTransformableAttributeType = 1800;
return textField;
}
- (void)_setOptions:(unsigned int)options
- (void)_setOptions:(unsigned)options
{
_predicateOptions = options;
}
- (void)_setModifier:(unsigned int)modifier
- (void)_setModifier:(unsigned)modifier
{
_predicateModifier = modifier;
}
@@ -786,5 +830,31 @@ var CPPredicateTemplateTypeKey = @"CPPredicateTemplateType",
[coder encodeObject:_views forKey:CPPredicateTemplateViewsKey];
}
@end
// Copy support for built-in types
@implementation CPDatePicker (CPCopying)
- (id)copy
{
var ret = [[[self class] alloc] initWithFrame:[self frame]];
[ret setTextFont:[self textFont]];
[ret setMinDate:[self minDate]];
[ret setMaxDate:[self maxDate]];
[ret setTimeInterval:[self timeInterval]];
[ret setDatePickerMode:[self datePickerMode]];
[ret setDatePickerElements:[self datePickerElements]];
[ret setDatePickerStyle:[self datePickerStyle]];
[ret setLocale:[self locale]];
[ret setDateValue:[self dateValue]];
[ret setBackgroundColor:[self backgroundColor]];
[ret setDrawsBackground:[self drawsBackground]];
[ret setBordered:[self isBordered]];
[ret _init];
return ret;
}
@end
/*! @endcond */
+174 -116
View File
@@ -20,35 +20,41 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import <AppKit/CPTextField.j>
@import <AppKit/CPViewAnimation.j>
@import <AppKit/CPView.j>
@import <Foundation/CPPredicate.j>
@import <Foundation/CPArray.j>
@import <Foundation/CPDictionary.j>
@import <Foundation/CPIndexSet.j>
@import "CPPasteboard.j"
@import "CPRuleEditor_Constants.j"
@import "CPTextField.j"
@import "CPViewAnimation.j"
@import "CPView.j"
@import "_CPRuleEditorViewSliceRow.j"
@import "_CPRuleEditorLocalizer.j"
CPRuleEditorPredicateLeftExpression = "CPRuleEditorPredicateLeftExpression";
CPRuleEditorPredicateRightExpression = "CPRuleEditorPredicateRightExpression";
CPRuleEditorPredicateComparisonModifier = "CPRuleEditorPredicateComparisonModifier";
CPRuleEditorPredicateOptions = "CPRuleEditorPredicateOptions";
CPRuleEditorPredicateOperatorType = "CPRuleEditorPredicateOperatorType";
CPRuleEditorPredicateCustomSelector = "CPRuleEditorPredicateCustomSelector";
CPRuleEditorPredicateCompoundType = "CPRuleEditorPredicateCompoundType";
@class CPCompoundPredicate
@class CPComparisonPredicate
CPRuleEditorRowsDidChangeNotification = "CPRuleEditorRowsDidChangeNotification";
CPRuleEditorRulesDidChangeNotification = "CPRuleEditorRulesDidChangeNotification";
@global CPDirectPredicateModifier
@global CPCaseInsensitivePredicateOption
@global CPOrPredicateType
CPRuleEditorNestingModeSingle = 0; // Only a single row is allowed. Plus/minus buttons will not be shown
CPRuleEditorNestingModeList = 1; // Allows a single list, with no nesting and no compound rows
CPRuleEditorNestingModeCompound = 2; // Unlimited nesting and compound rows; this is the default
CPRuleEditorNestingModeSimple = 3; // One compound row at the top with subrows beneath it, and no further nesting allowed
@protocol CPRuleEditorDelegate <CPObject>
CPRuleEditorRowTypeSimple = 0;
CPRuleEditorRowTypeCompound = 1;
@required
- (id)ruleEditor:(CPRuleEditor)editor child:(CPInteger)index forCriterion:(id)criterion withRowType:(CPRuleEditorRowType)rowType;
- (id)ruleEditor:(CPRuleEditor)editor displayValueForCriterion:(id)criterion inRow:(CPInteger)row;
- (CPInteger)ruleEditor:(CPRuleEditor)editor numberOfChildrenForCriterion:(id)criterion withRowType:(CPRuleEditorRowType)rowType;
@optional
- (CPDictionary)ruleEditor:(CPRuleEditor)editor predicatePartsForCriterion:(id)criterion withDisplayValue:(id)value inRow:(CPInteger)row;
- (void)ruleEditorRowsDidChange:(CPNotification)notification;
@end
var CPRuleEditorDelegate_ruleEditor_predicatePartsForCriterion_withDisplayValue_inRow_ = 1 << 1;
var CPRuleEditorItemPBoardType = @"CPRuleEditorItemPBoardType",
itemsContext = "items",
@@ -78,50 +84,51 @@ var CPRuleEditorItemPBoardType = @"CPRuleEditorItemPBoardType",
@implementation CPRuleEditor : CPControl
{
BOOL _suppressKeyDownHandling;
BOOL _allowsEmptyCompoundRows;
BOOL _disallowEmpty;
BOOL _delegateWantsValidation;
BOOL _editable;
BOOL _sendAction;
BOOL _suppressKeyDownHandling;
BOOL _allowsEmptyCompoundRows;
BOOL _disallowEmpty;
BOOL _delegateWantsValidation;
BOOL _editable;
BOOL _sendAction;
Class _rowClass;
Class _rowClass;
CPIndexSet _draggingRows;
CPInteger _subviewIndexOfDropLine;
CPView _dropLineView;
CPIndexSet _draggingRows;
CPInteger _subviewIndexOfDropLine;
CPView _dropLineView;
CPMutableArray _rowCache;
CPMutableArray _slices;
CPMutableArray _rowCache;
CPMutableArray _slices;
CPPredicate _predicate;
CPPredicate _predicate;
CPString _itemsKeyPath;
CPString _subrowsArrayKeyPath;
CPString _typeKeyPath;
CPString _valuesKeyPath;
CPString _boundArrayKeyPath @accessors(property=boundArrayKeyPath);
CPString _itemsKeyPath;
CPString _subrowsArrayKeyPath;
CPString _typeKeyPath;
CPString _valuesKeyPath;
CPString _boundArrayKeyPath @accessors(property=boundArrayKeyPath);
CPView _slicesHolder;
CPViewAnimation _currentAnimation;
CPView _slicesHolder;
CPViewAnimation _currentAnimation;
CPInteger _lastRow;
CPInteger _nestingMode;
CPInteger _lastRow;
CPInteger _nestingMode;
float _alignmentGridWidth;
float _sliceHeight;
float _alignmentGridWidth;
float _sliceHeight;
id _ruleDataSource;
id _ruleDelegate;
id _boundArrayOwner;
id _ruleDataSource;
id <CPRuleEditorDelegate> _ruleDelegate;
id _boundArrayOwner;
unsigned _implementedDelegateMethods;
CPString _stringsFilename;
CPString _stringsFilename;
BOOL _isKeyDown;
BOOL _nestingModeDidChange;
BOOL _isKeyDown;
BOOL _nestingModeDidChange;
_CPRuleEditorLocalizer _standardLocalizer @accessors(property=standardLocalizer);
CPDictionary _itemsAndValuesToAddForRowType;
_CPRuleEditorLocalizer _standardLocalizer @accessors(property=standardLocalizer);
CPDictionary _itemsAndValuesToAddForRowType;
}
/*! @cond */
@@ -131,10 +138,20 @@ var CPRuleEditorItemPBoardType = @"CPRuleEditorItemPBoardType",
return @"rule-editor";
}
+ (id)themeAttributes
+ (CPDictionary)themeAttributes
{
return [CPDictionary dictionaryWithObjects:[[CPNull null], [CPNull null], [CPNull null], [CPNull null], [CPNull null], [CPNull null], [CPNull null], [CPNull null]]
forKeys:[@"alternating-row-colors", @"selected-color", @"slice-top-border-color", @"slice-bottom-border-color", @"slice-last-bottom-border-color", @"font", @"add-image", @"remove-image"]];
return @{
@"alternating-row-colors": [CPNull null],
@"selected-color": [CPNull null],
@"slice-top-border-color": [CPNull null],
@"slice-bottom-border-color": [CPNull null],
@"slice-last-bottom-border-color": [CPNull null],
@"font": [CPFont systemFontOfSize:12],
@"font-color": [CPNull null],
@"add-image": [CPNull null],
@"remove-image": [CPNull null],
@"vertical-alignment": [CPNull null]
};
}
- (id)initWithFrame:(CGRect)frame
@@ -144,7 +161,7 @@ var CPRuleEditorItemPBoardType = @"CPRuleEditorItemPBoardType",
{
_slices = [[CPMutableArray alloc] init];
_sliceHeight = 26.;
_sliceHeight = 26.0;
_nestingMode = CPRuleEditorNestingModeSimple; // 10.5 default is CPRuleEditorNestingModeCompound
_editable = YES;
_allowsEmptyCompoundRows = NO;
@@ -214,19 +231,24 @@ var CPRuleEditorItemPBoardType = @"CPRuleEditorItemPBoardType",
@discussion CPRuleEditor requires a delegate that implements the required delegate methods to function.
@see delegate
*/
- (void)setDelegate:(id)aDelegate
- (void)setDelegate:(id <CPRuleEditorDelegate>)aDelegate
{
if (_ruleDelegate === aDelegate)
return;
var nc = [CPNotificationCenter defaultCenter];
if (_ruleDelegate)
[nc removeObserver:_ruleDelegate name:nil object:self];
_ruleDelegate = aDelegate;
_implementedDelegateMethods = 0;
if ([_ruleDelegate respondsToSelector:@selector(ruleEditorRowsDidChange:)])
[nc addObserver:_ruleDelegate selector:@selector(ruleEditorRowsDidChange:) name:CPRuleEditorRowsDidChangeNotification object:nil];
if ([_ruleDelegate respondsToSelector:@selector(ruleEditor:predicatePartsForCriterion:withDisplayValue:inRow:)])
_implementedDelegateMethods |= CPRuleEditorDelegate_ruleEditor_predicatePartsForCriterion_withDisplayValue_inRow_;
}
/*!
@brief Returns a Boolean value that indicates whether the receiver is editable.
@@ -462,7 +484,7 @@ var CPRuleEditorItemPBoardType = @"CPRuleEditorItemPBoardType",
@param row The index of a row in the receiver.
@return The currently chosen items for row @a row.
*/
- (id)criteriaForRow:(int)row
- (id)criteriaForRow:(CPInteger)row
{
var rowcache = [self _rowCacheForIndex:row];
if (rowcache)
@@ -481,7 +503,7 @@ var CPRuleEditorItemPBoardType = @"CPRuleEditorItemPBoardType",
@return The chosen values (strings, views, or menu items) for row row.
@discussion The values returned are the same as those returned from the delegate method -#ruleEditor:displayValueForCriterion:inRow:
*/
- (CPMutableArray)displayValuesForRow:(int)row
- (CPMutableArray)displayValuesForRow:(CPInteger)row
{
var rowcache = [self _rowCacheForIndex:row];
if (rowcache)
@@ -504,7 +526,7 @@ var CPRuleEditorItemPBoardType = @"CPRuleEditorItemPBoardType",
@param rowIndex The index of a row in the receiver.
@return The index of the parent of the row at @a rowIndex. If the row at @a rowIndex is a root row, returns @c -1.
*/
- (int)parentRowForRow:(int)rowIndex
- (int)parentRowForRow:(CPInteger)rowIndex
{
if (rowIndex < 0 || rowIndex >= [self numberOfRows])
[CPException raise:CPRangeException reason:_cmd + @" row " + rowIndex + " is out of range"];
@@ -545,7 +567,7 @@ TODO: implement
@return The type of the row at @a rowIndex.
@warning Raises a @c CPRangeException if rowIndex is less than @c 0 or greater than or equal to the number of rows.
*/
- (CPRuleEditorRowType)rowTypeForRow:(int)rowIndex
- (CPRuleEditorRowType)rowTypeForRow:(CPInteger)rowIndex
{
if (rowIndex < 0 || rowIndex > [self numberOfRows])
[CPException raise:CPRangeException reason:_cmd + @"row " + rowIndex + " is out of range"];
@@ -566,7 +588,7 @@ TODO: implement
@return The immediate subrows of the row at @a rowIndex.
@discussion Rows are numbered starting at @c 0.
*/
- (CPIndexSet)subrowIndexesForRow:(int)rowIndex
- (CPIndexSet)subrowIndexesForRow:(CPInteger)rowIndex
{
var object;
@@ -692,7 +714,7 @@ TODO: implement
@note Currently, @a shouldAnimate has no effect, rows are always animated when calling this method.
@see addRow:
*/
- (void)insertRowAtIndex:(int)rowIndex withType:(unsigned int)rowType asSubrowOfRow:(int)parentRow animate:(BOOL)shouldAnimate
- (void)insertRowAtIndex:(int)rowIndex withType:(unsigned int)rowType asSubrowOfRow:(CPInteger)parentRow animate:(BOOL)shouldAnimate
{
/*
TODO: raise exceptions if parentRow is greater than or equal to rowIndex, or if rowIndex would fall amongst the children of some other parent, or if the nesting mode forbids this configuration.
@@ -800,7 +822,7 @@ TODO: implement
*/
- (CPPredicate)predicateForRow:(CPInteger)aRow
{
var predicateParts = [CPDictionary dictionary],
var predicateParts = @{},
items = [self criteriaForRow:aRow],
count = [items count],
predicate,
@@ -811,7 +833,7 @@ TODO: implement
var item = [items objectAtIndex:i],
//var displayValue = [self _queryValueForItem:item inRow:aRow]; Ask the delegate or get cached value ?.
displayValue = [[self displayValuesForRow:aRow] objectAtIndex:i],
predpart = [_ruleDelegate ruleEditor:self predicatePartsForCriterion:item withDisplayValue:displayValue inRow:aRow];
predpart = [self _sendDelegateRuleEditorPredicatePartsForCriterion:item withDisplayValue:displayValue inRow:aRow];
if (predpart)
[predicateParts addEntriesFromDictionary:predpart];
@@ -1314,7 +1336,7 @@ TODO: implement
return [_boundArrayOwner mutableArrayValueForKey:_boundArrayKeyPath];
}
- (BOOL)_nextUnusedItems:(CPArray)items andValues:(CPArray)values forRow:(int)rowIndex forRowType:(unsigned int)type
- (BOOL)_nextUnusedItems:(CPArray)items andValues:(CPArray)values forRow:(CPInteger)rowIndex forRowType:(unsigned int)type
{
var parentItem = [items lastObject], // if empty items array, this is NULL aka the root item;
childrenCount = [self _queryNumberOfChildrenOfItem:parentItem withRowType:type],
@@ -1376,7 +1398,7 @@ TODO: implement
return YES;
}
- (CPMutableArray)_getItemsAndValuesToAddForRow:(int)rowIndex ofType:(CPRuleEditorRowType)type
- (CPMutableArray)_getItemsAndValuesToAddForRow:(CPInteger)rowIndex ofType:(CPRuleEditorRowType)type
{
//var cachedItemsAndValues = _itemsAndValuesToAddForRowType[type];
//if (cachedItemsAndValues)
@@ -1396,7 +1418,10 @@ TODO: implement
{
var item = [items objectAtIndex:i],
value = [values objectAtIndex:i],
itemAndValue = [CPDictionary dictionaryWithObjects:[item, value] forKeys:["item", "value"]];
itemAndValue = @{
"item": item,
"value": value,
};
[itemsAndValues addObject:itemAndValue];
}
@@ -1416,7 +1441,7 @@ TODO: implement
[self insertRowAtIndex:insertIndex withType:type asSubrowOfRow:parentRowIndex animate:YES];
}
- (id)_insertNewRowAtIndex:(int)insertIndex ofType:(CPRuleEditorRowType)rowtype withParentRow:(int)parentRowIndex
- (id)_insertNewRowAtIndex:(int)insertIndex ofType:(CPRuleEditorRowType)rowtype withParentRow:(CPInteger)parentRowIndex
{
var row = [[[self rowClass] alloc] init],
itemsandvalues = [self _getItemsAndValuesToAddForRow:insertIndex ofType:rowtype],
@@ -1512,26 +1537,13 @@ TODO: implement
oldRows = [CPArray arrayWithArray:newRows];
[oldRows removeObjectsInArray:changeNewValue];
}
else if (changeKind === CPKeyValueChangeRemoval)
{
newRows = [self _subrowObjectsOfObject:object];
oldRows = [CPArray arrayWithArray:newRows];
var delIndexes = [change objectForKey:CPKeyValueChangeIndexesKey];
[oldRows insertObjects:delObjects atIndexes:changeOldValue]; // Pas sur que ce soit bon
}
[self _changedRowArray:newRows withOldRowArray:oldRows forParent:object];
[self _reconfigureSubviewsAnimate:[self _wantsRowAnimations]];
}
else if (context === itemsContext)
{
}
else if (context === valuesContext)
{
}
}
- (void)_changedItem:(id)fromItem toItem:(id)toItem inRow:(int)aRow atCriteriaIndex:(int)fromItemIndex
- (void)_changedItem:(id)fromItem toItem:(id)toItem inRow:(CPInteger)aRow atCriteriaIndex:(int)fromItemIndex
{
var criteria = [self criteriaForRow:aRow],
displayValues = [self displayValuesForRow:aRow],
@@ -1695,7 +1707,7 @@ TODO: implement
[super bind:aBinding toObject:observableController withKeyPath:aKeyPath options:options];
}
- (void)unbind:(id)object
- (void)unbind:(CPString)object
{
_rowClass = [_CPRuleEditorRowObject class];
[super unbind:object];
@@ -1703,8 +1715,8 @@ TODO: implement
- (void)_setBoundDataSource:(id)datasource withKeyPath:(CPString)keyPath options:(CPDictionary)options
{
if ([observableController respondsToSelector:@selector(objectClass)])
_rowClass = [observableController objectClass];
if ([datasource respondsToSelector:@selector(objectClass)])
_rowClass = [datasource objectClass];
_boundArrayKeyPath = keyPath;
_boundArrayOwner = datasource;
@@ -1727,8 +1739,7 @@ TODO: implement
{
if (_delegateWantsValidation)
{
var selector = @selector(ruleEditor:predicatePartsForCriterion:withDisplayValue:inRow:);
if (![_ruleDelegate respondsToSelector:selector])
if (![self _delegateRespondsToRuleEditorPredicatePartsForCriterionWithDisplayValueInRow])
return;
_delegateWantsValidation = NO;
@@ -1793,7 +1804,7 @@ TODO: implement
if (animate)
{
var animation = [CPDictionary dictionary];
var animation = @{};
[animation setObject:aslice forKey:CPViewAnimationTargetKey];
[animation setObject:startRect forKey:CPViewAnimationStartFrameKey];
[animation setObject:targetRect forKey:CPViewAnimationEndFrameKey];
@@ -1876,29 +1887,49 @@ TODO: implement
return [self valueForThemeAttribute:@"font"];
}
- (CPImage)_addImage
- (CPColor)_fontColor
{
return [self valueForThemeAttribute:@"add-image"];
return [self valueForThemeAttribute:@"font-color"];
}
- (CPImage)_removeImage
- (CPImage)_imageAdd
{
return [self valueForThemeAttribute:@"remove-image"];
return [self valueForThemeAttribute:@"add-image" inState:CPThemeStateNormal];
}
- (CPImage)_imageAddHighlighted
{
return [self valueForThemeAttribute:@"add-image" inState:CPThemeStateHighlighted];
}
- (CPImage)_imageRemove
{
return [self valueForThemeAttribute:@"remove-image" inState:CPThemeStateNormal];
}
- (CPImage)_imageRemoveHighlighted
{
return [self valueForThemeAttribute:@"remove-image" inState:CPThemeStateHighlighted];
}
- (CPVerticalTextAlignment)_verticalAlignment
{
return [self valueForThemeAttribute:@"vertical-alignment"];
}
- (CPString)_toolTipForAddCompoundRowButton
{
return @"Add Compound row";
return [_standardLocalizer localizedStringForString:@"Add compound row"];
}
- (CPString)_toolTipForAddSimpleRowButton
{
return @"Add row";
return [_standardLocalizer localizedStringForString:@"Add row"];
}
- (CPString)_toolTipForDeleteRowButton
{
return @"Delete row";
return [_standardLocalizer localizedStringForString:@"Delete row"];
}
- (void)_updateSliceIndentations
@@ -2016,7 +2047,7 @@ TODO: implement
return [_ruleDelegate ruleEditor:self child:childIndex forCriterion:item withRowType:type];
}
- (id)_queryValueForItem:(id)item inRow:(int)row
- (id)_queryValueForItem:(id)item inRow:(CPInteger)row
{
return [_ruleDelegate ruleEditor:self displayValueForCriterion:item inRow:row];
}
@@ -2037,12 +2068,12 @@ TODO: implement
_alignmentGridWidth = width;
}
- (BOOL)_validateItem:(id)item value:(id)value inRow:(int)row
- (BOOL)_validateItem:(id)item value:(id)value inRow:(CPInteger)row
{
return [self _queryCanSelectItem:item displayValue:value inRow:row];
}
- (BOOL)_queryCanSelectItem:(id)item displayValue:(id)value inRow:(int)row
- (BOOL)_queryCanSelectItem:(id)item displayValue:(id)value inRow:(CPInteger)row
{
return YES;
}
@@ -2058,7 +2089,7 @@ TODO: implement
[super setNeedsDisplay:flag];
}
- (void)setFrameSize:(CPSize)size
- (void)setFrameSize:(CGSize)size
{
[self setNeedsDisplay:YES];
@@ -2090,7 +2121,7 @@ TODO: implement
return;
var point = [self convertPoint:[event locationInWindow] fromView:nil],
view = [_slices objectAtIndex:FLOOR(point.y / _sliceHeight)];
view = [_slices objectAtIndex:FLOOR(MAX(0, point.y) / _sliceHeight)];
if ([self _dragShouldBeginFromMouseDown:view])
[self _performDragForSlice:view withEvent:event];
@@ -2126,7 +2157,7 @@ TODO: implement
[dragview setBackgroundColor:[firstSlice backgroundColor]];
[dragview setAlphaValue:0.7];
dragPoint = CPMakePoint(0, firstIndex * _sliceHeight);
dragPoint = CGPointMake(0, firstIndex * _sliceHeight);
[self dragView:dragview
at:dragPoint
@@ -2139,7 +2170,7 @@ TODO: implement
return YES;
}
- (CPDragOperation)draggingEntered:(id < CPDraggingInfo >)sender
- (CPDragOperation)draggingEntered:(id /*< CPDraggingInfo >*/)sender
{
if ([sender draggingSource] === self)
{
@@ -2169,14 +2200,14 @@ TODO: implement
_subviewIndexOfDropLine = CPNotFound;
}
- (CPDragOperation)draggingUpdated:(id <CPDraggingInfo>)sender
- (CPDragOperation)draggingUpdated:(id /*<CPDraggingInfo>*/)sender
{
var point = [self convertPoint:[sender draggingLocation] fromView:nil],
y = point.y + _sliceHeight / 2,
indexOfDropLine = FLOOR(y / _sliceHeight),
numberOfRows = [self numberOfRows];
if (indexOfDropLine < 0 || indexOfDropLine > numberOfRows || (indexOfDropLine >= [_draggingRows firstIndex] && indexOfDropLine <= [_draggingRows lastIndex] + 1))
if (indexOfDropLine <= 0 || indexOfDropLine > numberOfRows || (indexOfDropLine >= [_draggingRows firstIndex] && indexOfDropLine <= [_draggingRows lastIndex] + 1))
{
if (_subviewIndexOfDropLine !== CPNotFound && indexOfDropLine !== _subviewIndexOfDropLine)
[self _clearDropLine];
@@ -2188,7 +2219,7 @@ TODO: implement
if (_subviewIndexOfDropLine !== CPNotFound && _subviewIndexOfDropLine < numberOfRows)
{
var previousBelowSlice = [_slices objectAtIndex:_subviewIndexOfDropLine];
[previousBelowSlice setFrameOrigin:CPMakePoint(0, [previousBelowSlice rowIndex] * _sliceHeight)];
[previousBelowSlice setFrameOrigin:CGPointMake(0, [previousBelowSlice rowIndex] * _sliceHeight)];
}
if (indexOfDropLine <= _lastRow && indexOfDropLine < numberOfRows)
@@ -2206,12 +2237,12 @@ TODO: implement
return CPDragOperationMove;
}
- (BOOL)prepareForDragOperation:(id < CPDraggingInfo >)sender
- (BOOL)prepareForDragOperation:(id /*< CPDraggingInfo >*/)sender
{
return (_subviewIndexOfDropLine !== CPNotFound);
}
- (BOOL)performDragOperation:(id < CPDraggingInfo >)info
- (BOOL)performDragOperation:(id /*< CPDraggingInfo >*/)info
{
var aboveInsertIndexCount = 0,
object,
@@ -2254,7 +2285,7 @@ TODO: implement
return [CPIndexSet indexSetWithIndex:CPDragOperationMove];
}
- (void)draggedView:(CPView)dragView endedAt:(CPPoint)aPoint operation:(CPDragOperation)operation
- (void)draggedView:(CPView)dragView endedAt:(CGPoint)aPoint operation:(CPDragOperation)operation
{
_draggingRows = nil;
@@ -2273,7 +2304,7 @@ TODO: implement
{
}
- (void)_setWindow:(id)window
- (void)_setWindow:(CPWindow)window
{
[super _setWindow:window];
}
@@ -2290,7 +2321,7 @@ TODO: implement
- (void)_postRowCountChangedNotificationOfType:(CPString)notificationName indexes:indexes
{
var userInfo = [CPDictionary dictionaryWithObject:indexes forKey:"indexes"];
var userInfo = indexes === nil ? @{} : @{ "indexes": indexes };
[[CPNotificationCenter defaultCenter] postNotificationName:notificationName object:self userInfo:userInfo];
}
@@ -2336,7 +2367,7 @@ TODO: implement
return YES;
}
- (void)_getAllAvailableItems:(id)items values:(id)values asChildrenOfItem:(id)parentItem inRow:(int)aRow
- (void)_getAllAvailableItems:(id)items values:(id)values asChildrenOfItem:(id)parentItem inRow:(CPInteger)aRow
{
var type,
indexofCriterion,
@@ -2388,6 +2419,33 @@ TODO: implement
@end
@implementation CPRuleEditor (CPRuleEditorDelegate)
/*!
@ignore
Check if the delegate responds to ruleEditor:predicatePartsForCriterion:withDisplayValue:inRow:
*/
- (BOOL)_delegateRespondsToRuleEditorPredicatePartsForCriterionWithDisplayValueInRow
{
return _implementedDelegateMethods & CPRuleEditorDelegate_ruleEditor_predicatePartsForCriterion_withDisplayValue_inRow_;
}
/*!
@ignore
Call delegate ruleEditor:predicatePartsForCriterion:withDisplayValue:inRow:
*/
- (CPDictionary)_sendDelegateRuleEditorPredicatePartsForCriterion:(id)criterion withDisplayValue:(id)value inRow:(CPInteger)row
{
if (!(_implementedDelegateMethods & CPRuleEditorDelegate_ruleEditor_predicatePartsForCriterion_withDisplayValue_inRow_))
return @{};
return [_ruleDelegate ruleEditor:self predicatePartsForCriterion:criterion withDisplayValue:value inRow:row];
}
@end
var CPRuleEditorAlignmentGridWidthKey = @"CPRuleEditorAlignmentGridWidth",
CPRuleEditorSliceHeightKey = @"CPRuleEditorSliceHeight",
CPRuleEditorStringsFilenameKey = @"CPRuleEditorStringsFilename",
@@ -2437,7 +2495,7 @@ var CPRuleEditorAlignmentGridWidthKey = @"CPRuleEditorAlignmentGridWidth",
return self;
}
- (void)encodeWithCoder:(id)coder
- (void)encodeWithCoder:(CPCoder)coder
{
[super encodeWithCoder:coder];
@@ -2492,7 +2550,7 @@ var CriteriaKey = @"criteria",
return "<" + [self className] + ">\nsubrows = " + [subrows description] + "\ncriteria = " + [criteria description] + "\ndisplayValues = " + [displayValues description];
}
- (id)initWithCoder:(id)coder
- (id)initWithCoder:(CPCoder)coder
{
self = [super init];
if (self !== nil)
@@ -2506,7 +2564,7 @@ var CriteriaKey = @"criteria",
return self;
}
- (void)encodeWithCoder:(id)coder
- (void)encodeWithCoder:(CPCoder)coder
{
[coder encodeObject:subrows forKey:SubrowsKey];
[coder encodeObject:criteria forKey:CriteriaKey];
@@ -2545,7 +2603,7 @@ var CPBoundArrayKey = @"CPBoundArray";
return self;
}
- (id)initWithCoder:(id)coder
- (id)initWithCoder:(CPCoder)coder
{
if (self = [super init])
boundArray = [coder decodeObjectForKey:CPBoundArrayKey];
@@ -2553,7 +2611,7 @@ var CPBoundArrayKey = @"CPBoundArray";
return self;
}
- (void)encodeWithCoder:(id)coder
- (void)encodeWithCoder:(CPCoder)coder
{
[coder encodeObject:boundArray forKey:CPBoundArrayKey];
}
@@ -2578,7 +2636,7 @@ var dropSeparatorColor = [CPColor colorWithHexString:@"4886ca"];
{
}
- (void)drawRect:(CPRect)rect
- (void)drawRect:(CGRect)rect
{
var context = [[CPGraphicsContext currentContext] graphicsPort];
CGContextSetFillColor(context, dropSeparatorColor);
@@ -0,0 +1,42 @@
/*
* CPRuleEditor_Constants.j
* AppKit
*
* Created by cacaodev.
* Copyright 2011, cacaodev.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
CPRuleEditorPredicateLeftExpression = "CPRuleEditorPredicateLeftExpression";
CPRuleEditorPredicateRightExpression = "CPRuleEditorPredicateRightExpression";
CPRuleEditorPredicateComparisonModifier = "CPRuleEditorPredicateComparisonModifier";
CPRuleEditorPredicateOptions = "CPRuleEditorPredicateOptions";
CPRuleEditorPredicateOperatorType = "CPRuleEditorPredicateOperatorType";
CPRuleEditorPredicateCustomSelector = "CPRuleEditorPredicateCustomSelector";
CPRuleEditorPredicateCompoundType = "CPRuleEditorPredicateCompoundType";
CPRuleEditorRowsDidChangeNotification = "CPRuleEditorRowsDidChangeNotification";
CPRuleEditorRulesDidChangeNotification = "CPRuleEditorRulesDidChangeNotification";
CPRuleEditorNestingModeSingle = 0; // Only a single row is allowed. Plus/minus buttons will not be shown
CPRuleEditorNestingModeList = 1; // Allows a single list, with no nesting and no compound rows
CPRuleEditorNestingModeCompound = 2; // Unlimited nesting and compound rows; this is the default
CPRuleEditorNestingModeSimple = 3; // One compound row at the top with subrows beneath it, and no further nesting allowed
@typedef CPRuleEditorRowType
CPRuleEditorRowTypeSimple = 0;
CPRuleEditorRowTypeCompound = 1;
@@ -1,9 +1,25 @@
/*
* Created by cacaodev@gmail.com.
* Copyright (c) 2011 Pear, Inc. All rights reserved.
* Created by cacaodev@gmail.com.
* Copyright (c) 2011 Pear, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@class _CPPredicateEditorTree;
@import <Foundation/CPObject.j>
@import <Foundation/CPString.j>
@implementation _CPPredicateEditorRowNode : CPObject
{
_CPPredicateEditorTree tree @accessors;
+21 -2
View File
@@ -1,8 +1,27 @@
/*
* Created by cacaodev@gmail.com.
* Copyright (c) 2011 Pear, Inc. All rights reserved.
* Created by cacaodev@gmail.com.
* Copyright (c) 2011 Pear, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import <Foundation/CPObject.j>
@import <Foundation/CPString.j>
@class CPPredicateEditorRowTemplate
@implementation _CPPredicateEditorTree : CPObject
{
CPPredicateEditorRowTemplate template @accessors;
+22 -4
View File
@@ -1,11 +1,27 @@
/*
* Created by cacaodev@gmail.com.
* Copyright (c) 2011 Pear, Inc. All rights reserved.
* Created by cacaodev@gmail.com.
* Copyright (c) 2011 Pear, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import <Foundation/CPObject.j>
@import <Foundation/CPDictionary.j>
@import <Foundation/CPString.j>
@import <Foundation/CPURLConnection.j>
@import <Foundation/CPURLRequest.j>
var LocalizerStringsRegex = new RegExp("\"(.+)\"\\s*=\\s*\"(.+)\"\\s*;\\s*(//.+)?");
@@ -13,7 +29,7 @@ var LocalizerStringsRegex = new RegExp("\"(.+)\"\\s*=\\s*\"(.+)\"\\s*;\\s*(//.+)
{
CPDictionary _dictionary @accessors(property=dictionary);
CPURLConnection connection;
CPURLRequest resquest;
CPURLRequest request;
}
- (void)loadContentOfURL:(CPURL)aURL
@@ -43,7 +59,7 @@ var LocalizerStringsRegex = new RegExp("\"(.+)\"\\s*=\\s*\"(.+)\"\\s*;\\s*(//.+)
- (void)loadContent:(CPString)aContent
{
var dict = [CPDictionary dictionary],
var dict = @{},
lines = [aContent componentsSeparatedByString:"\n"],
count = [lines count];
@@ -77,3 +93,5 @@ var LocalizerStringsRegex = new RegExp("\"(.+)\"\\s*=\\s*\"(.+)\"\\s*;\\s*(//.+)
return aString;
}
@end
@@ -1,178 +0,0 @@
/*
* Created by cacaodev@gmail.com.
* Copyright (c) 2011 Pear, Inc. All rights reserved.
*/
@import "CPPopUpButton.j"
var GRADIENT_START_COLOR = "#fcfcfc",
GRADIENT_END_COLOR = "#dfdfdf",
BORDER_COLOR = "#BDBDBD";
var GRADIENT_NORMAL,
GRADIENT_HIGHLIGHTED,
GRADIENT_PROPERTY;
if (CPBrowserIsEngine(CPWebKitBrowserEngine))
{
GRADIENT_NORMAL = "-webkit-gradient(linear, left top, left bottom, from(" + GRADIENT_START_COLOR + "), to(" + GRADIENT_END_COLOR + "))",
GRADIENT_HIGHLIGHTED = "-webkit-gradient(linear, left top, left bottom, from(" + GRADIENT_END_COLOR + "), to(" + GRADIENT_START_COLOR + "))";
GRADIENT_PROPERTY = "background";
}
else if (CPBrowserIsEngine(CPGeckoBrowserEngine))
{
GRADIENT_NORMAL = "-moz-linear-gradient(top, " + GRADIENT_START_COLOR + ", " + GRADIENT_END_COLOR + ")",
GRADIENT_HIGHLIGHTED = "-moz-linear-gradient(top, " + GRADIENT_END_COLOR + ", " + GRADIENT_START_COLOR + ")";
GRADIENT_PROPERTY = "background";
}
else if (CPBrowserIsEngine(CPInternetExplorerBrowserEngine))
{
GRADIENT_NORMAL = "progid:DXImageTransform.Microsoft.gradient(startColorstr='" + GRADIENT_START_COLOR + "', endColorstr='" + GRADIENT_END_COLOR + "')";
GRADIENT_HIGHLIGHTED = "progid:DXImageTransform.Microsoft.gradient(startColorstr='" + GRADIENT_END_COLOR + "', endColorstr='" + GRADIENT_START_COLOR + "')";
GRADIENT_PROPERTY = "filter";
}else
{
GRADIENT_NORMAL = GRADIENT_START_COLOR;
GRADIENT_HIGHLIGHTED = GRADIENT_END_COLOR;
GRADIENT_PROPERTY = "background";
}
@implementation _CPRuleEditorPopUpButton : CPPopUpButton
{
CPInteger radius;
}
- (void)_sharedInit
{
[self setBordered:NO];
var style = _DOMElement.style;
style.border = "1px solid " + BORDER_COLOR;
style[GRADIENT_PROPERTY] = GRADIENT_NORMAL;
}
- (id)initWithFrame:(CGRect)aFrame
{
if (self = [super initWithFrame:aFrame])
[self _sharedInit];
return self;
}
- (id)initWithCoder:(CPCoder)aCoder
{
self = [super initWithCoder:aCoder];
[self _sharedInit];
return self;
}
- (id)hitTest:(CPPoint)point
{
if (!CPRectContainsPoint([self frame], point) || ![self sliceIsEditable])
return nil;
return self;
}
- (BOOL)sliceIsEditable
{
var superview = [self superview];
return ![superview isKindOfClass:[_CPRuleEditorViewSlice]] || [superview isEditable];
}
- (BOOL)trackMouse:(CPEvent)theEvent
{
if (![self sliceIsEditable])
return NO;
return [super trackMouse:theEvent];
}
- (CGRect)contentRectForBounds:(CGRect)bounds
{
var contentRect = [super contentRectForBounds:bounds];
contentRect.origin.x += radius;
contentRect.size.width -= 2 * radius;
return contentRect;
}
- (void)layoutSubviews
{
radius = FLOOR(CGRectGetHeight([self bounds]) / 2);
var style = _DOMElement.style,
radiusCSS = radius + "px";
style.borderRadius = radiusCSS;
[super layoutSubviews];
}
- (void)drawRect:(CGRect)aRect
{
var context = [[CPGraphicsContext currentContext] graphicsPort],
bounds = [self bounds],
arrow_width = FLOOR(CGRectGetHeight(bounds) / 3.5);
CGContextTranslateCTM(context, CGRectGetWidth(bounds) - radius - arrow_width, CGRectGetHeight(bounds) / 2);
var arrowsPath = [CPBezierPath bezierPath];
[arrowsPath moveToPoint:CGPointMake(0, 1)];
[arrowsPath lineToPoint:CGPointMake(arrow_width, 1)];
[arrowsPath lineToPoint:CGPointMake(arrow_width / 2, arrow_width + 1)];
[arrowsPath closePath];
CGContextSetFillColor(context, [CPColor colorWithWhite:101 / 255 alpha:1]);
[arrowsPath fill];
CGContextScaleCTM(context, 1 , -1);
[arrowsPath fill];
}
@end
@implementation _CPRuleEditorButton : CPButton
{
CPInteger radius;
}
- (void)_sharedInit
{
[self setBordered:NO];
var style = _DOMElement.style;
style.border = "1px solid " + BORDER_COLOR;
style[GRADIENT_PROPERTY] = GRADIENT_NORMAL;
}
- (id)initWithFrame:(CGRect)aFrame
{
if (self = [super initWithFrame:aFrame])
[self _sharedInit];
return self;
}
- (id)initWithCoder:(CPCoder)aCoder
{
self = [super initWithCoder:aCoder];
[self _sharedInit];
return self;
}
- (void)layoutSubviews
{
radius = FLOOR(CGRectGetHeight([self bounds]) / 2);
var style = _DOMElement.style,
radiusCSS = radius + "px";
style.borderRadius = radiusCSS;
style[GRADIENT_PROPERTY] = ([self isHighlighted]) ? GRADIENT_HIGHLIGHTED : GRADIENT_NORMAL;
[super layoutSubviews];
}
@end
+35 -17
View File
@@ -1,17 +1,35 @@
/*
* Created by cacaodev@gmail.com.
* Copyright (c) 2011 Pear, Inc. All rights reserved.
* Created by cacaodev@gmail.com.
* Copyright (c) 2011 Pear, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "CPView.j"
@class CPRuleEditor
@implementation _CPRuleEditorViewSlice : CPView
{
CPRuleEditor _ruleEditor;
int _indentation @accessors(property=indentation);
int _rowIndex @accessors(property=rowIndex);
CPRect _animationTargetRect @accessors(property=_animationTargetRect);
CGRect _animationTargetRect @accessors(property=_animationTargetRect);
BOOL _selected @accessors(getter=_isSelected, setter=_setSelected:);
BOOL _lastSelected @accessors(getter=_isLastSelected, setter=_setLastSelected:);
CPColor _backgroundColor @accessors(property=backgroundColor);
BOOL _editable @accessors(getter=isEditable, setter=setEditable:);
}
- (void)removeFromSuperview
@@ -36,19 +54,19 @@
if (select == _selected)
return;
var selector = select ? @"setThemeState:" : @"unsetThemeState:";
[[self subviews] makeObjectsPerformSelector:CPSelectorFromString(selector) withObject:CPThemeStateSelectedDataView];
var selector = select ? @selector(setThemeState:) : @selector(unsetThemeState:);
[[self subviews] makeObjectsPerformSelector:selector withObject:CPThemeStateSelectedDataView];
_selected = select;
}
- (void)drawRect:(CPRect)rect
- (void)drawRect:(CGRect)rect
{
var context = [[CPGraphicsContext currentContext] graphicsPort],
bounds = [self bounds],
maxX = CGRectGetWidth(bounds),
maxY = CGRectGetHeight(bounds);
bounds = [self bounds],
maxX = CGRectGetWidth(bounds),
maxY = CGRectGetHeight(bounds);
// Draw background
// Draw background
if ([self _isSelected])
_backgroundColor = [_ruleEditor _selectedRowColor];
else
@@ -61,33 +79,33 @@
CGContextSetFillColor(context, _backgroundColor);
CGContextFillRect(context, rect);
// Draw Top Border
// Draw Top Border
CGContextBeginPath(context);
CGContextMoveToPoint(context, 0, 0);
CGContextAddLineToPoint(context, maxX, 0);
CGContextClosePath(context);
CGContextSetStrokeColor(context, [_ruleEditor _sliceTopBorderColor]);
CGContextStrokePath(context);
// Draw Bottom Border
// Draw Bottom Border
CGContextBeginPath(context);
CGContextMoveToPoint(context, 0, maxY);
CGContextAddLineToPoint(context, maxX, maxY);
CGContextClosePath(context);
var bottomColor = (_rowIndex == [_ruleEditor _lastRow]) ? [_ruleEditor _sliceLastBottomBorderColor] : [_ruleEditor _sliceBottomBorderColor];
CGContextSetStrokeColor(context, bottomColor);
CGContextStrokePath(context);
}
- (void)mouseDown:(CPEvent)theEvent
{
if (editable)
if (_editable)
[_ruleEditor _mouseDownOnSlice:self withEvent:theEvent];
}
- (void)mouseUp:(CPEvent)theEvent
{
if (editable)
if (_editable)
[_ruleEditor _mouseUpOnSlice:self withEvent:theEvent];
}
+125 -116
View File
@@ -1,26 +1,45 @@
/*
* Created by cacaodev@gmail.com.
* Copyright (c) 2011 Pear, Inc. All rights reserved.
* Created by cacaodev@gmail.com.
* Copyright (c) 2011 Pear, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "CPRuleEditor_Constants.j"
@import "_CPRuleEditorViewSlice.j"
@import "_CPRuleEditorPopUpButton.j"
@import "CPRuleEditor.j"
var CONTROL_HEIGHT = 16.,
BUTTON_HEIGHT = 16.;
@import "CPButton.j"
@import "CPDatePicker.j"
@import "CPPopUpButton.j"
@global CPApp
@global CPMiniControlSize
@global CPSmallControlSize
@implementation _CPRuleEditorViewSliceRow : _CPRuleEditorViewSlice
{
CPMutableArray _ruleOptionViews;
CPMutableArray _ruleOptionFrames;
CPMutableArray _correspondingRuleItems;
CPMutableArray _ruleOptionInitialViewFrames;
CPButton _addButton;
CPButton _subtractButton;
BOOL editable;
CPRuleEditorRowType _rowType @accessors;
CPRuleEditorRowType _plusButtonRowType;
CPButton _addButton;
CPButton _subtractButton;
CPMutableArray _correspondingRuleItems;
CPMutableArray _ruleOptionFrames;
CPMutableArray _ruleOptionInitialViewFrames;
CPMutableArray _ruleOptionViews;
CPRuleEditorRowType _rowType @accessors;
CPRuleEditorRowType _plusButtonRowType;
}
- (id)initWithFrame:(CGRect)frame ruleEditorView:(id)editor
@@ -33,34 +52,33 @@ var CONTROL_HEIGHT = 16.,
- (void)_initShared
{
_correspondingRuleItems = [[CPMutableArray alloc] init];
_ruleOptionFrames = [[CPMutableArray alloc] init];
_ruleOptionInitialViewFrames = [[CPMutableArray alloc] init];
_ruleOptionViews = [[CPMutableArray alloc] init];
editable = [_ruleEditor isEditable];
_correspondingRuleItems = [[CPMutableArray alloc] init];
_ruleOptionFrames = [[CPMutableArray alloc] init];
_ruleOptionInitialViewFrames = [[CPMutableArray alloc] init];
_ruleOptionViews = [[CPMutableArray alloc] init];
_editable = [_ruleEditor isEditable];
_addButton = [self _createAddRowButton];
_subtractButton = [self _createDeleteRowButton];
_addButton = [self _createAddRowButton];
_subtractButton = [self _createDeleteRowButton];
[_addButton setToolTip:[_ruleEditor _toolTipForAddSimpleRowButton]];
[_subtractButton setToolTip:[_ruleEditor _toolTipForDeleteRowButton]];
[_addButton setHidden:!editable];
[_subtractButton setHidden:!editable];
[self addSubview:_addButton];
[self addSubview:_subtractButton];
[self setAutoresizingMask:CPViewWidthSizable];
var center = [CPNotificationCenter defaultCenter];
[center addObserver:self selector:@selector(_textDidChange:) name:CPControlTextDidChangeNotification object:nil];
}
- (CPButton)_createRowButton
{
var button = [[_CPRuleEditorButton alloc] initWithFrame:CGRectMakeZero()];
[button setFont:[CPFont boldFontWithName:@"Apple Symbol" size:12.0]];
[button setTextColor:[CPColor colorWithWhite:150 / 255 alpha:1]];
var button = [[CPButton alloc] initWithFrame:CGRectMakeZero()];
[button setFont:[_ruleEditor font]];
[button setTextColor:[_ruleEditor _fontColor]];
[button setAlignment:CPCenterTextAlignment];
[button setAutoresizingMask:CPViewMinXMargin];
[button setButtonType:CPMomentaryChangeButton];
[button setBordered:NO];
[button setHidden:!_editable];
[button setImagePosition:CPImageOnly];
return button;
@@ -70,7 +88,10 @@ var CONTROL_HEIGHT = 16.,
{
var button = [self _createRowButton];
[button setImage:[_ruleEditor _addImage]];
[button setToolTip:[_ruleEditor _toolTipForAddSimpleRowButton]];
[button setValue:[_ruleEditor _imageAdd] forThemeAttribute:@"image" inState:CPThemeStateNormal];
[button setValue:[_ruleEditor _imageAddHighlighted] forThemeAttribute:@"image" inState:CPThemeStateHighlighted];
[button setAction:@selector(_addOption:)];
[button setTarget:self];
@@ -81,7 +102,10 @@ var CONTROL_HEIGHT = 16.,
{
var button = [self _createRowButton];
[button setImage:[_ruleEditor _removeImage]];
[button setToolTip:[_ruleEditor _toolTipForDeleteRowButton]];
[button setValue:[_ruleEditor _imageRemove] forThemeAttribute:@"image" inState:CPThemeStateNormal];
[button setValue:[_ruleEditor _imageRemoveHighlighted] forThemeAttribute:@"image" inState:CPThemeStateHighlighted];
[button setAction:@selector(_deleteOption:)];
[button setTarget:self];
@@ -91,20 +115,17 @@ var CONTROL_HEIGHT = 16.,
- (CPMenuItem)_createMenuItemWithTitle:(CPString )title
{
title = [[_ruleEditor standardLocalizer] localizedStringForString:title];
var mItem = [[CPMenuItem alloc] initWithTitle:title action:nil keyEquivalent:@""];
return mItem;
return [[CPMenuItem alloc] initWithTitle:title action:nil keyEquivalent:@""];
}
- (CPPopUpButton)_createPopUpButtonWithItems:(CPArray)itemsArray selectedItemIndex:(int)index
{
var title = [[itemsArray objectAtIndex:index] title],
font = [_ruleEditor font],
width = [title sizeWithFont:font].width + 20,
rect = CGRectMake(0, 0, (width - width % 40) + 80, CONTROL_HEIGHT),
var title = [[itemsArray objectAtIndex:index] title],
font = [_ruleEditor font],
width = [title sizeWithFont:font].width + 35, // 35 for right arrows + margins
rect = CGRectMake(0, 0, width, [_ruleEditor rowHeight]),
popup = [[CPPopUpButton alloc] initWithFrame:rect];
popup = [[_CPRuleEditorPopUpButton alloc] initWithFrame:rect];
[popup setTextColor:[CPColor colorWithWhite:101 / 255 alpha:1]];
[popup setValue:font forThemeAttribute:@"font"];
var count = [itemsArray count];
@@ -121,17 +142,18 @@ var CONTROL_HEIGHT = 16.,
return [CPMenuItem separatorItem];
}
- (_CPRuleEditorTextField)_createStaticTextFieldWithStringValue:(CPString)text
- (CPTextField)_createStaticTextFieldWithStringValue:(CPString)text
{
var textField = [[_CPRuleEditorTextField alloc] initWithFrame:CPMakeRect(0, 0, 200, CONTROL_HEIGHT)],
refont = [_ruleEditor font],
font = [CPFont fontWithName:[refont familyName] size:[refont size] + 2],
localizedText = [[_ruleEditor standardLocalizer] localizedStringForString:text];
var textField = [[CPTextField alloc] initWithFrame:CGRectMakeZero()],
ruleEditorFont = [_ruleEditor font],
font = [CPFont fontWithName:[ruleEditorFont familyName] size:[ruleEditorFont size] + 2],
localizedText = [[_ruleEditor standardLocalizer] localizedStringForString:text],
size = [localizedText sizeWithFont:font];
[textField setFrameSize:CGSizeMake(size.width + 4, [_ruleEditor rowHeight])];
[textField setValue:font forThemeAttribute:@"font"];
[textField setValue:[_ruleEditor _verticalAlignment] forThemeAttribute:@"vertical-alignment"];
[textField setStringValue:localizedText];
[textField sizeToFit];
return textField;
}
@@ -142,6 +164,7 @@ var CONTROL_HEIGHT = 16.,
[self setNeedsDisplay:YES];
var type = _plusButtonRowType;
if ([_ruleEditor nestingMode] == CPRuleEditorNestingModeCompound && ([[CPApp currentEvent] modifierFlags] & CPAlternateKeyMask))
type = CPRuleEditorRowTypeCompound;
@@ -153,12 +176,12 @@ var CONTROL_HEIGHT = 16.,
[_ruleEditor _deleteSlice:self];
}
- (void)_ruleOptionPopupChangedAction:(CPMenuItem )sender
- (void)_ruleOptionPopupChangedAction:(CPMenuItem)sender
{
var layoutdict = [sender representedObject],
newItem = [layoutdict objectForKey:@"item"],
var layoutdict = [sender representedObject],
newItem = [layoutdict objectForKey:@"item"],
indexInCriteria = [layoutdict objectForKey:@"indexInCriteria"],
oldItem = [_correspondingRuleItems objectAtIndex:indexInCriteria];
oldItem = [_correspondingRuleItems objectAtIndex:indexInCriteria];
if (![newItem isEqual:oldItem])
{
@@ -186,8 +209,7 @@ var CONTROL_HEIGHT = 16.,
- (void)_reconfigureSubviews
{
var ruleItems,
criteria,
var criteria,
repObject,
menuItem,
ruleView,
@@ -254,7 +276,11 @@ var CONTROL_HEIGHT = 16.,
}
}
repObject = [CPDictionary dictionaryWithObjectsAndKeys:childItem, @"item", childValue, @"value", i, @"indexInCriteria"];
repObject = @{
@"item": childItem,
@"value": childValue,
@"indexInCriteria": i
};
[menuItem setRepresentedObject:repObject];
[menuItems addObject:menuItem];
}
@@ -286,8 +312,16 @@ var CONTROL_HEIGHT = 16.,
if (ruleView != nil)
{
[ruleView setControlSize:CPSmallControlSize];
var minSize = [ruleView currentValueForThemeAttribute:@"min-size"],
frame = [ruleView frame];
// Force controls to their minimum size
frame.size.height = minSize.height;
[ruleView setFrame:frame];
[_ruleOptionViews addObject:ruleView];
var frame = [ruleView frame];
[_ruleOptionInitialViewFrames addObject:frame];
[_ruleOptionFrames addObject:frame];
@@ -300,7 +334,7 @@ var CONTROL_HEIGHT = 16.,
[_correspondingRuleItems setArray:ruleItems];
if (!editable)
if (!_editable)
[self _updateEnabledStateForSubviews];
[self _relayoutSubviewsWidthChanged:YES];
@@ -310,8 +344,6 @@ var CONTROL_HEIGHT = 16.,
var aView = [_ruleOptionViews objectAtIndex:firstResponderIndex];
[[self window] makeFirstResponder:aView]; // This is not working. bug in CPPopUpButton firstResponder ?
}
//[self setNeedsDisplay:YES];
}
- (void)_updateEnabledStateForSubviews
@@ -329,14 +361,16 @@ var CONTROL_HEIGHT = 16.,
var optionViewOriginX,
leftHorizontalPadding,
leftButtonMinX,
rowHeight = [_ruleEditor rowHeight],
count = [_ruleOptionViews count],
sliceFrame = [self frame],
rowHeight = [_ruleEditor rowHeight],
count = [_ruleOptionViews count],
sliceFrame = [self frame],
image = [_ruleEditor _imageAdd],
imageSize = image ? [image size] : CGSizeMake(0,0),
buttonFrame = CGRectMake(CGRectGetWidth(sliceFrame) - BUTTON_HEIGHT - [self _rowButtonsRightHorizontalPadding], ([_ruleEditor rowHeight] - BUTTON_HEIGHT) / 2 - 2, BUTTON_HEIGHT, BUTTON_HEIGHT);
buttonFrame = CGRectMake(CGRectGetWidth(sliceFrame) - imageSize.width - [self _rowButtonsRightHorizontalPadding], ([_ruleEditor rowHeight] - imageSize.height) / 2 - 1, imageSize.width, imageSize.height);
[_addButton setFrame:buttonFrame];
buttonFrame.origin.x -= BUTTON_HEIGHT + [self _rowButtonsInterviewHorizontalPadding];
buttonFrame.origin.x -= imageSize.width + [self _rowButtonsInterviewHorizontalPadding];
[_subtractButton setFrame:buttonFrame];
if (widthChanged)
@@ -351,15 +385,8 @@ var CONTROL_HEIGHT = 16.,
var ruleOptionView = _ruleOptionViews[i],
optionFrame = _ruleOptionFrames[i];
optionFrame.origin.y = (rowHeight - CGRectGetHeight(optionFrame)) / 2 - 2;
// small positioning fix
if ([ruleOptionView isKindOfClass:CPTextField])
{
optionFrame.origin.y += 2;
[_ruleOptionViews[i] setValue:CGInsetMake(7, 7, 7, 8) forThemeAttribute:@"content-inset"];
}
// Use a pixel correction to align controls
optionFrame.origin.y = (rowHeight - CGRectGetHeight(optionFrame)) / 2;
if (widthChanged)
{
@@ -390,14 +417,9 @@ var CONTROL_HEIGHT = 16.,
[self _setRowTypeToAddFromPlusButton:type];
}
- (BOOL)isEditable
{
return editable;
}
- (void)setEditable:(BOOL)value
{
editable = value;
[super setEditable:value]
// [self _updateEnabledStateForSubviews];
[self _updateButtonVisibilities];
}
@@ -473,22 +495,36 @@ var CONTROL_HEIGHT = 16.,
[self layoutSubviews];
}
- (void)drawRect:(CPRect)rect
- (void)_addObservers
{
if (_isObserving)
return;
[super _addObservers];
[[CPNotificationCenter defaultCenter] addObserver:self selector:@selector(_textDidChange:) name:CPControlTextDidChangeNotification object:nil];
}
- (void)_removeObservers
{
if (!_isObserving)
return;
[super _removeObservers];
[[CPNotificationCenter defaultCenter] removeObserver:self name:CPControlTextDidChangeNotification object:nil];
}
- (void)drawRect:(CGRect)rect
{
[super drawRect:rect];
}
- (BOOL)_isRulePopup:(CPView)view
{
if ([view isKindOfClass:[_CPRuleEditorPopUpButton class]])
if ([view isKindOfClass:[CPPopUpButton class]])
return YES;
return NO;
}
- (BOOL)_isRuleStaticTextField:(CPView)view
{
if ([view isKindOfClass:[_CPRuleEditorTextField class]])
return YES;
return NO;
}
@@ -505,30 +541,3 @@ var CONTROL_HEIGHT = 16.,
}
@end
@implementation _CPRuleEditorTextField : CPTextField
{
}
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self != nil)
{
[self setBordered:NO];
[self setEditable:NO];
[self setDrawsBackground:NO];
}
return self;
}
- (id)hitTest:(CPPoint)point
{
if (!CPRectContainsPoint([self frame], point))
return nil;
return [self superview];
}
@end
+5
View File
@@ -35,6 +35,11 @@
CPArray _allowedFileTypes @accessors(property=allowedFileTypes);
}
+ (CPURL)proposedFileURLWithDocumentName:(CPString)aDocumentName
{
return [CPURL URLWithString:aDocumentName];
}
+ (id)savePanel
{
return [[CPSavePanel alloc] init];
+2 -2
View File
@@ -43,9 +43,9 @@
- (CGRect)visibleFrame
{
#if PLATFORM(DOM)
return _CGRectMake(window.screen.availLeft, window.screen.availTop, window.screen.availWidth, window.screen.availHeight);
return CGRectMake(window.screen.availLeft, window.screen.availTop, window.screen.availWidth, window.screen.availHeight);
#else
return _CGRectMakeZero();
return CGRectMakeZero();
#endif
}
+170 -112
View File
@@ -33,49 +33,59 @@
#define SHOULD_SHOW_CORNER_VIEW() (_scrollerStyle === CPScrollerStyleLegacy && _verticalScroller && ![_verticalScroller isHidden])
@protocol CPScrollViewDelegate <CPObject>
@optional
- (void)scrollViewWillScroll:(CPScrollView)aScrollView;
- (void)scrollViewDidScroll:(CPScrollView)aScrollView;
@end
/*! @ignore */
var _isSystemUsingOverlayScrollers = function()
var _isBrowserUsingOverlayScrollers = function()
{
#if PLATFORM(DOM)
var inner = document.createElement('p'),
outer = document.createElement('div');
/*
Even if the system supports overlay (Lion) scrollers,
the browser (e.g. FireFox *cough*) may not.
inner.style.width = "100%";
inner.style.height = "200px";
To determine if the browser is using overlay scrollbars,
we put a <p> element inside a shorter <div> and set its
overflow to scroll. If the browser is using visible scrollers,
the outer div's clientWidth will less than the offsetWidth, because
clientWidth does not include scrollbars, whereas offsetWidth does.
So if clientWidth === offsetWidth, the scrollers must be overlay.
Even IE gets this right.
*/
var outer = document.createElement('div'),
inner = document.createElement('p');
// position it absolute so it doesn't affect existing DOM elements
outer.style.position = "absolute";
outer.style.top = "0px";
outer.style.left = "0px";
outer.style.visibility = "hidden";
outer.style.width = "200px";
outer.style.height = "150px";
outer.style.overflow = "hidden";
outer.appendChild (inner);
outer.style.overflow = "scroll";
document.body.appendChild (outer);
var w1 = inner.offsetWidth;
outer.style.overflow = 'scroll';
var w2 = inner.offsetWidth;
if (w1 == w2)
w2 = outer.clientWidth;
inner.style.width = "100%";
inner.style.height = "200px";
outer.appendChild(inner);
document.body.removeChild (outer);
document.body.appendChild(outer);
return (w1 - w2 == 0);
var usingOverlayScrollers = outer.clientWidth === outer.offsetWidth;
document.body.removeChild(outer);
return usingOverlayScrollers;
#else
return NO;
#endif
};
/*!
@ingroup appkit
@class CPScrollView
Used to display views that are too large for the viewing area. the CPScrollView
places scroll bars on the side of the view to allow the user to scroll and see the entire
contents of the view.
*/
var TIMER_INTERVAL = 0.2,
CPScrollViewDelegate_scrollViewWillScroll_ = 1 << 0,
CPScrollViewDelegate_scrollViewDidScroll_ = 1 << 1,
@@ -85,38 +95,45 @@ var TIMER_INTERVAL = 0.2,
var CPScrollerStyleGlobal = CPScrollerStyleOverlay,
CPScrollerStyleGlobalChangeNotification = @"CPScrollerStyleGlobalChangeNotification";
/*!
@ingroup appkit
@class CPScrollView
Used to display views that are too large for the viewing area. the CPScrollView
places scroll bars on the side of the view to allow the user to scroll and see the entire
contents of the view.
*/
@implementation CPScrollView : CPView
{
CPClipView _contentView;
CPClipView _headerClipView;
CPView _cornerView;
CPView _bottomCornerView;
CPClipView _contentView;
CPClipView _headerClipView;
CPView _cornerView;
CPView _bottomCornerView;
id _delegate;
CPTimer _scrollTimer;
id <CPScrollViewDelegate> _delegate;
CPTimer _scrollTimer;
BOOL _hasVerticalScroller;
BOOL _hasHorizontalScroller;
BOOL _autohidesScrollers;
BOOL _hasVerticalScroller;
BOOL _hasHorizontalScroller;
BOOL _autohidesScrollers;
CPScroller _verticalScroller;
CPScroller _horizontalScroller;
CPScroller _verticalScroller;
CPScroller _horizontalScroller;
CPInteger _recursionCount;
CPInteger _implementedDelegateMethods;
CPInteger _recursionCount;
CPInteger _implementedDelegateMethods;
float _verticalLineScroll;
float _verticalPageScroll;
float _horizontalLineScroll;
float _horizontalPageScroll;
float _verticalLineScroll;
float _verticalPageScroll;
float _horizontalLineScroll;
float _horizontalPageScroll;
CPBorderType _borderType;
CPBorderType _borderType;
CPTimer _timerScrollersHide;
CPTimer _timerScrollersHide;
int _scrollerStyle;
int _scrollerKnobStyle;
int _scrollerStyle;
int _scrollerKnobStyle;
}
@@ -130,8 +147,8 @@ var CPScrollerStyleGlobal = CPScrollerStyleOverlay,
var globalValue = [[CPBundle mainBundle] objectForInfoDictionaryKey:@"CPScrollersGlobalStyle"];
if (globalValue == nil || globalValue == -1)
CPScrollerStyleGlobal = _isSystemUsingOverlayScrollers() ? CPScrollerStyleOverlay : CPScrollerStyleLegacy
if (globalValue === nil || globalValue === -1)
CPScrollerStyleGlobal = _isBrowserUsingOverlayScrollers() ? CPScrollerStyleOverlay : CPScrollerStyleLegacy
else
CPScrollerStyleGlobal = globalValue;
}
@@ -143,15 +160,15 @@ var CPScrollerStyleGlobal = CPScrollerStyleOverlay,
+ (CPDictionary)themeAttributes
{
return [CPDictionary dictionaryWithJSObject:{
@"bottom-corner-color": [CPColor whiteColor],
@"border-color": [CPColor blackColor]
}];
return @{
@"bottom-corner-color": [CPColor whiteColor],
@"border-color": [CPColor blackColor]
};
}
+ (CGSize)contentSizeForFrameSize:(CGSize)frameSize hasHorizontalScroller:(BOOL)hFlag hasVerticalScroller:(BOOL)vFlag borderType:(CPBorderType)borderType
{
var bounds = [self _insetBounds:_CGRectMake(0.0, 0.0, frameSize.width, frameSize.height) borderType:borderType],
var bounds = [self _insetBounds:CGRectMake(0.0, 0.0, frameSize.width, frameSize.height) borderType:borderType],
scrollerWidth = [CPScroller scrollerWidth];
if (hFlag)
@@ -165,10 +182,10 @@ var CPScrollerStyleGlobal = CPScrollerStyleOverlay,
+ (CGSize)frameSizeForContentSize:(CGSize)contentSize hasHorizontalScroller:(BOOL)hFlag hasVerticalScroller:(BOOL)vFlag borderType:(CPBorderType)borderType
{
var bounds = [self _insetBounds:_CGRectMake(0.0, 0.0, contentSize.width, contentSize.height) borderType:borderType],
var bounds = [self _insetBounds:CGRectMake(0.0, 0.0, contentSize.width, contentSize.height) borderType:borderType],
widthInset = contentSize.width - bounds.size.width,
heightInset = contentSize.height - bounds.size.height,
frameSize = _CGSizeMake(contentSize.width + widthInset, contentSize.height + heightInset),
frameSize = CGSizeMake(contentSize.width + widthInset, contentSize.height + heightInset),
scrollerWidth = [CPScroller scrollerWidth];
if (hFlag)
@@ -186,10 +203,10 @@ var CPScrollerStyleGlobal = CPScrollerStyleOverlay,
{
case CPLineBorder:
case CPBezelBorder:
return _CGRectInset(bounds, 1.0, 1.0);
return CGRectInset(bounds, 1.0, 1.0);
case CPGrooveBorder:
bounds = _CGRectInset(bounds, 2.0, 2.0);
bounds = CGRectInset(bounds, 2.0, 2.0);
++bounds.origin.y;
--bounds.size.height;
return bounds;
@@ -254,11 +271,6 @@ var CPScrollerStyleGlobal = CPScrollerStyleOverlay,
_delegate = nil;
_scrollTimer = nil;
_implementedDelegateMethods = 0;
[[CPNotificationCenter defaultCenter] addObserver:self
selector:@selector(_didReceiveDefaultStyleChange:)
name:CPScrollerStyleGlobalChangeNotification
object:nil];
}
return self;
@@ -291,7 +303,7 @@ Notifies the delegate when the scroll view has finished scrolling.
@endcode
*/
- (void)setDelegate:(id)aDelegate
- (void)setDelegate:(id <CPScrollViewDelegate>)aDelegate
{
if (aDelegate === _delegate)
return;
@@ -517,8 +529,8 @@ Notifies the delegate when the scroll view has finished scrolling.
{
var bounds = [self _insetBounds];
[self setHorizontalScroller:[[CPScroller alloc] initWithFrame:CGRectMake(0.0, 0.0, MAX(_CGRectGetWidth(bounds), [CPScroller scrollerWidthInStyle:_scrollerStyle] + 1), [CPScroller scrollerWidthInStyle:_scrollerStyle])]];
[[self horizontalScroller] setFrameSize:CGSizeMake(_CGRectGetWidth(bounds), [CPScroller scrollerWidthInStyle:_scrollerStyle])];
[self setHorizontalScroller:[[CPScroller alloc] initWithFrame:CGRectMake(0.0, 0.0, MAX(CGRectGetWidth(bounds), [CPScroller scrollerWidthInStyle:_scrollerStyle] + 1), [CPScroller scrollerWidthInStyle:_scrollerStyle])]];
[[self horizontalScroller] setFrameSize:CGSizeMake(CGRectGetWidth(bounds), [CPScroller scrollerWidthInStyle:_scrollerStyle])];
}
[self reflectScrolledClipView:_contentView];
@@ -582,8 +594,8 @@ Notifies the delegate when the scroll view has finished scrolling.
{
var bounds = [self _insetBounds];
[self setVerticalScroller:[[CPScroller alloc] initWithFrame:_CGRectMake(0.0, 0.0, [CPScroller scrollerWidthInStyle:_scrollerStyle], MAX(_CGRectGetHeight(bounds), [CPScroller scrollerWidthInStyle:_scrollerStyle] + 1))]];
[[self verticalScroller] setFrameSize:CGSizeMake([CPScroller scrollerWidthInStyle:_scrollerStyle], _CGRectGetHeight(bounds))];
[self setVerticalScroller:[[CPScroller alloc] initWithFrame:CGRectMake(0.0, 0.0, [CPScroller scrollerWidthInStyle:_scrollerStyle], MAX(CGRectGetHeight(bounds), [CPScroller scrollerWidthInStyle:_scrollerStyle] + 1))]];
[[self verticalScroller] setFrameSize:CGSizeMake([CPScroller scrollerWidthInStyle:_scrollerStyle], CGRectGetHeight(bounds))];
}
[self reflectScrolledClipView:_contentView];
@@ -859,13 +871,13 @@ Notifies the delegate when the scroll view has finished scrolling.
- (CGRect)_cornerViewFrame
{
if (!_cornerView)
return _CGRectMakeZero();
return CGRectMakeZero();
var bounds = [self _insetBounds],
frame = [_cornerView frame];
frame.origin.x = _CGRectGetMaxX(bounds) - _CGRectGetWidth(frame);
frame.origin.y = _CGRectGetMinY(bounds);
frame.origin.x = CGRectGetMaxX(bounds) - CGRectGetWidth(frame);
frame.origin.y = CGRectGetMinY(bounds);
return frame;
}
@@ -876,14 +888,14 @@ Notifies the delegate when the scroll view has finished scrolling.
var headerView = [self _headerView];
if (!headerView)
return _CGRectMakeZero();
return CGRectMakeZero();
var frame = [self _insetBounds];
frame.size.height = _CGRectGetHeight([headerView frame]);
frame.size.height = CGRectGetHeight([headerView frame]);
if (SHOULD_SHOW_CORNER_VIEW())
frame.size.width -= _CGRectGetWidth([self _cornerViewFrame]);
frame.size.width -= CGRectGetWidth([self _cornerViewFrame]);
return frame;
}
@@ -924,18 +936,18 @@ Notifies the delegate when the scroll view has finished scrolling.
break;
case CPScrollerDecrementPage:
contentBounds.origin.y -= _CGRectGetHeight(contentBounds) - _verticalPageScroll;
contentBounds.origin.y -= CGRectGetHeight(contentBounds) - _verticalPageScroll;
break;
case CPScrollerIncrementPage:
contentBounds.origin.y += _CGRectGetHeight(contentBounds) - _verticalPageScroll;
contentBounds.origin.y += CGRectGetHeight(contentBounds) - _verticalPageScroll;
break;
// We want integral bounds!
case CPScrollerKnobSlot:
case CPScrollerKnob:
default:
contentBounds.origin.y = ROUND(value * (_CGRectGetHeight(documentFrame) - _CGRectGetHeight(contentBounds)));
contentBounds.origin.y = ROUND(value * (CGRectGetHeight(documentFrame) - CGRectGetHeight(contentBounds)));
}
[self _sendDelegateMessages];
@@ -961,18 +973,18 @@ Notifies the delegate when the scroll view has finished scrolling.
break;
case CPScrollerDecrementPage:
contentBounds.origin.x -= _CGRectGetWidth(contentBounds) - _horizontalPageScroll;
contentBounds.origin.x -= CGRectGetWidth(contentBounds) - _horizontalPageScroll;
break;
case CPScrollerIncrementPage:
contentBounds.origin.x += _CGRectGetWidth(contentBounds) - _horizontalPageScroll;
contentBounds.origin.x += CGRectGetWidth(contentBounds) - _horizontalPageScroll;
break;
// We want integral bounds!
case CPScrollerKnobSlot:
case CPScrollerKnob:
default:
contentBounds.origin.x = ROUND(value * (_CGRectGetWidth(documentFrame) - _CGRectGetWidth(contentBounds)));
contentBounds.origin.x = ROUND(value * (CGRectGetWidth(documentFrame) - CGRectGetWidth(contentBounds)));
}
[self _sendDelegateMessages];
@@ -1096,7 +1108,7 @@ Notifies the delegate when the scroll view has finished scrolling.
}
[_contentView setFrame:[self _insetBounds]];
[_headerClipView setFrame:_CGRectMakeZero()];
[_headerClipView setFrame:CGRectMakeZero()];
--_recursionCount;
@@ -1106,14 +1118,14 @@ Notifies the delegate when the scroll view has finished scrolling.
var documentFrame = [documentView frame], // the size of the whole document
contentFrame = [self _insetBounds], // assume it takes up the entire size of the scrollview (no scrollers)
headerClipViewFrame = [self _headerClipViewFrame],
headerClipViewHeight = _CGRectGetHeight(headerClipViewFrame);
headerClipViewHeight = CGRectGetHeight(headerClipViewFrame);
contentFrame.origin.y += headerClipViewHeight;
contentFrame.size.height -= headerClipViewHeight;
var difference = _CGSizeMake(_CGRectGetWidth(documentFrame) - _CGRectGetWidth(contentFrame), _CGRectGetHeight(documentFrame) - _CGRectGetHeight(contentFrame)),
verticalScrollerWidth = _CGRectGetWidth([_verticalScroller frame]),
horizontalScrollerHeight = _CGRectGetHeight([_horizontalScroller frame]),
var difference = CGSizeMake(CGRectGetWidth(documentFrame) - CGRectGetWidth(contentFrame), CGRectGetHeight(documentFrame) - CGRectGetHeight(contentFrame)),
verticalScrollerWidth = [CPScroller scrollerWidthInStyle:[_verticalScroller style]],
horizontalScrollerHeight = [CPScroller scrollerWidthInStyle:[_horizontalScroller style]],
hasVerticalScroll = difference.height > 0.0,
hasHorizontalScroll = difference.width > 0.0,
shouldShowVerticalScroller = _hasVerticalScroller && (!_autohidesScrollers || hasVerticalScroll),
@@ -1162,18 +1174,18 @@ Notifies the delegate when the scroll view has finished scrolling.
if (shouldShowVerticalScroller)
{
var verticalScrollerY =
MAX(_CGRectGetMinY(contentFrame), MAX(_CGRectGetMaxY([self _cornerViewFrame]), _CGRectGetMaxY(headerClipViewFrame)));
MAX(CGRectGetMinY(contentFrame), MAX(CGRectGetMaxY([self _cornerViewFrame]), CGRectGetMaxY(headerClipViewFrame)));
var verticalScrollerHeight = _CGRectGetMaxY(contentFrame) - verticalScrollerY;
var verticalScrollerHeight = CGRectGetMaxY(contentFrame) - verticalScrollerY;
// Make a gap at the bottom of the vertical scroller so that the horizontal and vertical can't overlap.
if (_scrollerStyle === CPScrollerStyleOverlay && hasHorizontalScroll)
verticalScrollerHeight -= horizontalScrollerHeight;
var documentHeight = _CGRectGetHeight(documentFrame);
var documentHeight = CGRectGetHeight(documentFrame);
[_verticalScroller setFloatValue:(difference.height <= 0.0) ? 0.0 : scrollPoint.y / difference.height];
[_verticalScroller setKnobProportion:documentHeight > 0 ? _CGRectGetHeight(contentFrame) / documentHeight : 1.0];
[_verticalScroller setFrame:_CGRectMake(_CGRectGetMaxX(contentFrame) - overlay, verticalScrollerY, verticalScrollerWidth, verticalScrollerHeight)];
[_verticalScroller setKnobProportion:documentHeight > 0 ? CGRectGetHeight(contentFrame) / documentHeight : 1.0];
[_verticalScroller setFrame:CGRectMake(CGRectGetMaxX(contentFrame) - overlay, verticalScrollerY, verticalScrollerWidth, verticalScrollerHeight)];
}
else if (wasShowingVerticalScroller)
{
@@ -1183,16 +1195,16 @@ Notifies the delegate when the scroll view has finished scrolling.
if (shouldShowHorizontalScroller)
{
var horizontalScrollerWidth = _CGRectGetWidth(contentFrame);
var horizontalScrollerWidth = CGRectGetWidth(contentFrame);
// Make a gap at the bottom of the vertical scroller so that the horizontal and vertical can't overlap.
if (_scrollerStyle === CPScrollerStyleOverlay && hasVerticalScroll)
horizontalScrollerWidth -= verticalScrollerWidth;
var documentWidth = _CGRectGetWidth(documentFrame);
var documentWidth = CGRectGetWidth(documentFrame);
[_horizontalScroller setFloatValue:(difference.width <= 0.0) ? 0.0 : scrollPoint.x / difference.width];
[_horizontalScroller setKnobProportion:documentWidth > 0 ? _CGRectGetWidth(contentFrame) / documentWidth : 1.0];
[_horizontalScroller setFrame:_CGRectMake(_CGRectGetMinX(contentFrame), _CGRectGetMaxY(contentFrame) - overlay, horizontalScrollerWidth, horizontalScrollerHeight)];
[_horizontalScroller setKnobProportion:documentWidth > 0 ? CGRectGetWidth(contentFrame) / documentWidth : 1.0];
[_horizontalScroller setFrame:CGRectMake(CGRectGetMinX(contentFrame), CGRectGetMaxY(contentFrame) - overlay, horizontalScrollerWidth, horizontalScrollerHeight)];
}
else if (wasShowingHorizontalScroller)
{
@@ -1241,7 +1253,7 @@ Notifies the delegate when the scroll view has finished scrolling.
}
if (_timerScrollersHide)
[_timerScrollersHide invalidate]
[_timerScrollersHide invalidate];
_timerScrollersHide = [CPTimer scheduledTimerWithTimeInterval:CPScrollViewFadeOutTime target:self selector:@selector(_hideScrollers:) userInfo:nil repeats:NO];
}
@@ -1252,11 +1264,46 @@ Notifies the delegate when the scroll view has finished scrolling.
[self reflectScrolledClipView:_contentView];
}
- (CGRect)documentVisibleRect
{
return [_contentView documentVisibleRect];
}
#pragma mark -
#pragma mark Overrides
- (void)drawRect:(CPRect)aRect
- (void)_removeObservers
{
if (!_isObserving)
return;
[[CPNotificationCenter defaultCenter] removeObserver:self
name:CPScrollerStyleGlobalChangeNotification
object:nil];
[super _removeObservers];
}
- (void)_addObservers
{
if (_isObserving)
return;
//Make sure to have the last global style for the scroller
[self _didReceiveDefaultStyleChange:nil];
[[CPNotificationCenter defaultCenter] addObserver:self
selector:@selector(_didReceiveDefaultStyleChange:)
name:CPScrollerStyleGlobalChangeNotification
object:nil];
[super _addObservers];
}
- (void)drawRect:(CGRect)aRect
{
[super drawRect:aRect];
@@ -1272,7 +1319,7 @@ Notifies the delegate when the scroll view has finished scrolling.
{
case CPLineBorder:
CGContextSetStrokeColor(context, [self currentValueForThemeAttribute:@"border-color"]);
CGContextStrokeRect(context, _CGRectInset(strokeRect, 0.5, 0.5));
CGContextStrokeRect(context, CGRectInset(strokeRect, 0.5, 0.5));
break;
case CPBezelBorder:
@@ -1290,10 +1337,10 @@ Notifies the delegate when the scroll view has finished scrolling.
- (void)_drawGrayBezelInContext:(CGContext)context bounds:(CGRect)aRect
{
var minX = _CGRectGetMinX(aRect),
maxX = _CGRectGetMaxX(aRect),
minY = _CGRectGetMinY(aRect),
maxY = _CGRectGetMaxY(aRect),
var minX = CGRectGetMinX(aRect),
maxX = CGRectGetMaxX(aRect),
minY = CGRectGetMinY(aRect),
maxY = CGRectGetMaxY(aRect),
y = minY + 0.5;
// Slightly darker line on top.
@@ -1324,10 +1371,10 @@ Notifies the delegate when the scroll view has finished scrolling.
- (void)_drawGrooveInContext:(CGContext)context bounds:(CGRect)aRect
{
var minX = _CGRectGetMinX(aRect),
maxX = _CGRectGetMaxX(aRect),
minY = _CGRectGetMinY(aRect),
maxY = _CGRectGetMaxY(aRect);
var minX = CGRectGetMinX(aRect),
maxX = CGRectGetMaxX(aRect),
minY = CGRectGetMinY(aRect),
maxY = CGRectGetMaxY(aRect);
CGContextBeginPath(context);
CGContextSetStrokeColor(context, [CPColor colorWithWhite:159.0 / 255.0 alpha:1.0]);
@@ -1357,11 +1404,11 @@ Notifies the delegate when the scroll view has finished scrolling.
CGContextBeginPath(context);
CGContextSetStrokeColor(context, [CPColor whiteColor]);
var rect = _CGRectOffset(aRect, 1.0, 1.0);
var rect = CGRectOffset(aRect, 1.0, 1.0);
rect.size.width -= 1.0;
rect.size.height -= 1.0;
CGContextStrokeRect(context, _CGRectInset(rect, 0.5, 0.5));
CGContextStrokeRect(context, CGRectInset(rect, 0.5, 0.5));
CGContextBeginPath(context);
CGContextSetStrokeColor(context, [CPColor colorWithWhite:192.0 / 255.0 alpha:1.0]);
@@ -1389,35 +1436,44 @@ Notifies the delegate when the scroll view has finished scrolling.
if (![_horizontalScroller isHidden] || ![_verticalScroller isHidden])
_timerScrollersHide = [CPTimer scheduledTimerWithTimeInterval:CPScrollViewFadeOutTime target:self selector:@selector(_hideScrollers:) userInfo:nil repeats:NO];
[self _respondToScrollWheelEventWithDeltaX:[anEvent deltaX] deltaY:[anEvent deltaY]];
var deltaX = [anEvent scrollingDeltaX],
deltaY = [anEvent scrollingDeltaY];
if (![anEvent hasPreciseScrollingDeltas])
{
deltaX *= (_horizontalLineScroll || 1.0);
deltaY *= (_verticalLineScroll || 1.0);
}
[self _respondToScrollWheelEventWithDeltaX:deltaX deltaY:deltaY];
}
- (void)scrollPageUp:(id)sender
{
var contentBounds = [_contentView bounds];
[self moveByOffset:CGSizeMake(0.0, -(_CGRectGetHeight(contentBounds) - _verticalPageScroll))];
[self moveByOffset:CGSizeMake(0.0, -(CGRectGetHeight(contentBounds) - _verticalPageScroll))];
}
- (void)scrollPageDown:(id)sender
{
var contentBounds = [_contentView bounds];
[self moveByOffset:CGSizeMake(0.0, _CGRectGetHeight(contentBounds) - _verticalPageScroll)];
[self moveByOffset:CGSizeMake(0.0, CGRectGetHeight(contentBounds) - _verticalPageScroll)];
}
- (void)scrollToBeginningOfDocument:(id)sender
{
[_contentView scrollToPoint:_CGPointMakeZero()];
[_headerClipView scrollToPoint:_CGPointMakeZero()];
[_contentView scrollToPoint:CGPointMakeZero()];
[_headerClipView scrollToPoint:CGPointMakeZero()];
}
- (void)scrollToEndOfDocument:(id)sender
{
var contentBounds = [_contentView bounds],
documentFrame = [[self documentView] frame],
scrollPoint = _CGPointMake(0.0, _CGRectGetHeight(documentFrame) - _CGRectGetHeight(contentBounds));
scrollPoint = CGPointMake(0.0, CGRectGetHeight(documentFrame) - CGRectGetHeight(contentBounds));
[_contentView scrollToPoint:scrollPoint];
[_headerClipView scrollToPoint:_CGPointMakeZero()];
[_headerClipView scrollToPoint:CGPointMakeZero()];
}
- (void)moveLeft:(id)sender
@@ -1526,6 +1582,8 @@ var CPScrollViewContentViewKey = @"CPScrollViewContentView",
*/
- (void)awakeFromCib
{
[super awakeFromCib];
[self _updateScrollerStyle];
[self _updateCornerAndHeaderView];
}
+111 -119
View File
@@ -25,9 +25,15 @@
#include "../Foundation/Foundation.h"
@import "CPAnimation.j"
@import "CPControl.j"
@import "CPWindow_Constants.j"
@import "CPViewAnimation.j"
@global CPApp
// CPScroller Constants
@typedef CPScrollerPart
CPScrollerNoPart = 0;
CPScrollerDecrementPage = 1;
CPScrollerKnob = 2;
@@ -39,19 +45,17 @@ CPScrollerKnobSlot = 6;
CPScrollerIncrementArrow = 0;
CPScrollerDecrementArrow = 1;
@typedef CPUsableScrollerParts
CPNoScrollerParts = 0;
CPOnlyScrollerArrows = 1;
CPAllScrollerParts = 2;
/*!
@ingroup appkit
@class CPScroller
*/
var PARTS_ARRANGEMENT = [CPScrollerKnobSlot, CPScrollerDecrementLine, CPScrollerIncrementLine, CPScrollerKnob],
NAMES_FOR_PARTS = {},
PARTS_FOR_NAMES = {};
var _CACHED_THEME_SCROLLER = nil; // This is used by the class methods to pull the theme attributes.
NAMES_FOR_PARTS[CPScrollerDecrementLine] = @"decrement-line";
NAMES_FOR_PARTS[CPScrollerIncrementLine] = @"increment-line";
NAMES_FOR_PARTS[CPScrollerKnobSlot] = @"knob-slot";
@@ -69,9 +73,13 @@ CPThemeStateScrollViewLegacy = CPThemeState("scroller-style-legacy");
CPThemeStateScrollerKnobLight = CPThemeState("scroller-knob-light");
CPThemeStateScrollerKnobDark = CPThemeState("scroller-knob-dark");
/*!
@ingroup appkit
@class CPScroller
*/
@implementation CPScroller : CPControl
{
CPControlSize _controlSize;
CPUsableScrollerParts _usableParts;
CPArray _partRects;
@@ -101,21 +109,21 @@ CPThemeStateScrollerKnobDark = CPThemeState("scroller-knob-dark");
return "scroller";
}
+ (id)themeAttributes
+ (CPDictionary)themeAttributes
{
return [CPDictionary dictionaryWithJSObject:{
@"scroller-width": 7.0,
@"knob-slot-color": [CPNull null],
@"decrement-line-color": [CPNull null],
@"increment-line-color": [CPNull null],
@"knob-color": [CPNull null],
@"decrement-line-size":_CGSizeMakeZero(),
@"increment-line-size":_CGSizeMakeZero(),
@"track-inset":_CGInsetMakeZero(),
@"knob-inset": _CGInsetMakeZero(),
@"minimum-knob-length":21.0,
@"track-border-overlay": 9.0
}];
return @{
@"scroller-width": 7.0,
@"knob-slot-color": [CPNull null],
@"decrement-line-color": [CPNull null],
@"increment-line-color": [CPNull null],
@"knob-color": [CPNull null],
@"decrement-line-size": CGSizeMakeZero(),
@"increment-line-size": CGSizeMakeZero(),
@"track-inset": CGInsetMakeZero(),
@"knob-inset": CGInsetMakeZero(),
@"minimum-knob-length": 21.0,
@"track-border-overlay": 9.0
};
}
+ (float)scrollerWidth
@@ -128,11 +136,13 @@ CPThemeStateScrollerKnobDark = CPThemeState("scroller-knob-dark");
*/
+ (float)scrollerWidthInStyle:(int)aStyle
{
var scroller = [[self alloc] init];
if (!_CACHED_THEME_SCROLLER)
_CACHED_THEME_SCROLLER = [[self alloc] init];
if (aStyle == CPScrollerStyleLegacy)
return [scroller valueForThemeAttribute:@"scroller-width" inState:CPThemeStateScrollViewLegacy];
return [scroller currentValueForThemeAttribute:@"scroller-width"];
return [_CACHED_THEME_SCROLLER valueForThemeAttribute:@"scroller-width" inState:CPThemeStateScrollViewLegacy];
return [_CACHED_THEME_SCROLLER currentValueForThemeAttribute:@"scroller-width"];
}
/*!
@@ -140,7 +150,10 @@ CPThemeStateScrollerKnobDark = CPThemeState("scroller-knob-dark");
*/
+ (float)scrollerOverlay
{
return [[[self alloc] init] currentValueForThemeAttribute:@"track-border-overlay"];
if (!_CACHED_THEME_SCROLLER)
_CACHED_THEME_SCROLLER = [[self alloc] init];
return [_CACHED_THEME_SCROLLER currentValueForThemeAttribute:@"track-border-overlay"];
}
/*!
@@ -160,7 +173,6 @@ CPThemeStateScrollerKnobDark = CPThemeState("scroller-knob-dark");
{
if (self = [super initWithFrame:aFrame])
{
_controlSize = CPRegularControlSize;
_partRects = [];
[self setFloatValue:0.0];
@@ -170,14 +182,20 @@ CPThemeStateScrollerKnobDark = CPThemeState("scroller-knob-dark");
_allowFadingOut = YES;
_isMouseOver = NO;
_style = CPScrollerStyleOverlay;
var paramAnimFadeOut = [CPDictionary dictionaryWithObjects:[self, CPViewAnimationFadeOutEffect]
forKeys:[CPViewAnimationTargetKey, CPViewAnimationEffectKey]];
var paramAnimFadeOut = @{
CPViewAnimationTargetKey: self,
CPViewAnimationEffectKey: CPViewAnimationFadeOutEffect,
};
_animationScroller = [[CPViewAnimation alloc] initWithDuration:0.2 animationCurve:CPAnimationEaseInOut];
[_animationScroller setViewAnimations:[paramAnimFadeOut]];
[_animationScroller setDelegate:self];
[self setAlphaValue:0.0];
[self _calculateIsVertical];
// We have to choose an orientation. If for some bizarre reason width === height,
// punt and choose vertical.
[self _setIsVertical:CGRectGetHeight(aFrame) >= CGRectGetWidth(aFrame)];
}
return self;
@@ -217,7 +235,7 @@ CPThemeStateScrollerKnobDark = CPThemeState("scroller-knob-dark");
[self unsetThemeState:CPThemeStateScrollViewLegacy];
}
[self _adjustScrollerSize];
//[self _adjustScrollerSize];
}
- (void)setObjectValue:(id)aValue
@@ -225,29 +243,6 @@ CPThemeStateScrollerKnobDark = CPThemeState("scroller-knob-dark");
[super setObjectValue:MIN(1.0, MAX(0.0, +aValue))];
}
/*!
Returns the scroller's control size
*/
- (CPControlSize)controlSize
{
return _controlSize;
}
/*!
Sets the scroller's size.
@param aControlSize the scroller's size
*/
- (void)setControlSize:(CPControlSize)aControlSize
{
if (_controlSize == aControlSize)
return;
_controlSize = aControlSize;
[self setNeedsLayout];
[self setNeedsDisplay:YES];
}
/*!
Return's the knob's proportion
*/
@@ -304,7 +299,7 @@ CPThemeStateScrollerKnobDark = CPThemeState("scroller-knob-dark");
- (CGRect)rectForPart:(CPScrollerPart)aPart
{
if (aPart == CPScrollerNoPart)
return _CGRectMakeZero();
return CGRectMakeZero();
return _partRects[aPart];
}
@@ -321,7 +316,7 @@ CPThemeStateScrollerKnobDark = CPThemeState("scroller-knob-dark");
// 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])
if (![self hasThemeState:CPThemeStateSelected] && ![self hasThemeState:CPThemeStateScrollViewLegacy])
return CPScrollerNoPart;
if (CGRectContainsPoint([self rectForPart:CPScrollerKnob], aPoint))
@@ -374,8 +369,8 @@ CPThemeStateScrollerKnobDark = CPThemeState("scroller-knob-dark");
var knobInset = [self currentValueForThemeAttribute:@"knob-inset"],
trackInset = [self currentValueForThemeAttribute:@"track-inset"],
width = _CGRectGetWidth(bounds),
height = _CGRectGetHeight(bounds);
width = CGRectGetWidth(bounds),
height = CGRectGetHeight(bounds);
if ([self isVertical])
{
@@ -385,25 +380,26 @@ CPThemeStateScrollerKnobDark = CPThemeState("scroller-knob-dark");
effectiveIncrementLineHeight = incrementLineSize.height + trackInset.bottom,
slotSize = height - effectiveDecrementLineHeight - effectiveIncrementLineHeight,
minimumKnobLength = [self currentValueForThemeAttribute:"minimum-knob-length"],
knobVerticalInset = knobInset.top + knobInset.bottom,
knobWidth = width - knobInset.left - knobInset.right,
knobHeight = MAX(minimumKnobLength, (slotSize * _knobProportion)),
knobLocation = effectiveDecrementLineHeight + (slotSize - knobHeight) * [self floatValue];
knobHeight = MAX(minimumKnobLength, ((slotSize - knobVerticalInset) * _knobProportion)),
knobLocation = effectiveDecrementLineHeight + (slotSize - knobHeight - knobVerticalInset) * [self floatValue] + knobInset.top;
_partRects[CPScrollerDecrementPage] = _CGRectMake(0.0, effectiveDecrementLineHeight, width, knobLocation - effectiveDecrementLineHeight);
_partRects[CPScrollerKnob] = _CGRectMake(knobInset.left, knobLocation, knobWidth, knobHeight);
_partRects[CPScrollerIncrementPage] = _CGRectMake(0.0, knobLocation + knobHeight, width, height - (knobLocation + knobHeight) - effectiveIncrementLineHeight);
_partRects[CPScrollerKnobSlot] = _CGRectMake(trackInset.left, effectiveDecrementLineHeight, width - trackInset.left - trackInset.right, slotSize);
_partRects[CPScrollerDecrementLine] = _CGRectMake(0.0, 0.0, decrementLineSize.width, decrementLineSize.height);
_partRects[CPScrollerIncrementLine] = _CGRectMake(0.0, height - incrementLineSize.height, incrementLineSize.width, incrementLineSize.height);
_partRects[CPScrollerDecrementPage] = CGRectMake(0.0, effectiveDecrementLineHeight, width, knobLocation - effectiveDecrementLineHeight);
_partRects[CPScrollerKnob] = CGRectMake(knobInset.left, knobLocation, knobWidth, knobHeight);
_partRects[CPScrollerIncrementPage] = CGRectMake(0.0, knobLocation + knobHeight, width, height - (knobLocation + knobHeight) - effectiveIncrementLineHeight);
_partRects[CPScrollerKnobSlot] = CGRectMake(trackInset.left, effectiveDecrementLineHeight, width - trackInset.left - trackInset.right, slotSize);
_partRects[CPScrollerDecrementLine] = CGRectMake(0.0, 0.0, decrementLineSize.width, decrementLineSize.height);
_partRects[CPScrollerIncrementLine] = CGRectMake(0.0, height - incrementLineSize.height, incrementLineSize.width, incrementLineSize.height);
if (height < knobHeight + decrementLineSize.height + incrementLineSize.height + trackInset.top + trackInset.bottom)
_partRects[CPScrollerKnob] = _CGRectMakeZero();
_partRects[CPScrollerKnob] = CGRectMakeZero();
if (height < decrementLineSize.height + incrementLineSize.height - 2)
{
_partRects[CPScrollerIncrementLine] = _CGRectMakeZero();
_partRects[CPScrollerDecrementLine] = _CGRectMakeZero();
_partRects[CPScrollerKnobSlot] = _CGRectMake(trackInset.left, 0, width - trackInset.left - trackInset.right, height);
_partRects[CPScrollerIncrementLine] = CGRectMakeZero();
_partRects[CPScrollerDecrementLine] = CGRectMakeZero();
_partRects[CPScrollerKnobSlot] = CGRectMake(trackInset.left, 0, width - trackInset.left - trackInset.right, height);
}
}
else
@@ -414,25 +410,26 @@ CPThemeStateScrollerKnobDark = CPThemeState("scroller-knob-dark");
effectiveIncrementLineWidth = incrementLineSize.width + trackInset.right,
slotSize = width - effectiveDecrementLineWidth - effectiveIncrementLineWidth,
minimumKnobLength = [self currentValueForThemeAttribute:"minimum-knob-length"],
knobWidth = MAX(minimumKnobLength, (slotSize * _knobProportion)),
knobHorizontalInset = knobInset.left + knobInset.right,
knobWidth = MAX(minimumKnobLength, ((slotSize - knobHorizontalInset) * _knobProportion)),
knobHeight = height - knobInset.top - knobInset.bottom,
knobLocation = effectiveDecrementLineWidth + (slotSize - knobWidth) * [self floatValue];
knobLocation = effectiveDecrementLineWidth + (slotSize - knobWidth - knobHorizontalInset) * [self floatValue] + knobInset.left;
_partRects[CPScrollerDecrementPage] = _CGRectMake(effectiveDecrementLineWidth, 0.0, knobLocation - effectiveDecrementLineWidth, height);
_partRects[CPScrollerKnob] = _CGRectMake(knobLocation, knobInset.top, knobWidth, knobHeight);
_partRects[CPScrollerIncrementPage] = _CGRectMake(knobLocation + knobWidth, 0.0, width - (knobLocation + knobWidth) - effectiveIncrementLineWidth, height);
_partRects[CPScrollerKnobSlot] = _CGRectMake(effectiveDecrementLineWidth, trackInset.top, slotSize, height - trackInset.top - trackInset.bottom);
_partRects[CPScrollerDecrementLine] = _CGRectMake(0.0, 0.0, decrementLineSize.width, decrementLineSize.height);
_partRects[CPScrollerIncrementLine] = _CGRectMake(width - incrementLineSize.width, 0.0, incrementLineSize.width, incrementLineSize.height);
_partRects[CPScrollerDecrementPage] = CGRectMake(effectiveDecrementLineWidth, 0.0, knobLocation - effectiveDecrementLineWidth, height);
_partRects[CPScrollerKnob] = CGRectMake(knobLocation, knobInset.top, knobWidth, knobHeight);
_partRects[CPScrollerIncrementPage] = CGRectMake(knobLocation + knobWidth, 0.0, width - (knobLocation + knobWidth) - effectiveIncrementLineWidth, height);
_partRects[CPScrollerKnobSlot] = CGRectMake(effectiveDecrementLineWidth, trackInset.top, slotSize, height - trackInset.top - trackInset.bottom);
_partRects[CPScrollerDecrementLine] = CGRectMake(0.0, 0.0, decrementLineSize.width, decrementLineSize.height);
_partRects[CPScrollerIncrementLine] = CGRectMake(width - incrementLineSize.width, 0.0, incrementLineSize.width, incrementLineSize.height);
if (width < knobWidth + decrementLineSize.width + incrementLineSize.width + trackInset.left + trackInset.right)
_partRects[CPScrollerKnob] = _CGRectMakeZero();
_partRects[CPScrollerKnob] = CGRectMakeZero();
if (width < decrementLineSize.width + incrementLineSize.width - 2)
{
_partRects[CPScrollerIncrementLine] = _CGRectMakeZero();
_partRects[CPScrollerDecrementLine] = _CGRectMakeZero();
_partRects[CPScrollerKnobSlot] = _CGRectMake(0.0, 0.0, width, slotSize);
_partRects[CPScrollerIncrementLine] = CGRectMakeZero();
_partRects[CPScrollerDecrementLine] = CGRectMakeZero();
_partRects[CPScrollerKnobSlot] = CGRectMake(0.0, 0.0, width, slotSize);
}
}
}
@@ -465,9 +462,6 @@ CPThemeStateScrollerKnobDark = CPThemeState("scroller-knob-dark");
*/
- (void)fadeOut
{
if ([self hasThemeState:CPThemeStateScrollViewLegacy])
return;
[_animationScroller startAnimation];
}
@@ -500,7 +494,7 @@ CPThemeStateScrollerKnobDark = CPThemeState("scroller-knob-dark");
- (CPView)createViewForPart:(CPScrollerPart)aPart
{
var view = [[CPView alloc] initWithFrame:_CGRectMakeZero()];
var view = [[CPView alloc] initWithFrame:CGRectMakeZero()];
[view setHitTests:NO];
@@ -514,7 +508,7 @@ CPThemeStateScrollerKnobDark = CPThemeState("scroller-knob-dark");
- (CPView)createEphemeralSubviewNamed:(CPString)aName
{
var view = [[CPView alloc] initWithFrame:_CGRectMakeZero()];
var view = [[CPView alloc] initWithFrame:CGRectMakeZero()];
[view setHitTests:NO];
@@ -523,6 +517,7 @@ CPThemeStateScrollerKnobDark = CPThemeState("scroller-knob-dark");
- (void)layoutSubviews
{
[self _adjustScrollerSize];
[self checkSpaceForParts];
var index = 0,
@@ -588,7 +583,7 @@ CPThemeStateScrollerKnobDark = CPThemeState("scroller-knob-dark");
{
var knobRect = [self rectForPart:CPScrollerKnob],
knobSlotRect = [self rectForPart:CPScrollerKnobSlot],
remainder = ![self isVertical] ? (_CGRectGetWidth(knobSlotRect) - _CGRectGetWidth(knobRect)) : (_CGRectGetHeight(knobSlotRect) - _CGRectGetHeight(knobRect));
remainder = ![self isVertical] ? (CGRectGetWidth(knobSlotRect) - CGRectGetWidth(knobRect)) : (CGRectGetHeight(knobSlotRect) - CGRectGetHeight(knobRect));
if (remainder <= 0)
[self setFloatValue:0.0];
@@ -633,20 +628,20 @@ CPThemeStateScrollerKnobDark = CPThemeState("scroller-knob-dark");
if ([anEvent modifierFlags] & CPAlternateKeyMask)
{
if (_trackingPart == CPScrollerDecrementLine)
if (_trackingPart === CPScrollerDecrementLine)
_hitPart = CPScrollerDecrementPage;
else if (_trackingPart == CPScrollerIncrementLine)
else if (_trackingPart === CPScrollerIncrementLine)
_hitPart = CPScrollerIncrementPage;
else if (_trackingPart == CPScrollerDecrementPage || _trackingPart == CPScrollerIncrementPage)
else if (_trackingPart === CPScrollerDecrementPage || _trackingPart === CPScrollerIncrementPage)
{
var knobRect = [self rectForPart:CPScrollerKnob],
knobWidth = ![self isVertical] ? _CGRectGetWidth(knobRect) : _CGRectGetHeight(knobRect),
knobWidth = ![self isVertical] ? CGRectGetWidth(knobRect) : CGRectGetHeight(knobRect),
knobSlotRect = [self rectForPart:CPScrollerKnobSlot],
remainder = (![self isVertical] ? _CGRectGetWidth(knobSlotRect) : _CGRectGetHeight(knobSlotRect)) - knobWidth;
remainder = (![self isVertical] ? CGRectGetWidth(knobSlotRect) : CGRectGetHeight(knobSlotRect)) - knobWidth;
[self setFloatValue:((![self isVertical] ? _trackingStartPoint.x - _CGRectGetMinX(knobSlotRect) : _trackingStartPoint.y - _CGRectGetMinY(knobSlotRect)) - knobWidth / 2.0) / remainder];
[self setFloatValue:((![self isVertical] ? _trackingStartPoint.x - CGRectGetMinX(knobSlotRect) : _trackingStartPoint.y - CGRectGetMinY(knobSlotRect)) - knobWidth / 2.0) / remainder];
_hitPart = CPScrollerKnob;
@@ -667,11 +662,11 @@ CPThemeStateScrollerKnobDark = CPThemeState("scroller-knob-dark");
{
_trackingStartPoint = [self convertPoint:[anEvent locationInWindow] fromView:nil];
if (_trackingPart == CPScrollerDecrementPage || _trackingPart == CPScrollerIncrementPage)
if (_trackingPart === CPScrollerDecrementPage || _trackingPart === CPScrollerIncrementPage)
{
var hitPart = [self testPart:[anEvent locationInWindow]];
if (hitPart == CPScrollerDecrementPage || hitPart == CPScrollerIncrementPage)
if (hitPart === CPScrollerDecrementPage || hitPart === CPScrollerIncrementPage)
{
_trackingPart = hitPart;
_hitPart = hitPart;
@@ -687,18 +682,13 @@ CPThemeStateScrollerKnobDark = CPThemeState("scroller-knob-dark");
}
- (void)_calculateIsVertical
- (void)_setIsVertical:(BOOL)isVertical
{
// Recalculate isVertical.
var bounds = [self bounds],
width = _CGRectGetWidth(bounds),
height = _CGRectGetHeight(bounds);
_isVertical = isVertical;
_isVertical = width < height ? 1 : (width > height ? 0 : -1);
if (_isVertical === 1)
if (_isVertical)
[self setThemeState:CPThemeStateVertical];
else if (_isVertical === 0)
else
[self unsetThemeState:CPThemeStateVertical];
}
@@ -719,7 +709,7 @@ CPThemeStateScrollerKnobDark = CPThemeState("scroller-knob-dark");
var themeState = _themeState;
if (NAMES_FOR_PARTS[_hitPart] + "-color" !== anAttributeName)
themeState &= ~CPThemeStateHighlighted;
themeState = themeState.without(CPThemeStateHighlighted);
return [self valueForThemeAttribute:anAttributeName inState:themeState];
}
@@ -733,12 +723,14 @@ CPThemeStateScrollerKnobDark = CPThemeState("scroller-knob-dark");
switch (_hitPart)
{
case CPScrollerKnob: return [self trackKnob:anEvent];
case CPScrollerKnob:
return [self trackKnob:anEvent];
case CPScrollerDecrementLine:
case CPScrollerIncrementLine:
case CPScrollerDecrementPage:
case CPScrollerIncrementPage: return [self trackScrollButtons:anEvent];
case CPScrollerIncrementPage:
return [self trackScrollButtons:anEvent];
}
}
@@ -772,7 +764,10 @@ CPThemeStateScrollerKnobDark = CPThemeState("scroller-knob-dark");
if (_timerFadeOut)
[_timerFadeOut invalidate];
_timerFadeOut = [CPTimer scheduledTimerWithTimeInterval:1.2 target:self selector:@selector(_performFadeOut:) userInfo:nil repeats:NO];
if ([self hasThemeState:CPThemeStateScrollViewLegacy])
[self unsetThemeState:CPThemeStateSelected];
else
_timerFadeOut = [CPTimer scheduledTimerWithTimeInterval:1.2 target:self selector:@selector(_performFadeOut:) userInfo:nil repeats:NO];
}
@@ -786,9 +781,9 @@ CPThemeStateScrollerKnobDark = CPThemeState("scroller-knob-dark");
@end
var CPScrollerControlSizeKey = @"CPScrollerControlSize",
var CPScrollerIsVerticalKey = @"CPScrollerIsVerticalKey",
CPScrollerKnobProportionKey = @"CPScrollerKnobProportion",
CPScrollerStyleKey = @"CPScrollerStyleKey";
CPScrollerStyleKey = @"CPScrollerStyleKey";
@implementation CPScroller (CPCoding)
@@ -796,11 +791,6 @@ var CPScrollerControlSizeKey = @"CPScrollerControlSize",
{
if (self = [super initWithCoder:aCoder])
{
_controlSize = CPRegularControlSize;
if ([aCoder containsValueForKey:CPScrollerControlSizeKey])
_controlSize = [aCoder decodeIntForKey:CPScrollerControlSizeKey];
_knobProportion = 1.0;
if ([aCoder containsValueForKey:CPScrollerKnobProportionKey])
@@ -813,17 +803,19 @@ var CPScrollerControlSizeKey = @"CPScrollerControlSize",
_allowFadingOut = YES;
_isMouseOver = NO;
var paramAnimFadeOut = [CPDictionary dictionaryWithObjects:[self, CPViewAnimationFadeOutEffect]
forKeys:[CPViewAnimationTargetKey, CPViewAnimationEffectKey]];
var paramAnimFadeOut = @{
CPViewAnimationTargetKey: self,
CPViewAnimationEffectKey: CPViewAnimationFadeOutEffect,
};
_animationScroller = [[CPViewAnimation alloc] initWithDuration:0.2 animationCurve:CPAnimationEaseInOut];
[_animationScroller setViewAnimations:[paramAnimFadeOut]];
[_animationScroller setDelegate:self];
[self setAlphaValue:0.0];
[self _calculateIsVertical];
[self setStyle:[aCoder decodeIntForKey:CPScrollerStyleKey]];
[self _setIsVertical:[aCoder decodeBoolForKey:CPScrollerIsVerticalKey]];
}
return self;
@@ -833,7 +825,7 @@ var CPScrollerControlSizeKey = @"CPScrollerControlSize",
{
[super encodeWithCoder:aCoder];
[aCoder encodeInt:_controlSize forKey:CPScrollerControlSizeKey];
[aCoder encodeInt:_isVertical forKey:CPScrollerIsVerticalKey];
[aCoder encodeFloat:_knobProportion forKey:CPScrollerKnobProportionKey];
[aCoder encodeInt:_style forKey:CPScrollerStyleKey];
}
+192 -73
View File
@@ -21,26 +21,21 @@
*/
@import "CPButton.j"
@import "CPMenu.j"
@import "CPMenuItem.j"
@import "CPTextField.j"
@class CPUserDefaults
@global CPApp
CPSearchFieldRecentsTitleMenuItemTag = 1000;
CPSearchFieldRecentsMenuItemTag = 1001;
CPSearchFieldClearRecentsMenuItemTag = 1002;
CPSearchFieldNoRecentsMenuItemTag = 1003;
var CPSearchFieldSearchImage = nil,
CPSearchFieldFindImage = nil,
CPSearchFieldCancelImage = nil,
CPSearchFieldCancelPressedImage = nil;
var SEARCH_BUTTON_DEFAULT_WIDTH = 25.0,
CANCEL_BUTTON_DEFAULT_WIDTH = 22.0,
BUTTON_DEFAULT_HEIGHT = 22.0;
var CPAutosavedRecentsChangedNotification = @"CPAutosavedRecentsChangedNotification";
var RECENT_SEARCH_PREFIX = @" ";
/*!
@ingroup appkit
@class CPSearchField
@@ -70,16 +65,25 @@ var RECENT_SEARCH_PREFIX = @" ";
return @"searchfield"
}
+ (void)initialize
+ (CPDictionary)themeAttributes
{
if (self !== [CPSearchField class])
return;
return @{
@"image-search": [CPNull null],
@"image-find": [CPNull null],
@"image-cancel": [CPNull null],
@"image-cancel-pressed": [CPNull null],
@"image-search-inset" : CGInsetMake(0, 0, 0, 5),
@"image-cancel-inset" : CGInsetMake(0, 5, 0, 0),
@"search-right-margin": 2
};
}
var bundle = [CPBundle bundleForClass:self];
CPSearchFieldSearchImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPSearchField/CPSearchFieldSearch.png"] size:_CGSizeMake(SEARCH_BUTTON_DEFAULT_WIDTH, BUTTON_DEFAULT_HEIGHT)];
CPSearchFieldFindImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPSearchField/CPSearchFieldFind.png"] size:_CGSizeMake(SEARCH_BUTTON_DEFAULT_WIDTH, BUTTON_DEFAULT_HEIGHT)];
CPSearchFieldCancelImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPSearchField/CPSearchFieldCancel.png"] size:_CGSizeMake(CANCEL_BUTTON_DEFAULT_WIDTH, BUTTON_DEFAULT_HEIGHT)];
CPSearchFieldCancelPressedImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPSearchField/CPSearchFieldCancelPressed.png"] size:_CGSizeMake(CANCEL_BUTTON_DEFAULT_WIDTH, BUTTON_DEFAULT_HEIGHT)];
+ (Class)_binderClassForBinding:(CPString)aBinding
{
if (aBinding === CPPredicateBinding)
return [_CPSearchFieldPredicateBinder class];
return [super _binderClassForBinding:aBinding];
}
- (id)initWithFrame:(CGRect)frame
@@ -92,10 +96,6 @@ var RECENT_SEARCH_PREFIX = @" ";
_recentsAutosaveName = nil;
[self _init];
#if PLATFORM(DOM)
_cancelButton._DOMElement.style.cursor = "default";
_searchButton._DOMElement.style.cursor = "default";
#endif
}
return self;
@@ -124,16 +124,28 @@ var RECENT_SEARCH_PREFIX = @" ";
_canResignFirstResponder = YES;
}
- (void)viewWillMoveToSuperview:(CPView)aView
#pragma mark -
#pragma mark Override observers
- (void)_removeObservers
{
[super viewWillMoveToSuperview:aView];
if (!_isObserving)
return;
[super _removeObservers];
// First we remove any observer that may have been in place to avoid memory leakage.
[[CPNotificationCenter defaultCenter] removeObserver:self name:CPControlTextDidChangeNotification object:self];
}
// Register the observe here if we need to.
if (aView)
[[CPNotificationCenter defaultCenter] addObserver:self selector:@selector(_searchFieldTextDidChange:) name:CPControlTextDidChangeNotification object:self];
- (void)_addObservers
{
if (_isObserving)
return;
[super _addObservers];
[[CPNotificationCenter defaultCenter] addObserver:self selector:@selector(_searchFieldTextDidChange:) name:CPControlTextDidChangeNotification object:self];
}
// Managing Buttons
@@ -170,7 +182,7 @@ var RECENT_SEARCH_PREFIX = @" ";
- (void)resetSearchButton
{
var button = [self searchButton],
searchButtonImage = (_searchMenuTemplate === nil) ? CPSearchFieldSearchImage : CPSearchFieldFindImage;
searchButtonImage = (_searchMenuTemplate === nil) ? [self currentValueForThemeAttribute:@"image-search"] : [self currentValueForThemeAttribute:@"image-find"];
[button setBordered:NO];
[button setImageScaling:CPImageScaleAxesIndependently];
@@ -193,6 +205,7 @@ var RECENT_SEARCH_PREFIX = @" ";
[_cancelButton setAutoresizingMask:CPViewMinXMargin];
[_cancelButton setTarget:self];
[_cancelButton setAction:@selector(cancelOperation:)];
[_cancelButton setButtonType:CPMomentaryChangeButton];
[self _updateCancelButtonVisibility];
[self addSubview:_cancelButton];
}
@@ -216,8 +229,8 @@ var RECENT_SEARCH_PREFIX = @" ";
var button = [self cancelButton];
[button setBordered:NO];
[button setImageScaling:CPImageScaleAxesIndependently];
[button setImage:CPSearchFieldCancelImage];
[button setAlternateImage:CPSearchFieldCancelPressedImage];
[button setImage:[self valueForThemeAttribute:@"image-cancel"]];
[button setAlternateImage:[self valueForThemeAttribute:@"image-cancel-pressed"]];
[button setAutoresizingMask:CPViewMinXMargin];
[button setTarget:self];
[button setAction:@selector(cancelOperation:)];
@@ -233,22 +246,23 @@ var RECENT_SEARCH_PREFIX = @" ";
- (CGRect)searchTextRectForBounds:(CGRect)rect
{
var leftOffset = 0,
width = _CGRectGetWidth(rect),
width = CGRectGetWidth(rect),
bounds = [self bounds];
if (_searchButton)
{
var searchBounds = [self searchButtonRectForBounds:bounds];
leftOffset = _CGRectGetMaxX(searchBounds) + 2;
var searchBounds = [self searchButtonRectForBounds:bounds],
rightMargin = [self currentValueForThemeAttribute:@"search-right-margin"];
leftOffset = CGRectGetMaxX(searchBounds) + rightMargin;
}
if (_cancelButton)
{
var cancelRect = [self cancelButtonRectForBounds:bounds];
width = _CGRectGetMinX(cancelRect) - leftOffset;
width = CGRectGetMinX(cancelRect) - leftOffset;
}
return _CGRectMake(leftOffset, _CGRectGetMinY(rect), width, _CGRectGetHeight(rect));
return CGRectMake(leftOffset, CGRectGetMinY(rect), width, CGRectGetHeight(rect));
}
/*!
@@ -258,7 +272,10 @@ var RECENT_SEARCH_PREFIX = @" ";
*/
- (CGRect)searchButtonRectForBounds:(CGRect)rect
{
return _CGRectMake(5, (_CGRectGetHeight(rect) - BUTTON_DEFAULT_HEIGHT) / 2, SEARCH_BUTTON_DEFAULT_WIDTH, BUTTON_DEFAULT_HEIGHT);
var size = [[self currentValueForThemeAttribute:@"image-search"] size] || CGSizeMakeZero(),
inset = [self currentValueForThemeAttribute:@"image-search-inset"];
return CGRectMake(inset.left - inset.right, inset.top - inset.bottom + (CGRectGetHeight(rect) - size.height) / 2, size.width, size.height);
}
/*!
@@ -268,7 +285,10 @@ var RECENT_SEARCH_PREFIX = @" ";
*/
- (CGRect)cancelButtonRectForBounds:(CGRect)rect
{
return _CGRectMake(_CGRectGetWidth(rect) - CANCEL_BUTTON_DEFAULT_WIDTH - 5, (_CGRectGetHeight(rect) - CANCEL_BUTTON_DEFAULT_WIDTH) / 2, BUTTON_DEFAULT_HEIGHT, BUTTON_DEFAULT_HEIGHT);
var size = [[self currentValueForThemeAttribute:@"image-cancel"] size] || CGSizeMakeZero(),
inset = [self currentValueForThemeAttribute:@"image-cancel-inset"];
return CGRectMake(CGRectGetWidth(rect) - size.width + inset.left - inset.right, inset.top - inset.bottom + (CGRectGetHeight(rect) - size.width) / 2, size.height, size.height);
}
// Managing Menu Templates
@@ -372,9 +392,9 @@ var RECENT_SEARCH_PREFIX = @" ";
*/
- (void)setRecentSearches:(CPArray)searches
{
var max = MIN([self maximumRecents], [searches count]),
searches = [searches subarrayWithRange:CPMakeRange(0, max)];
var max = MIN([self maximumRecents], [searches count]);
searches = [searches subarrayWithRange:CPMakeRange(0, max)];
_recentSearches = searches;
[self _autosaveRecentSearchList];
}
@@ -458,7 +478,7 @@ var RECENT_SEARCH_PREFIX = @" ";
[self sendAction:[self action] to:[self target]];
}
- (void)sendAction:(SEL)anAction to:(id)anObject
- (BOOL)sendAction:(SEL)anAction to:(id)anObject
{
[super sendAction:anAction to:anObject];
@@ -482,7 +502,7 @@ var RECENT_SEARCH_PREFIX = @" ";
- (CPView)hitTest:(CGPoint)aPoint
{
// Make sure a hit anywhere within the search field returns the search field itself
if (_CGRectContainsPoint([self frame], aPoint))
if (CGRectContainsPoint([self frame], aPoint))
return self;
else
return nil;
@@ -498,7 +518,7 @@ var RECENT_SEARCH_PREFIX = @" ";
var location = [anEvent locationInWindow],
point = [self convertPoint:location fromView:nil];
if (_CGRectContainsPoint([self searchButtonRectForBounds:[self bounds]], point))
if (CGRectContainsPoint([self searchButtonRectForBounds:[self bounds]], point))
{
if (_searchMenuTemplate == nil)
{
@@ -510,26 +530,23 @@ var RECENT_SEARCH_PREFIX = @" ";
else
[self _showMenu];
}
else if (_CGRectContainsPoint([self cancelButtonRectForBounds:[self bounds]], point))
else if (CGRectContainsPoint([self cancelButtonRectForBounds:[self bounds]], point))
[_cancelButton mouseDown:anEvent];
else
[super mouseDown:anEvent];
}
/*!
Provides the common case items for a recent searches menu. If there are not recent searches,
displays a single disabled item:
No Recent Searches
Provides the common case items for a recent searches menu.
If there are 1 more recent searches, it displays:
Recent Searches
recent search 1
recent search 2
etc.
Clear
---------------------
Clear Recent Searches
Recent Searches
recent search 1
recent search 2
etc.
If you wish to add items before or after the template, you can. If you put items
before, a separator will automatically be placed before the default template item.
@@ -554,6 +571,13 @@ var RECENT_SEARCH_PREFIX = @" ";
var template = [[CPMenu alloc] init],
item;
item = [[CPMenuItem alloc] initWithTitle:@"Clear"
action:@selector(_searchFieldClearRecents:)
keyEquivalent:@""];
[item setTag:CPSearchFieldClearRecentsMenuItemTag];
[item setTarget:self];
[template addItem:item];
item = [[CPMenuItem alloc] initWithTitle:@"Recent Searches"
action:nil
keyEquivalent:@""];
@@ -568,20 +592,6 @@ var RECENT_SEARCH_PREFIX = @" ";
[item setTarget:self];
[template addItem:item];
item = [[CPMenuItem alloc] initWithTitle:@"Clear Recent Searches"
action:@selector(_searchFieldClearRecents:)
keyEquivalent:@""];
[item setTag:CPSearchFieldClearRecentsMenuItemTag];
[item setTarget:self];
[template addItem:item];
item = [[CPMenuItem alloc] initWithTitle:@"No Recent Searches"
action:nil
keyEquivalent:@""];
[item setTag:CPSearchFieldNoRecentsMenuItemTag];
[item setEnabled:NO];
[template addItem:item];
return template;
}
@@ -594,6 +604,8 @@ var RECENT_SEARCH_PREFIX = @" ";
countOfRecents = [_recentSearches count],
numberOfItems = [_searchMenuTemplate numberOfItems];
[menu setAutoenablesItems:NO];
for (var i = 0; i < numberOfItems; i++)
{
var item = [[_searchMenuTemplate itemAtIndex:i] copy];
@@ -614,8 +626,7 @@ var RECENT_SEARCH_PREFIX = @" ";
for (var recentIndex = 0; recentIndex < countOfRecents; ++recentIndex)
{
// RECENT_SEARCH_PREFIX is a hack until CPMenuItem -setIndentationLevel works
var recentItem = [[CPMenuItem alloc] initWithTitle:RECENT_SEARCH_PREFIX + [_recentSearches objectAtIndex:recentIndex]
var recentItem = [[CPMenuItem alloc] initWithTitle:[_recentSearches objectAtIndex:recentIndex]
action:itemAction
keyEquivalent:[item keyEquivalent]];
[item setTarget:self];
@@ -675,11 +686,11 @@ var RECENT_SEARCH_PREFIX = @" ";
- (void)_showMenu
{
if (_searchMenu === nil || [_searchMenu numberOfItems] === 0 || ![self isEnabled])
if (_searchMenu === nil || [_searchMenu numberOfItems] === 0 || ![self isEnabled] || ([_recentSearches count] === 0))
return;
var aFrame = [[self superview] convertRect:[self frame] toView:nil],
location = CPMakePoint(aFrame.origin.x + 10, aFrame.origin.y + aFrame.size.height - 4);
location = CGPointMake(aFrame.origin.x + 10, aFrame.origin.y + aFrame.size.height - 4);
var anEvent = [CPEvent mouseEventWithType:CPRightMouseDown location:location modifierFlags:0 timestamp:[[CPApp currentEvent] timestamp] windowNumber:[[self window] windowNumber] context:nil eventNumber:1 clickCount:1 pressure:0];
@@ -703,7 +714,7 @@ var RECENT_SEARCH_PREFIX = @" ";
- (void)_searchFieldSearch:(id)sender
{
var searchString = [[sender title] substringFromIndex:[RECENT_SEARCH_PREFIX length]];
var searchString = [sender title];
if ([sender tag] != CPSearchFieldRecentsMenuItemTag)
[self _addStringToRecentSearches:searchString];
@@ -757,8 +768,75 @@ var RECENT_SEARCH_PREFIX = @" ";
_recentSearches = list;
}
- (void)unbind:(CPString)aBinding
{
[super unbind:aBinding];
// our CPPredicateBinding binder adds a binding to the value.
// this private binding has to be also removed
if (aBinding === CPPredicateBinding)
[[[self class] _binderClassForBinding:aBinding] unbind:CPValueBinding forObject:self];
}
@end
#pragma mark -
@implementation CPSearchField (CPTrackingArea)
{
CPTrackingArea _searchButtonTrackingArea;
CPTrackingArea _cancelButtonTrackingArea;
}
- (void)updateTrackingAreas
{
if (_searchButtonTrackingArea)
{
[self removeTrackingArea:_searchButtonTrackingArea];
_searchButtonTrackingArea = nil;
}
if (_cancelButtonTrackingArea)
{
[self removeTrackingArea:_cancelButtonTrackingArea];
_cancelButtonTrackingArea = nil;
}
if (_searchButton)
{
_searchButtonTrackingArea = [[CPTrackingArea alloc] initWithRect:[_searchButton frame]
options:CPTrackingCursorUpdate | CPTrackingActiveInKeyWindow
owner:self
userInfo:@{ @"isButton": YES }];
[self addTrackingArea:_searchButtonTrackingArea];
}
if (_cancelButton)
{
_cancelButtonTrackingArea = [[CPTrackingArea alloc] initWithRect:[_cancelButton frame]
options:CPTrackingCursorUpdate | CPTrackingActiveInKeyWindow
owner:self
userInfo:@{ @"isButton": YES }];
[self addTrackingArea:_cancelButtonTrackingArea];
}
[super updateTrackingAreas];
}
- (void)cursorUpdate:(CPEvent)anEvent
{
if ([[[anEvent trackingArea] userInfo] objectForKey:@"isButton"])
[[CPCursor arrowCursor] set];
else
[super cursorUpdate:anEvent];
}
@end
#pragma mark -
var CPRecentsAutosaveNameKey = @"CPRecentsAutosaveNameKey",
CPSendsWholeSearchStringKey = @"CPSendsWholeSearchStringKey",
CPSendsSearchStringImmediatelyKey = @"CPSendsSearchStringImmediatelyKey",
@@ -811,3 +889,44 @@ var CPRecentsAutosaveNameKey = @"CPRecentsAutosaveNameKey",
}
@end
@implementation _CPSearchFieldPredicateBinder : CPBinder
{
CPArrayController _controller;
CPString _predicateFormat;
}
- (void)setValue:(id)aValue forBinding:(CPString)aBinding
{
if (aBinding === CPPredicateBinding)
{
var options = [_info objectForKey:CPOptionsKey];
_controller = [_info objectForKey:CPObservedObjectKey];
_predicateFormat = [options objectForKey:"CPPredicateFormat"];
[_source bind:CPValueBinding toObject:self withKeyPath:"searchFieldValue" options:nil];
}
}
- (void)setSearchFieldValue:(CPString)aValue
{
var destination = [_info objectForKey:CPObservedObjectKey],
keyPath = [_info objectForKey:CPObservedKeyPathKey];
var formatString = _predicateFormat.replace(/\$value/g, "%@");
[self suppressSpecificNotificationFromObject:destination keyPath:keyPath];
if (aValue)
[_controller setFilterPredicate:[CPPredicate predicateWithFormat:formatString, aValue]];
else
[_controller setFilterPredicate:nil];
[self unsuppressSpecificNotificationFromObject:destination keyPath:keyPath];
}
- (CPString)searchFieldValue
{
return [_source stringValue];
}
@end
+436 -203
View File
@@ -23,8 +23,13 @@
@import <Foundation/CPArray.j>
@import "CPControl.j"
@import "CPWindow_Constants.j"
@import "_CPImageAndTextView.j"
@import "CPMenu.j"
@global CPApp
@typedef CPSegmentSwitchTracking
CPSegmentSwitchTrackingSelectOne = 0;
CPSegmentSwitchTrackingSelectAny = 1;
CPSegmentSwitchTrackingMomentary = 2;
@@ -37,7 +42,7 @@ CPSegmentSwitchTrackingMomentary = 2;
*/
@implementation CPSegmentedControl : CPControl
{
CPArray _segments;
CPArray _segments @accessors(getter=segments);
CPArray _themeStates;
int _selectedSegment;
@@ -53,10 +58,21 @@ CPSegmentSwitchTrackingMomentary = 2;
return "segmented-control";
}
+ (id)themeAttributes
+ (CPDictionary)themeAttributes
{
return [CPDictionary dictionaryWithObjects:[CPCenterTextAlignment, CPCenterVerticalTextAlignment, CPImageLeft, CPImageScaleNone, _CGInsetMakeZero(), _CGInsetMakeZero(), [CPNull null], [CPNull null], [CPNull null], [CPNull null], 1.0, 24.0]
forKeys:[@"alignment", @"vertical-alignment", @"image-position", @"image-scaling", @"bezel-inset", @"content-inset", @"left-segment-bezel-color", @"right-segment-bezel-color", @"center-segment-bezel-color", @"divider-bezel-color", @"divider-thickness", @"default-height"]];
return @{
@"alignment": CPCenterTextAlignment,
@"vertical-alignment": CPCenterVerticalTextAlignment,
@"image-position": CPImageLeft,
@"image-scaling": CPImageScaleNone,
@"bezel-inset": CGInsetMakeZero(),
@"content-inset": CGInsetMakeZero(),
@"left-segment-bezel-color": [CPNull null],
@"right-segment-bezel-color": [CPNull null],
@"center-segment-bezel-color": [CPNull null],
@"divider-bezel-color": [CPNull null],
@"divider-thickness": 1.0,
};
}
- (id)initWithFrame:(CGRect)aRect
@@ -71,17 +87,76 @@ CPSegmentSwitchTrackingMomentary = 2;
_selectedSegment = -1;
_trackingMode = CPSegmentSwitchTrackingSelectOne;
_trackingHighlighted = NO;
_trackingSegment = -1;
}
return self;
}
/*!
Sets the control's size.
@param aControlSize the control's size
*/
- (void)setControlSize:(CPControlSize)aControlSize
{
[super setControlSize:aControlSize];
[self _sizeToControlSize];
}
/*!
Returns the tag of the selected segment.
*/
- (int)selectedTag
{
return [_segments[_selectedSegment] tag];
return [[_segments objectAtIndex:_selectedSegment] tag];
}
/*! @ignore */
- (void)setSegments:(CPArray)segments
{
[self removeSegmentsAtIndexes:[CPIndexSet indexSetWithIndexesInRange:CPMakeRange(0, [self segmentCount])]];
[self insertSegments:segments atIndexes:[CPIndexSet indexSetWithIndexesInRange:CPMakeRange(0, [segments count])]];
}
/*! @ignore */
- (void)insertSegments:(CPArray)segments atIndexes:(CPIndexSet)indices
{
if ([segments count] == 0)
return;
var newStates = @[],
count = [indices count];
while (count--)
[newStates addObject:CPThemeStateNormal];
[_segments insertObjects:segments atIndexes:indices];
[_themeStates insertObjects:newStates atIndexes:indices];
if (_selectedSegment >= [indices firstIndex])
_selectedSegment += [indices count];
}
/*! @ignore */
- (void)removeSegmentsAtIndexes:(CPIndexSet)indices
{
if ([indices count] == 0)
return;
[indices enumerateIndexesUsingBlock:function(idx, stop)
{
[[_segments objectAtIndex:idx] setSelected:NO];
}];
if ([indices containsIndex:_selectedSegment])
_selectedSegment = -1;
else if ([indices lastIndex] < _selectedSegment)
_selectedSegment -= [indices count];
[_segments removeObjectsAtIndexes:indices];
[_themeStates removeObjectsAtIndexes:indices];
}
// Specifying the number of segments
@@ -91,41 +166,32 @@ CPSegmentSwitchTrackingMomentary = 2;
*/
- (void)setSegmentCount:(unsigned)aCount
{
if (_segments.length == aCount)
var prevCount = [_segments count];
if (aCount == prevCount)
return;
var height = CGRectGetHeight([self bounds]),
dividersBefore = MAX(0, _segments.length - 1),
dividersAfter = MAX(0, aCount - 1);
if (_segments.length < aCount)
if (aCount > prevCount)
{
for (var index = _segments.length; index < aCount; ++index)
{
_segments[index] = [[_CPSegmentItem alloc] init];
_themeStates[index] = CPThemeStateNormal;
}
}
else if (aCount < _segments.length)
{
_segments.length = aCount;
_themeStates.length = aCount;
}
var count = aCount - prevCount,
segments = @[];
if (_selectedSegment >= _segments.length)
while (count--)
[segments addObject:[[_CPSegmentItem alloc] init]];
[self insertSegments:segments atIndexes:[CPIndexSet indexSetWithIndexesInRange:CPMakeRange(prevCount, aCount - prevCount)]];
}
else
[self removeSegmentsAtIndexes:[CPIndexSet indexSetWithIndexesInRange:CPMakeRange(aCount, prevCount - aCount)]];
[self _updateSelectionIfNeeded];
[self tileWithChangedSegment:MAX(MIN(prevCount, aCount) - 1, 0)];
}
- (void)_updateSelectionIfNeeded
{
if (_selectedSegment >= [self segmentCount])
_selectedSegment = -1;
var thickness = [self currentValueForThemeAttribute:@"divider-thickness"],
frame = [self frame],
widthOfAllSegments = 0,
dividerExtraSpace = ([_segments count] - 1) * thickness;
for (var i = 0; i < [_segments count]; i++)
widthOfAllSegments += [_segments[i] width];
[self setFrameSize:CGSizeMake(widthOfAllSegments + dividerExtraSpace, frame.size.height)];
[self tileWithChangedSegment:0];
}
/*!
@@ -133,7 +199,7 @@ CPSegmentSwitchTrackingMomentary = 2;
*/
- (unsigned)segmentCount
{
return _segments.length;
return [_segments count];
}
// Specifying Selected Segment
@@ -145,7 +211,20 @@ CPSegmentSwitchTrackingMomentary = 2;
- (void)setSelectedSegment:(unsigned)aSegment
{
// setSelected:forSegment throws the exception for us (if necessary)
[self setSelected:YES forSegment:aSegment];
if (_selectedSegment == aSegment)
return;
if (aSegment == -1)
{
var count = [self segmentCount];
while (count--)
[self setSelected:NO forSegment:count];
_selectedSegment = -1;
}
else
[self setSelected:YES forSegment:aSegment];
}
/*!
@@ -163,8 +242,23 @@ CPSegmentSwitchTrackingMomentary = 2;
{
var index = 0;
for (; index < _segments.length; ++index)
if (_segments[index].tag == aTag)
for (; index < [_segments count]; ++index)
if ([[_segments objectAtIndex:index] tag] == aTag)
{
[self setSelectedSegment:index];
return YES;
}
return NO;
}
- (BOOL)_selectSegmentWithLabel:(CPString)aLabel
{
var index = 0;
for (; index < [_segments count]; ++index)
if ([[_segments objectAtIndex:index] label] == aLabel)
{
[self setSelectedSegment:index];
@@ -175,7 +269,7 @@ CPSegmentSwitchTrackingMomentary = 2;
}
// Specifying Tracking Mode
/*! @ignore */
- (BOOL)isTracking
{
@@ -193,7 +287,7 @@ CPSegmentSwitchTrackingMomentary = 2;
var index = 0,
selected = NO;
for (; index < _segments.length; ++index)
for (; index < [self segmentCount]; ++index)
if ([_segments[index] selected])
if (selected)
[self setSelected:NO forSegment:index];
@@ -205,7 +299,7 @@ CPSegmentSwitchTrackingMomentary = 2;
{
var index = 0;
for (; index < _segments.length; ++index)
for (; index < [self segmentCount]; ++index)
if ([_segments[index] selected])
[self setSelected:NO forSegment:index];
}
@@ -228,8 +322,7 @@ CPSegmentSwitchTrackingMomentary = 2;
*/
- (void)setWidth:(float)aWidth forSegment:(unsigned)aSegment
{
[_segments[aSegment] setWidth:aWidth];
[[_segments objectAtIndex:aSegment] setWidth:aWidth];
[self tileWithChangedSegment:aSegment];
}
@@ -240,7 +333,7 @@ CPSegmentSwitchTrackingMomentary = 2;
*/
- (float)widthForSegment:(unsigned)aSegment
{
return [_segments[aSegment] width];
return [[_segments objectAtIndex:aSegment] width];
}
/*!
@@ -251,7 +344,7 @@ CPSegmentSwitchTrackingMomentary = 2;
*/
- (void)setImage:(CPImage)anImage forSegment:(unsigned)aSegment
{
[_segments[aSegment] setImage:anImage];
[[_segments objectAtIndex:aSegment] setImage:anImage];
[self tileWithChangedSegment:aSegment];
}
@@ -263,7 +356,7 @@ CPSegmentSwitchTrackingMomentary = 2;
*/
- (CPImage)imageForSegment:(unsigned)aSegment
{
return [_segments[aSegment] image];
return [[_segments objectAtIndex:aSegment] image];
}
/*!
@@ -274,7 +367,7 @@ CPSegmentSwitchTrackingMomentary = 2;
*/
- (void)setLabel:(CPString)aLabel forSegment:(unsigned)aSegment
{
[_segments[aSegment] setLabel:aLabel];
[[_segments objectAtIndex:aSegment] setLabel:aLabel];
[self tileWithChangedSegment:aSegment];
}
@@ -286,7 +379,7 @@ CPSegmentSwitchTrackingMomentary = 2;
*/
- (CPString)labelForSegment:(unsigned)aSegment
{
return [_segments[aSegment] label];
return [[_segments objectAtIndex:aSegment] label];
}
/*!
@@ -297,7 +390,7 @@ CPSegmentSwitchTrackingMomentary = 2;
*/
- (void)setMenu:(CPMenu)aMenu forSegment:(unsigned)aSegment
{
[_segments[aSegment] setMenu:aMenu];
[[_segments objectAtIndex:aSegment] setMenu:aMenu];
}
/*!
@@ -307,7 +400,7 @@ CPSegmentSwitchTrackingMomentary = 2;
*/
- (CPMenu)menuForSegment:(unsigned)aSegment
{
return [_segments[aSegment] menu];
return [[_segments objectAtIndex:aSegment] menu];
}
/*!
@@ -319,7 +412,7 @@ CPSegmentSwitchTrackingMomentary = 2;
*/
- (void)setSelected:(BOOL)isSelected forSegment:(unsigned)aSegment
{
var segment = _segments[aSegment];
var segment = [_segments objectAtIndex:aSegment];
// If we're already in this state, bail.
if ([segment selected] == isSelected)
@@ -336,7 +429,7 @@ CPSegmentSwitchTrackingMomentary = 2;
_selectedSegment = aSegment;
if (_trackingMode == CPSegmentSwitchTrackingSelectOne && oldSelectedSegment != aSegment && oldSelectedSegment != -1)
if (_trackingMode == CPSegmentSwitchTrackingSelectOne && oldSelectedSegment != aSegment && oldSelectedSegment != -1 && oldSelectedSegment < _segments.length)
{
[_segments[oldSelectedSegment] setSelected:NO];
_themeStates[oldSelectedSegment] = CPThemeStateNormal;
@@ -359,7 +452,7 @@ CPSegmentSwitchTrackingMomentary = 2;
*/
- (BOOL)isSelectedForSegment:(unsigned)aSegment
{
return [_segments[aSegment] selected];
return [[_segments objectAtIndex:aSegment] selected];
}
/*!
@@ -370,15 +463,17 @@ CPSegmentSwitchTrackingMomentary = 2;
*/
- (void)setEnabled:(BOOL)shouldBeEnabled forSegment:(unsigned)aSegment
{
if ([_segments[aSegment] enabled] === shouldBeEnabled)
var segment = [_segments objectAtIndex:aSegment];
if ([segment enabled] === shouldBeEnabled)
return;
[_segments[aSegment] setEnabled:shouldBeEnabled];
[segment setEnabled:shouldBeEnabled];
if (shouldBeEnabled)
_themeStates[aSegment] &= ~CPThemeStateDisabled;
_themeStates[aSegment] = _themeStates[aSegment].without(CPThemeStateDisabled);
else
_themeStates[aSegment] |= CPThemeStateDisabled;
_themeStates[aSegment] = _themeStates[aSegment].and(CPThemeStateDisabled);
[self setNeedsLayout];
[self setNeedsDisplay:YES];
@@ -391,7 +486,7 @@ CPSegmentSwitchTrackingMomentary = 2;
*/
- (BOOL)isEnabledForSegment:(unsigned)aSegment
{
return [_segments[aSegment] enabled];
return [[_segments objectAtIndex:aSegment] enabled];
}
/*!
@@ -401,7 +496,7 @@ CPSegmentSwitchTrackingMomentary = 2;
*/
- (void)setTag:(int)aTag forSegment:(unsigned)aSegment
{
[_segments[aSegment] setTag:aTag];
[[_segments objectAtIndex:aSegment] setTag:aTag];
}
/*!
@@ -410,7 +505,7 @@ CPSegmentSwitchTrackingMomentary = 2;
*/
- (int)tagForSegment:(unsigned)aSegment
{
return [_segments[aSegment] tag];
return [[_segments objectAtIndex:aSegment] tag];
}
// Drawings
@@ -421,10 +516,13 @@ CPSegmentSwitchTrackingMomentary = 2;
*/
- (void)drawSegmentBezel:(int)aSegment highlight:(BOOL)shouldHighlight
{
if (shouldHighlight)
_themeStates[aSegment] |= CPThemeStateHighlighted;
else
_themeStates[aSegment] &= ~CPThemeStateHighlighted;
if (aSegment < _themeStates.length)
{
if (shouldHighlight)
_themeStates[aSegment] = _themeStates[aSegment].and(CPThemeStateHighlighted);
else
_themeStates[aSegment] = _themeStates[aSegment].without(CPThemeStateHighlighted);
}
[self setNeedsLayout];
[self setNeedsDisplay:YES];
@@ -432,14 +530,12 @@ CPSegmentSwitchTrackingMomentary = 2;
- (float)_leftOffsetForSegment:(unsigned)segment
{
var bezelInset = [self currentValueForThemeAttribute:@"bezel-inset"];
if (segment == 0)
return bezelInset.left;
return [self currentValueForThemeAttribute:@"bezel-inset"].left;
var thickness = [self currentValueForThemeAttribute:@"divider-thickness"];
return [self _leftOffsetForSegment:segment - 1] + [self widthForSegment:segment - 1] + thickness;
return [self _leftOffsetForSegment:segment - 1] + CGRectGetWidth([self frameForSegment:segment - 1]) + thickness;
}
- (unsigned)_indexOfLastSegment
@@ -454,7 +550,7 @@ CPSegmentSwitchTrackingMomentary = 2;
- (CGRect)rectForEphemeralSubviewNamed:(CPString)aName
{
var height = [self currentValueForThemeAttribute:@"default-height"],
var height = [self currentValueForThemeAttribute:@"min-size"].height,
contentInset = [self currentValueForThemeAttribute:@"content-inset"],
bezelInset = [self currentValueForThemeAttribute:@"bezel-inset"],
bounds = [self bounds];
@@ -465,7 +561,7 @@ CPSegmentSwitchTrackingMomentary = 2;
}
else if (aName === "right-segment-bezel")
{
return CPRectMake(CGRectGetWidth([self bounds]) - contentInset.right,
return CGRectMake(CGRectGetWidth([self bounds]) - contentInset.right,
bezelInset.top,
contentInset.right,
height);
@@ -473,7 +569,7 @@ CPSegmentSwitchTrackingMomentary = 2;
else if (aName.indexOf("segment-bezel") === 0)
{
var segment = parseInt(aName.substring("segment-bezel-".length), 10),
frame = CGRectCreateCopy([_segments[segment] frame]);
frame = CGRectCreateCopy([self frameForSegment:segment]);
if (segment === 0)
{
@@ -481,7 +577,7 @@ CPSegmentSwitchTrackingMomentary = 2;
frame.size.width -= contentInset.left;
}
if (segment === _segments.length - 1)
if (segment === [self segmentCount] - 1)
frame.size.width = CGRectGetWidth([self bounds]) - contentInset.right - frame.origin.x;
return frame;
@@ -489,7 +585,7 @@ CPSegmentSwitchTrackingMomentary = 2;
else if (aName.indexOf("divider-bezel") === 0)
{
var segment = parseInt(aName.substring("divider-bezel-".length), 10),
width = [self widthForSegment:segment],
width = CGRectGetWidth([self frameForSegment:segment]),
left = [self _leftOffsetForSegment:segment],
thickness = [self currentValueForThemeAttribute:@"divider-thickness"];
@@ -508,19 +604,32 @@ CPSegmentSwitchTrackingMomentary = 2;
- (CPView)createEphemeralSubviewNamed:(CPString)aName
{
if ([aName hasPrefix:@"segment-content"])
return [[_CPImageAndTextView alloc] initWithFrame:_CGRectMakeZero()];
{
var view = [[_CPImageAndTextView alloc] initWithFrame:CGRectMakeZero()];
[view _setUsesSingleLineMode:YES];
return [[CPView alloc] initWithFrame:_CGRectMakeZero()];
return view;
}
return [[CPView alloc] initWithFrame:CGRectMakeZero()];
}
- (void)layoutSubviews
{
if (_segments.length <= 0)
if ([self segmentCount] <= 0)
return;
var themeState = _themeStates[0];
var themeState = _themeStates[0],
isDisabled = [self hasThemeState:CPThemeStateDisabled],
isControlSizeSmall = [self hasThemeState:CPThemeStateControlSizeSmall],
isControlSizeMini = [self hasThemeState:CPThemeStateControlSizeMini];
themeState |= _themeState & CPThemeStateDisabled;
themeState = isDisabled ? themeState.and(CPThemeStateDisabled) : themeState;
if (isControlSizeSmall)
themeState = themeState.and(CPThemeStateControlSizeSmall);
else if (isControlSizeMini)
themeState = themeState.and(CPThemeStateControlSizeMini);
var leftCapColor = [self valueForThemeAttribute:@"left-segment-bezel-color"
inState:themeState],
@@ -533,7 +642,12 @@ CPSegmentSwitchTrackingMomentary = 2;
var themeState = _themeStates[_themeStates.length - 1];
themeState |= _themeState & CPThemeStateDisabled;
themeState = isDisabled ? themeState.and(CPThemeStateDisabled) : themeState;
if (isControlSizeSmall)
themeState = themeState.and(CPThemeStateControlSizeSmall);
else if (isControlSizeMini)
themeState = themeState.and(CPThemeStateControlSizeMini);
var rightCapColor = [self valueForThemeAttribute:@"right-segment-bezel-color"
inState:themeState],
@@ -548,7 +662,12 @@ CPSegmentSwitchTrackingMomentary = 2;
{
var themeState = _themeStates[i];
themeState |= _themeState & CPThemeStateDisabled;
themeState = isDisabled ? themeState.and(CPThemeStateDisabled) : themeState;
if (isControlSizeSmall)
themeState = themeState.and(CPThemeStateControlSizeSmall);
else if (isControlSizeMini)
themeState = themeState.and(CPThemeStateControlSizeMini);
var bezelColor = [self valueForThemeAttribute:@"center-segment-bezel-color"
inState:themeState],
@@ -559,7 +678,6 @@ CPSegmentSwitchTrackingMomentary = 2;
[bezelView setBackgroundColor:bezelColor];
// layout image/title views
var segment = _segments[i],
contentView = [self layoutEphemeralSubviewNamed:@"segment-content-" + i
@@ -586,11 +704,15 @@ CPSegmentSwitchTrackingMomentary = 2;
if (i == count - 1)
continue;
var borderState = _themeStates[i] | _themeStates[i + 1];
borderState = (borderState & CPThemeStateSelected & ~CPThemeStateHighlighted) ? CPThemeStateSelected : CPThemeStateNormal;
var borderState = _themeStates[i].and(_themeStates[i + 1]);
borderState |= _themeState & CPThemeStateDisabled;
borderState = isDisabled ? borderState.and(CPThemeStateDisabled) : borderState;
if (isControlSizeSmall)
borderState = borderState.and(CPThemeStateControlSizeSmall);
else if (isControlSizeMini)
borderState = borderState.and(CPThemeStateControlSizeMini);
var borderColor = [self valueForThemeAttribute:@"divider-bezel-color"
inState:borderState],
@@ -613,61 +735,33 @@ CPSegmentSwitchTrackingMomentary = 2;
{
}
- (void)tileWithChangedSegment:(unsigned)aSegment
/*! @ignore */
- (void)tile
{
if (aSegment >= _segments.length)
[self tileWithChangedSegment:0];
}
/*! @ignore */
- (void)tileWithChangedSegment:(CPInteger)aSegment
{
var segmentCount = [self segmentCount];
// Corner case: when segmentCount == 0 and aSegment == 0, we do not return here because we still need to set the new frameSize bellow.
if (aSegment < 0 || (segmentCount > 0 && aSegment >= segmentCount))
return;
var segment = _segments[aSegment],
segmentWidth = [segment width],
themeState = _themeStates[aSegment] | (_themeState & CPThemeStateDisabled),
contentInset = [self valueForThemeAttribute:@"content-inset" inState:themeState],
font = [self font];
var width = 0;
if (!segmentWidth)
if (segmentCount > 0)
{
if ([segment image] && [segment label])
segmentWidth = [[segment label] sizeWithFont:font].width + [[segment image] size].width + contentInset.left + contentInset.right;
else if (segment.image)
segmentWidth = [[segment image] size].width + contentInset.left + contentInset.right;
else if (segment.label)
segmentWidth = [[segment label] sizeWithFont:font].width + contentInset.left + contentInset.right;
else
segmentWidth = 0.0;
// Invalidate frames for segments on the right. They will be lazily computed by -frameForSegment:.
for (var i = aSegment; i < segmentCount; i++)
[_segments[i] setFrame:CGRectMakeZero()];
width = CGRectGetMaxX([self frameForSegment:(segmentCount - 1)]);
}
var delta = segmentWidth - CGRectGetWidth([segment frame]);
if (!delta)
{
[self setNeedsLayout];
[self setNeedsDisplay:YES];
return;
}
// Update control size
var frame = [self frame];
[self setFrameSize:CGSizeMake(CGRectGetWidth(frame) + delta, CGRectGetHeight(frame))];
// Update segment width
[segment setWidth:segmentWidth];
[segment setFrame:[self frameForSegment:aSegment]];
// Update following segments widths
var index = aSegment + 1;
for (; index < _segments.length; ++index)
{
[_segments[index] frame].origin.x += delta;
[self drawSegmentBezel:index highlight:NO];
[self drawSegment:index highlight:NO];
}
[self drawSegmentBezel:aSegment highlight:NO];
[self drawSegment:aSegment highlight:NO];
[self setFrameSize:CGSizeMake(width, CGRectGetHeight([self frame]))];
[self setNeedsLayout];
[self setNeedsDisplay:YES];
@@ -679,29 +773,57 @@ CPSegmentSwitchTrackingMomentary = 2;
*/
- (CGRect)frameForSegment:(unsigned)aSegment
{
return [self bezelFrameForSegment:aSegment];
var segment = [_segments objectAtIndex:aSegment],
frame = [segment frame];
if (CGRectEqualToRect(frame, CGRectMakeZero()))
{
frame = [self bezelFrameForSegment:aSegment];
[segment setFrame:frame];
}
return frame;
}
- (CGRect)bezelFrameForSegment:(unsigned)aSegment
{
var height = [self currentValueForThemeAttribute:@"default-height"],
bezelInset = [self currentValueForThemeAttribute:@"bezel-inset"],
var left = [self _leftOffsetForSegment:aSegment],
top = [self currentValueForThemeAttribute:@"bezel-inset"].top,
width = [self widthForSegment:aSegment],
left = [self _leftOffsetForSegment:aSegment];
height = [self currentValueForThemeAttribute:@"min-size"].height;
return CGRectMake(left, bezelInset.top, width, height);
if (width == 0)
{
var themeState = _themeState.hasThemeState(CPThemeStateDisabled) ? _themeStates[aSegment].and(CPThemeStateDisabled) : _themeStates[aSegment],
contentInset = [self valueForThemeAttribute:@"content-inset" inState:themeState],
contentInsetWidth = contentInset.left + contentInset.right,
segment = _segments[aSegment],
label = [segment label],
image = [segment image];
width = (label ? [label sizeWithFont:[self font]].width : 4.0) + (image ? [image size].width : 0) + contentInsetWidth;
}
return CGRectMake(left, top, width, height);
}
- (CGRect)contentFrameForSegment:(unsigned)aSegment
{
var height = [self currentValueForThemeAttribute:@"default-height"],
var height = [self currentValueForThemeAttribute:@"min-size"].height,
contentInset = [self currentValueForThemeAttribute:@"content-inset"],
width = [self widthForSegment:aSegment],
width = CGRectGetWidth([self frameForSegment:aSegment]),
left = [self _leftOffsetForSegment:aSegment];
return CGRectMake(left + contentInset.left, contentInset.top, width - contentInset.left - contentInset.right, height - contentInset.top - contentInset.bottom);
}
- (CGSize)_minimumFrameSize
{
// The current width is always the minimum width.
return CGSizeMake(CGRectGetWidth([self frame]), [self currentValueForThemeAttribute:@"min-size"].height);
}
/*!
Returns the segment that is hit by the specified point.
@param aPoint the point to test for a segment hit
@@ -710,19 +832,19 @@ CPSegmentSwitchTrackingMomentary = 2;
- (unsigned)testSegment:(CGPoint)aPoint
{
var location = [self convertPoint:aPoint fromView:nil],
count = _segments.length;
count = [self segmentCount];
while (count--)
if (CGRectContainsPoint([_segments[count] frame], aPoint))
if (CGRectContainsPoint([self frameForSegment:count], aPoint))
return count;
if (_segments.length)
if ([self segmentCount])
{
var adjustedLastFrame = CGRectCreateCopy([_segments[_segments.length - 1] frame]);
var adjustedLastFrame = CGRectCreateCopy([self frameForSegment:(_segments.length - 1)]);
adjustedLastFrame.size.width = CGRectGetWidth([self bounds]) - adjustedLastFrame.origin.x;
if (CGRectContainsPoint(adjustedLastFrame, aPoint))
return _segments.length - 1;
return [self segmentCount] - 1;
}
return -1;
@@ -750,63 +872,68 @@ CPSegmentSwitchTrackingMomentary = 2;
var type = [anEvent type],
location = [self convertPoint:[anEvent locationInWindow] fromView:nil];
if (type == CPLeftMouseUp)
switch (type)
{
if (_trackingSegment == -1)
case CPLeftMouseUp:
if (_trackingSegment === CPNotFound)
return;
if (_trackingSegment === [self testSegment:location])
{
if (_trackingMode == CPSegmentSwitchTrackingSelectAny)
{
[self setSelected:![self isSelectedForSegment:_trackingSegment] forSegment:_trackingSegment];
// With ANY, _selectedSegment means last pressed.
_selectedSegment = _trackingSegment;
}
else
[self setSelected:YES forSegment:_trackingSegment];
[self sendAction:[self action] to:[self target]];
if (_trackingMode == CPSegmentSwitchTrackingMomentary)
{
[self setSelected:NO forSegment:_trackingSegment];
_selectedSegment = CPNotFound;
}
}
[self drawSegmentBezel:_trackingSegment highlight:NO];
_trackingSegment = CPNotFound;
return;
if (_trackingSegment === [self testSegment:location])
{
if (_trackingMode == CPSegmentSwitchTrackingSelectAny)
case CPLeftMouseDown:
var trackingSegment = [self testSegment:location];
if (trackingSegment > CPNotFound && [self isEnabledForSegment:trackingSegment])
{
[self setSelected:![self isSelectedForSegment:_trackingSegment] forSegment:_trackingSegment];
// With ANY, _selectedSegment means last pressed.
_selectedSegment = _trackingSegment;
_trackingHighlighted = YES;
_trackingSegment = trackingSegment;
[self drawSegmentBezel:_trackingSegment highlight:YES];
}
else
[self setSelected:YES forSegment:_trackingSegment];
[self sendAction:[self action] to:[self target]];
break;
if (_trackingMode == CPSegmentSwitchTrackingMomentary)
case CPLeftMouseDragged:
if (_trackingSegment === CPNotFound)
return;
var highlighted = [self testSegment:location] === _trackingSegment;
if (highlighted != _trackingHighlighted)
{
[self setSelected:NO forSegment:_trackingSegment];
_trackingHighlighted = highlighted;
_selectedSegment = -1;
[self drawSegmentBezel:_trackingSegment highlight:_trackingHighlighted];
}
}
[self drawSegmentBezel:_trackingSegment highlight:NO];
_trackingSegment = -1;
return;
}
if (type == CPLeftMouseDown)
{
var trackingSegment = [self testSegment:location];
if (trackingSegment > -1 && [self isEnabledForSegment:trackingSegment])
{
_trackingHighlighted = YES;
_trackingSegment = trackingSegment;
[self drawSegmentBezel:_trackingSegment highlight:YES];
}
}
else if (type == CPLeftMouseDragged)
{
if (_trackingSegment == -1)
return;
var highlighted = [self testSegment:location] === _trackingSegment;
if (highlighted != _trackingHighlighted)
{
_trackingHighlighted = highlighted;
[self drawSegmentBezel:_trackingSegment highlight:_trackingHighlighted];
}
break;
}
[CPApp setTarget:self selector:@selector(trackSegment:) forNextEventMatchingMask:CPLeftMouseDraggedMask | CPLeftMouseUpMask untilDate:nil inMode:nil dequeue:YES];
@@ -816,7 +943,7 @@ CPSegmentSwitchTrackingMomentary = 2;
{
[super setFont:aFont];
[self tileWithChangedSegment:0];
[self tile];
}
@end
@@ -848,28 +975,49 @@ var CPSegmentedControlSegmentsKey = "CPSegmentedControlSegmentsKey",
if ([aCoder containsValueForKey:CPSegmentedControlSelectedKey])
_selectedSegment = [aCoder decodeIntForKey:CPSegmentedControlSelectedKey];
else
_selectedSegment = -1;
_selectedSegment = CPNotFound;
if ([aCoder containsValueForKey:CPSegmentedControlTrackingModeKey])
_trackingMode = [aCoder decodeIntForKey:CPSegmentedControlTrackingModeKey];
else
_trackingMode = CPSegmentSwitchTrackingSelectOne;
// HACK
for (var i = 0; i < _segments.length; i++)
{
// Here we update the themeStates array for each segments to know if there are selected or not
for (var i = 0; i < [self segmentCount]; i++)
_themeStates[i] = [_segments[i] selected] ? CPThemeStateSelected : CPThemeStateNormal;
[self tileWithChangedSegment:i];
[self tile];
var thickness = [self currentValueForThemeAttribute:@"divider-thickness"],
dividerExtraSpace = ([_segments count] - 1) * thickness,
difference = MAX(originalWidth - [self frame].size.width - dividerExtraSpace, 0.0),
remainingWidth = FLOOR(difference / [self segmentCount]),
widthOfAllSegments = 0;
// We do this in a second loop because it relies on all the themeStates being set first
for (var i = 0; i < [self segmentCount]; i++)
{
var frame = [_segments[i] frame];
frame.size.width += remainingWidth;
widthOfAllSegments += CGRectGetWidth(frame);
}
var difference = MAX(originalWidth - [self frame].size.width, 0.0),
remainingWidth = FLOOR(difference / _segments.length);
// Here we handle the leftovers pixel, and we will add one pixel to each segment cell till we have the same size as the originalSize.
// This is needed to have a perfect/same alignment between our application and xCode.
var leftOversPixel = originalWidth - (widthOfAllSegments + dividerExtraSpace);
for (var i = 0; i < _segments.length; i++)
[self setWidth:[_segments[i] width] + remainingWidth forSegment:i];
// Make sure we don't make an out of range
if (leftOversPixel < [self segmentCount] - 1)
{
for (var i = 0; i < leftOversPixel; i++)
{
[_segments[i] frame].size.width += 1;
}
}
[self tileWithChangedSegment:0];
[self setFrameSize:CGSizeMake(originalWidth, CGRectGetHeight([self frame]))];
[self tile];
}
return self;
@@ -887,6 +1035,91 @@ var CPSegmentedControlSegmentsKey = "CPSegmentedControlSegmentsKey",
@end
@implementation CPSegmentedControl (BindingSupport)
+ (Class)_binderClassForBinding:(CPString)aBinding
{
if ([self _isSelectionBinding:aBinding])
return [_CPSegmentedControlBinder class];
return [super _binderClassForBinding:aBinding];
}
+ (BOOL)_isSelectionBinding:(CPString)aBinding
{
return (aBinding === CPSelectedIndexBinding || aBinding === CPSelectedLabelBinding || aBinding === CPSelectedTagBinding);
}
+ (BOOL)isBindingExclusive:(CPString)aBinding
{
return [self _isSelectionBinding:aBinding];
}
- (void)bind:(CPString)aBinding toObject:(id)anObject withKeyPath:(CPString)aKeyPath options:(CPDictionary)options
{
if ([[self class] _isSelectionBinding:aBinding] && _trackingMode !== CPSegmentSwitchTrackingSelectOne)
{
CPLog.warn("Binding " + aBinding + " needs CPSegmentSwitchTrackingSelectOne tracking mode");
return;
}
[super bind:aBinding toObject:anObject withKeyPath:aKeyPath options:options];
}
- (void)_reverseSetBinding
{
[_CPSegmentedControlBinder _reverseSetValueFromExclusiveBinderForObject:self];
}
@end
var CPSegmentedControlNoSelectionPlaceholder = "CPSegmentedControlNoSelectionPlaceholder";
@implementation _CPSegmentedControlBinder : CPBinder
{
}
- (void)_updatePlaceholdersWithOptions:(CPDictionary)options
{
[super _updatePlaceholdersWithOptions:options];
[self _setPlaceholder:CPSegmentedControlNoSelectionPlaceholder forMarker:CPMultipleValuesMarker isDefault:YES];
[self _setPlaceholder:CPSegmentedControlNoSelectionPlaceholder forMarker:CPNoSelectionMarker isDefault:YES];
[self _setPlaceholder:CPSegmentedControlNoSelectionPlaceholder forMarker:CPNotApplicableMarker isDefault:YES];
[self _setPlaceholder:CPSegmentedControlNoSelectionPlaceholder forMarker:CPNullMarker isDefault:YES];
}
- (void)setPlaceholderValue:(id)aValue withMarker:(CPString)aMarker forBinding:(CPString)aBinding
{
if (aValue == CPSegmentedControlNoSelectionPlaceholder)
[_source setSelected:NO forSegment:[_source selectedSegment]];
else
[self setValue:aValue forBinding:aBinding];
}
- (void)setValue:(id)aValue forBinding:(CPString)aBinding
{
if (aBinding == CPSelectedIndexBinding)
[_source setSelectedSegment:aValue];
else if (aBinding == CPSelectedTagBinding)
[_source selectSegmentWithTag:aValue];
else if (aBinding == CPSelectedLabelBinding)
[_source _selectSegmentWithLabel:aValue];
}
- (id)valueForBinding:(CPString)aBinding
{
var selectedIndex = [_source selectedSegment];
if (aBinding == CPSelectedIndexBinding)
return selectedIndex;
else if (aBinding == CPSelectedTagBinding)
return [_source tagForSegment:selectedIndex];
else if (aBinding == CPSelectedLabelBinding)
return [_source labelForSegment:selectedIndex];
}
@end
@implementation _CPSegmentItem : CPObject
{
+12 -30
View File
@@ -22,6 +22,9 @@
@import <Foundation/CPObject.j>
@import "CGGeometry.j"
@import "CPColor.j"
@import "CPGraphicsContext.j"
/*!
@deprecated
@@ -31,11 +34,9 @@
*/
@implementation CPShadow : CPObject
{
CPSize _offset;
float _blurRadius;
CPColor _color;
CPString _cssString;
CGSize _offset @accessors(property=shadowOffset);
float _blurRadius @accessors(property=shadowBlurRadius);
CPColor _color @accessors(property=shadowColor);
}
/*!
@@ -51,7 +52,7 @@
}
/* @ignore */
- (id)_initWithOffset:(CPSize)anOffset blurRadius:(float)aBlurRadius color:(CPColor)aColor
- (id)_initWithOffset:(CGSize)anOffset blurRadius:(float)aBlurRadius color:(CPColor)aColor
{
self = [super init];
@@ -60,35 +61,16 @@
_offset = anOffset;
_blurRadius = aBlurRadius;
_color = aColor;
_cssString = [_color cssString] + " " + ROUND(anOffset.width) + @"px " + ROUND(anOffset.height) + @"px " + ROUND(_blurRadius) + @"px";
}
return self;
}
/*!
Returns the shadow's offset.
*/
- (CGSize)shadowOffset
- (void)set
{
return _offset;
}
var context = [[CPGraphicsContext currentContext] graphicsPort];
/*!
Returns the shadow's blur radius
*/
- (float)shadowBlurRadius
{
return _blurRadius;
}
/*!
Returns the shadow's color.
*/
- (CPColor)shadowColor
{
return _color;
CGContextSetShadowWithColor(context, _offset, _blurRadius, _color);
}
/*!
@@ -96,7 +78,7 @@
*/
- (CPString)cssString
{
return _cssString;
return [_color cssString] + " " + ROUND(_offset.width) + @"px " + ROUND(_offset.height) + @"px " + ROUND(_blurRadius) + @"px";
}
@end
@end
+42 -70
View File
@@ -24,25 +24,15 @@
@import "CGGeometry.j"
@import "CPImage.j"
@import "CPImageView.j"
@import "CPView.j"
@typedef CPShadowWeight
CPLightShadow = 0;
CPHeavyShadow = 1;
var CPShadowViewLightBackgroundColor = nil,
CPShadowViewHeavyBackgroundColor = nil;
CPThemeStateShadowViewLight = CPThemeState("shadowview-style-light");
CPThemeStateShadowViewHeavy = CPThemeState("shadowview-style-heavy");
var LIGHT_LEFT_INSET = 3.0,
LIGHT_RIGHT_INSET = 3.0,
LIGHT_TOP_INSET = 3.0,
LIGHT_BOTTOM_INSET = 5.0,
HEAVY_LEFT_INSET = 7.0,
HEAVY_RIGHT_INSET = 7.0,
HEAVY_TOP_INSET = 5.0,
HEAVY_BOTTOM_INSET = 5.0;
/*!
@ingroup appkit
@@ -52,40 +42,25 @@ var LIGHT_LEFT_INSET = 3.0,
CPShadowWeight _weight;
}
+ (void)initialize
+ (CPString)defaultThemeClass
{
if (self !== [CPShadowView class])
return;
return "shadow-view";
}
var bundle = [CPBundle bundleForClass:[self class]];
+ (CPDictionary)themeAttributes
{
return @{
@"bezel-color": [CPNull null],
@"content-inset": CGInsetMakeZero()
};
}
CPShadowViewLightBackgroundColor = CPColorWithImages([
[@"CPShadowView/CPShadowViewLightTopLeft.png", 9.0, 9.0, bundle],
[@"CPShadowView/CPShadowViewLightTop.png", 1.0, 9.0, bundle],
[@"CPShadowView/CPShadowViewLightTopRight.png", 9.0, 9.0, bundle],
+ (CGRect)frameForContentFrame:(CGRect)aFrame withWeight:(CPShadowWeight)aWeight
{
var shadowView = [CPShadowView new],
inset = [shadowView valueForThemeAttribute:@"content-inset" inState:(aWeight == CPLightShadow) ? CPThemeStateShadowViewLight : CPThemeStateShadowViewHeavy];
[@"CPShadowView/CPShadowViewLightLeft.png", 9.0, 1.0, bundle],
nil,
[@"CPShadowView/CPShadowViewLightRight.png", 9.0, 1.0, bundle],
[@"CPShadowView/CPShadowViewLightBottomLeft.png", 9.0, 9.0, bundle],
[@"CPShadowView/CPShadowViewLightBottom.png", 1.0, 9.0, bundle],
[@"CPShadowView/CPShadowViewLightBottomRight.png", 9.0, 9.0, bundle]
]);
CPShadowViewHeavyBackgroundColor = CPColorWithImages([
[@"CPShadowView/CPShadowViewHeavyTopLeft.png", 17.0, 17.0, bundle],
[@"CPShadowView/CPShadowViewHeavyTop.png", 1.0, 17.0, bundle],
[@"CPShadowView/CPShadowViewHeavyTopRight.png", 17.0, 17.0, bundle],
[@"CPShadowView/CPShadowViewHeavyLeft.png", 17.0, 1.0, bundle],
nil,
[@"CPShadowView/CPShadowViewHeavyRight.png", 17.0, 1.0, bundle],
[@"CPShadowView/CPShadowViewHeavyBottomLeft.png", 17.0, 17.0, bundle],
[@"CPShadowView/CPShadowViewHeavyBottom.png", 1.0, 17.0, bundle],
[@"CPShadowView/CPShadowViewHeavyBottomRight.png", 17.0, 17.0, bundle]
]);
return CGRectMake(CGRectGetMinX(aFrame) - inset.left, CGRectGetMinY(aFrame) - inset.top, CGRectGetWidth(aFrame) + inset.left + inset.right, CGRectGetHeight(aFrame) + inset.top + inset.bottom);
}
+ (id)shadowViewEnclosingView:(CPView)aView
@@ -102,15 +77,16 @@ var LIGHT_LEFT_INSET = 3.0,
[shadowView setWeight:aWeight];
var size = [shadowView frame].size,
width = size.width - [shadowView leftInset] - [shadowView rightInset],
height = size.height - [shadowView topInset] - [shadowView bottomInset],
inset = [shadowView currentValueForThemeAttribute:@"content-inset"],
width = size.width - inset.left - inset.right,
height = size.height - inset.top - inset.bottom,
enclosingView = [aView superview];
[shadowView setHitTests:[aView hitTests]];
[shadowView setAutoresizingMask:[aView autoresizingMask]];
[aView removeFromSuperview];
[shadowView addSubview:aView];
[aView setFrame:CGRectMake([shadowView leftInset], [shadowView topInset], width, height)]
[aView setFrame:CGRectMake(inset.left, inset.top, width, height)];
[enclosingView addSubview:shadowView];
}
@@ -123,9 +99,7 @@ var LIGHT_LEFT_INSET = 3.0,
if (self)
{
_weight = CPLightShadow;
[self setBackgroundColor:CPShadowViewLightBackgroundColor];
[self setWeight:CPLightShadow];
[self setHitTests:NO];
}
@@ -141,54 +115,45 @@ var LIGHT_LEFT_INSET = 3.0,
_weight = aWeight;
if (_weight == CPLightShadow)
[self setBackgroundColor:CPShadowViewLightBackgroundColor];
[self setThemeState:CPThemeStateShadowViewLight];
else
[self setBackgroundColor:CPShadowViewHeavyBackgroundColor];
[self setThemeState:CPThemeStateShadowViewHeavy];
[self setNeedsLayout];
}
- (float)leftInset
{
return _weight == CPLightShadow ? LIGHT_LEFT_INSET : HEAVY_LEFT_INSET;
return [self currentValueForThemeAttribute:@"content-inset"].left;
}
- (float)rightInset
{
return _weight == CPLightShadow ? LIGHT_RIGHT_INSET : HEAVY_RIGHT_INSET;
return [self currentValueForThemeAttribute:@"content-inset"].right;
}
- (float)topInset
{
return _weight == CPLightShadow ? LIGHT_TOP_INSET : HEAVY_TOP_INSET;
return [self currentValueForThemeAttribute:@"content-inset"].top;
}
- (float)bottomInset
{
return _weight == CPLightShadow ? LIGHT_BOTTOM_INSET : HEAVY_BOTTOM_INSET;
return [self currentValueForThemeAttribute:@"content-inset"].bottom;
}
- (float)horizontalInset
{
if (_weight == CPLightShadow)
return LIGHT_LEFT_INSET + LIGHT_RIGHT_INSET;
var currentContentInset = [self currentValueForThemeAttribute:@"content-inset"];
return HEAVY_LEFT_INSET + HEAVY_RIGHT_INSET;
return currentContentInset.left + currentContentInset.right;
}
- (float)verticalInset
{
if (_weight == CPLightShadow)
return LIGHT_TOP_INSET + LIGHT_BOTTOM_INSET;
var currentContentInset = [self currentValueForThemeAttribute:@"content-inset"];
return HEAVY_TOP_INSET + HEAVY_BOTTOM_INSET;
}
+ (CGRect)frameForContentFrame:(CGRect)aFrame withWeight:(CPShadowWeight)aWeight
{
if (aWeight == CPLightShadow)
return CGRectMake(_CGRectGetMinX(aFrame) - LIGHT_LEFT_INSET, _CGRectGetMinY(aFrame) - LIGHT_TOP_INSET, _CGRectGetWidth(aFrame) + LIGHT_LEFT_INSET + LIGHT_RIGHT_INSET, _CGRectGetHeight(aFrame) + LIGHT_TOP_INSET + LIGHT_BOTTOM_INSET);
else
return CGRectMake(_CGRectGetMinX(aFrame) - HEAVY_LEFT_INSET, _CGRectGetMinY(aFrame) - HEAVY_TOP_INSET, _CGRectGetWidth(aFrame) + HEAVY_LEFT_INSET + HEAVY_RIGHT_INSET, _CGRectGetHeight(aFrame) + HEAVY_TOP_INSET + HEAVY_BOTTOM_INSET);
return currentContentInset.top + currentContentInset.bottom;
}
- (CGRect)frameForContentFrame:(CGRect)aFrame
@@ -201,4 +166,11 @@ var LIGHT_LEFT_INSET = 3.0,
[self setFrame:[self frameForContentFrame:aFrame]];
}
- (void)layoutSubviews
{
[super layoutSubviews];
[self setBackgroundColor:[self currentValueForThemeAttribute:@"bezel-color"]];
}
@end
+35 -28
View File
@@ -21,6 +21,7 @@
*/
@import "CPControl.j"
@import "CPWindow_Constants.j"
/*! SLIDER STATES */
@@ -39,6 +40,8 @@ CPCircularSlider = 1;
double _altIncrementValue;
BOOL _isVertical;
CGSize _dragOffset;
}
+ (CPString)defaultThemeClass
@@ -46,10 +49,14 @@ CPCircularSlider = 1;
return "slider";
}
+ (id)themeAttributes
+ (CPDictionary)themeAttributes
{
return [CPDictionary dictionaryWithObjects:[[CPNull null], _CGSizeMakeZero(), 0.0, [CPNull null]]
forKeys:[@"knob-color", @"knob-size", @"track-width", @"track-color"]];
return @{
@"knob-color": [CPNull null],
@"knob-size": CGSizeMakeZero(),
@"track-width": 0.0,
@"track-color": [CPNull null],
};
}
- (id)initWithFrame:(CGRect)aFrame
@@ -155,16 +162,16 @@ CPCircularSlider = 1;
var trackWidth = [self currentValueForThemeAttribute:@"track-width"];
if (trackWidth <= 0)
return _CGRectMakeZero();
return CGRectMakeZero();
if ([self isVertical])
{
bounds.origin.x = (_CGRectGetWidth(bounds) - trackWidth) / 2.0;
bounds.origin.x = (CGRectGetWidth(bounds) - trackWidth) / 2.0;
bounds.size.width = trackWidth;
}
else
{
bounds.origin.y = (_CGRectGetHeight(bounds) - trackWidth) / 2.0;
bounds.origin.y = (CGRectGetHeight(bounds) - trackWidth) / 2.0;
bounds.size.height = trackWidth;
}
}
@@ -177,13 +184,13 @@ CPCircularSlider = 1;
var knobSize = [self currentValueForThemeAttribute:@"knob-size"];
if (knobSize.width <= 0 || knobSize.height <= 0)
return _CGRectMakeZero();
return CGRectMakeZero();
var knobRect = _CGRectMake(0.0, 0.0, knobSize.width, knobSize.height),
var knobRect = CGRectMake(0.0, 0.0, knobSize.width, knobSize.height),
trackRect = [self trackRectForBounds:bounds];
// No track, do our best to approximate a place for this thing.
if (!trackRect || _CGRectIsEmpty(trackRect))
if (!trackRect || CGRectIsEmpty(trackRect))
trackRect = bounds;
if ([self hasThemeState:CPThemeStateCircular])
@@ -196,13 +203,13 @@ CPCircularSlider = 1;
}
else if ([self isVertical])
{
knobRect.origin.x = _CGRectGetMidX(trackRect) - knobSize.width / 2.0;
knobRect.origin.y = ((_maxValue - [self doubleValue]) / (_maxValue - _minValue)) * (_CGRectGetHeight(trackRect) - knobSize.height);
knobRect.origin.x = CGRectGetMidX(trackRect) - knobSize.width / 2.0;
knobRect.origin.y = ((_maxValue - [self doubleValue]) / (_maxValue - _minValue)) * (CGRectGetHeight(trackRect) - knobSize.height);
}
else
{
knobRect.origin.x = (([self doubleValue] - _minValue) / (_maxValue - _minValue)) * (_CGRectGetWidth(trackRect) - knobSize.width);
knobRect.origin.y = _CGRectGetMidY(trackRect) - knobSize.height / 2.0;
knobRect.origin.x = (([self doubleValue] - _minValue) / (_maxValue - _minValue)) * (CGRectGetWidth(trackRect) - knobSize.width);
knobRect.origin.y = CGRectGetMidY(trackRect) - knobSize.height / 2.0;
}
return knobRect;
@@ -253,8 +260,8 @@ CPCircularSlider = 1;
{
// Recalculate isVertical.
var bounds = [self bounds],
width = _CGRectGetWidth(bounds),
height = _CGRectGetHeight(bounds);
width = CGRectGetWidth(bounds),
height = CGRectGetHeight(bounds);
_isVertical = width < height ? 1 : (width > height ? 0 : -1);
@@ -299,55 +306,55 @@ CPCircularSlider = 1;
if ([self hasThemeState:CPThemeStateCircular])
{
var knobWidth = _CGRectGetWidth(knobRect);
var knobWidth = CGRectGetWidth(knobRect);
trackRect.origin.x += knobWidth / 2;
trackRect.size.width -= knobWidth;
var minValue = [self minValue],
dx = aPoint.x - _CGRectGetMidX(trackRect),
dy = aPoint.y - _CGRectGetMidY(trackRect);
dx = aPoint.x - CGRectGetMidX(trackRect),
dy = aPoint.y - CGRectGetMidY(trackRect);
return MAX(0.0, MIN(1.0, 1.0 - (3 * PI_2 - ATAN2(dy, dx)) % PI2 / PI2)) * ([self maxValue] - minValue) + minValue;
}
else if ([self isVertical])
{
var knobHeight = _CGRectGetHeight(knobRect);
var knobHeight = CGRectGetHeight(knobRect);
trackRect.origin.y += knobHeight / 2;
trackRect.size.height -= knobHeight;
var minValue = [self minValue];
return MAX(0.0, MIN(1.0, (_CGRectGetMaxY(trackRect) - aPoint.y) / _CGRectGetHeight(trackRect))) * ([self maxValue] - minValue) + minValue;
return MAX(0.0, MIN(1.0, (CGRectGetMaxY(trackRect) - aPoint.y) / CGRectGetHeight(trackRect))) * ([self maxValue] - minValue) + minValue;
}
else
{
var knobWidth = _CGRectGetWidth(knobRect);
var knobWidth = CGRectGetWidth(knobRect);
trackRect.origin.x += knobWidth / 2;
trackRect.size.width -= knobWidth;
var minValue = [self minValue];
return MAX(0.0, MIN(1.0, (aPoint.x - _CGRectGetMinX(trackRect)) / _CGRectGetWidth(trackRect))) * ([self maxValue] - minValue) + minValue;
return MAX(0.0, MIN(1.0, (aPoint.x - CGRectGetMinX(trackRect)) / CGRectGetWidth(trackRect))) * ([self maxValue] - minValue) + minValue;
}
}
- (BOOL)startTrackingAt:(CGPoint)aPoint
{
var bounds = [self bounds],
knobRect = [self knobRectForBounds:_CGRectMakeCopy(bounds)];
knobRect = [self knobRectForBounds:CGRectMakeCopy(bounds)];
if (_CGRectContainsPoint(knobRect, aPoint))
_dragOffset = _CGSizeMake(_CGRectGetMidX(knobRect) - aPoint.x, _CGRectGetMidY(knobRect) - aPoint.y);
if (CGRectContainsPoint(knobRect, aPoint))
_dragOffset = CGSizeMake(CGRectGetMidX(knobRect) - aPoint.x, CGRectGetMidY(knobRect) - aPoint.y);
else
{
var trackRect = [self trackRectForBounds:bounds];
if (trackRect && _CGRectContainsPoint(trackRect, aPoint))
if (trackRect && CGRectContainsPoint(trackRect, aPoint))
{
_dragOffset = _CGSizeMakeZero();
_dragOffset = CGSizeMakeZero();
[self setObjectValue:[self _valueAtPoint:aPoint]];
}
@@ -366,7 +373,7 @@ CPCircularSlider = 1;
- (BOOL)continueTracking:(CGPoint)lastPoint at:(CGPoint)aPoint
{
[self setObjectValue:[self _valueAtPoint:_CGPointMake(aPoint.x + _dragOffset.width, aPoint.y + _dragOffset.height)]];
[self setObjectValue:[self _valueAtPoint:CGPointMake(aPoint.x + _dragOffset.width, aPoint.y + _dragOffset.height)]];
return YES;
}
+20 -12
View File
@@ -20,8 +20,14 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "CPView.j"
@import "CPColorPicker.j"
@import "CPSlider.j"
@import "CPTextField.j"
@import "CPView.j"
@global CPColorPickerViewWidth
@global CPColorPickerViewHeight
@global CPSliderColorPickerMode
/*
@@ -49,7 +55,6 @@
CPTextField _hexLabel;
CPTextField _hexValue;
CPTextField _hexValue;
CPTextField _redValue;
CPTextField _greenValue;
CPTextField _blueValue;
@@ -65,7 +70,7 @@
- (id)initView
{
aFrame = CGRectMake(0, 0, CPColorPickerViewWidth, CPColorPickerViewHeight);
var aFrame = CGRectMake(0, 0, CPColorPickerViewWidth, CPColorPickerViewHeight);
_contentView = [[CPView alloc] initWithFrame:aFrame];
[_contentView setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
@@ -140,7 +145,7 @@
[_hueLabel setTextColor:[CPColor blackColor]];
_hueSlider = [[CPSlider alloc] initWithFrame:CGRectMake(15, 143, aFrame.size.width - 70, 20)];
[_hueSlider setMaxValue:359.0];
[_hueSlider setMaxValue:0.999];
[_hueSlider setMinValue:0.0];
[_hueSlider setTarget:self];
[_hueSlider setAction:@selector(sliderChanged:)];
@@ -159,7 +164,7 @@
[_saturationLabel setTextColor:[CPColor blackColor]];
_saturationSlider = [[CPSlider alloc] initWithFrame:CGRectMake(15, 168, aFrame.size.width - 70, 20)];
[_saturationSlider setMaxValue:100.0];
[_saturationSlider setMaxValue:1.0];
[_saturationSlider setMinValue:0.0];
[_saturationSlider setTarget:self];
[_saturationSlider setAction:@selector(sliderChanged:)];
@@ -178,7 +183,7 @@
[_brightnessLabel setTextColor:[CPColor blackColor]];
_brightnessSlider = [[CPSlider alloc] initWithFrame:CGRectMake(15, 194, aFrame.size.width - 70, 20)];
[_brightnessSlider setMaxValue:100.0];
[_brightnessSlider setMaxValue:1.0];
[_brightnessSlider setMinValue:0.0];
[_brightnessSlider setTarget:self];
[_brightnessSlider setAction:@selector(sliderChanged:)];
@@ -276,6 +281,9 @@
- (void)setColor:(CPColor)aColor
{
if (!aColor)
[CPException raise:CPInvalidArgumentException reason:"aColor can't be nil"];
[self updateRGBSliders:aColor];
[self updateHSBSliders:aColor];
[self updateHex:aColor];
@@ -307,9 +315,9 @@
- (void)updateLabels
{
[_hueValue setStringValue:ROUND([_hueSlider floatValue])];
[_saturationValue setStringValue:ROUND([_saturationSlider floatValue])];
[_brightnessValue setStringValue:ROUND([_brightnessSlider floatValue])];
[_hueValue setStringValue:ROUND([_hueSlider floatValue] * 360.0)];
[_saturationValue setStringValue:ROUND([_saturationSlider floatValue] * 100.0)];
[_brightnessValue setStringValue:ROUND([_brightnessSlider floatValue] * 100.0)];
[_redValue setStringValue:ROUND([_redSlider floatValue] * 255)];
[_greenValue setStringValue:ROUND([_greenSlider floatValue] * 255)];
@@ -357,15 +365,15 @@
[self sliderChanged:_blueSlider];
break;
case _hueValue: [_hueSlider setFloatValue:MAX(MIN(ROUND(value), 360), 0)];
case _hueValue: [_hueSlider setFloatValue:MAX(MIN(ROUND(value), 360) / 360.0, 0)];
[self sliderChanged:_hueSlider];
break;
case _saturationValue: [_saturationSlider setFloatValue:MAX(MIN(ROUND(value), 100), 0)];
case _saturationValue: [_saturationSlider setFloatValue:MAX(MIN(ROUND(value), 100) / 100.0, 0)];
[self sliderChanged:_saturationSlider];
break;
case _brightnessValue: [_brightnessSlider setFloatValue:MAX(MIN(ROUND(value), 100), 0)];
case _brightnessValue: [_brightnessSlider setFloatValue:MAX(MIN(ROUND(value), 100) / 100.0, 0)];
[self sliderChanged:_brightnessSlider];
break;
}
+52 -3
View File
@@ -21,6 +21,19 @@
*/
@import <Foundation/CPObject.j>
@import <Foundation/CPRunLoop.j>
@typedef HTMLAudioElement
@protocol CPSoundDelegate <CPObject>
@optional
- (void)sound:(CPSound)aSound didFinishPlaying:(BOOL)finishedLoading;
@end
var CPSoundDelegate_sound_didFinishPlaying_ = 1 << 1;
CPSoundLoadStateEmpty = 0;
CPSoundLoadStateLoading = 1;
@@ -49,6 +62,7 @@ CPSoundPlayBackStatePause = 2;
HTMLAudioElement _audioTag;
int _loadStatus;
int _playBackStatus;
unsigned _implementedDelegateMethods;
}
#pragma mark -
@@ -59,7 +73,7 @@ CPSoundPlayBackStatePause = 2;
if (self = [super init])
{
_loadStatus = CPSoundLoadStateEmpty;
_loops = NO;
// _loops = NO;
_audioTag = document.createElement("audio");
_audioTag.preload = YES;
_playRequestBeforeLoad = NO;
@@ -132,6 +146,25 @@ CPSoundPlayBackStatePause = 2;
}
#pragma mark -
#pragma mark Delegate methods
/*!
Sets the sound's delegate.
@param aDelegate the new delegate
*/
- (void)setDelegate:(id)aDelegate
{
if (_delegate === aDelegate)
return;
_delegate = aDelegate;
_implementedDelegateMethods = 0;
if ([_delegate respondsToSelector:@selector(sound:didFinishPlaying:)])
_implementedDelegateMethods |= CPSoundDelegate_sound_didFinishPlaying_;
}
#pragma mark -
#pragma mark Events listener
@@ -206,8 +239,7 @@ CPSoundPlayBackStatePause = 2;
_audioTag.currentTime = 0.0;
_playBackStatus = CPSoundPlayBackStateStop;
if (_delegate && [_delegate respondsToSelector:@selector(sound:didFinishPlaying:)])
[_delegate sound:self didFinishPlaying:YES];
[self _sendDelegateSoundDidFinishPlaying:YES];
return YES;
}
@@ -315,3 +347,20 @@ CPSoundPlayBackStatePause = 2;
}
@end
@implementation CPSound (CPSoundDelegate)
/*!
@ignore
Call delegate sound:didFinishPlaying:
*/
- (void)_sendDelegateSoundDidFinishPlaying:(BOOL)finishedPlaying
{
if (!(_implementedDelegateMethods & CPSoundDelegate_sound_didFinishPlaying_))
return;
[_delegate sound:self didFinishPlaying:finishedPlaying];
}
@end
+429 -203
View File
@@ -25,6 +25,40 @@
@import "CPButtonBar.j"
@import "CPImage.j"
@import "CPView.j"
@import "CPCursor.j"
@import "CPTrackingArea.j"
@class CPUserDefaults
@global CPApp
@protocol CPSplitViewDelegate <CPObject>
@optional
- (BOOL)splitView:(CPSplitView)splitView canCollapseSubview:(CPView)subview;
- (BOOL)splitView:(CPSplitView)splitView shouldAdjustSizeOfSubview:(CPView)subview;
- (BOOL)splitView:(CPSplitView)splitView shouldCollapseSubview:(CPView)subview forDoubleClickOnDividerAtIndex:(CPInteger)dividerIndex;
- (CGRect)splitView:(CPSplitView)splitView additionalEffectiveRectOfDividerAtIndex:(CPInteger)dividerIndex;
- (CGRect)splitView:(CPSplitView)splitView effectiveRect:(CGRect)proposedEffectiveRect forDrawnRect:(CGRect)drawnRect ofDividerAtIndex:(CPInteger)dividerIndex;
- (float)splitView:(CPSplitView)splitView constrainMaxCoordinate:(float)proposedMax ofSubviewAt:(CPInteger)dividerIndex;
- (float)splitView:(CPSplitView)splitView constrainMinCoordinate:(float)proposedMin ofSubviewAt:(CPInteger)dividerIndex;
- (float)splitView:(CPSplitView)splitView constrainSplitPosition:(float)proposedPosition ofSubviewAt:(CPInteger)dividerIndex;
- (void)splitView:(CPSplitView)splitView resizeSubviewsWithOldSize:(CGSize)oldSize;
- (void)splitViewDidResizeSubviews:(CPNotification)aNotification;
- (void)splitViewWillResizeSubviews:(CPNotification)aNotification;
@end
var CPSplitViewDelegate_splitView_canCollapseSubview_ = 1 << 0,
CPSplitViewDelegate_splitView_shouldAdjustSizeOfSubview_ = 1 << 1,
CPSplitViewDelegate_splitView_shouldCollapseSubview_forDoubleClickOnDividerAtIndex_ = 1 << 2,
CPSplitViewDelegate_splitView_additionalEffectiveRectOfDividerAtIndex_ = 1 << 3,
CPSplitViewDelegate_splitView_effectiveRect_forDrawnRect_ofDividerAtIndex_ = 1 << 4,
CPSplitViewDelegate_splitView_constrainMaxCoordinate_ofSubviewAt_ = 1 << 5,
CPSplitViewDelegate_splitView_constrainMinCoordinate_ofSubviewAt_ = 1 << 6,
CPSplitViewDelegate_splitView_constrainSplitPosition_ofSubviewAt_ = 1 << 7,
CPSplitViewDelegate_splitView_resizeSubviewsWithOldSize_ = 1 << 8,
CPSplitViewDelegate_splitViewDidResizeSubviews_ = 1 << 9,
CPSplitViewDelegate_splitViewWillResizeSubviews_ = 1 << 10;
#define SPLIT_VIEW_MAYBE_POST_WILL_RESIZE() \
if ((_suppressResizeNotificationsMask & DidPostWillResizeNotification) === 0) \
@@ -51,10 +85,7 @@
CPSplitViewDidResizeSubviewsNotification = @"CPSplitViewDidResizeSubviewsNotification";
CPSplitViewWillResizeSubviewsNotification = @"CPSplitViewWillResizeSubviewsNotification";
var CPSplitViewHorizontalImage = nil,
CPSplitViewVerticalImage = nil,
ShouldSuppressResizeNotifications = 1,
var ShouldSuppressResizeNotifications = 1,
DidPostWillResizeNotification = 1 << 1,
DidSuppressResizeNotification = 1 << 2;
@@ -72,29 +103,32 @@ var CPSplitViewHorizontalImage = nil,
@implementation CPSplitView : CPView
{
id _delegate;
BOOL _isVertical;
BOOL _isPaneSplitter;
id <CPSplitViewDelegate> _delegate;
BOOL _isVertical;
BOOL _isPaneSplitter;
int _currentDivider;
float _initialOffset;
CPDictionary _preCollapsePositions;
int _currentDivider;
float _initialOffset;
CPDictionary _preCollapsePositions;
CPString _originComponent;
CPString _sizeComponent;
CPString _originComponent;
CPString _sizeComponent;
CPArray _DOMDividerElements;
CPString _dividerImagePath;
int _drawingDivider;
CPArray _DOMDividerElements;
CPString _dividerImagePath;
int _drawingDivider;
BOOL _isTracking;
CPString _autosaveName;
BOOL _shouldAutosave;
CGSize _shouldRestoreFromAutosaveUnlessFrameSize;
CPString _autosaveName;
BOOL _shouldAutosave;
CGSize _shouldRestoreFromAutosaveUnlessFrameSize;
BOOL _needsResizeSubviews;
int _suppressResizeNotificationsMask;
BOOL _needsResizeSubviews;
int _suppressResizeNotificationsMask;
CPArray _buttonBars;
CPArray _buttonBars;
unsigned _implementedDelegateMethods;
}
+ (CPString)defaultThemeClass
@@ -102,24 +136,15 @@ var CPSplitViewHorizontalImage = nil,
return @"splitview";
}
+ (id)themeAttributes
+ (CPDictionary)themeAttributes
{
return [CPDictionary dictionaryWithObjects:[1.0, 10.0, [CPColor grayColor]]
forKeys:[@"divider-thickness", @"pane-divider-thickness", @"pane-divider-color"]];
}
/*
@ignore
*/
+ (void)initialize
{
if (self !== [CPSplitView class])
return;
var bundle = [CPBundle bundleForClass:self];
CPSplitViewHorizontalImage = CPImageInBundle("CPSplitView/CPSplitViewHorizontal.png", CGSizeMake(5.0, 10.0), bundle);
CPSplitViewVerticalImage = CPImageInBundle("CPSplitView/CPSplitViewVertical.png", CGSizeMake(10.0, 5.0), bundle);
return @{
@"divider-thickness": 1.0,
@"pane-divider-thickness": 10.0,
@"pane-divider-color": [CPColor grayColor],
@"horizontal-divider-color": [CPNull null],
@"vertical-divider-color": [CPNull null],
};
}
- (id)initWithFrame:(CGRect)aFrame
@@ -134,6 +159,7 @@ var CPSplitViewHorizontalImage = nil,
_buttonBars = [];
_shouldAutosave = YES;
_isTracking = NO;
[self _setVertical:YES];
}
@@ -189,6 +215,9 @@ var CPSplitViewHorizontalImage = nil,
[_subviews[index] setFrame:CGRectMake(0, ROUND((eachSize + dividerThickness) * index), frame.size.width, eachSize)];
}
if (_DOMDividerElements[_drawingDivider])
[self _setupDOMDivider];
[self setNeedsDisplay:YES];
[self _postNotificationDidResize];
@@ -202,7 +231,7 @@ var CPSplitViewHorizontalImage = nil,
_originComponent = [self isVertical] ? "x" : "y";
_sizeComponent = [self isVertical] ? "width" : "height";
_dividerImagePath = [self isVertical] ? [CPSplitViewVerticalImage filename] : [CPSplitViewHorizontalImage filename];
_dividerImagePath = [self isVertical] ? [[self valueForThemeAttribute:@"vertical-divider-color"] filename] : [[self valueForThemeAttribute:@"horizontal-divider-color"] filename];
return changed;
}
@@ -339,11 +368,11 @@ var CPSplitViewHorizontalImage = nil,
_DOMDividerElements[_drawingDivider].style.backgroundRepeat = "repeat";
CPDOMDisplayServerAppendChild(_DOMElement, _DOMDividerElements[_drawingDivider]);
[self _setupDOMDivider];
}
[self _setupDOMDivider];
CPDOMDisplayServerSetStyleLeftTop(_DOMDividerElements[_drawingDivider], NULL, _CGRectGetMinX(aRect), _CGRectGetMinY(aRect));
CPDOMDisplayServerSetStyleSize(_DOMDividerElements[_drawingDivider], _CGRectGetWidth(aRect), _CGRectGetHeight(aRect));
CPDOMDisplayServerSetStyleLeftTop(_DOMDividerElements[_drawingDivider], NULL, CGRectGetMinX(aRect), CGRectGetMinY(aRect));
CPDOMDisplayServerSetStyleSize(_DOMDividerElements[_drawingDivider], CGRectGetWidth(aRect), CGRectGetHeight(aRect));
#endif
}
@@ -414,11 +443,8 @@ var CPSplitViewHorizontalImage = nil,
buttonBarRect.origin = [self convertPoint:buttonBarRect.origin fromView:buttonBar];
}
if ([_delegate respondsToSelector:@selector(splitView:effectiveRect:forDrawnRect:ofDividerAtIndex:)])
effectiveRect = [_delegate splitView:self effectiveRect:effectiveRect forDrawnRect:effectiveRect ofDividerAtIndex:anIndex];
if ([_delegate respondsToSelector:@selector(splitView:additionalEffectiveRectOfDividerAtIndex:)])
additionalRect = [_delegate splitView:self additionalEffectiveRectOfDividerAtIndex:anIndex];
effectiveRect = [self _sendDelegateSplitViewEffectiveRect:effectiveRect forDrawnRect:effectiveRect ofDividerAtIndex:anIndex];
additionalRect = [self _sendDelegateSplitViewAdditionalEffectiveRectOfDividerAtIndex:anIndex];
return CGRectContainsPoint(effectiveRect, aPoint) ||
(additionalRect && CGRectContainsPoint(additionalRect, aPoint)) ||
@@ -431,17 +457,26 @@ var CPSplitViewHorizontalImage = nil,
return nil;
var point = [self convertPoint:aPoint fromView:[self superview]],
count = [_subviews count] - 1;
dividerIndex = [self _dividerAtPoint:point];
for (var i = 0; i < count; i++)
{
if ([self cursorAtPoint:point hitDividerAtIndex:i])
return self;
}
if (dividerIndex !== CPNotFound)
return self;
return [super hitTest:aPoint];
}
- (CPInteger)_dividerAtPoint:(CGPoint)aPoint
{
var count = [_subviews count] - 1;
for (var i = 0; i < count; i++)
{
if ([self cursorAtPoint:aPoint hitDividerAtIndex:i])
return i;
}
return CPNotFound;
}
/*
Tracks the divider.
@param anEvent the input event
@@ -452,12 +487,13 @@ var CPSplitViewHorizontalImage = nil,
if (type == CPLeftMouseUp)
{
// We disabled autosaving during tracking.
_shouldAutosave = YES;
if (_currentDivider != CPNotFound)
if ([anEvent clickCount] == 2 || (_isTracking && _currentDivider != CPNotFound))
{
// We disabled autosaving during tracking.
_shouldAutosave = YES;
_currentDivider = CPNotFound;
_isTracking = NO;
[self _autosave];
[self _updateResizeCursor:anEvent];
}
@@ -467,59 +503,55 @@ var CPSplitViewHorizontalImage = nil,
if (type == CPLeftMouseDown)
{
var point = [self convertPoint:[anEvent locationInWindow] fromView:nil],
count = [_subviews count] - 1;
var point = [self convertPoint:[anEvent locationInWindow] fromView:nil];
_currentDivider = [self _dividerAtPoint:point];
_currentDivider = CPNotFound;
var frame = [_subviews[_currentDivider] frame],
startPosition = frame.origin[_originComponent] + frame.size[_sizeComponent];
for (var i = 0; i < count; i++)
if ([anEvent clickCount] == 2 &&
[self _delegateRespondsToSplitViewCanCollapseSubview] &&
[self _delegateRespondsToSplitViewshouldCollapseSubviewForDoubleClickOnDividerAtIndex])
{
var frame = [_subviews[i] frame],
startPosition = frame.origin[_originComponent] + frame.size[_sizeComponent];
var minPosition = [self minPossiblePositionOfDividerAtIndex:_currentDivider],
maxPosition = [self maxPossiblePositionOfDividerAtIndex:_currentDivider],
preCollapsePosition = [_preCollapsePositions objectForKey:"" + _currentDivider] || 0;
if ([self cursorAtPoint:point hitDividerAtIndex:i])
if ([self _sendDelegateSplitViewCanCollapseSubview:_subviews[_currentDivider]] && [self _sendDelegateSplitViewShouldCollapseSubview:_subviews[_currentDivider] forDoubleClickOnDividerAtIndex:_currentDivider])
{
if ([anEvent clickCount] == 2 &&
[_delegate respondsToSelector:@selector(splitView:canCollapseSubview:)] &&
[_delegate respondsToSelector:@selector(splitView:shouldCollapseSubview:forDoubleClickOnDividerAtIndex:)])
{
var minPosition = [self minPossiblePositionOfDividerAtIndex:i],
maxPosition = [self maxPossiblePositionOfDividerAtIndex:i],
preCollapsePosition = [_preCollapsePositions objectForKey:"" + i] || 0;
if ([_delegate splitView:self canCollapseSubview:_subviews[i]] && [_delegate splitView:self shouldCollapseSubview:_subviews[i] forDoubleClickOnDividerAtIndex:i])
{
if ([self isSubviewCollapsed:_subviews[i]])
[self setPosition:preCollapsePosition ? preCollapsePosition : (minPosition + (maxPosition - minPosition) / 2) ofDividerAtIndex:i];
else
[self setPosition:minPosition ofDividerAtIndex:i];
}
else if ([_delegate splitView:self canCollapseSubview:_subviews[i + 1]] && [_delegate splitView:self shouldCollapseSubview:_subviews[i + 1] forDoubleClickOnDividerAtIndex:i])
{
if ([self isSubviewCollapsed:_subviews[i + 1]])
[self setPosition:preCollapsePosition ? preCollapsePosition : (minPosition + (maxPosition - minPosition) / 2) ofDividerAtIndex:i];
else
[self setPosition:maxPosition ofDividerAtIndex:i];
}
}
if ([self isSubviewCollapsed:_subviews[_currentDivider]])
[self setPosition:preCollapsePosition ? preCollapsePosition : (minPosition + (maxPosition - minPosition) / 2) ofDividerAtIndex:_currentDivider];
else
{
_currentDivider = i;
_initialOffset = startPosition - point[_originComponent];
// Don't autosave during a resize. We'll wait until it's done.
_shouldAutosave = NO;
[self _postNotificationWillResize];
}
[self setPosition:minPosition ofDividerAtIndex:_currentDivider];
}
else if ([self _sendDelegateSplitViewCanCollapseSubview:_subviews[_currentDivider + 1]] && [self _sendDelegateSplitViewShouldCollapseSubview:_subviews[_currentDivider + 1] forDoubleClickOnDividerAtIndex:_currentDivider])
{
if ([self isSubviewCollapsed:_subviews[_currentDivider + 1]])
[self setPosition:preCollapsePosition ? preCollapsePosition : (minPosition + (maxPosition - minPosition) / 2) ofDividerAtIndex:_currentDivider];
else
[self setPosition:maxPosition ofDividerAtIndex:_currentDivider];
}
}
else
{
_initialOffset = startPosition - point[_originComponent];
// Don't autosave during a resize. We'll wait until it's done.
_shouldAutosave = NO;
[self _postNotificationWillResize];
}
if (_currentDivider === CPNotFound)
return;
}
else if (type == CPLeftMouseDragged && _currentDivider != CPNotFound)
{
if (!_isTracking)
{
// Don't autosave during a resize. We'll wait until it's done.
_shouldAutosave = NO;
[self _postNotificationWillResize];
_isTracking = YES;
}
var point = [self convertPoint:[anEvent locationInWindow] fromView:nil];
[self setPosition:(point[_originComponent] + _initialOffset) ofDividerAtIndex:_currentDivider];
@@ -532,8 +564,11 @@ var CPSplitViewHorizontalImage = nil,
- (void)mouseDown:(CPEvent)anEvent
{
// FIXME: This should not trap events if not on a divider!
[self trackDivider:anEvent];
var point = [self convertPoint:[anEvent locationInWindow] fromView:nil],
dividerIndex = [self _dividerAtPoint:point];
if (dividerIndex !== CPNotFound)
[self trackDivider:anEvent];
}
- (void)viewDidMoveToWindow
@@ -542,26 +577,6 @@ var CPSplitViewHorizontalImage = nil,
//[[self window] setAcceptsMouseMovedEvents:YES];
}
- (void)mouseEntered:(CPEvent)anEvent
{
// Tracking code handles cursor by itself.
if (_currentDivider == CPNotFound)
[self _updateResizeCursor:anEvent];
}
- (void)mouseMoved:(CPEvent)anEvent
{
if (_currentDivider == CPNotFound)
[self _updateResizeCursor:anEvent];
}
- (void)mouseExited:(CPEvent)anEvent
{
if (_currentDivider == CPNotFound)
// FIXME: we should use CPCursor push/pop (if previous currentCursor != arrow).
[[CPCursor arrowCursor] set];
}
- (void)_updateResizeCursor:(CPEvent)anEvent
{
var point = [self convertPoint:[anEvent locationInWindow] fromView:nil];
@@ -588,12 +603,8 @@ var CPSplitViewHorizontalImage = nil,
if (sizeA === 0)
canGrow = YES; // Subview is collapsed.
else if (!canShrink &&
[_delegate respondsToSelector:@selector(splitView:canCollapseSubview:)] &&
[_delegate splitView:self canCollapseSubview:_subviews[i]])
{
else if (!canShrink && [self _sendDelegateSplitViewCanCollapseSubview:_subviews[i]])
canShrink = YES; // Subview is collapsible.
}
if (sizeB === 0)
{
@@ -602,9 +613,7 @@ var CPSplitViewHorizontalImage = nil,
// It's safe to assume it can always be uncollapsed.
canShrink = YES;
}
else if (!canGrow &&
[_delegate respondsToSelector:@selector(splitView:canCollapseSubview:)] &&
[_delegate splitView:self canCollapseSubview:_subviews[i + 1]])
else if (!canGrow && [self _sendDelegateSplitViewCanCollapseSubview:_subviews[i + 1]])
{
canGrow = YES; // Right/lower subview is collapsible.
}
@@ -665,53 +674,38 @@ var CPSplitViewHorizontalImage = nil,
- (int)_realPositionForPosition:(float)position ofDividerAtIndex:(int)dividerIndex
{
// not sure where this should override other positions?
if ([_delegate respondsToSelector:@selector(splitView:constrainSplitPosition:ofSubviewAt:)])
{
var proposedPosition = [_delegate splitView:self constrainSplitPosition:position ofSubviewAt:dividerIndex];
var proposedPosition = [self _sendDelegateSplitViewConstrainSplitPosition:position ofSubviewAt:dividerIndex];
// Silently ignore bad positions which could result from odd delegate responses. We don't want these
// bad results to go into the system and cause havoc with frame sizes as the split view tries to resize
// its subviews.
if (_IS_NUMERIC(proposedPosition))
position = proposedPosition;
}
// Silently ignore bad positions which could result from odd delegate responses. We don't want these
// bad results to go into the system and cause havoc with frame sizes as the split view tries to resize
// its subviews.
if (_IS_NUMERIC(proposedPosition))
position = proposedPosition;
var proposedMax = [self maxPossiblePositionOfDividerAtIndex:dividerIndex],
proposedMin = [self minPossiblePositionOfDividerAtIndex:dividerIndex],
actualMax = proposedMax,
actualMin = proposedMin;
actualMin = proposedMin,
proposedActualMin = [self _sendDelegateSplitViewConstrainMinCoordinate:proposedMin ofSubviewAt:dividerIndex],
proposedActualMax = [self _sendDelegateSplitViewConstrainMaxCoordinate:proposedMax ofSubviewAt:dividerIndex];
if ([_delegate respondsToSelector:@selector(splitView:constrainMinCoordinate:ofSubviewAt:)])
{
var proposedActualMin = [_delegate splitView:self constrainMinCoordinate:proposedMin ofSubviewAt:dividerIndex];
if (_IS_NUMERIC(proposedActualMin))
actualMin = proposedActualMin;
if (_IS_NUMERIC(proposedActualMin))
actualMin = proposedActualMin;
}
if ([_delegate respondsToSelector:@selector(splitView:constrainMaxCoordinate:ofSubviewAt:)])
{
var proposedActualMax = [_delegate splitView:self constrainMaxCoordinate:proposedMax ofSubviewAt:dividerIndex];
if (_IS_NUMERIC(proposedActualMax))
actualMax = proposedActualMax;
}
if (_IS_NUMERIC(proposedActualMax))
actualMax = proposedActualMax;
var viewA = _subviews[dividerIndex],
viewB = _subviews[dividerIndex + 1],
realPosition = MAX(MIN(position, actualMax), actualMin);
// Is this position past the halfway point to collapse?
if (position < proposedMin + (actualMin - proposedMin) / 2)
if ([_delegate respondsToSelector:@selector(splitView:canCollapseSubview:)])
if ([_delegate splitView:self canCollapseSubview:viewA])
realPosition = proposedMin;
if ((position < proposedMin + (actualMin - proposedMin) / 2) && [self _sendDelegateSplitViewCanCollapseSubview:viewA])
realPosition = proposedMin;
// We can also collapse to the right.
if (position > proposedMax - (proposedMax - actualMax) / 2)
if ([_delegate respondsToSelector:@selector(splitView:canCollapseSubview:)])
if ([_delegate splitView:self canCollapseSubview:viewB])
realPosition = proposedMax;
if ((position > proposedMax - (proposedMax - actualMax) / 2) && [self _sendDelegateSplitViewCanCollapseSubview:viewB])
realPosition = proposedMax;
return realPosition;
}
@@ -793,11 +787,11 @@ var CPSplitViewHorizontalImage = nil,
[self setNeedsDisplay:YES];
}
- (void)resizeSubviewsWithOldSize:(CPSize)oldSize
- (void)resizeSubviewsWithOldSize:(CGSize)oldSize
{
if ([_delegate respondsToSelector:@selector(splitView:resizeSubviewsWithOldSize:)])
if ([self _delegateRespondsToSplitViewResizeSubviewsWithOldSize])
{
[_delegate splitView:self resizeSubviewsWithOldSize:oldSize];
[self _sendDelegateSplitViewResizeSubviewsWithOldSize:oldSize];
return;
}
@@ -823,8 +817,7 @@ var CPSplitViewHorizontalImage = nil,
oldFlexibleSpace = 0,
totalSizablePanes = 0,
isSizableMap = {},
viewSizes = [],
delegateRespondsToShouldAdjust = [_delegate respondsToSelector:@selector(splitView:shouldAdjustSizeOfSubview:)];
viewSizes = [];
// What we want to do is to preserve non resizable sizes first, and then to preserve the ratio of size to available
// non fixed space for every other subview. E.g. assume fixed space was 20 pixels initially, view 1 was 20 and
@@ -840,7 +833,7 @@ var CPSplitViewHorizontalImage = nil,
for (index = 0; index < count; ++index)
{
var view = _subviews[index],
isSizable = !delegateRespondsToShouldAdjust || [_delegate splitView:self shouldAdjustSizeOfSubview:view],
isSizable = [self _sendDelegateSplitViewShouldAdjustSizeOfSubview:view],
size = [view frame].size[_sizeComponent];
isSizableMap[index] = isSizable;
@@ -966,25 +959,47 @@ The sum of the views and the sum of the dividers should be equal to the size of
@param delegate - The delegate of the splitview.
*/
- (void)setDelegate:(id)delegate
- (void)setDelegate:(id <CPSplitViewDelegate>)aDelegate
{
if ([_delegate respondsToSelector:@selector(splitViewDidResizeSubviews:)])
[[CPNotificationCenter defaultCenter] removeObserver:_delegate name:CPSplitViewDidResizeSubviewsNotification object:self];
if (_delegate === aDelegate)
return;
_delegate = aDelegate;
_implementedDelegateMethods = 0;
if ([_delegate respondsToSelector:@selector(splitViewWillResizeSubviews:)])
[[CPNotificationCenter defaultCenter] removeObserver:_delegate name:CPSplitViewWillResizeSubviewsNotification object:self];
_implementedDelegateMethods |= CPSplitViewDelegate_splitViewWillResizeSubviews_;
_delegate = delegate;
if ([_delegate respondsToSelector:@selector(splitViewDidResizeSubviews:)])
_implementedDelegateMethods |= CPSplitViewDelegate_splitViewDidResizeSubviews_;
if ([_delegate respondsToSelector:@selector(splitView:canCollapseSubview:)])
_implementedDelegateMethods |= CPSplitViewDelegate_splitView_canCollapseSubview_;
if ([_delegate respondsToSelector:@selector(splitView:shouldAdjustSizeOfSubview:)])
_implementedDelegateMethods |= CPSplitViewDelegate_splitView_shouldAdjustSizeOfSubview_;
if ([_delegate respondsToSelector:@selector(splitView:shouldCollapseSubview:forDoubleClickOnDividerAtIndex:)])
_implementedDelegateMethods |= CPSplitViewDelegate_splitView_shouldCollapseSubview_forDoubleClickOnDividerAtIndex_;
if ([_delegate respondsToSelector:@selector(splitView:additionalEffectiveRectOfDividerAtIndex:)])
_implementedDelegateMethods |= CPSplitViewDelegate_splitView_additionalEffectiveRectOfDividerAtIndex_;
if ([_delegate respondsToSelector:@selector(splitView:effectiveRect:forDrawnRect:ofDividerAtIndex:)])
_implementedDelegateMethods |= CPSplitViewDelegate_splitView_effectiveRect_forDrawnRect_ofDividerAtIndex_;
if ([_delegate respondsToSelector:@selector(splitView:constrainMaxCoordinate:ofSubviewAt:)])
_implementedDelegateMethods |= CPSplitViewDelegate_splitView_constrainMaxCoordinate_ofSubviewAt_;
if ([_delegate respondsToSelector:@selector(splitView:constrainMinCoordinate:ofSubviewAt:)])
_implementedDelegateMethods |= CPSplitViewDelegate_splitView_constrainMinCoordinate_ofSubviewAt_;
if ([_delegate respondsToSelector:@selector(splitView:constrainSplitPosition:ofSubviewAt:)])
_implementedDelegateMethods |= CPSplitViewDelegate_splitView_constrainSplitPosition_ofSubviewAt_;
if ([_delegate respondsToSelector:@selector(splitView:resizeSubviewsWithOldSize:)])
_implementedDelegateMethods |= CPSplitViewDelegate_splitView_resizeSubviewsWithOldSize_;
if ([_delegate respondsToSelector:@selector(splitViewDidResizeSubviews:)])
[[CPNotificationCenter defaultCenter] addObserver:_delegate
selector:@selector(splitViewDidResizeSubviews:)
name:CPSplitViewDidResizeSubviewsNotification
object:self];
if ([_delegate respondsToSelector:@selector(splitViewWillResizeSubviews:)])
[[CPNotificationCenter defaultCenter] addObserver:_delegate
selector:@selector(splitViewWillResizeSubviews:)
name:CPSplitViewWillResizeSubviewsNotification
object:self];
}
/*!
@@ -1003,7 +1018,7 @@ The sum of the views and the sum of the dividers should be equal to the size of
@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
- (void)setButtonBar:(CPButtonBar)aButtonBar forDividerAtIndex:(CPUInteger)dividerIndex
{
if (!aButtonBar)
{
@@ -1034,27 +1049,12 @@ The sum of the views and the sum of the dividers should be equal to the size of
- (void)_postNotificationWillResize
{
var userInfo = nil;
if (_currentDivider !== CPNotFound)
userInfo = [CPDictionary dictionaryWithObject:_currentDivider forKey:@"CPSplitViewDividerIndex"];
[[CPNotificationCenter defaultCenter] postNotificationName:CPSplitViewWillResizeSubviewsNotification
object:self
userInfo:userInfo];
[self _sendDelegateSplitViewWillResizeSubviews];
}
- (void)_postNotificationDidResize
{
var userInfo = nil;
if (_currentDivider !== CPNotFound)
userInfo = [CPDictionary dictionaryWithObject:_currentDivider forKey:@"CPSplitViewDividerIndex"];
[[CPNotificationCenter defaultCenter] postNotificationName:CPSplitViewDidResizeSubviewsNotification
object:self
userInfo:userInfo];
[self _sendDelegateSplitViewDidResizeSubviews];
// TODO Cocoa always autosaves on "viewDidEndLiveResize". If Cappuccino adds support for this we
// should do the same.
@@ -1102,7 +1102,7 @@ The sum of the views and the sum of the dividers should be equal to the size of
for (var i = 0; i < count; i++)
{
var frame = [_subviews[i] frame];
[positions addObject:CPStringFromRect(frame)];
[positions addObject:CGStringFromRect(frame)];
[preCollapseArray addObject:[_preCollapsePositions objectForKey:"" + i]];
}
@@ -1118,7 +1118,7 @@ The sum of the views and the sum of the dividers should be equal to the size of
*/
- (void)_restoreFromAutosaveIfNeeded
{
if (_shouldRestoreFromAutosaveUnlessFrameSize && !_CGSizeEqualToSize([self frameSize], _shouldRestoreFromAutosaveUnlessFrameSize))
if (_shouldRestoreFromAutosaveUnlessFrameSize && !CGSizeEqualToSize([self frameSize], _shouldRestoreFromAutosaveUnlessFrameSize))
{
[self _restoreFromAutosave];
}
@@ -1149,7 +1149,7 @@ The sum of the views and the sum of the dividers should be equal to the size of
for (var i = 0, count = [frames count] - 1; i < count; i++)
{
var frame = CPRectFromString(frames[i]);
var frame = CGRectFromString(frames[i]);
position += frame.size[_sizeComponent];
[self setPosition:position ofDividerAtIndex:i];
@@ -1165,7 +1165,14 @@ The sum of the views and the sum of the dividers should be equal to the size of
_preCollapsePositions = [CPMutableDictionary new];
for (var i = 0, count = [preCollapseArray count]; i < count; i++)
[_preCollapsePositions setObject:preCollapseArray[i] forKey:i + ""];
{
var item = preCollapseArray[i];
if (item === nil)
[_preCollapsePositions removeObjectForKey:String(i)];
else
[_preCollapsePositions setObject:item forKey:String(i)];
}
}
}
@@ -1193,6 +1200,224 @@ The sum of the views and the sum of the dividers should be equal to the size of
@end
@implementation CPSplitView (CPTrackingArea)
{
CPMutableArray _splitViewTrackingAreas;
}
- (void)updateTrackingAreas
{
if (_splitViewTrackingAreas)
{
for (var i = 0, count = [_splitViewTrackingAreas count]; i < count; i++)
[self removeTrackingArea:_splitViewTrackingAreas[i]];
_splitViewTrackingAreas = nil;
}
var options = CPTrackingCursorUpdate | CPTrackingActiveInKeyWindow;
_splitViewTrackingAreas = @[];
for (var i = 0; i < _subviews.length - 1; i++)
{
[_splitViewTrackingAreas addObject:[[CPTrackingArea alloc] initWithRect:[self effectiveRectOfDividerAtIndex:i]
options:options
owner:self
userInfo:nil]];
[self addTrackingArea:_splitViewTrackingAreas[i]];
}
[super updateTrackingAreas];
}
- (void)cursorUpdate:(CPEvent)anEvent
{
if (_currentDivider === CPNotFound)
[self _updateResizeCursor:anEvent];
}
@end
@implementation CPSplitView (CPSplitViewDelegate)
/*!
@ignore
Return YES if the delegate implements splitView:resizeSubviewsWithOldSize:
*/
- (BOOL)_delegateRespondsToSplitViewResizeSubviewsWithOldSize
{
return _implementedDelegateMethods & CPSplitViewDelegate_splitView_resizeSubviewsWithOldSize_;
}
/*!
@ignore
Return YES if the delegate implements splitView:canCollapseSubview:
*/
- (BOOL)_delegateRespondsToSplitViewCanCollapseSubview
{
return _implementedDelegateMethods & CPSplitViewDelegate_splitView_canCollapseSubview_;
}
/*!
@ignore
Return YES if the delegate implements splitView:shouldCollapseSubview:forDoubleClickOnDividerAtIndex
*/
- (BOOL)_delegateRespondsToSplitViewshouldCollapseSubviewForDoubleClickOnDividerAtIndex
{
return _implementedDelegateMethods & CPSplitViewDelegate_splitView_shouldCollapseSubview_forDoubleClickOnDividerAtIndex_;
}
/*!
@ignore
Call the delegate splitView:canCollapseSubview:
*/
- (BOOL)_sendDelegateSplitViewCanCollapseSubview:(CPView)aView
{
if (!(_implementedDelegateMethods & CPSplitViewDelegate_splitView_canCollapseSubview_))
return NO;
return [_delegate splitView:self canCollapseSubview:aView];
}
/*!
@ignore
Call the delegate splitView:shouldAdjustSizeOfSubview:
*/
- (BOOL)_sendDelegateSplitViewShouldAdjustSizeOfSubview:(CPView)aView
{
if (!(_implementedDelegateMethods & CPSplitViewDelegate_splitView_shouldAdjustSizeOfSubview_))
return YES;
return [_delegate splitView:self shouldAdjustSizeOfSubview:aView];
}
/*!
@ignore
Call the delegate splitView:shouldCollapseSubview:forDoubleClickOnDividerAtIndex:
*/
- (BOOL)_sendDelegateSplitViewShouldCollapseSubview:(CPView)aView forDoubleClickOnDividerAtIndex:(int)anIndex
{
if (!(_implementedDelegateMethods & CPSplitViewDelegate_splitView_shouldCollapseSubview_forDoubleClickOnDividerAtIndex_))
return NO;
return [_delegate splitView:self shouldCollapseSubview:aView forDoubleClickOnDividerAtIndex:anIndex];
}
/*!
@ignore
Call the delegate splitView:additionalEffectiveRectOfDividerAtIndex:
*/
- (CGRect)_sendDelegateSplitViewAdditionalEffectiveRectOfDividerAtIndex:(int)anIndex
{
if (!(_implementedDelegateMethods & CPSplitViewDelegate_splitView_additionalEffectiveRectOfDividerAtIndex_))
return nil;
return [_delegate splitView:self additionalEffectiveRectOfDividerAtIndex:anIndex];
}
/*!
@ignore
Call the delegate splitView:effectiveRect:forDrawnRect:ofDividerAtIndex:
*/
- (CGRect)_sendDelegateSplitViewEffectiveRect:(CGRect)proposedEffectiveRect forDrawnRect:(CGRect)drawnRect ofDividerAtIndex:(CPInteger)dividerIndex
{
if (!(_implementedDelegateMethods & CPSplitViewDelegate_splitView_effectiveRect_forDrawnRect_ofDividerAtIndex_))
return proposedEffectiveRect;
return [_delegate splitView:self effectiveRect:proposedEffectiveRect forDrawnRect:drawnRect ofDividerAtIndex:dividerIndex];
}
/*!
@ignore
Call the delegate splitView:constrainMaxCoordinate:ofSubviewAt:
*/
- (float)_sendDelegateSplitViewConstrainMaxCoordinate:(float)proposedMax ofSubviewAt:(CPInteger)dividerIndex
{
if (!(_implementedDelegateMethods & CPSplitViewDelegate_splitView_constrainMaxCoordinate_ofSubviewAt_))
return nil;
return [_delegate splitView:self constrainMaxCoordinate:proposedMax ofSubviewAt:dividerIndex];
}
/*!
@ignore
Call the delegate splitView:constrainMinCoordinate:ofSubviewAt:
*/
- (float)_sendDelegateSplitViewConstrainMinCoordinate:(float)proposedMin ofSubviewAt:(CPInteger)dividerIndex
{
if (!(_implementedDelegateMethods & CPSplitViewDelegate_splitView_constrainMinCoordinate_ofSubviewAt_))
return nil;
return [_delegate splitView:self constrainMinCoordinate:proposedMin ofSubviewAt:dividerIndex];
}
/*!
@ignore
Call the delegate splitView:constrainSplitPosition:ofSubviewAt:
*/
- (float)_sendDelegateSplitViewConstrainSplitPosition:(float)proposedMax ofSubviewAt:(CPInteger)dividerIndex
{
if (!(_implementedDelegateMethods & CPSplitViewDelegate_splitView_constrainSplitPosition_ofSubviewAt_))
return nil;
return [_delegate splitView:self constrainSplitPosition:proposedMax ofSubviewAt:dividerIndex];
}
/*!
@ignore
Call the delegate splitView:resizeSubviewsWithOldSize:
*/
- (void)_sendDelegateSplitViewResizeSubviewsWithOldSize:(CGSize)oldSize
{
if (!(_implementedDelegateMethods & CPSplitViewDelegate_splitView_resizeSubviewsWithOldSize_))
return;
[_delegate splitView:self resizeSubviewsWithOldSize:oldSize];
}
/*!
@ignore
Call the delegate splitViewWillResizeSubviews:
*/
- (void)_sendDelegateSplitViewWillResizeSubviews
{
var userInfo = nil;
if (_currentDivider !== CPNotFound)
userInfo = @{ @"CPSplitViewDividerIndex": _currentDivider };
if (_implementedDelegateMethods & CPSplitViewDelegate_splitViewWillResizeSubviews_)
[_delegate splitViewWillResizeSubviews:[[CPNotification alloc] initWithName:CPSplitViewWillResizeSubviewsNotification object:self userInfo:userInfo]];
[[CPNotificationCenter defaultCenter] postNotificationName:CPSplitViewWillResizeSubviewsNotification object:self userInfo:userInfo];
}
/*!
@ignore
Call the delegate splitViewDidResizeSubviews:
*/
- (void)_sendDelegateSplitViewDidResizeSubviews
{
var userInfo = nil;
if (_currentDivider !== CPNotFound)
userInfo = @{ @"CPSplitViewDividerIndex": _currentDivider };
if (_implementedDelegateMethods & CPSplitViewDelegate_splitViewDidResizeSubviews_)
[_delegate splitViewDidResizeSubviews:[[CPNotification alloc] initWithName:CPSplitViewDidResizeSubviewsNotification object:self userInfo:userInfo]];
[[CPNotificationCenter defaultCenter] postNotificationName:CPSplitViewDidResizeSubviewsNotification object:self userInfo:userInfo];
[self updateTrackingAreas];
}
@end
var CPSplitViewDelegateKey = "CPSplitViewDelegateKey",
CPSplitViewIsVerticalKey = "CPSplitViewIsVerticalKey",
CPSplitViewIsPaneSplitterKey = "CPSplitViewIsPaneSplitterKey",
@@ -1244,6 +1469,7 @@ var CPSplitViewDelegateKey = "CPSplitViewDelegateKey",
_currentDivider = CPNotFound;
_shouldAutosave = YES;
_isTracking = NO;
_DOMDividerElements = [];
+56 -35
View File
@@ -20,10 +20,9 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import <AppKit/CPControl.j>
@import <AppKit/CPButton.j>
@import <AppKit/CPTextField.j>
@import "CPControl.j"
@import "CPButton.j"
@import "CPTextField.j"
/*!
@@ -53,13 +52,17 @@
@param maxValue the maximal acceptable value of the stepper
@return Initialized CPStepper
*/
+ (CPStepper)stepperWithInitialValue:(float)aValue minValue:(float)aMinValue maxValue:(float)aMaxValue
+ (id)stepperWithInitialValue:(float)aValue minValue:(float)aMinValue maxValue:(float)aMaxValue
{
var stepper = [[CPStepper alloc] initWithFrame:_CGRectMake(0, 0, 19, 25)];
var stepper = [[self alloc] initWithFrame:CGRectMakeZero()];
[stepper setDoubleValue:aValue];
[stepper setMinValue:aMinValue];
[stepper setMaxValue:aMaxValue];
// _sizeToFit will put the good size for the stepper depending of the current theme
[stepper _sizeToFit];
return stepper;
}
@@ -71,22 +74,22 @@
@return Initialized CPStepper
*/
+ (CPStepper)stepper
+ (id)stepper
{
return [CPStepper stepperWithInitialValue:0.0 minValue:0.0 maxValue:59.0];
}
+ (Class)_binderClassForBinding:(CPString)theBinding
+ (Class)_binderClassForBinding:(CPString)aBinding
{
if (theBinding == CPValueBinding || theBinding == CPMinValueBinding || theBinding == CPMaxValueBinding)
if (aBinding === CPValueBinding || aBinding === CPMinValueBinding || aBinding === CPMaxValueBinding)
return [_CPStepperValueBinder class];
return [super _binderClassForBinding:theBinding];
return [super _binderClassForBinding:aBinding];
}
- (id)_replacementKeyPathForBinding:(CPString)aBinding
- (CPString)_replacementKeyPathForBinding:(CPString)aBinding
{
if (aBinding == CPValueBinding)
if (aBinding === CPValueBinding)
return @"doubleValue";
return [super _replacementKeyPathForBinding:aBinding];
@@ -118,14 +121,14 @@
- (void)_init
{
_buttonUp = [[CPButton alloc] initWithFrame:_CGRectMakeZero()];
_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 = [[CPButton alloc] initWithFrame:CGRectMakeZero()];
[_buttonDown setContinuous:_autorepeat];
[_buttonDown setTarget:self];
[_buttonDown setAction:@selector(_buttonDidClick:)];
@@ -134,9 +137,16 @@
[self setContinuous:_autorepeat];
[self addSubview:_buttonDown];
[self _sizeToFit];
[self setNeedsLayout];
}
- (void)setControlSize:(CPControlSize)aControlSize
{
[super setControlSize:aControlSize];
[self _sizeToFit];
}
#pragma mark -
#pragma mark Superclass overrides
@@ -155,10 +165,10 @@
- (void)setFrame:(CGRect)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);
var upSize = [self currentValueForThemeAttribute:@"up-button-size"],
downSize = [self currentValueForThemeAttribute:@"down-button-size"],
minSize = CGSizeMake(upSize.width, upSize.height + downSize.height),
frame = CGRectMakeCopy(aFrame);
frame.size.width = MAX(minSize.width, frame.size.width);
frame.size.height = MAX(minSize.height, frame.size.height);
@@ -168,20 +178,27 @@
/*! @ignore */
- (void)layoutSubviews
{
var aFrame = [self frame],
upSize = [self valueForThemeAttribute:@"up-button-size"],
downSize = [self valueForThemeAttribute:@"down-button-size"],
upFrame = _CGRectMake(aFrame.size.width - upSize.width, 0, upSize.width, upSize.height),
downFrame = _CGRectMake(aFrame.size.width - downSize.width, upSize.height, downSize.width, downSize.height);
var controlSizeThemeState = [self _controlSizeThemeState],
aFrame = [self frame],
upSize = [self valueForThemeAttribute:@"up-button-size" inState:controlSizeThemeState],
downSize = [self valueForThemeAttribute:@"down-button-size" inState:controlSizeThemeState],
upFrame = CGRectMake(0, 0, upSize.width, upSize.height),
downFrame = CGRectMake(0, upSize.height, downSize.width, downSize.height);
[_buttonUp setFrame:upFrame];
[_buttonDown setFrame:downFrame];
[_buttonUp setValue:[self valueForThemeAttribute:@"bezel-color-up-button" inState:CPThemeStateBordered] forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered];
[_buttonUp setValue:[self valueForThemeAttribute:@"bezel-color-up-button" inState:CPThemeStateBordered | CPThemeStateDisabled] forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered | CPThemeStateDisabled];
[_buttonUp setValue:[self valueForThemeAttribute:@"bezel-color-up-button" inState:CPThemeStateBordered | CPThemeStateHighlighted] forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered | CPThemeStateHighlighted];
[_buttonDown setValue:[self valueForThemeAttribute:@"bezel-color-down-button" inState:CPThemeStateBordered] forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered];
[_buttonDown setValue:[self valueForThemeAttribute:@"bezel-color-down-button" inState:CPThemeStateBordered | CPThemeStateDisabled] forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered | CPThemeStateDisabled];
[_buttonDown setValue:[self valueForThemeAttribute:@"bezel-color-down-button" inState:CPThemeStateBordered | CPThemeStateHighlighted] forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered | CPThemeStateHighlighted];
[_buttonUp setValue:[self valueForThemeAttribute:@"bezel-color-up-button" inStates:[controlSizeThemeState, CPThemeStateBordered]] forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered];
[_buttonUp setValue:[self valueForThemeAttribute:@"bezel-color-up-button" inStates:[controlSizeThemeState, CPThemeStateBordered, CPThemeStateDisabled]] forThemeAttribute:@"bezel-color" inStates:[CPThemeStateBordered, CPThemeStateDisabled]];
[_buttonUp setValue:[self valueForThemeAttribute:@"bezel-color-up-button" inStates:[controlSizeThemeState, CPThemeStateBordered, CPThemeStateHighlighted]] forThemeAttribute:@"bezel-color" inStates:[CPThemeStateBordered, CPThemeStateHighlighted]];
[_buttonDown setValue:[self valueForThemeAttribute:@"bezel-color-down-button" inStates:[controlSizeThemeState, CPThemeStateBordered]] forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered];
[_buttonDown setValue:[self valueForThemeAttribute:@"bezel-color-down-button" inStates:[controlSizeThemeState, CPThemeStateBordered, CPThemeStateDisabled]] forThemeAttribute:@"bezel-color" inStates:[CPThemeStateBordered, CPThemeStateDisabled]];
[_buttonDown setValue:[self valueForThemeAttribute:@"bezel-color-down-button" inStates:[controlSizeThemeState, CPThemeStateBordered, CPThemeStateHighlighted]] forThemeAttribute:@"bezel-color" inStates:[CPThemeStateBordered, CPThemeStateHighlighted]];
}
- (void)_sizeToFit
{
[self setFrame:CGRectMake([self frameOrigin].x, [self frameOrigin].y, 0, 0)];
}
/*!
@@ -203,7 +220,7 @@
Set the current value of the stepper.
@param aValue a float containing the value
*/
- (void)setDoubleValue:(float)aValue
- (void)setDoubleValue:(double)aValue
{
if (aValue > _maxValue)
[super setDoubleValue:_valueWraps ? _minValue : _maxValue];
@@ -222,7 +239,7 @@
if (![self isEnabled])
return;
if (aSender == _buttonUp)
if (aSender === _buttonUp)
[self setDoubleValue:([self doubleValue] + _increment)];
else
[self setDoubleValue:([self doubleValue] - _increment)];
@@ -257,10 +274,14 @@
return @"stepper";
}
+ (id)themeAttributes
+ (CPDictionary)themeAttributes
{
return [CPDictionary dictionaryWithObjects:[[CPNull null], [CPNull null], _CGSizeMakeZero(), _CGSizeMakeZero()]
forKeys:[@"bezel-color-up-button", @"bezel-color-down-button", @"up-button-size", @"down-button-size"]];
return @{
@"bezel-color-up-button": [CPNull null],
@"bezel-color-down-button": [CPNull null],
@"up-button-size": CGSizeMakeZero(),
@"down-button-size": CGSizeMakeZero(),
};
}
@end
@@ -271,7 +292,7 @@
- (void)_updatePlaceholdersWithOptions:(CPDictionary)options forBinding:(CPString)aBinding
{
var placeholder = (aBinding == CPMaxValueBinding) ? [_source maxValue] : [_source minValue];
var placeholder = (aBinding === CPMaxValueBinding) ? [_source maxValue] : [_source minValue];
[super _updatePlaceholdersWithOptions:options];
+58 -7
View File
@@ -22,10 +22,15 @@
@import <Foundation/CPString.j>
@import "CGGeometry.j"
@import "CPPlatformString.j"
@import "CPFont.j"
@import "CPCompatibility.j"
var CPStringSizeWithFontInWidthCache = {};
var CPStringSizeWithFontInWidthCache = [],
CPStringSizeWithFontHeightCache = [],
CPStringSizeMeasuringContext;
CPStringSizeCachingEnabled = YES;
@@ -52,21 +57,67 @@ CPStringSizeCachingEnabled = YES;
return [self sizeWithFont:aFont inWidth:NULL];
}
- (CGSize)sizeWithFont:(CPFont)aFont inWidth:(float)aWidth
+ (void) initialize
{
if ([self class] != [CPString class])
return;
#if PLATFORM(DOM)
if (CPFeatureIsCompatible(CPHTMLCanvasFeature) && !CPStringSizeMeasuringContext)
CPStringSizeMeasuringContext = CGBitmapGraphicsContextCreate();
#endif
}
- (CGSize)_sizeWithFont:(CPFont)aFont inWidth:(float)aWidth
{
var size;
#if PLATFORM(DOM)
if (!CPStringSizeCachingEnabled)
return [CPPlatformString sizeOfString:self withFont:aFont forWidth:aWidth];
var cacheKey = self + [aFont cssString] + aWidth,
size = CPStringSizeWithFontInWidthCache[cacheKey];
var sizeCacheForFont = CPStringSizeWithFontInWidthCache[self];
if (size === undefined)
{
if (sizeCacheForFont === undefined)
sizeCacheForFont = CPStringSizeWithFontInWidthCache[self] = [];
if (!aWidth)
aWidth = '0';
var cssString = [aFont cssString],
cacheKey = cssString + '_' + aWidth;
size = sizeCacheForFont[cacheKey];
if (size !== undefined && sizeCacheForFont.hasOwnProperty(cacheKey))
return CGSizeMakeCopy(size);
if (!CPFeatureIsCompatible(CPHTMLCanvasFeature) || aWidth > 0)
size = [CPPlatformString sizeOfString:self withFont:aFont forWidth:aWidth];
CPStringSizeWithFontInWidthCache[cacheKey] = size;
else
{
if (CPPlatformHasBug(CPTextSizingAlwaysNeedsSetFontBug) || CPStringSizeMeasuringContext.font !== cssString)
CPStringSizeMeasuringContext.font = cssString;
var fontHeight = CPStringSizeWithFontHeightCache[cssString];
if (fontHeight === undefined)
fontHeight = CPStringSizeWithFontHeightCache[cssString] = [aFont defaultLineHeightForFont];
size = CGSizeMake(CPStringSizeMeasuringContext.measureText(self).width, fontHeight);
}
sizeCacheForFont[cacheKey] = size;
#else
size = CGSizeMake(0, 0);
#endif
return CGSizeMakeCopy(size);
}
- (CGSize)sizeWithFont:(CPFont)aFont inWidth:(float)aWidth
{
var size = [self _sizeWithFont:aFont inWidth:aWidth];
return CGSizeMake(CEIL(size.width), size.height);
}
@end
+538 -121
View File
@@ -25,6 +25,7 @@
@import "CPTabViewItem.j"
@import "CPView.j"
@typedef CPTabViewType
CPTopTabsBezelBorder = 0;
//CPLeftTabsBezelBorder = 1;
CPBottomTabsBezelBorder = 2;
@@ -33,10 +34,25 @@ CPNoTabsBezelBorder = 4; //Displays no tabs and has a bezeled border.
CPNoTabsLineBorder = 5; //Has no tabs and displays a line border.
CPNoTabsNoBorder = 6; //Displays no tabs and no border.
var CPTabViewDidSelectTabViewItemSelector = 1,
CPTabViewShouldSelectTabViewItemSelector = 2,
CPTabViewWillSelectTabViewItemSelector = 4,
CPTabViewDidChangeNumberOfTabViewItemsSelector = 8;
@class _CPTabViewBox
@class _CPSegmentedControl
var CPTabViewDidSelectTabViewItemSelector = 1 << 1,
CPTabViewShouldSelectTabViewItemSelector = 1 << 2,
CPTabViewWillSelectTabViewItemSelector = 1 << 3,
CPTabViewDidChangeNumberOfTabViewItemsSelector = 1 << 4;
@protocol CPTabViewDelegate <CPObject>
@optional
- (BOOL)tabView:(CPTabView)tabView shouldSelectTabViewItem:(CPTabViewItem)tabViewItem;
- (void)tabView:(CPTabView)tabView didSelectTabViewItem:(CPTabViewItem)tabViewItem;
- (void)tabView:(CPTabView)tabView willSelectTabViewItem:(CPTabViewItem)tabViewItem;
- (void)tabViewDidChangeNumberOfTabViewItems:(CPTabView)tabView;
@end
/*!
@ingroup appkit
@@ -48,27 +64,27 @@ var CPTabViewDidSelectTabViewItemSelector = 1,
*/
@implementation CPTabView : CPView
{
CPArray _items;
CPArray _items;
CPSegmentedControl _tabs;
CPBox _box;
_CPSegmentedControl _tabs;
_CPTabViewBox _box;
CPView _placeholderView @accessors;
CPNumber _selectedIndex;
CPTabViewItem _selectedTabViewItem;
CPTabViewType _type;
CPFont _font;
CPTabViewType _type;
CPFont _font;
id _delegate;
unsigned _delegateSelectors;
id <CPTabViewDelegate> _delegate;
unsigned _delegateSelectors;
}
- (id)initWithFrame:(CGRect)aFrame
{
if (self = [super initWithFrame:aFrame])
{
_items = [CPArray array];
[self _init];
_selectedTabViewItem = nil;
[self setTabViewType:CPTopTabsBezelBorder];
}
@@ -77,19 +93,26 @@ var CPTabViewDidSelectTabViewItemSelector = 1,
- (void)_init
{
_selectedIndex = CPNotFound;
_tabs = [[_CPSegmentedControl alloc] initWithFrame:CGRectMakeZero()];
[_tabs setTabView:self];
[_tabs setSegments:[CPArray array]];
_tabs = [[CPSegmentedControl alloc] initWithFrame:_CGRectMake(0, 0, 0, 0)];
[_tabs setHitTests:NO];
var height = [_tabs valueForThemeAttribute:@"min-size"].height;
[_tabs setFrameSize:CGSizeMake(0, height)];
var height = [_tabs valueForThemeAttribute:@"default-height"];
[_tabs setFrameSize:_CGSizeMake(0, height)];
_box = [[CPBox alloc] initWithFrame:[self bounds]];
_box = [[_CPTabViewBox alloc] initWithFrame:[self bounds]];
[_box setTabView:self];
[self setBackgroundColor:[CPColor colorWithCalibratedWhite:0.95 alpha:1.0]];
[self addSubview:_box];
[self addSubview:_tabs];
_placeholderView = nil;
}
- (CPArray)items
{
return [_tabs segments];
}
// Adding and Removing Tabs
@@ -99,7 +122,7 @@ var CPTabViewDidSelectTabViewItemSelector = 1,
*/
- (void)addTabViewItem:(CPTabViewItem)aTabViewItem
{
[self insertTabViewItem:aTabViewItem atIndex:[_items count]];
[self insertTabViewItem:aTabViewItem atIndex:[self numberOfTabViewItems]];
}
/*!
@@ -107,17 +130,26 @@ var CPTabViewDidSelectTabViewItemSelector = 1,
@param aTabViewItem the item to insert
@param anIndex the index for the item
*/
- (void)insertTabViewItem:(CPTabViewItem)aTabViewItem atIndex:(unsigned)anIndex
- (void)insertTabViewItem:(CPTabViewItem)aTabViewItem atIndex:(CPUInteger)anIndex
{
[_items insertObject:aTabViewItem atIndex:anIndex];
[self _insertTabViewItems:[aTabViewItem] atIndexes:[CPIndexSet indexSetWithIndex:anIndex]];
}
[self _updateItems];
[self _repositionTabs];
- (void)_insertTabViewItems:(CPArray)tabViewItems atIndexes:(CPIndexSet)indexes
{
var prevItemsCount = [self numberOfTabViewItems];
[aTabViewItem _setTabView:self];
[_tabs insertSegments:tabViewItems atIndexes:indexes];
[tabViewItems makeObjectsPerformSelector:@selector(_setTabView:) withObject:self];
if (_delegateSelectors & CPTabViewDidChangeNumberOfTabViewItemsSelector)
[_delegate tabViewDidChangeNumberOfTabViewItems:self];
[self tileWithChangedItem:[tabViewItems firstObject]];
[self _reverseSetContent];
[self _sendDelegateTabViewDidChangeNumberOfTabViewItems];
// Do not allow empty selection if selection bindings are not enabled.
if (prevItemsCount == 0 && [self numberOfTabViewItems] > 0 && ![self _isSelectionBinded])
[self _selectTabViewItemAtIndex:0];
}
/*!
@@ -126,23 +158,39 @@ var CPTabViewDidSelectTabViewItemSelector = 1,
*/
- (void)removeTabViewItem:(CPTabViewItem)aTabViewItem
{
var count = [_items count];
for (var i = 0; i < count; i++)
{
if ([_items objectAtIndex:i] === aTabViewItem)
{
[_items removeObjectAtIndex:i];
break;
}
}
var idx = [[self items] indexOfObjectIdenticalTo:aTabViewItem];
[self _updateItems];
[self _repositionTabs];
if (idx == CPNotFound)
return;
[_tabs removeSegmentsAtIndexes:[CPIndexSet indexSetWithIndex:idx]];
[aTabViewItem _setTabView:nil];
if (_delegateSelectors & CPTabViewDidChangeNumberOfTabViewItemsSelector)
[_delegate tabViewDidChangeNumberOfTabViewItems:self];
[self tileWithChangedItem:nil];
[self _didRemoveTabViewItem:aTabViewItem atIndex:idx];
[self _reverseSetContent];
[self _sendDelegateTabViewDidChangeNumberOfTabViewItems];
}
- (void)_didRemoveTabViewItem:(CPTabViewItem)aTabViewItem atIndex:(CPInteger)idx
{
// If the selection is managed by bindings, let the binder do that.
if ([self _isSelectionBinded])
return;
if (_selectedTabViewItem == aTabViewItem)
{
var didSelect = NO;
if (idx > 0)
didSelect = [self selectTabViewItemAtIndex:idx - 1];
else if ([self numberOfTabViewItems] > 0)
didSelect = [self selectTabViewItemAtIndex:0];
if (didSelect == NO)
_selectedTabViewItem == nil;
}
}
// Accessing Tabs
@@ -153,7 +201,7 @@ var CPTabViewDidSelectTabViewItemSelector = 1,
*/
- (int)indexOfTabViewItem:(CPTabViewItem)aTabViewItem
{
return [_items indexOfObjectIdenticalTo:aTabViewItem];
return [[self items] indexOfObjectIdenticalTo:aTabViewItem];
}
/*!
@@ -163,11 +211,10 @@ var CPTabViewDidSelectTabViewItemSelector = 1,
*/
- (int)indexOfTabViewItemWithIdentifier:(CPString)anIdentifier
{
for (var index = [_items count]; index >= 0; index--)
if ([[_items[index] identifier] isEqual:anIdentifier])
return index;
return CPNotFound;
return [[self items] indexOfObjectPassingTest:function(item, idx, stop)
{
return [[item identifier] isEqual:anIdentifier];
}];
}
/*!
@@ -176,16 +223,16 @@ var CPTabViewDidSelectTabViewItemSelector = 1,
*/
- (unsigned)numberOfTabViewItems
{
return [_items count];
return [[self items] count];
}
/*!
Returns the CPTabViewItem at the specified index.
@return a tab view item, or nil
*/
- (CPTabViewItem)tabViewItemAtIndex:(unsigned)anIndex
- (CPTabViewItem)tabViewItemAtIndex:(CPUInteger)anIndex
{
return [_items objectAtIndex:anIndex];
return [[self items] objectAtIndex:anIndex];
}
/*!
@@ -194,7 +241,7 @@ var CPTabViewDidSelectTabViewItemSelector = 1,
*/
- (CPArray)tabViewItems
{
return [_items copy]; // Copy?
return [[self items] copy]; // Copy?
}
// Selecting a Tab
@@ -204,7 +251,7 @@ var CPTabViewDidSelectTabViewItemSelector = 1,
*/
- (void)selectFirstTabViewItem:(id)aSender
{
if ([_items count] === 0)
if ([self numberOfTabViewItems] === 0)
return; // throw?
[self selectTabViewItemAtIndex:0];
@@ -216,10 +263,10 @@ var CPTabViewDidSelectTabViewItemSelector = 1,
*/
- (void)selectLastTabViewItem:(id)aSender
{
if ([_items count] === 0)
if ([self numberOfTabViewItems] === 0)
return; // throw?
[self selectTabViewItemAtIndex:[_items count] - 1];
[self selectTabViewItemAtIndex:[self numberOfTabViewItems] - 1];
}
/*!
@@ -228,12 +275,12 @@ var CPTabViewDidSelectTabViewItemSelector = 1,
*/
- (void)selectNextTabViewItem:(id)aSender
{
if (_selectedIndex === CPNotFound)
if (_selectedTabViewItem === nil)
return;
var nextIndex = _selectedIndex + 1;
var nextIndex = [self indexOfTabViewItem:_selectedTabViewItem] + 1;
if (nextIndex === [_items count])
if (nextIndex === [self numberOfTabViewItems])
// does nothing. According to spec at (http://developer.apple.com/mac/library/DOCUMENTATION/Cocoa/Reference/ApplicationKit/Classes/NSTabView_Class/Reference/Reference.html#//apple_ref/occ/instm/NSTabView/selectNextTabViewItem:)
return;
@@ -246,10 +293,10 @@ var CPTabViewDidSelectTabViewItemSelector = 1,
*/
- (void)selectPreviousTabViewItem:(id)aSender
{
if (_selectedIndex === CPNotFound)
if (_selectedTabViewItem === nil)
return;
var previousIndex = _selectedIndex - 1;
var previousIndex = [self indexOfTabViewItem:_selectedTabViewItem] - 1;
if (previousIndex < 0)
return; // does nothing. See above.
@@ -270,38 +317,72 @@ var CPTabViewDidSelectTabViewItemSelector = 1,
Selects the item at the specified index.
@param anIndex the index of the item to display.
*/
- (BOOL)selectTabViewItemAtIndex:(unsigned)anIndex
- (BOOL)selectTabViewItemAtIndex:(CPUInteger)anIndex
{
if (anIndex === _selectedIndex)
return;
var aTabViewItem = [self tabViewItemAtIndex:anIndex];
if ((_delegateSelectors & CPTabViewShouldSelectTabViewItemSelector) && ![_delegate tabView:self shouldSelectTabViewItem:aTabViewItem])
if (![self _selectTabViewItemAtIndex:anIndex])
return NO;
if (_delegateSelectors & CPTabViewWillSelectTabViewItemSelector)
[_delegate tabView:self willSelectTabViewItem:aTabViewItem];
[_tabs selectSegmentWithTag:anIndex];
[self _setSelectedIndex:anIndex];
if (_delegateSelectors & CPTabViewDidSelectTabViewItemSelector)
[_delegate tabView:self didSelectTabViewItem:aTabViewItem];
[self _reverseSetSelectedIndex];
return YES;
}
// Like selectTabViewItemAtIndex: but without bindings interaction
- (BOOL)_selectTabViewItemAtIndex:(CPUInteger)anIndex
{
var aTabViewItem = [self tabViewItemAtIndex:anIndex];
if (aTabViewItem == _selectedTabViewItem)
return NO;
if (![self _sendDelegateShouldSelectTabViewItem:aTabViewItem])
return NO;
[self _sendDelegateWillSelectTabViewItem:aTabViewItem];
[_tabs setSelectedSegment:anIndex];
_selectedTabViewItem = aTabViewItem;
[self _loadTabViewItem:aTabViewItem];
[self _sendDelegateDidSelectTabViewItem:aTabViewItem];
return YES;
}
- (void)_loadTabViewItem:(CPTabViewItem)aTabViewItem
{
var controller = [aTabViewItem viewController];
if (controller !== nil && ![controller isViewLoaded])
{
[controller loadViewWithCompletionHandler:function(view, error)
{
if (error !== nil)
{
CPLog.warn("Could not load the view for item " + aTabViewItem + ". " + error);
}
else if (view !== nil)
{
[aTabViewItem setView:view];
if ([self selectedTabViewItem] == aTabViewItem)
[self _displayItemView:view];
}
}];
}
else
{
[self _displayItemView:[aTabViewItem view]];
}
}
/*!
Returns the current item being displayed.
@return the tab view item currenly being displayed by the receiver
*/
- (CPTabViewItem)selectedTabViewItem
{
if (_selectedIndex != CPNotFound)
return [_items objectAtIndex:_selectedIndex];
return nil;
return _selectedTabViewItem;
}
// Modifying the font
@@ -362,6 +443,14 @@ var CPTabViewDidSelectTabViewItemSelector = 1,
[self setNeedsLayout];
}
- (void)tileWithChangedItem:(CPTabViewItem)aTabViewItem
{
var segment = aTabViewItem ? [self indexOfTabViewItem:aTabViewItem] : 0;
[_tabs tileWithChangedSegment:segment];
[self setNeedsLayout];
}
- (void)layoutSubviews
{
// Even if CPTabView's autoresizesSubviews is NO, _tabs and _box has to be laid out.
@@ -373,11 +462,11 @@ var CPTabViewDidSelectTabViewItemSelector = 1,
else
{
var aFrame = [self frame],
segmentedHeight = _CGRectGetHeight([_tabs frame]),
segmentedHeight = CGRectGetHeight([_tabs frame]),
origin = _type === CPTopTabsBezelBorder ? segmentedHeight / 2 : 0;
[_box setFrame:_CGRectMake(0, origin, _CGRectGetWidth(aFrame),
_CGRectGetHeight(aFrame) - segmentedHeight / 2)];
[_box setFrame:CGRectMake(0, origin, CGRectGetWidth(aFrame),
CGRectGetHeight(aFrame) - segmentedHeight / 2)];
[self _repositionTabs];
}
@@ -405,7 +494,7 @@ var CPTabViewDidSelectTabViewItemSelector = 1,
Sets the delegate for this tab view.
@param aDelegate the tab view's delegate
*/
- (void)setDelegate:(id)aDelegate
- (void)setDelegate:(id <CPTabViewDelegate>)aDelegate
{
if (_delegate == aDelegate)
return;
@@ -437,49 +526,254 @@ var CPTabViewDidSelectTabViewItemSelector = 1,
return [_box backgroundColor];
}
- (void)mouseDown:(CPEvent)anEvent
{
var segmentIndex = [_tabs testSegment:[_tabs convertPoint:[anEvent locationInWindow] fromView:nil]];
if (segmentIndex != CPNotFound && [self selectTabViewItemAtIndex:segmentIndex])
[_tabs trackSegment:anEvent];
}
- (void)_repositionTabs
{
var horizontalCenterOfSelf = _CGRectGetWidth([self bounds]) / 2,
verticalCenterOfTabs = _CGRectGetHeight([_tabs bounds]) / 2;
var horizontalCenterOfSelf = CGRectGetWidth([self bounds]) / 2,
verticalCenterOfTabs = CGRectGetHeight([_tabs bounds]) / 2;
if (_type === CPBottomTabsBezelBorder)
[_tabs setCenter:_CGPointMake(horizontalCenterOfSelf, _CGRectGetHeight([self bounds]) - verticalCenterOfTabs)];
[_tabs setCenter:CGPointMake(horizontalCenterOfSelf, CGRectGetHeight([self bounds]) - verticalCenterOfTabs)];
else
[_tabs setCenter:_CGPointMake(horizontalCenterOfSelf, verticalCenterOfTabs)];
[_tabs setCenter:CGPointMake(horizontalCenterOfSelf, verticalCenterOfTabs)];
}
- (void)_setSelectedIndex:(CPNumber)index
- (void)_displayItemView:(CPView)aView
{
_selectedIndex = index;
[self _setContentViewFromItem:[_items objectAtIndex:_selectedIndex]];
[_box setContentView:aView];
}
- (void)_setContentViewFromItem:(CPTabViewItem)anItem
// DELEGATE METHODS
- (BOOL)_sendDelegateShouldSelectTabViewItem:(CPTabViewItem)aTabViewItem
{
[_box setContentView:[anItem view]];
if (_delegateSelectors & CPTabViewShouldSelectTabViewItemSelector)
return [_delegate tabView:self shouldSelectTabViewItem:aTabViewItem];
return YES;
}
- (void)_updateItems
- (void)_sendDelegateWillSelectTabViewItem:(CPTabViewItem)aTabViewItem
{
var count = [_items count];
[_tabs setSegmentCount:count];
if (_delegateSelectors & CPTabViewWillSelectTabViewItemSelector)
[_delegate tabView:self willSelectTabViewItem:aTabViewItem];
}
for (var i = 0; i < count; i++)
- (void)_sendDelegateDidSelectTabViewItem:(CPTabViewItem)aTabViewItem
{
if (_delegateSelectors & CPTabViewDidSelectTabViewItemSelector)
[_delegate tabView:self didSelectTabViewItem:aTabViewItem];
}
- (void)_sendDelegateTabViewDidChangeNumberOfTabViewItems
{
if (_delegateSelectors & CPTabViewDidChangeNumberOfTabViewItemsSelector)
[_delegate tabViewDidChangeNumberOfTabViewItems:self];
}
@end
@implementation CPTabView (BindingSupport)
+ (Class)_binderClassForBinding:(CPString)aBinding
{
if (aBinding == CPContentBinding)
return [_CPTabViewContentBinder class];
else if (aBinding == CPSelectionIndexesBinding || aBinding == CPSelectedIndexBinding)
return [_CPTabViewSelectionBinder class];
return [super _binderClassForBinding:aBinding];
}
+ (BOOL)isBindingExclusive:(CPString)aBinding
{
return (aBinding == CPSelectionIndexesBinding || aBinding == CPSelectedIndexBinding);
}
- (void)_reverseSetContent
{
var theBinder = [self binderForBinding:CPContentBinding];
[theBinder reverseSetValueFor:@"items"];
}
- (void)_reverseSetSelectedIndex
{
var theBinder = [self binderForBinding:CPSelectionIndexesBinding];
if (theBinder !== nil)
[theBinder reverseSetValueFor:@"selectionIndexes"];
else
{
[_tabs setLabel:[[_items objectAtIndex:i] label] forSegment:i];
[_tabs setTag:i forSegment:i];
theBinder = [self binderForBinding:CPSelectedIndexBinding];
[theBinder reverseSetValueFor:@"selectedIndex"];
}
}
- (CPBinder)binderForBinding:(CPString)aBinding
{
var cls = [[self class] _binderClassForBinding:aBinding];
return [cls getBinding:aBinding forObject:self];
}
- (BOOL)_isSelectionBinded
{
return [self binderForBinding:CPSelectionIndexesBinding] || [self binderForBinding:CPSelectedIndexBinding];
}
- (void)setItems:(CPArray)tabViewItems
{
if ([tabViewItems isEqualToArray:[_tabs segments]])
return;
[[self items] makeObjectsPerformSelector:@selector(_setTabView:) withObject:nil];
[_tabs setSegments:tabViewItems];
[tabViewItems makeObjectsPerformSelector:@selector(_setTabView:) withObject:self];
[self tileWithChangedItem:nil];
// Update the selection because setSegments: did remove all previous segments AND the selection.
[_tabs setSelectedSegment:[self indexOfTabViewItem:_selectedTabViewItem]];
// should we send delegate methods in bindings mode ?
//[self _delegateTabViewDidChangeNumberOfTabViewItems:self];
}
- (void)_deselectAll
{
[_tabs setSelectedSegment:-1];
_selectedTabViewItem = nil;
}
- (void)_displayPlaceholder:(CPString)aPlaceholder
{
if (_placeholderView == nil)
{
_placeholderView = [[CPView alloc] initWithFrame:CGRectMakeZero()];
var textField = [[CPTextField alloc] initWithFrame:CGRectMakeZero()];
[textField setTag:1000];
[textField setTextColor:[CPColor whiteColor]];
[textField setFont:[CPFont boldFontWithName:@"Geneva" size:18 italic:YES]];
[_placeholderView addSubview:textField];
}
if (_selectedIndex === CPNotFound)
[self selectFirstTabViewItem:self];
var textField = [_placeholderView viewWithTag:1000];
[textField setStringValue:aPlaceholder];
[textField sizeToFit];
var boxBounds = [_box bounds],
textFieldBounds = [textField bounds],
origin = CGPointMake(CGRectGetWidth(boxBounds)/2 - CGRectGetWidth(textFieldBounds)/2, CGRectGetHeight(boxBounds)/2 - CGRectGetHeight(textFieldBounds));
[textField setFrameOrigin:origin];
[self _displayItemView:_placeholderView];
}
#pragma mark -
#pragma mark Override
/*!
Enabled controls accept first mouse by default.
*/
- (BOOL)acceptsFirstMouse:(CPEvent)anEvent
{
return YES;
}
@end
var _CPTabViewContentBinderNull = @"NO CONTENT";
@implementation _CPTabViewContentBinder : CPBinder
{
}
- (void)_updatePlaceholdersWithOptions:(CPDictionary)options
{
[super _updatePlaceholdersWithOptions:options];
[self _setPlaceholder:_CPTabViewContentBinderNull forMarker:CPNullMarker isDefault:YES];
}
- (void)setPlaceholderValue:(id)aValue withMarker:(CPString)aMarker forBinding:(CPString)aBinding
{
[_source setItems:@[]];
[_source _setPlaceholderView:aValue];
}
- (void)setValue:(id)aValue forBinding:(CPString)aBinding
{
[_source setItems:aValue];
}
- (id)valueForBinding:(CPString)aBinding
{
return [_source items];
}
@end
var _CPTabViewSelectionBinderMultipleValues = @"Multiple Selection",
_CPTabViewSelectionBinderNoSelection = @"No Selection";
@implementation _CPTabViewSelectionBinder : CPBinder
{
}
- (void)_updatePlaceholdersWithOptions:(CPDictionary)options
{
[super _updatePlaceholdersWithOptions:options];
[self _setPlaceholder:_CPTabViewSelectionBinderMultipleValues forMarker:CPMultipleValuesMarker isDefault:YES];
[self _setPlaceholder:_CPTabViewSelectionBinderNoSelection forMarker:CPNoSelectionMarker isDefault:YES];
}
- (void)setPlaceholderValue:(id)aValue withMarker:(CPString)aMarker forBinding:(CPString)aBinding
{
if (aMarker == CPNoSelectionMarker || aMarker == CPNullMarker)
[_source _deselectAll];
[_source _displayPlaceholder:aValue];
}
- (void)setValue:(id)aValue forBinding:(CPString)aBinding
{
if (aBinding == CPSelectionIndexesBinding)
{
if (aValue == nil || [aValue count] == 0)
{
[_source _deselectAll];
[_source _displayPlaceholder:_CPTabViewSelectionBinderNoSelection];
}
else if ([aValue count] > 1)
[_source _displayPlaceholder:_CPTabViewSelectionBinderMultipleValues];
else if ([aValue firstIndex] < [_source numberOfTabViewItems])
[_source _selectTabViewItemAtIndex:[aValue firstIndex]];
}
else if (aBinding == CPSelectedIndexBinding)
{
if (aValue == CPNotFound)
{
[_source _deselectAll];
[_source _displayPlaceholder:_CPTabViewSelectionBinderNoSelection];
}
else if (aValue < [_source numberOfTabViewItems])
[_source _selectTabViewItemAtIndex:aValue];
}
}
- (id)valueForBinding:(CPString)aBinding
{
if (aBinding == CPSelectionIndexesBinding)
{
var result = [CPIndexSet indexSet],
idx = [_source indexOfTabViewItem:[_source selectedTabViewItem]];
if (idx !== CPNotFound)
[result addIndex:idx];
return result;
}
else if (aBinding == CPSelectedIndexBinding)
return [_source indexOfTabViewItem:[_source selectedTabViewItem]];
}
@end
@@ -501,34 +795,60 @@ var CPTabViewItemsKey = "CPTabViewItemsKey",
_font = [aCoder decodeObjectForKey:CPTabViewFontKey];
[_tabs setFont:_font];
_items = [aCoder decodeObjectForKey:CPTabViewItemsKey];
[_items makeObjectsPerformSelector:@selector(_setTabView:) withObject:self];
[self _updateItems];
var items = [aCoder decodeObjectForKey:CPTabViewItemsKey] || [CPArray array];
[self _insertTabViewItems:items atIndexes:[CPIndexSet indexSetWithIndexesInRange:CPMakeRange(0, [items count])]];
[self setDelegate:[aCoder decodeObjectForKey:CPTabViewDelegateKey]];
var selected = [aCoder decodeObjectForKey:CPTabViewSelectedItemKey];
if (selected)
[self selectTabViewItem:selected];
_selectedTabViewItem = [aCoder decodeObjectForKey:CPTabViewSelectedItemKey];
[self setTabViewType:[aCoder decodeIntForKey:CPTabViewTypeKey]];
[self setNeedsLayout];
_type = [aCoder decodeIntForKey:CPTabViewTypeKey];
}
return self;
}
- (void)awakeFromCib
{
[super awakeFromCib];
// This cannot be run in initWithCoder because it might call selectTabViewItem:, which is
// not safe to call before the views of the tab views items are fully decoded.
if (_selectedTabViewItem)
{
var idx = [self indexOfTabViewItem:_selectedTabViewItem];
if (idx !== CPNotFound)
{
// Temporarily set the selected item to not selected.
// It allows the initial selection to be made correctly.
_selectedTabViewItem = nil;
[self selectTabViewItemAtIndex:idx];
}
}
var type = _type;
_type = nil;
[self setTabViewType:type];
[self setNeedsLayout];
}
- (void)encodeWithCoder:(CPCoder)aCoder
{
// Don't bother to encode the CPBox. We will recreate it on decode and its content view is already
// stored by the tab view item. Not encoding _box makes the resulting archive smaller and reduces
// the surface for decoding bugs (of which we've had many in tab view).
var subviews = [self subviews];
[_box removeFromSuperview];
[super encodeWithCoder:aCoder];
[self setSubviews:subviews];
[aCoder encodeObject:_items forKey:CPTabViewItemsKey];
var selected = [self selectedTabViewItem];
if (selected)
[aCoder encodeObject:selected forKey:CPTabViewSelectedItemKey];
[aCoder encodeConditionalObject:_selectedTabViewItem forKey:CPTabViewSelectedItemKey];
[aCoder encodeInt:_type forKey:CPTabViewTypeKey];
[aCoder encodeObject:_font forKey:CPTabViewFontKey];
@@ -537,3 +857,100 @@ var CPTabViewItemsKey = "CPTabViewItemsKey",
}
@end
@implementation _CPTabViewBox : CPBox
{
CPTabView _tabView @accessors(property=tabView);
}
#pragma mark -
#pragma mark Override
- (CPView)hitTest:(CGPoint)aPoint
{
// Here we check if we have clicked on the segmentedControl of the tabView or not
// If YES, the CPBox should not handle the click
var segmentIndex = [_tabView._tabs testSegment:[_tabView._tabs convertPoint:aPoint fromView:[self superview]]];
if (segmentIndex != CPNotFound)
return nil;
return [super hitTest:aPoint];
}
@end
# pragma mark -
// This subclass of CPSegmentedControl implements specific behaviour needed by CPTabView, which
// differs in some ways from normal CPSegmentedControl habits :
//
// - all items are enabled
// - when you select a tab (mouse down, holding) and drag upon another tab, the second one reacts
// (showing a pushed state) and can then be selected by releasing the mouse over it.
// - a delegate has the opportunity to accept or not the selection of an item
@implementation _CPSegmentedControl : CPSegmentedControl
{
CPTabView _tabView @accessors(property=tabView);
}
- (void)trackSegment:(CPEvent)anEvent
{
var type = [anEvent type],
location = [self convertPoint:[anEvent locationInWindow] fromView:nil],
currentSegment = [self testSegment:location];
switch (type)
{
case CPLeftMouseUp:
if (_trackingSegment === CPNotFound)
return;
if ((_trackingSegment !== _selectedSegment) &&
[_tabView _sendDelegateShouldSelectTabViewItem:[_tabView tabViewItemAtIndex:_trackingSegment]])
{
[self setSelected:YES forSegment:_trackingSegment];
_selectedSegment = _trackingSegment;
[_tabView selectTabViewItemAtIndex:_selectedSegment];
}
[self drawSegmentBezel:_trackingSegment highlight:NO];
_trackingSegment = CPNotFound;
return;
case CPLeftMouseDown:
if (currentSegment > CPNotFound)
{
_trackingSegment = currentSegment;
[self drawSegmentBezel:_trackingSegment highlight:YES];
}
break;
case CPLeftMouseDragged:
if (_trackingSegment !== currentSegment)
{
if (_trackingSegment > CPNotFound)
[self drawSegmentBezel:_trackingSegment highlight:NO];
_trackingSegment = currentSegment;
if (_trackingSegment > CPNotFound)
[self drawSegmentBezel:_trackingSegment highlight:YES];
}
break;
}
[CPApp setTarget:self selector:@selector(trackSegment:) forNextEventMatchingMask:CPLeftMouseDraggedMask | CPLeftMouseUpMask untilDate:nil inMode:nil dequeue:YES];
}
@end
+103 -9
View File
@@ -23,7 +23,8 @@
@import <Foundation/CPObject.j>
@import "CPView.j"
@class CPTabView
@class CPViewController
/*
The tab is currently selected.
@@ -53,13 +54,34 @@ CPPressedTab = 2;
*/
@implementation CPTabViewItem : CPObject
{
id _identifier;
CPString _label;
id _identifier;
CPString _label;
CPInteger _tag @accessors(property=tag);
CPView _view;
CPView _auxiliaryView;
CPView _view;
CPView _auxiliaryView;
CPTabView _tabView;
CPTabView _tabView;
unsigned _tabState; // Looks like it is not yet implemented
CPImage _image @accessors(property=image);
CPViewController _viewController @accessors(getter=viewController);
BOOL _enabled @accessors(property=enabled);
BOOL _selected @accessors(property=selected);
CGRect _tabRect @accessors(property=frame);
float _width @accessors(property=width);
}
/*
*/
+ (CPTabViewItem)tabViewItemWithViewController:(CPViewController)aViewController
{
var item = [[CPTabViewItem alloc] init];
[item setViewController:aViewController];
return item;
}
- (id)init
@@ -67,6 +89,19 @@ CPPressedTab = 2;
return [self initWithIdentifier:@""];
}
- (void)_init
{
_tag = 0;
_viewController = nil;
_image = nil;
_tabState = 0;
_tabView = nil;
_enabled = YES;
_selected = NO;
_tabRect = CGRectMakeZero();
_width = 0;
}
/*!
Initializes the tab view item with the specified identifier.
@return the initialized CPTabViewItem
@@ -75,8 +110,12 @@ CPPressedTab = 2;
{
self = [super init];
if (self)
_identifier = anIdentifier;
[self _init];
_identifier = anIdentifier;
_label = nil;
_view = nil;
//_auxiliaryView = nil;
return self;
}
@@ -88,7 +127,11 @@ CPPressedTab = 2;
*/
- (void)setLabel:(CPString)aLabel
{
if ([aLabel isEqualToString:_label])
return;
_label = aLabel;
[_tabView tileWithChangedItem:self];
}
/*!
@@ -99,6 +142,28 @@ CPPressedTab = 2;
return _label;
}
// Working With Images
/*!
Sets the CPTabViewItem's image.
@param anImage the image for the item
*/
- (void)setImage:(CPImage)anImage
{
if ([anImage isEqual:_image])
return;
_image = anImage;
[_tabView tileWithChangedItem:self];
}
/*!
Returns the CPTabViewItem's image
*/
- (CPImage)image
{
return _image;
}
// Checking the Tab Display State
/*!
Returns the tab's current state.
@@ -138,7 +203,7 @@ CPPressedTab = 2;
_view = aView;
if ([_tabView selectedTabViewItem] == self)
[_tabView _setContentViewFromItem:self];
[_tabView _displayItemView:_view];
}
/*!
@@ -146,6 +211,9 @@ CPPressedTab = 2;
*/
- (CPView)view
{
if (!_view && _viewController)
return [_viewController view]; // The view controller loads here.
return _view;
}
@@ -184,10 +252,32 @@ CPPressedTab = 2;
_tabView = aView;
}
/*!
Sets the specified view controller for the tab view item.
@param aViewController an instance of CPViewController.
*/
- (void)setViewController:(CPViewController)aViewController
{
_viewController = aViewController;
var identifier = [aViewController cibName],
title = [_viewController title];
if (identifier)
_identifier = identifier;
if (title)
[self setLabel:title];
if ([_tabView selectedTabViewItem] == self)
[_tabView _loadTabViewItem:self];
}
@end
var CPTabViewItemIdentifierKey = "CPTabViewItemIdentifierKey",
CPTabViewItemLabelKey = "CPTabViewItemLabelKey",
CPTabViewItemImageKey = "CPTabViewItemImageKey",
CPTabViewItemViewKey = "CPTabViewItemViewKey",
CPTabViewItemAuxViewKey = "CPTabViewItemAuxViewKey";
@@ -200,8 +290,11 @@ var CPTabViewItemIdentifierKey = "CPTabViewItemIdentifierKey",
if (self)
{
[self _init];
_identifier = [aCoder decodeObjectForKey:CPTabViewItemIdentifierKey];
_label = [aCoder decodeObjectForKey:CPTabViewItemLabelKey];
_image = [aCoder decodeObjectForKey:CPTabViewItemImageKey];
_view = [aCoder decodeObjectForKey:CPTabViewItemViewKey];
_auxiliaryView = [aCoder decodeObjectForKey:CPTabViewItemAuxViewKey];
@@ -214,6 +307,7 @@ var CPTabViewItemIdentifierKey = "CPTabViewItemIdentifierKey",
{
[aCoder encodeObject:_identifier forKey:CPTabViewItemIdentifierKey];
[aCoder encodeObject:_label forKey:CPTabViewItemLabelKey];
[aCoder encodeObject:_image forKey:CPTabViewItemImageKey];
[aCoder encodeObject:_view forKey:CPTabViewItemViewKey];
[aCoder encodeObject:_auxiliaryView forKey:CPTabViewItemAuxViewKey];
+39 -43
View File
@@ -26,8 +26,10 @@
@import <Foundation/CPSortDescriptor.j>
@import <Foundation/CPString.j>
@import "CPTableHeaderView.j"
@import "CPTextField.j"
@class _CPTableColumnHeaderView
@class CPTableView
CPTableColumnNoResizing = 0;
CPTableColumnAutoresizingMask = 1 << 0;
@@ -49,7 +51,7 @@ CPTableColumnUserResizingMask = 1 << 1;
CPTableView _tableView;
CPView _headerView;
CPView _dataView;
Object _dataViewData;
CPData _dataViewData;
float _width;
float _minWidth;
@@ -83,7 +85,7 @@ CPTableColumnUserResizingMask = 1 << 1;
if (self)
{
_dataViewData = { };
_dataViewData = nil;
_width = 100.0;
_minWidth = 10.0;
@@ -178,11 +180,11 @@ CPTableColumnUserResizingMask = 1 << 1;
columns = [CPIndexSet indexSetWithIndexesInRange:CPMakeRange(index, [tableView._exposedColumns lastIndex] - index + 1)];
// FIXME: Would be faster with some sort of -setNeedsDisplayInColumns: that updates a dirtyTableColumnForDisplay cache; then marked columns would relayout their data views at display time.
[tableView _layoutDataViewsInRows:rows columns:columns];
[tableView _layoutViewsForRowIndexes:rows columnIndexes:columns];
[tableView tile];
if (!_disableResizingPosting)
[self _postDidResizeNotificationWithOldWidth:oldWidth];
[[self tableView] _didResizeTableColumn:self oldWidth:oldWidth];
}
}
@@ -280,12 +282,12 @@ CPTableColumnUserResizingMask = 1 << 1;
*/
- (void)sizeToFit
{
var width = _CGRectGetWidth([_headerView frame]);
var width = CGRectGetWidth([_headerView frame]);
if (width < [self minWidth])
[self setMinWidth:width];
else if (width > [self maxWidth])
[self setMaxWidth:width]
[self setMaxWidth:width];
if (_width !== width)
[self setWidth:width];
@@ -391,13 +393,13 @@ CPTableColumnUserResizingMask = 1 << 1;
*/
- (void)setDataView:(CPView)aView
{
if (_dataView)
_dataViewData[[_dataView UID]] = nil;
if (_dataView === aView)
return;
[aView setThemeState:CPThemeStateTableDataView];
_dataView = aView;
_dataViewData[[aView UID]] = [CPKeyedArchiver archivedDataWithRootObject:aView];
_dataViewData = [CPKeyedArchiver archivedDataWithRootObject:aView];
}
- (CPView)dataView
@@ -413,7 +415,7 @@ CPTableColumnUserResizingMask = 1 << 1;
to be invoked with row equal to -1 in cases where no actual row is involved but the table
view needs to get some generic cell info.
*/
- (id)dataViewForRow:(int)aRowIndex
- (id)dataViewForRow:(CPInteger)aRowIndex
{
return [self dataView];
}
@@ -421,24 +423,12 @@ CPTableColumnUserResizingMask = 1 << 1;
/*!
@ignore
*/
- (id)_newDataViewForRow:(int)aRowIndex
- (id)_newDataView
{
var dataView = [self dataViewForRow:aRowIndex],
dataViewUID = [dataView UID];
if (!_dataViewData)
return nil;
var x = [self tableView]._cachedDataViews[dataViewUID];
if (x && x.length)
return x.pop();
// if we haven't cached an archive of the data view, do it now
if (!_dataViewData[dataViewUID])
_dataViewData[dataViewUID] = [CPKeyedArchiver archivedDataWithRootObject:dataView];
// unarchive the data view cache
var newDataView = [CPKeyedUnarchiver unarchiveObjectWithData:_dataViewData[dataViewUID]];
newDataView.identifier = dataViewUID;
// make sure only we have control over the size and placement
var newDataView = [CPKeyedUnarchiver unarchiveObjectWithData:_dataViewData];
[newDataView setAutoresizingMask:CPViewNotSizable];
return newDataView;
@@ -509,7 +499,7 @@ CPTableColumnUserResizingMask = 1 << 1;
*/
- (void)setHidden:(BOOL)shouldBeHidden
{
shouldBeHidden = !!shouldBeHidden
shouldBeHidden = !!shouldBeHidden;
if (_isHidden === shouldBeHidden)
return;
@@ -550,14 +540,9 @@ CPTableColumnUserResizingMask = 1 << 1;
/*!
@ignore
*/
- (void)_postDidResizeNotificationWithOldWidth:(float)oldWidth
- (CPString)description
{
[[self tableView] _didResizeTableColumn:self];
[[CPNotificationCenter defaultCenter]
postNotificationName:CPTableViewColumnDidResizeNotification
object:[self tableView]
userInfo:[CPDictionary dictionaryWithObjects:[self, oldWidth] forKeys:[@"CPTableColumn", "CPOldWidth"]]];
return [CPString stringWithFormat:"<%@ 0x%@ identifier=%@>", [self className], [CPString stringWithHash:[self UID]], [self identifier]];
}
@end
@@ -569,11 +554,22 @@ CPTableColumnUserResizingMask = 1 << 1;
- (void)setValueFor:(CPString)aBinding
{
var tableView = [_source tableView],
column = [[tableView tableColumns] indexOfObjectIdenticalTo:_source],
rowIndexes = [CPIndexSet indexSetWithIndexesInRange:CPMakeRange(0, [tableView numberOfRows])],
columnIndexes = [CPIndexSet indexSetWithIndex:column];
newNumberOfRows = [tableView _numberOfRows];
[tableView reloadDataForRowIndexes:rowIndexes columnIndexes:columnIndexes];
if ([tableView numberOfRows] == newNumberOfRows)
{
var rowIndexes = [CPIndexSet indexSetWithIndexesInRange:CPMakeRange(0, newNumberOfRows)],
column = [[tableView tableColumns] indexOfObjectIdenticalTo:_source],
columnIndexes = [CPIndexSet indexSetWithIndex:column];
// Reloads objectValues only, not the views.
// FIXME: reload data for all rows or just rows intersecting exposed rows ?
[tableView _reloadDataForRowIndexes:rowIndexes columnIndexes:columnIndexes];
}
else
{
[tableView reloadData];
}
}
- (CPSortDescriptor)_defaultSortDescriptorPrototype
@@ -604,7 +600,7 @@ CPTableColumnUserResizingMask = 1 << 1;
@implementation CPTableColumn (Bindings)
+ (id)_binderClassForBinding:(CPString)aBinding
+ (Class)_binderClassForBinding:(CPString)aBinding
{
if (aBinding == CPValueBinding)
return [CPTableColumnValueBinder class];
@@ -613,7 +609,7 @@ CPTableColumnUserResizingMask = 1 << 1;
}
/*!
Binds the receiver to an object.
Binds the receiver to an object. Note that unlike Cocoa, this works only *after* the receiver has been added to a \c CPTableView.
@param CPString aBinding - The binding you wish to make. Typically CPValueBinding.
@param id anObject - The object to bind the receiver to.
@@ -754,7 +750,7 @@ var CPTableColumnIdentifierKey = @"CPTableColumnIdentifierKey",
if (self)
{
_dataViewData = { };
_dataViewData = nil;
_width = [aCoder decodeFloatForKey:CPTableColumnWidthKey];
_minWidth = [aCoder decodeFloatForKey:CPTableColumnMinWidthKey];
@@ -837,7 +833,7 @@ var CPTableColumnIdentifierKey = @"CPTableColumnIdentifierKey",
/*!
@ignore
*/
- (id)dataCellForRow:(int)row
- (id)dataCellForRow:(CPInteger)row
{
[CPException raise:CPUnsupportedMethodException
reason:@"dataCellForRow: is not supported. Use -dataViewForRow:row instead."];
+444 -356
View File
File diff suppressed because it is too large Load Diff
+2447 -1115
View File
File diff suppressed because it is too large Load Diff
+331
View File
@@ -5,6 +5,13 @@
* Created by Alexander Ljungberg.
* Copyright 2010, WireLoad, LLC.
*
* additions from
*
* Daniel Boehringer on 8/02/2014.
* Copyright Daniel Boehringer on 8/02/2014.
*
*
*
* 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,6 +27,30 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import <Foundation/Foundation.j>
@import "CPPasteboard.j"
@import "CPView.j"
@global CPStringPboardType
@global _CPSmartPboardType
@class CPAttributedString
@class _CPRTFParser
@protocol CPTextDelegate <CPObject>
@optional
- (BOOL)textShouldBeginEditing:(CPText)aTextObject;
- (BOOL)textShouldEndEditing:(CPText)aTextObject;
- (void)textDidBeginEditing:(CPNotification)aNotification;
- (void)textDidChange:(CPNotification)aNotification;
- (void)textDidEndEditing:(CPNotification)aNotification;
@end
CPParagraphSeparatorCharacter = 0x2029;
CPLineSeparatorCharacter = 0x2028;
CPEnterCharacter = "\u0003";
CPBackspaceCharacter = "\u0008";
CPTabCharacter = "\u0009";
@@ -28,3 +59,303 @@ CPFormFeedCharacter = "\u000c";
CPCarriageReturnCharacter = "\u000d";
CPBackTabCharacter = "\u0019";
CPDeleteCharacter = "\u007f";
@typedef CPTextMovement
CPIllegalTextMovement = 0;
CPOtherTextMovement = 0;
CPReturnTextMovement = 16;
CPTabTextMovement = 17;
CPBacktabTextMovement = 18;
CPLeftTextMovement = 19;
CPRightTextMovement = 20;
CPUpTextMovement = 21;
CPDownTextMovement = 22;
CPCancelTextMovement = 23;
@typedef CPWritingDirection
CPWritingDirectionNatural = -1;
CPWritingDirectionLeftToRight = 0;
CPWritingDirectionRightToLeft = 1;
@typedef CPTextAlignment
CPLeftTextAlignment = 0;
CPRightTextAlignment = 1;
CPCenterTextAlignment = 2;
CPJustifiedTextAlignment = 3;
CPNaturalTextAlignment = 4;
/*
CPText notifications
*/
CPTextDidBeginEditingNotification = @"CPTextDidBeginEditingNotification";
CPTextDidChangeNotification = @"CPTextDidChangeNotification";
CPTextDidEndEditingNotification = @"CPTextDidEndEditingNotification";
/*
CPTextView Notifications
*/
CPTextViewDidChangeSelectionNotification = @"CPTextViewDidChangeSelectionNotification";
CPTextViewDidChangeTypingAttributesNotification = @"CPTextViewDidChangeTypingAttributesNotification";
/*
FIXME: move these to CPAttributed string
Make use of attributed keys in AppKit
*/
CPFontAttributeName = @"CPFontAttributeName";
CPForegroundColorAttributeName = @"CPForegroundColorAttributeName";
CPBackgroundColorAttributeName = @"CPBackgroundColorAttributeName";
CPShadowAttributeName = @"CPShadowAttributeName";
CPUnderlineStyleAttributeName = @"CPUnderlineStyleAttributeName";
CPSuperscriptAttributeName = @"CPSuperscriptAttributeName";
CPBaselineOffsetAttributeName = @"CPBaselineOffsetAttributeName";
CPAttachmentAttributeName = @"CPAttachmentAttributeName";
CPLigatureAttributeName = @"CPLigatureAttributeName";
CPKernAttributeName = @"CPKernAttributeName";
@implementation CPText : CPView
{
BOOL _isEditable @accessors(getter=isEditable, setter=setEditable:);
BOOL _isSelectable @accessors(getter=isSelectable, setter=setSelectable:);
BOOL _isRichText @accessors(getter=isRichText, setter=setRichText:);
}
- (void)setSelectable:(BOOL)flag
{
[self willChangeValueForKey:@"selectable"];
_isSelectable = flag;
[self didChangeValueForKey:@"selectable"];
if (!flag)
[self setEditable:flag];
}
- (void)setEditable:(BOOL)flag
{
[self willChangeValueForKey:@"editable"];
_isEditable = flag;
[self didChangeValueForKey:@"editable"];
if (flag)
[self setSelectable:flag];
}
- (void)changeFont:(id)sender
{
_CPRaiseInvalidAbstractInvocation(self, _cmd);
}
- (void)copy:(id)sender
{
var selectedRange = [self selectedRange];
if (selectedRange.length < 1)
return;
var pasteboard = [CPPasteboard generalPasteboard];
// put plain representation on the pasteboad unconditionally
[pasteboard declareTypes:[CPStringPboardType] owner:nil];
[pasteboard setString:[[self stringValue] substringWithRange:selectedRange] forType:CPStringPboardType];
}
- (id)_plainStringForPasting
{
return [[CPPasteboard generalPasteboard] stringForType:CPStringPboardType];
}
- (id)_stringForPasting
{
var pasteboard = [CPPasteboard generalPasteboard],
dataForPasting = [pasteboard stringForType:CPRTFPboardType],
stringForPasting = [pasteboard stringForType:CPStringPboardType];
if (dataForPasting || [stringForPasting hasPrefix:"{\\rtf1\\ansi"])
stringForPasting = [[_CPRTFParser new] parseRTF:dataForPasting ? dataForPasting : stringForPasting];
if (![self isRichText] && [stringForPasting isKindOfClass:[CPAttributedString class]])
stringForPasting = stringForPasting._string;
return stringForPasting;
}
- (BOOL)_shouldUseSmartPasting
{
return parseInt([[CPPasteboard generalPasteboard] stringForType:_CPSmartPboardType], 10) > 0 || NO;
}
- (void)paste:(id)sender
{
var stringForPasting = [self _stringForPasting];
if (stringForPasting)
[self insertText:stringForPasting];
}
- (void)copyFont:(id)sender
{
_CPRaiseInvalidAbstractInvocation(self, _cmd);
}
- (void)delete:(id)sender
{
_CPRaiseInvalidAbstractInvocation(self, _cmd);
}
- (CPFont)font:(CPFont)aFont
{
_CPRaiseInvalidAbstractInvocation(self, _cmd);
return nil;
}
- (BOOL)isHorizontallyResizable
{
_CPRaiseInvalidAbstractInvocation(self, _cmd);
return NO;
}
- (BOOL)isRulerVisible
{
_CPRaiseInvalidAbstractInvocation(self, _cmd);
return NO;
}
- (BOOL)isVerticallyResizable
{
_CPRaiseInvalidAbstractInvocation(self, _cmd);
return NO;
}
- (CGSize)maxSize
{
_CPRaiseInvalidAbstractInvocation(self, _cmd);
return CGSizeMake(0,0);
}
- (CGSize)minSize
{
_CPRaiseInvalidAbstractInvocation(self, _cmd);
return CGSizeMake(0,0);
}
- (void)pasteFont:(id)sender
{
_CPRaiseInvalidAbstractInvocation(self, _cmd);
}
- (void)replaceCharactersInRange:(CPRange)aRange withString:(CPString)aString
{
_CPRaiseInvalidAbstractInvocation(self, _cmd);
}
- (void)scrollRangeToVisible:(CPRange)aRange
{
_CPRaiseInvalidAbstractInvocation(self, _cmd);
}
- (void)selectedAll:(id)sender
{
_CPRaiseInvalidAbstractInvocation(self, _cmd);
}
- (CPRange)selectedRange
{
_CPRaiseInvalidAbstractInvocation(self, _cmd);
return CPMakeRange(CPNotFound, 0);
}
- (void)setFont:(CPFont)aFont
{
_CPRaiseInvalidAbstractInvocation(self, _cmd);
}
- (void)setFont:(CPFont)aFont range:(CPRange)aRange
{
_CPRaiseInvalidAbstractInvocation(self, _cmd);
}
- (void)setHorizontallyResizable:(BOOL)flag
{
_CPRaiseInvalidAbstractInvocation(self, _cmd);
}
- (void)setMaxSize:(CGSize)aSize
{
_CPRaiseInvalidAbstractInvocation(self, _cmd);
}
- (void)setMinSize:(CGSize)aSize
{
_CPRaiseInvalidAbstractInvocation(self, _cmd);
}
- (void)setString:(CPString)aString
{
[self replaceCharactersInRange:CPMakeRange(0, [[self string] length]) withString:aString];
}
- (void)setUsesFontPanel:(BOOL)flag
{
_CPRaiseInvalidAbstractInvocation(self, _cmd);
}
- (void)setVerticallyResizable:(BOOL)flag
{
_CPRaiseInvalidAbstractInvocation(self, _cmd);
}
- (CPString)string
{
_CPRaiseInvalidAbstractInvocation(self, _cmd);
return nil;
}
- (void)underline:(id)sender
{
_CPRaiseInvalidAbstractInvocation(self, _cmd);
}
- (BOOL)usesFontPanel
{
_CPRaiseInvalidAbstractInvocation(self, _cmd);
return NO;
}
@end
var CPTextViewIsEditableKey = @"CPTextViewIsEditableKey",
CPTextViewIsSelectableKey = @"CPTextViewIsSelectableKey",
CPTextViewIsRichTextKey = @"CPTextViewIsRichTextKey";
@implementation CPText (CPCoding)
- (id)initWithCoder:(CPCoder)aCoder
{
self = [super initWithCoder:aCoder];
if (self)
{
[self setSelectable:[aCoder decodeBoolForKey:CPTextViewIsSelectableKey]];
[self setEditable:[aCoder decodeBoolForKey:CPTextViewIsEditableKey]];
[self setRichText:[aCoder decodeBoolForKey:CPTextViewIsRichTextKey]];
}
return self;
}
- (void)encodeWithCoder:(CPCoder)aCoder
{
[super encodeWithCoder:aCoder];
[aCoder encodeBool:_isEditable forKey:CPTextViewIsEditableKey];
[aCoder encodeBool:_isSelectable forKey:CPTextViewIsSelectableKey];
[aCoder encodeBool:_isRichText forKey:CPTextViewIsRichTextKey];
}
@end

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