Compare commits

...
338 Commits
Author SHA1 Message Date
Alexander Ljungberg 9744aa79b3 Fixed: doc generation crash due to bad UTF.
Not clear what's causing the problem, but the ± in CPDate.j get prefixed with some garbage bytes in the Doxygen output even that the input encoding looks fine.

The work-around for now is to just discard the bad bytes in the Python step. The output comes out correct (with the ± preserved).
2018-09-10 12:14:35 +01:00
Alexander Ljungberg 181fb9edb6 New: Dockerfile which helps test bootstrap itself. 2018-09-10 10:39:07 +01:00
Alexander Ljungberg 9ddbdfb80a Fixed: new rsync-base option always on.
Whether enabled or not, this new feature would try to rsync from the current folder.

Refs #2769.
2018-09-10 10:21:57 +01:00
Alexander Ljungberg 1cab88181d Fixed: XcodeCapp good build reporting failure.
After a recent change, a successful build of XcodeCapp actually resulted in the message "Unable to build  XcodeCapp."
2018-09-07 23:52:08 +01:00
Alexander Ljungberg 803cc6e402 New: bump XcodeCapp copyright year. 2018-09-07 23:49:20 +01:00
Alexander Ljungberg 2e0b9f5ea5 New: tweak flash view warning. 2018-09-07 23:16:31 +01:00
Alexander Ljungberg fe60311072 This is Cappuccino 1.0. 2018-09-06 18:38:52 +01:00
Alexander Ljungberg de4a1d1e93 Fixed: building the source link. 2018-09-03 14:54:48 +02:00
David RichardsonandMartin Carlberg de36a2f4d1 Fixed: Update XcodeCapp code and Jakefile to install properly and launch without crashing when built with Xcode 10/ macOSSDK10.14 (#2773)
Disable YRKSpinningProgressIndicator threaded animation (causing immediate crash on launch since Xcode 10 beta 6).
Simplify Jakefile build process to 'xcodebuild install' to avoid permissions problems when building (still requires sudo when using Cappuccino defaults).
Increment version number to 4.0.1 to reflect minor nature of change.
Update About window version number field to fully display and properly align longer version numbers.
2018-09-03 10:29:43 +02:00
David RichardsonandMartin Carlberg 57f6f3b318 New: Add --rsync-base option to bootstrap.sh (#2769)
Existing --copy-local option to use local cappuccino-base has following limitations which are cumbersome when updating bootstrap process
* local source must be a zip archive - which requires an extra step after making changes to source
* local zip archive is erased after install - which makes repetitive testing more difficult

This commit intended to allow testing of updates to cappuccino-base narwhal-jsc.
With macOS 10.14 and later, narwhal-jsc must use modern c++ standard library.
libedit must do the same, so the dependency reference to it is updated to version which is current at this time.
2018-08-31 14:51:20 +02:00
Didier KorthoudtandMartin Carlberg 8a3eb0d83b FIXED: This PR fixes a side effect of #2744 on table data views (#2767)
When a textField is used in a tableView, setValue forThemeAttribute
should refer to state CPThemeStateTableDataView instead of
CPThemeStateNormal as #2744 is now more accurate on states.
2018-08-31 09:14:54 +02:00
Didier KorthoudtandMartin Carlberg dd68b37a2a Fixed: CPButtonBar with actionPopupButton was outside the visible rect. Fixes #2770 (#2771) 2018-08-31 09:10:44 +02:00
cacaodev 96793b39ba Revert "Fixed: Define header-view-height attribute in ThemeDescriptors. (#2764)"
This reverts commit 9ad44e6dc2.
2018-08-30 16:02:48 +02:00
cacaodevandMartin Carlberg 9ad44e6dc2 Fixed: Define header-view-height attribute in ThemeDescriptors. (#2764)
This is a better solution for problem introduced by  #2758
2018-08-29 14:28:02 +02:00
Didier KorthoudtandMartin Carlberg 988b3d27b8 Fixed: allowFadingOut side effect introduced by #2718 (#2768) 2018-08-29 11:27:50 +02:00
Didier KorthoudtandMartin Carlberg c0ee5f6563 Fixed: Problem with nib2cib introduced by #2758 (#2763) 2018-08-22 09:41:37 +02:00
cacaodevandMartin Carlberg f02d0ab1dd STYLE: refactoring using CPCharacterSet (#2762) 2018-08-22 09:18:21 +02:00
Didier Korthoudtandcacaodev ff6d17990f FIXED: Before this PR, starting a column drag within a scrolled down table would scroll the table content to the bottom (#2753)
Before this commit, in the method [view convertPoint:aPoint toView:aView] : aPoint was not in the coordinate system of view.
2018-08-21 19:26:42 +02:00
Didier KorthoudtandMartin Carlberg 586c419c46 Fixed: Before this PR, Nib2Cib wasn't using theme attribute "header-view-height" (#2758) 2018-08-21 09:26:40 +02:00
Didier KorthoudtandMartin Carlberg 73f02cc1bf NEW: Add first responder management based on content view to CPScrollView (#2757) 2018-08-21 09:14:21 +02:00
Didier KorthoudtandMartin Carlberg eb27d24923 Fixed: CPTableView-visual-problem(#2755) 2018-08-21 09:08:16 +02:00
Didier KorthoudtandMartin Carlberg eeb056d509 Fixed: CPCursor-fix-and-update, some cursors were badly or not displayed (#2752) 2018-08-20 13:35:18 +02:00
Didier KorthoudtandMartin Carlberg 3615912ce0 Fixed: Before this PR, loading of a CPTabView from a CIB file could crash the app (#2686) 2018-08-20 13:30:02 +02:00
Didier KorthoudtandMartin Carlberg 4518dfc0ca FIXED: CPSearchField was positionning its menu with hard coded offset (#2691) 2018-08-20 13:12:22 +02:00
Didier KorthoudtandMartin Carlberg d5a7e8938d CPTrackingArea-manual-test-fix (#2759) 2018-08-20 13:01:52 +02:00
Didier KorthoudtandMartin Carlberg 3d15844f7c CPTableView-bad-selection-color (#2756) 2018-08-20 12:55:35 +02:00
Didier KorthoudtandMartin Carlberg 62ed21b316 Fixed: Before this PR, when dragging a partially masked column, the dragged view was truncated (#2754) 2018-08-20 12:54:17 +02:00
daboe01andMartin Carlberg a178d43b01 Fixed: return key was not swallowed by textview but triggered the default button. (#2598) 2018-08-20 12:52:53 +02:00
daboe01andMartin Carlberg ef2152beea FIXED: click to key window in the background did not bring it forward (take 2) (#2705) 2018-08-20 12:48:58 +02:00
daboe01andMartin Carlberg e6475c1a9e Fixed: setMinSize: had no effect in platform windows (#2609) 2018-08-20 12:47:29 +02:00
daboe01andMartin Carlberg 091debd2a7 Fixed: deviation from cocoa when calling setTitle:'' (#2607) 2018-08-20 11:40:00 +02:00
daboe01andMartin Carlberg e7eff3e585 Fixed: attached sheets were not put to front after calls to makeKeyAndOrderFront: in code (#2606) 2018-08-20 11:34:21 +02:00
daboe01andMartin Carlberg 86a90e39d2 Fixed: key equivalent takes precedence over event tracking which is not the case in cocoa (#2600) 2018-08-20 11:31:36 +02:00
Didier KorthoudtandMartin Carlberg 2887fbb251 Edge-browser-detection (#2751) 2018-08-20 11:29:28 +02:00
daboe01andMartin Carlberg fa6177b56d Fixed: touch scrolling events to scrollviews also scrolled the document body (#2750) 2018-08-20 11:05:13 +02:00
Alexandre WilhelmandMartin Carlberg 78524cdde7 Fixed: deprecate FlashView, this old technology is now almost banned for all browser (#2748) 2018-08-20 10:59:27 +02:00
Didier KorthoudtandMartin Carlberg 6077d3f4c3 FIXED: _CPThemeAttribute valueForState was, under some circumstances, ignoring theme settings (#2744) 2018-08-20 10:50:08 +02:00
cacaodevandMartin Carlberg fd3acc456d FIXED: Before this commit, CPScrollerView was not correctly differentiating the scroller-width attribute (#2740)
between the vertical scroller and the horizontal scroller.
The scroller width was picked from a common CPScroller instance cached in CPScroller.
The bug was not visible because the method -_adjustScrollerSize was correcting the size repeatidly in the layout pass.
This was causing unnecessary calls to setFrame: in a performance sensitive method (triggered by scroll events).
The ScrollView is now picking the right width from the theme and a setFrame: call is skipped.

Tests: Manual/CPScrollView2/

TODO : The _adjustScrollerSize method should be enabled with a flag only when a width change is explicitely requested.
2018-08-20 10:36:59 +02: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
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
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 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
daboe01 15f6f6a90a Merge remote-tracking branch 'cappuccino/master' 2017-03-18 11:02:38 +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
daboe01 30edd9e8dd Merge remote-tracking branch 'cappuccino/master' 2017-01-06 13:05:18 +01:00
Didier Korthoudt 8dbbe34dfc Merge remote-tracking branch 'cappuccino/master' 2016-11-08 15:21:17 +01:00
Didier Korthoudt e1bcf6c47e Merge remote-tracking branch 'cappuccino/master' 2016-10-31 16:11:38 +01:00
Martin Carlberg 02e71c23de Merge branch 'master' of https://github.com/cappuccino/cappuccino 2016-04-05 23:12:07 +02:00
Martin Carlberg ec5454de44 Merge branch 'cpobject_controller_extension' 2016-03-03 15:09:10 +01:00
247 changed files with 15634 additions and 1431 deletions
+1
View File
@@ -17,3 +17,4 @@ Tests/Manual/**/*.xcodeproj
*.sublime-project
*.sublime-workspace
*.tm_properties
*.idea
+6 -6
View File
@@ -216,7 +216,7 @@ var CPApplicationDelegate_applicationShouldTerminate_ = 1 << 0,
}
if ([_delegate respondsToSelector:@selector(applicationShouldTerminate:)])
_implementedDelegateMethods |= CPApplicationDelegate_applicationShouldTerminate_
_implementedDelegateMethods |= CPApplicationDelegate_applicationShouldTerminate_;
if ([_delegate respondsToSelector:@selector(applicationShouldTerminateMessage:)])
_implementedDelegateMethods |= CPApplicationDelegate_applicationShouldTerminateMessage_
@@ -628,11 +628,6 @@ var CPApplicationDelegate_applicationShouldTerminate_ = 1 << 0,
var theWindow = [anEvent window];
// Check if this is a candidate for key equivalent...
if ([anEvent _couldBeKeyEquivalent] && [self _handleKeyEquivalent:anEvent])
// The key equivalent was handled.
return;
if ([anEvent type] == CPMouseMoved)
{
if (theWindow !== _lastMouseMoveWindow)
@@ -669,6 +664,11 @@ var CPApplicationDelegate_applicationShouldTerminate_ = 1 << 0,
_eventListenerInsertionIndex = _eventListeners.length;
// Check if this is a candidate for key equivalent...
if ([anEvent _couldBeKeyEquivalent] && [self _handleKeyEquivalent:anEvent])
// The key equivalent was handled.
return;
if (theWindow)
[theWindow sendEvent:anEvent];
}
+1 -1
View File
@@ -563,7 +563,7 @@
*/
- (BOOL)setSelectionIndexes:(CPIndexSet)indexes
{
[self _selectionWillChange]
[self _selectionWillChange];
var r = [self __setSelectionIndexes:indexes avoidEmpty:NO];
[self _selectionDidChange];
return r;
+1 -1
View File
@@ -378,7 +378,7 @@ CPButtonImageOffset = 3.0;
- (void)setImage:(CPImage)anImage
{
[self setValue:anImage forThemeAttribute:@"image"];
[self setValue:anImage forThemeAttribute:@"image" inState:CPThemeStateNormal];
}
- (CPImage)image
+1 -1
View File
@@ -70,7 +70,7 @@
[button addItemWithTitle:nil];
[[button lastItem] setImage:image];
[button setImagePosition:CPImageOnly];
[button setValue:CGInsetMake(0, 0, 0, 0) forThemeAttribute:"content-inset"];
[button setValue:CGInsetMake(0, 0, 0, 0) forThemeAttribute:"content-inset" inState:CPPopUpButtonStatePullsDown];
[button setPullsDown:YES];
+17
View File
@@ -163,3 +163,20 @@ CPCheckBoxImageOffset = 4.0;
}
@end
#pragma mark -
@implementation CPCheckBox (TableDataView)
// We overide here _CPObject+Theme setValue:forThemeAttribute as CPCheckBox can be used as tableView data view
// So, when outside a table data view, setValue:forThemeAttribute should store the value with the CPThemeStateNormal (default behavior)
// When inside a table data view, it should store the value with the CPThemeStateTableDataView. If not, the value won't be used if the
// theme defined a value for this attribute for state CPThemeStateTableDataView
- (void)setValue:(id)aValue forThemeAttribute:(CPString)aName
{
[super setValue:aValue forThemeAttribute:aName];
[super setValue:aValue forThemeAttribute:aName inState:CPThemeStateTableDataView];
}
@end
+1 -1
View File
@@ -56,7 +56,7 @@ var CPCollectionViewDelegate_collectionView_acceptDrop_index_dropOperation_
- (CPData)collectionView:(CPCollectionView)collectionView dataForItemsAtIndexes:(CPIndexSet)indices forType:(CPString)aType;
- (CPDragOperation)collectionView:(CPCollectionView)collectionView validateDrop:(id)draggingInfo proposedIndex:(CPInteger)proposedDropIndex dropOperation:(CPCollectionViewDropOperation)proposedDropOperation;
- (CPMenu)collectionView:(CPCollectionView)collectionView menuForItemAtIndex:(CPInteger)anIndex;
- (CPView)collectionView:(CPCollectionView)collectionView dragginViewForItemsAtIndexes:(CPIndexSet)indexes withEvent:(CPEvent)event offset:(CGPoint)dragImageOffset;
- (CPView)collectionView:(CPCollectionView)collectionView draggingViewForItemsAtIndexes:(CPIndexSet)indexes withEvent:(CPEvent)event offset:(CGPoint)dragImageOffset;
- (void)collectionView:(CPCollectionView)collectionView didDoubleClickOnItemAtIndex:(int)index;
@end
+228 -4
View File
@@ -103,7 +103,8 @@ var cachedBlackColor,
@"alternate-selected-control-color": [CPNull null],
@"secondary-selected-control-color": [CPNull null],
@"selected-text-background-color": [CPNull null],
@"selected-text-inactive-background-color": [CPNull null]
@"selected-text-inactive-background-color": [CPNull null],
@"css-based": NO
};
}
@@ -876,9 +877,221 @@ url("data:image/png;base64,BASE64ENCODEDDATA") // if there is a pattern image
@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 CPColor (and CPImage) 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 CPColor that uses CSS, simply use the new class method :
// + (CPColor)colorWithCSSDictionary:(CPDictionary)aDictionary beforeDictionary:(CPDictionary)beforeDictionary afterDictionary:(CPDictionary)afterDictionary
// where beforeDictionary & afterDictionary are related to ::before & ::after pseudo-elements.
// If you don't need them, just use the simplified class method :
// + (CPColor)colorWithCSSDictionary:(CPDictionary)aDictionary
//
// Example :
// buttonCssColor = [CPColor colorWithCSSDictionary:@{
// @"background-color": A3ColorBackgroundWhite,
// @"border-color": A3ColorActiveBorder,
// @"border-style": @"solid",
// @"border-width": @"1px",
// @"border-radius": @"3px",
// @"box-sizing": @"border-box"
// }
// beforeDictionary:@{
// @"background-color": @"rgb(225,225,225)",
// @"bottom": @"3px",
// @"content": @"''",
// @"position": @"absolute",
// @"right": @"21px",
// @"top": @"3px",
// @"width": @"1px"
// }
// afterDictionary:@{
// @"content": @"''",
// @"bottom": @"3px",
// @"right": @"6px",
// @"top": @"1px",
// @"position": @"absolute",
// @"height": @"14px",
// @"width": @"9px",
// @"margin": @"2px 0px 2px 0px",
// @"background-image": @"url(%%packed.png)",
// @"background-position": @"0px -64px",
// @"background-repeat": @"no-repeat",
// @"background-size": @"100px 400px"
// }];
//
// 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 :
// aCssColor = [CPColor colorWithCSSDictionary:@{} 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 : -(void)restorePreviousCSSState and -(DOMElement)applyCSSColorForView are meant to be used by low level UI widgets (like CPView) to implement
// CSS theme support.
@implementation CPColor (CSSTheming)
{
CPDictionary _cssDictionary @accessors(property=cssDictionary);
CPDictionary _cssBeforeDictionary @accessors(property=cssBeforeDictionary);
CPDictionary _cssAfterDictionary @accessors(property=cssAfterDictionary);
}
+ (CPColor)colorWithCSSDictionary:(CPDictionary)aDictionary
{
return [[CPColor alloc] _initWithCSSDictionary:aDictionary beforeDictionary:nil afterDictionary:nil];
}
+ (CPColor)colorWithCSSDictionary:(CPDictionary)aDictionary beforeDictionary:(CPDictionary)beforeDictionary afterDictionary:(CPDictionary)afterDictionary
{
return [[CPColor alloc] _initWithCSSDictionary:aDictionary beforeDictionary:beforeDictionary afterDictionary:afterDictionary];
}
- (id)_initWithCSSDictionary:(CPDictionary)aDictionary beforeDictionary:(CPDictionary)beforeDictionary afterDictionary:(CPDictionary)afterDictionary
{
self = [super init];
if (self)
{
_cssDictionary = aDictionary;
_cssBeforeDictionary = beforeDictionary;
_cssAfterDictionary = afterDictionary;
_components = [0.0, 0.0, 0.0, 1.0];
_theme = [CPTheme defaultTheme];
_themeState = CPThemeStateNormal;
[self _loadThemeAttributes];
}
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);
}
- (void)restorePreviousCSSState:(CPArrayRef)aPreviousStateRef forDOMElement:(DOMElement)aDOMElement
{
#if PLATFORM(DOM)
var aPreviousState = @deref(aPreviousStateRef);
for (var i = 0, count = aPreviousState.length; i < count; i++)
aDOMElement.style[aPreviousState[i][0]] = aPreviousState[i][1];
@deref(aPreviousStateRef) = @[];
#endif
}
- (DOMElement)applyCSSColorForView:(CPView)aView onDOMElement:(DOMElement)aDOMElement styleNode:(DOMElement)aStyleNode previousState:(CPArrayRef)aPreviousStateRef
{
#if PLATFORM(DOM)
var aPreviousState = @deref(aPreviousStateRef);
[_cssDictionary enumerateKeysAndObjectsUsingBlock:function(aKey, anObject, stop)
{
[aPreviousState addObject:@[aKey, aDOMElement.style[aKey]]];
aDOMElement.style[aKey] = anObject;
}];
if ([self hasCSSBeforeDictionary] || [self hasCSSAfterDictionary])
{
// We need to create a unique class name
var styleClassName = @".CP" + [aView UID],
styleContent = @"";
if ([self hasCSSBeforeDictionary])
{
styleContent += styleClassName + @"::before { ";
[_cssBeforeDictionary enumerateKeysAndObjectsUsingBlock:function(aKey, anObject, stop)
{
styleContent += aKey + ": " + anObject + "; ";
}];
styleContent += "} ";
}
if ([self hasCSSAfterDictionary])
{
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
#pragma mark -
/// @cond IGNORE
var CPColorComponentsKey = @"CPColorComponentsKey",
CPColorPatternImageKey = @"CPColorPatternImageKey";
var CPColorComponentsKey = @"CPColorComponentsKey",
CPColorPatternImageKey = @"CPColorPatternImageKey",
CPColorCssDictionaryKey = @"CPColorCssDictionaryKey",
CPColorCssBeforeDictionaryKey = @"CPColorCssBeforeDictionaryKey",
CPColorCssAfterDictionaryKey = @"CPColorCssAfterDictionaryKey";
/// @endcond
@implementation CPColor (CPCoding)
@@ -891,6 +1104,10 @@ var CPColorComponentsKey = @"CPColorComponentsKey",
{
if ([aCoder containsValueForKey:CPColorPatternImageKey])
self = [self _initWithPatternImage:[aCoder decodeObjectForKey:CPColorPatternImageKey]];
else if ([aCoder containsValueForKey:CPColorCssDictionaryKey])
self = [self _initWithCSSDictionary:[aCoder decodeObjectForKey:CPColorCssDictionaryKey]
beforeDictionary:[aCoder decodeObjectForKey:CPColorCssBeforeDictionaryKey]
afterDictionary:[aCoder decodeObjectForKey:CPColorCssAfterDictionaryKey]];
else
self = [self _initWithRGBA:[aCoder decodeObjectForKey:CPColorComponentsKey]];
@@ -907,6 +1124,12 @@ var CPColorComponentsKey = @"CPColorComponentsKey",
{
if (_patternImage)
[aCoder encodeObject:_patternImage forKey:CPColorPatternImageKey];
else if (_cssDictionary)
{
[aCoder encodeObject:_cssDictionary forKey:CPColorCssDictionaryKey];
[aCoder encodeObject:_cssBeforeDictionary forKey:CPColorCssBeforeDictionaryKey];
[aCoder encodeObject:_cssAfterDictionary forKey:CPColorCssAfterDictionaryKey];
}
else
[aCoder encodeObject:_components forKey:CPColorComponentsKey];
@@ -1247,7 +1470,8 @@ var patternColorsFromPattern = function(pattern, attributes, imageFactory)
bottomHeight,
centerWidthHeight,
centerIsNil,
numParts;
numParts,
isVertical;
// positions are mandatory
if (pattern.indexOf("{position}") < 0)
+1 -1
View File
@@ -247,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);
+23
View File
@@ -32,6 +32,7 @@ CPKHTMLBrowserEngine = 1 << 2;
CPOperaBrowserEngine = 1 << 3;
CPWebKitBrowserEngine = 1 << 4; // Safari + Chrome
CPBlinkBrowserEngine = 1 << 5; // Recent Chrome
CPEdgeBrowserEngine = 1 << 6;
// Operating Systems
CPMacOperatingSystem = 0;
@@ -146,6 +147,28 @@ else if (typeof window !== "undefined" && (window.attachEvent || (!(window.Activ
PLATFORM_FEATURES[CPJavaScriptClipboardAccessFeature] = YES;
}
// Edge
else if (USER_AGENT.indexOf("Edge/") != -1)
{
PLATFORM_ENGINE |= CPEdgeBrowserEngine;
PLATFORM_FEATURES[CPCSSRGBAFeature] = YES;
PLATFORM_FEATURES[CPHTMLContentEditableFeature] = YES;
PLATFORM_FEATURES[CPJavaScriptClipboardEventsFeature] = YES;
PLATFORM_FEATURES[CPJavaScriptClipboardAccessFeature] = NO;
PLATFORM_FEATURES[CPJavaScriptShadowFeature] = YES;
var versionStart = USER_AGENT.indexOf("Edge/") + "Edge/".length,
versionEnd = USER_AGENT.indexOf(" ", versionStart),
versionString = USER_AGENT.substring(versionStart, versionEnd),
versionDivision = versionString.indexOf('.'),
majorVersion = parseInt(versionString.substring(0, versionDivision)),
minorVersion = parseInt(versionString.substr(versionDivision + 1));
PLATFORM_FEATURES[CPJavaScriptRemedialKeySupport] = YES;
}
// Safari + Chrome (WebKit and Blink)
else if (USER_AGENT.indexOf("AppleWebKit/") != -1)
{
+12 -5
View File
@@ -1057,14 +1057,21 @@ var CPControlBlackColor = [CPColor blackColor];
@end
@implementation CPControl (CPTrackingArea)
{
CPTrackingArea _controlTrackingArea;
}
- (void)updateTrackingAreas
{
[self removeAllTrackingAreas];
[self addTrackingArea:[[CPTrackingArea alloc] initWithRect:CGRectMakeZero()
options:CPTrackingMouseEnteredAndExited | CPTrackingActiveInKeyWindow | CPTrackingInVisibleRect
owner:self
userInfo:nil]];
if (_controlTrackingArea)
[self removeTrackingArea:_controlTrackingArea];
_controlTrackingArea = [[CPTrackingArea alloc] initWithRect:CGRectMakeZero()
options:CPTrackingMouseEnteredAndExited | CPTrackingActiveInKeyWindow | CPTrackingInVisibleRect
owner:self
userInfo:nil];
[self addTrackingArea:_controlTrackingArea];
[super updateTrackingAreas];
}
@end
+113 -44
View File
@@ -23,6 +23,7 @@ Cursor support by browser:
@import <Foundation/CPObject.j>
@import "CPImage.j"
@import "CPCompatibility.j"
@global CPApp
@@ -31,6 +32,12 @@ var currentCursor = nil,
cursors = {},
ieCursorMap = {};
@typedef CPCursorPlatform
CPCursorPlatformNone = 0;
CPCursorPlatformMac = 1;
CPCursorPlatformWindows = 2;
CPCursorPlatformBoth = 3;
@implementation CPCursor : CPObject
{
CPString _cssString @accessors(readonly);
@@ -157,7 +164,7 @@ var currentCursor = nil,
}
// Internal method that is used to return the system cursors. Caches the system cursors for performance.
+ (CPCursor)_systemCursorWithName:(CPString)cursorName cssString:(CPString)aString hasImage:(BOOL)doesHaveImage
+ (CPCursor)_nativeSystemCursorWithName:(CPString)cursorName cssString:(CPString)aString
{
var cursor = cursors[cursorName];
@@ -165,155 +172,217 @@ var currentCursor = nil,
{
var cssString;
if (doesHaveImage)
{
var themeResourcePath = [[[CPApp themeBlend] bundle] resourcePath],
extension = CPBrowserIsEngine(CPInternetExplorerBrowserEngine) ? @"cur" : @"png";
cssString = [CPString stringWithFormat:@"url(%@cursors/%@.%@), %@", themeResourcePath, cursorName, extension, aString];
}
// IE <= 8 does not support some cursors, map them to supported cursors
var ieLessThan9 = CPBrowserIsEngine(CPInternetExplorerBrowserEngine) && !CPFeatureIsCompatible(CPHTMLCanvasFeature);
if (ieLessThan9)
cssString = ieCursorMap[aString] || aString;
else
{
// IE <= 8 does not support some cursors, map them to supported cursors
var ieLessThan9 = CPBrowserIsEngine(CPInternetExplorerBrowserEngine) && !CPFeatureIsCompatible(CPHTMLCanvasFeature);
cssString = aString;
if (ieLessThan9)
cssString = ieCursorMap[aString] || aString;
else
cssString = aString;
}
cursor = [[CPCursor alloc] initWithCSSString:cssString];
cursors[cursorName] = cursor;
cursors[cursorName] = cursor = [[CPCursor alloc] initWithCSSString:cssString];
}
return cursor;
}
+ (CPCursor)_imageCursorWithName:(CPString)cursorName cssString:(CPString)aString
{
var cursor = cursors[cursorName];
if (typeof cursor === "undefined")
{
var themeResourcePath = [[[CPApp themeBlend] bundle] resourcePath],
extension = CPBrowserIsOperatingSystem(CPWindowsOperatingSystem) ? @"cur" : @"png";
cssString = [CPString stringWithFormat:@"url(%@cursors/%@.%@), %@", themeResourcePath, cursorName, extension, aString];
cursors[cursorName] = cursor = [[CPCursor alloc] initWithCSSString:cssString];
}
return cursor;
}
+ (CPCursor)_tryUsingNativeSystemCursorWithName:(CPString)cursorName cssString:(CPString)cssName onPlatform:(CPCursorPlatform)shouldUseNativeCursorOn fallingBackWithImageAndCSSPointer:(CPString)aString
{
var useNativeSystemCursor = (((shouldUseNativeCursorOn == CPCursorPlatformBoth) ||
((shouldUseNativeCursorOn == CPCursorPlatformMac) && CPBrowserIsOperatingSystem(CPMacOperatingSystem)) ||
((shouldUseNativeCursorOn == CPCursorPlatformWindows) && CPBrowserIsOperatingSystem(CPWindowsOperatingSystem)))
&& [CPCursor _nativeCursorExists:cssName]);
if (useNativeSystemCursor)
return [CPCursor _nativeSystemCursorWithName:cursorName cssString:cssName];
else
return [CPCursor _imageCursorWithName:cursorName cssString:aString];
}
+ (BOOL)_nativeCursorExists:(CPString)cursorCSSName
{
#if PLATFORM(DOM)
// FIXME: Trick until FF/Win & Chrome/Win correctly implement context-menu cursor
// They will answer that they implement it but they actually don't
if ([cursorCSSName isEqualToString:@"context-menu"] && CPBrowserIsOperatingSystem(CPWindowsOperatingSystem) && !CPBrowserIsEngine(CPInternetExplorerBrowserEngine) && !CPBrowserIsEngine(CPEdgeBrowserEngine))
return NO;
// Normal usage : try to set the cursor and check if resulting cursor is the one we tried to set.
// If yes, then the browser implements the cursor. If no (and usually we get "default"), then it doesn't.
var platformWindows = [[CPPlatformWindow visiblePlatformWindows] allObjects],
count = [platformWindows count];
if (count > 0)
{
var currentPlatformCursor = platformWindows[0]._DOMBodyElement.style.cursor;
platformWindows[0]._DOMBodyElement.style.cursor = cursorCSSName;
var doesExist = (platformWindows[0]._DOMBodyElement.style.cursor == cursorCSSName);
platformWindows[0]._DOMBodyElement.style.cursor = currentPlatformCursor;
return doesExist;
}
#endif
return NO;
}
+ (CPCursor)arrowCursor
{
return [CPCursor _systemCursorWithName:CPStringFromSelector(_cmd) cssString:@"default" hasImage:NO];
return [CPCursor _nativeSystemCursorWithName:CPStringFromSelector(_cmd) cssString:@"default"];
}
+ (CPCursor)crosshairCursor
{
return [CPCursor _systemCursorWithName:CPStringFromSelector(_cmd) cssString:@"crosshair" hasImage:NO];
return [CPCursor _nativeSystemCursorWithName:CPStringFromSelector(_cmd) cssString:@"crosshair"];
}
+ (CPCursor)IBeamCursor
{
return [CPCursor _systemCursorWithName:CPStringFromSelector(_cmd) cssString:@"text" hasImage:NO];
return [CPCursor _nativeSystemCursorWithName:CPStringFromSelector(_cmd) cssString:@"text"];
}
+ (CPCursor)pointingHandCursor
{
return [CPCursor _systemCursorWithName:CPStringFromSelector(_cmd) cssString:@"pointer" hasImage:NO];
return [CPCursor _nativeSystemCursorWithName:CPStringFromSelector(_cmd) cssString:@"pointer"];
}
+ (CPCursor)resizeNorthwestCursor
{
return [CPCursor _systemCursorWithName:CPStringFromSelector(_cmd) cssString:@"nw-resize" hasImage:NO];
return [CPCursor _nativeSystemCursorWithName:CPStringFromSelector(_cmd) cssString:@"nw-resize"];
}
+ (CPCursor)resizeNorthwestSoutheastCursor
{
return [CPCursor _systemCursorWithName:CPStringFromSelector(_cmd) cssString:@"nwse-resize" hasImage:NO];
return [CPCursor _nativeSystemCursorWithName:CPStringFromSelector(_cmd) cssString:@"nwse-resize"];
}
+ (CPCursor)resizeNortheastCursor
{
return [CPCursor _systemCursorWithName:CPStringFromSelector(_cmd) cssString:@"ne-resize" hasImage:NO];
return [CPCursor _nativeSystemCursorWithName:CPStringFromSelector(_cmd) cssString:@"ne-resize"];
}
+ (CPCursor)resizeNortheastSouthwestCursor
{
return [CPCursor _systemCursorWithName:CPStringFromSelector(_cmd) cssString:@"nesw-resize" hasImage:NO];
return [CPCursor _nativeSystemCursorWithName:CPStringFromSelector(_cmd) cssString:@"nesw-resize"];
}
+ (CPCursor)resizeSouthwestCursor
{
return [CPCursor _systemCursorWithName:CPStringFromSelector(_cmd) cssString:@"sw-resize" hasImage:NO];
return [CPCursor _nativeSystemCursorWithName:CPStringFromSelector(_cmd) cssString:@"sw-resize"];
}
+ (CPCursor)resizeSoutheastCursor
{
return [CPCursor _systemCursorWithName:CPStringFromSelector(_cmd) cssString:@"se-resize" hasImage:NO];
return [CPCursor _nativeSystemCursorWithName:CPStringFromSelector(_cmd) cssString:@"se-resize"];
}
+ (CPCursor)resizeDownCursor
{
return [CPCursor _systemCursorWithName:CPStringFromSelector(_cmd) cssString:@"s-resize" hasImage:NO];
return [CPCursor _nativeSystemCursorWithName:CPStringFromSelector(_cmd) cssString:@"s-resize"];
}
+ (CPCursor)resizeUpCursor
{
return [CPCursor _systemCursorWithName:CPStringFromSelector(_cmd) cssString:@"n-resize" hasImage:NO];
return [CPCursor _nativeSystemCursorWithName:CPStringFromSelector(_cmd) cssString:@"n-resize"];
}
+ (CPCursor)resizeLeftCursor
{
return [CPCursor _systemCursorWithName:CPStringFromSelector(_cmd) cssString:@"w-resize" hasImage:NO];
return [CPCursor _nativeSystemCursorWithName:CPStringFromSelector(_cmd) cssString:@"w-resize"];
}
+ (CPCursor)resizeRightCursor
{
return [CPCursor _systemCursorWithName:CPStringFromSelector(_cmd) cssString:@"e-resize" hasImage:NO];
return [CPCursor _nativeSystemCursorWithName:CPStringFromSelector(_cmd) cssString:@"e-resize"];
}
+ (CPCursor)resizeLeftRightCursor
{
return [CPCursor _systemCursorWithName:CPStringFromSelector(_cmd) cssString:@"col-resize" hasImage:NO];
return [CPCursor _nativeSystemCursorWithName:CPStringFromSelector(_cmd) cssString:@"col-resize"];
}
+ (CPCursor)resizeEastWestCursor
{
return [CPCursor _systemCursorWithName:CPStringFromSelector(_cmd) cssString:@"ew-resize" hasImage:NO];
return [CPCursor _nativeSystemCursorWithName:CPStringFromSelector(_cmd) cssString:@"ew-resize"];
}
+ (CPCursor)resizeUpDownCursor
{
return [CPCursor _systemCursorWithName:CPStringFromSelector(_cmd) cssString:@"row-resize" hasImage:NO];
return [CPCursor _nativeSystemCursorWithName:CPStringFromSelector(_cmd) cssString:@"row-resize"];
}
+ (CPCursor)resizeNorthSouthCursor
{
return [CPCursor _systemCursorWithName:CPStringFromSelector(_cmd) cssString:@"ns-resize" hasImage:NO];
return [CPCursor _nativeSystemCursorWithName:CPStringFromSelector(_cmd) cssString:@"ns-resize"];
}
+ (CPCursor)operationNotAllowedCursor
{
return [CPCursor _systemCursorWithName:CPStringFromSelector(_cmd) cssString:@"not-allowed" hasImage:NO];
return [CPCursor _nativeSystemCursorWithName:CPStringFromSelector(_cmd) cssString:@"not-allowed"];
}
+ (CPCursor)dragCopyCursor
{
return [CPCursor _systemCursorWithName:CPStringFromSelector(_cmd) cssString:@"copy" hasImage:YES];
return [CPCursor _nativeSystemCursorWithName:CPStringFromSelector(_cmd) cssString:@"copy"];
}
+ (CPCursor)dragLinkCursor
{
return [CPCursor _systemCursorWithName:CPStringFromSelector(_cmd) cssString:@"alias" hasImage:YES];
return [CPCursor _nativeSystemCursorWithName:CPStringFromSelector(_cmd) cssString:@"alias"];
}
+ (CPCursor)contextualMenuCursor
{
return [CPCursor _systemCursorWithName:CPStringFromSelector(_cmd) cssString:@"context-menu" hasImage:YES];
return [CPCursor _tryUsingNativeSystemCursorWithName:CPStringFromSelector(_cmd)
cssString:@"context-menu"
onPlatform:CPCursorPlatformBoth
fallingBackWithImageAndCSSPointer:@"default"];
}
+ (CPCursor)openHandCursor
{
return [CPCursor _systemCursorWithName:CPStringFromSelector(_cmd) cssString:@"move" hasImage:YES];
return [CPCursor _tryUsingNativeSystemCursorWithName:CPStringFromSelector(_cmd)
cssString:@"grab"
onPlatform:CPCursorPlatformMac
fallingBackWithImageAndCSSPointer:@"default"];
}
+ (CPCursor)closedHandCursor
{
return [CPCursor _systemCursorWithName:CPStringFromSelector(_cmd) cssString:@"-moz-grabbing" hasImage:YES];
return [CPCursor _tryUsingNativeSystemCursorWithName:CPStringFromSelector(_cmd)
cssString:@"grabbing"
onPlatform:CPCursorPlatformMac
fallingBackWithImageAndCSSPointer:@"default"];
}
+ (CPCursor)disappearingItemCursor
{
return [CPCursor _systemCursorWithName:CPStringFromSelector(_cmd) cssString:@"auto" hasImage:YES];
return [CPCursor _imageCursorWithName:CPStringFromSelector(_cmd) cssString:@"default"];
}
+ (CPCursor)IBeamCursorForVerticalLayout
{
return [CPCursor _nativeSystemCursorWithName:CPStringFromSelector(_cmd) cssString:@"vertical-text"];
}
@end
+3 -3
View File
@@ -352,8 +352,8 @@ CPEraDatePickerElementFlag = 0x0100;
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;}
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];
}
@@ -694,7 +694,7 @@ var CPDatePickerModeKey = @"CPDatePickerModeKey",
[aCoder encodeInt:_datePickerStyle forKey:CPDatePickerStyleKey];
[aCoder encodeInt:_datePickerElements forKey:CPDatePickerElementsKey];
[aCoder encodeObject:_minDate forKey:CPMinDateKey];
[aCoder encodeObject:_maxDate forKey:CPMaxDateKey]
[aCoder encodeObject:_maxDate forKey:CPMaxDateKey];
[aCoder encodeObject:_dateValue forKey:CPDateValueKey];;
[aCoder encodeObject:_textFont forKey:CPTextFontKey];
[aCoder encodeObject:_locale forKey:CPLocaleKey];
+10 -10
View File
@@ -85,7 +85,7 @@ var CPShortWeekDayNameArrayEn = [@"Mo", @"Tu", @"We", @"Th", @"Fr", @"Sa", @"Su"
{
if (self = [super initWithFrame:aFrame])
{
_datePicker = aDatePicker
_datePicker = aDatePicker;
[self _init];
}
@@ -435,7 +435,7 @@ var CPShortWeekDayNameArrayEn = [@"Mo", @"Tu", @"We", @"Th", @"Fr", @"Sa", @"Su"
break;
default:
return CPShortWeekDayNameArrayEn
return CPShortWeekDayNameArrayEn;
break;
}
}
@@ -464,7 +464,7 @@ var CPShortWeekDayNameArrayEn = [@"Mo", @"Tu", @"We", @"Th", @"Fr", @"Sa", @"Su"
break;
default:
return CPShortMonthNameArrayEn
return CPShortMonthNameArrayEn;
break;
}
@@ -526,11 +526,11 @@ var CPShortWeekDayNameArrayEn = [@"Mo", @"Tu", @"We", @"Th", @"Fr", @"Sa", @"Su"
var dayLabel = _dayLabels[i];
[dayLabel setStringValue:dayNames[i]];
[dayLabel sizeToFit]
[dayLabel sizeToFit];
[dayLabel setFrameOrigin:CGPointMake(sizeTileWidth * (i + 1) - sizeTileWidth / 2 - [dayLabel frameSize].width / 2, 23)];
if (i == 0)
firstDayTileX = sizeTileWidth * (i + 1) - sizeTileWidth / 2 - [dayLabel frameSize].width / 2
firstDayTileX = sizeTileWidth * (i + 1) - sizeTileWidth / 2 - [dayLabel frameSize].width / 2;
}
// Title
@@ -769,7 +769,7 @@ var CPShortWeekDayNameArrayEn = [@"Mo", @"Tu", @"We", @"Th", @"Fr", @"Sa", @"Su"
tileDate = [[tile date] copy],
selected = NO;
[tileDate _resetToMidnight]
[tileDate _resetToMidnight];
if (aStartDate)
selected = tileDate >= aStartDate && tileDate <= endDate;
@@ -845,7 +845,7 @@ var CPShortWeekDayNameArrayEn = [@"Mo", @"Tu", @"We", @"Th", @"Fr", @"Sa", @"Su"
// Very usefull to avoid to have a line of two pixels instead one
if (!isBorderPair)
y += 0.5
y += 0.5;
CGContextMoveToPoint(context, 0, y);
CGContextAddLineToPoint(context, [self bounds].size.width, y);
@@ -857,7 +857,7 @@ var CPShortWeekDayNameArrayEn = [@"Mo", @"Tu", @"We", @"Th", @"Fr", @"Sa", @"Su"
// Very usefull to avoid to have a line of two pixels instead one
if (!isBorderPair)
x += 0.5
x += 0.5;
CGContextMoveToPoint(context, x, 0);
CGContextAddLineToPoint(context, x, [self bounds].size.height);
@@ -869,7 +869,7 @@ var CPShortWeekDayNameArrayEn = [@"Mo", @"Tu", @"We", @"Th", @"Fr", @"Sa", @"Su"
// Very usefull to avoid to have a line of two pixels instead one
if (!isBorderPair)
y += 0.5
y += 0.5;
CGContextMoveToPoint(context, 0, y);
CGContextAddLineToPoint(context, [self bounds].size.width, y);
@@ -897,7 +897,7 @@ var CPShortWeekDayNameArrayEn = [@"Mo", @"Tu", @"We", @"Th", @"Fr", @"Sa", @"Su"
_clickDate = [dateTile copy];
_dragDate = nil;
_indexDayTile = -1;
_eventDragged = nil
_eventDragged = nil;
_datePicker._invokedByUserEvent = YES;
+1 -1
View File
@@ -142,7 +142,7 @@ var RADIANS = Math.PI / 180;
if ([_datePicker _isAmericanFormat])
{
if (dateValue.getHours() > 11)
[_PMAMTextField setStringValue:@"PM"]
[_PMAMTextField setStringValue:@"PM"];
else
[_PMAMTextField setStringValue:@"AM"];
+1 -1
View File
@@ -80,7 +80,7 @@ var CPZeroKeyCode = 48,
{
if (self = [super initWithFrame:aFrame])
{
_datePicker = aDatePicker
_datePicker = aDatePicker;
[self _init];
}
return self;
+2 -2
View File
@@ -66,7 +66,7 @@ var _CPEventPeriodicEventPeriod = 0,
CPWindow _window;
Number _windowNumber;
CPString _characters;
CPString _charactersIgnoringModifiers
CPString _charactersIgnoringModifiers;
BOOL _isARepeat;
unsigned _keyCode;
DOMEvent _DOMEvent;
@@ -642,7 +642,7 @@ var _CPEventPeriodicEventPeriod = 0,
- (CPTrackingArea)trackingArea
{
if ((_type !== CPMouseEntered) && (_type !== CPMouseExited) && (_type !== CPCursorUpdate))
[CPException raise:CPInternalInconsistencyException format:@"You can't call trackingArea for events of type %#x", _type]
[CPException raise:CPInternalInconsistencyException format:@"You can't call trackingArea for events of type %#x", _type];
return _trackingArea;
}
+3
View File
@@ -43,6 +43,9 @@ var IEFlashCLSID = "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000";
- (id)initWithFrame:(CGRect)aFrame
{
CPLog.warn("CPFlashView is deprecated and it will be removed in version 1.1.");
self = [super initWithFrame:aFrame];
if (self)
+1 -1
View File
@@ -163,7 +163,7 @@ following:
if (normalizedFaces === _CPFontSystemFontFace)
return;
[self _invalidateSystemFontCache]
[self _invalidateSystemFontCache];
_CPFontSystemFontFace = aFace;
}
+219 -2
View File
@@ -246,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);
@@ -509,6 +509,212 @@ function CPAppKitImage(aFilename, aSize)
@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)
/*!
@@ -518,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"]];
}
/*!
@@ -529,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
+33 -6
View File
@@ -98,10 +98,32 @@ var CPImageViewEmptyPlaceholderImage = nil;
- (void)_createDOMImageElement
{
#if PLATFORM(DOM)
if (_DOMImageElement)
return;
var image = [self objectValue],
isCSSBasedImage = [image isCSSBased],
isIMGImageElement = _DOMImageElement && (_DOMImageElement.nodeName == "IMG");
_DOMImageElement = document.createElement("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";
@@ -150,10 +172,15 @@ var CPImageViewEmptyPlaceholderImage = nil;
var newImage = [self objectValue];
#if PLATFORM(DOM)
if (!_DOMImageElement)
[self _createDOMImageElement];
[self _createDOMImageElement];
_DOMImageElement.src = newImage ? [newImage filename] : [CPImageViewEmptyPlaceholderImage filename];
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];
+1 -1
View File
@@ -857,7 +857,7 @@ var CPBindingOperationAnd = 0,
- (id)initWithName:(CPString)aName
{
if (self = [super init])
_name = aName
_name = aName;
return self;
}
+2 -2
View File
@@ -292,7 +292,7 @@ CPRatingLevelIndicatorStyle = 3;
[self setNeedsLayout];
}
- (void)setWarningValue:(double)warningValue;
- (void)setWarningValue:(double)warningValue
{
if (_warningValue === warningValue)
return;
@@ -301,7 +301,7 @@ CPRatingLevelIndicatorStyle = 3;
[self setNeedsLayout];
}
- (void)setCriticalValue:(double)criticalValue;
- (void)setCriticalValue:(double)criticalValue
{
if (_criticalValue === criticalValue)
return;
+2 -2
View File
@@ -505,7 +505,7 @@ CPOffState
if (_submenu)
{
[_submenu setSupermenu:_menu];
[_submenu setTitle:[self title]]
[_submenu setTitle:[self title]];
[self setTarget:_menu];
[self setAction:@selector(submenuAction:)];
@@ -843,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];
+2 -1
View File
@@ -55,6 +55,7 @@
@"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],
@@ -124,7 +125,7 @@
- (CPColor)textColor
{
if (![_menuItem isEnabled])
return [CPColor lightGrayColor];
return [self valueForThemeAttribute:@"menu-item-disabled-text-color"];
if (_highlighted)
return [CPColor whiteColor];
+2 -2
View File
@@ -1923,7 +1923,7 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
while (index !== CPNotFound)
{
[items addObject:[_outlineView itemAtRow:index]]
[items addObject:[_outlineView itemAtRow:index]];
index = [theIndexes indexGreaterThanIndex:index];
}
@@ -1957,7 +1957,7 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
- (void)_parentItemForDropOperation:(CPTableViewDropOperation)theDropOperation row:(CPInteger)theRow offset:(CGPoint)theOffset
{
if (theDropOperation === CPTableViewDropAbove)
return [_outlineView _parentItemForUpperRow:theRow - 1 andLowerRow:theRow atMouseOffset:theOffset]
return [_outlineView _parentItemForUpperRow:theRow - 1 andLowerRow:theRow atMouseOffset:theOffset];
return [_outlineView itemAtRow:theRow];
}
+1
View File
@@ -45,6 +45,7 @@ CPURLPboardType = @"CPURLPboardType";
CPImagesPboardType = @"CPImagesPboardType";
CPVideosPboardType = @"CPVideosPboardType";
CPRTFPboardType = @"CPRTFPboardType";
_CPSmartPboardType = @"_CPSmartPboardType";
UTF8PboardType = @"public.utf8-plain-text";
+10 -2
View File
@@ -491,9 +491,17 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
if (index < 0)
{
[self addItemWithTitle:aTitle];
index = [self numberOfItems] - 1;
// this ist to match cocoa where setting an empty string does not add it but simply clears the title
// and sets objectValue to -1
if (aTitle === '')
[self selectItemAtIndex:-1];
else
{
[self addItemWithTitle:aTitle];
index = [self numberOfItems] - 1;
}
}
[self selectItemAtIndex:index];
+4 -4
View File
@@ -463,13 +463,13 @@ var CPProgressIndicatorSpinningStyleColors = [];
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)
radius = MIN(rect.size.width / 2, rect.size.height / 2);
CGContextBeginPath(context);
CGContextSetLineWidth(context, borderSize);
CGContextSetFillColor(context, [self currentValueForThemeAttribute:@"circular-color"])
CGContextSetFillColor(context, [self currentValueForThemeAttribute:@"circular-color"]);
CGContextMoveToPoint(context, midX, midY);
CGContextAddArc(context, midX, midY, radius, 3 * Math.PI / 2, endAngle, YES)
CGContextAddArc(context, midX, midY, radius, 3 * Math.PI / 2, endAngle, YES);
CGContextAddLineToPoint(context, midX, midY);
CGContextClosePath(context);
CGContextFillPath(context);
@@ -478,7 +478,7 @@ var CPProgressIndicatorSpinningStyleColors = [];
else if ([self doubleValue] == [self maxValue])
{
CGContextBeginPath(context);
CGContextSetFillColor(context, [self currentValueForThemeAttribute:@"circular-color"])
CGContextSetFillColor(context, [self currentValueForThemeAttribute:@"circular-color"]);
CGContextAddEllipseInRect(context, rect);
CGContextClosePath(context);
CGContextFillPath(context);
@@ -209,8 +209,7 @@
- (void)_reconfigureSubviews
{
var ruleItems,
criteria,
var criteria,
repObject,
menuItem,
ruleView,
+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];
+60 -17
View File
@@ -168,14 +168,13 @@ var CPScrollerStyleGlobal = CPScrollerStyleOverlay,
+ (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],
scrollerWidth = [CPScroller scrollerWidth];
var bounds = [self _insetBounds:CGRectMake(0.0, 0.0, frameSize.width, frameSize.height) borderType:borderType];
if (hFlag)
bounds.size.height -= scrollerWidth;
bounds.size.height -= [_horizontalScroller scrollerWidth];
if (vFlag)
bounds.size.width -= scrollerWidth;
bounds.size.width -= [_verticalScroller scrollerWidth];
return bounds.size;
}
@@ -185,14 +184,13 @@ var CPScrollerStyleGlobal = CPScrollerStyleOverlay,
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),
scrollerWidth = [CPScroller scrollerWidth];
frameSize = CGSizeMake(contentSize.width + widthInset, contentSize.height + heightInset);
if (hFlag)
frameSize.height += scrollerWidth;
frameSize.height += [_horizontalScroller scrollerWidth];
if (vFlag)
frameSize.width += scrollerWidth;
frameSize.width += [_verticalScroller scrollerWidth];
return frameSize;
}
@@ -529,8 +527,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), [_horizontalScroller scrollerWidth] + 1), [_horizontalScroller scrollerWidth])]];
[[self horizontalScroller] setFrameSize:CGSizeMake(CGRectGetWidth(bounds), [_horizontalScroller scrollerWidth])];
}
[self reflectScrolledClipView:_contentView];
@@ -594,8 +592,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, [_verticalScroller scrollerWidth], MAX(CGRectGetHeight(bounds), [_verticalScroller scrollerWidth] + 1))]];
[[self verticalScroller] setFrameSize:CGSizeMake([_verticalScroller scrollerWidth], CGRectGetHeight(bounds))];
}
[self reflectScrolledClipView:_contentView];
@@ -911,8 +909,8 @@ Notifies the delegate when the scroll view has finished scrolling.
bottomCornerFrame.origin.x = CGRectGetMinX(verticalFrame);
bottomCornerFrame.origin.y = CGRectGetMaxY(verticalFrame);
bottomCornerFrame.size.width = [CPScroller scrollerWidthInStyle:_scrollerStyle];
bottomCornerFrame.size.height = [CPScroller scrollerWidthInStyle:_scrollerStyle];
bottomCornerFrame.size.width = [_verticalScroller scrollerWidth];
bottomCornerFrame.size.height = [_horizontalScroller scrollerWidth];
return bottomCornerFrame;
}
@@ -1124,8 +1122,8 @@ Notifies the delegate when the scroll view has finished scrolling.
contentFrame.size.height -= headerClipViewHeight;
var difference = CGSizeMake(CGRectGetWidth(documentFrame) - CGRectGetWidth(contentFrame), CGRectGetHeight(documentFrame) - CGRectGetHeight(contentFrame)),
verticalScrollerWidth = [CPScroller scrollerWidthInStyle:[_verticalScroller style]],
horizontalScrollerHeight = [CPScroller scrollerWidthInStyle:[_horizontalScroller style]],
verticalScrollerWidth = [_verticalScroller scrollerWidth],
horizontalScrollerHeight = [_horizontalScroller scrollerWidth],
hasVerticalScroll = difference.height > 0.0,
hasHorizontalScroll = difference.width > 0.0,
shouldShowVerticalScroller = _hasVerticalScroller && (!_autohidesScrollers || hasVerticalScroll),
@@ -1253,7 +1251,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];
}
@@ -1510,6 +1508,51 @@ Notifies the delegate when the scroll view has finished scrolling.
@end
#pragma mark -
@implementation CPScrollView (FirstResponder)
// Those 4 next methods are needed to (un)set CPThemeStateFirstResponder based on content view
- (void)viewWillMoveToWindow:(CPWindow)aWindow
{
[super viewWillMoveToWindow:aWindow];
[self _stopObservingFirstResponderForWindow:[self window]];
if (aWindow)
[self _startObservingFirstResponderForWindow:aWindow];
}
- (void)_startObservingFirstResponderForWindow:(CPWindow)aWindow
{
[[CPNotificationCenter defaultCenter] addObserver:self selector:@selector(_firstResponderDidChange:) name:_CPWindowDidChangeFirstResponderNotification object:aWindow];
}
- (void)_stopObservingFirstResponderForWindow:(CPWindow)aWindow
{
[[CPNotificationCenter defaultCenter] removeObserver:self name:_CPWindowDidChangeFirstResponderNotification object:aWindow];
}
- (void)_firstResponderDidChange:(CPNotification)aNotification
{
var responder = [[self window] firstResponder],
// FIXME: We add focus ring only on table views right now. When focus ring management will be added, this must be adapted.
shouldAddFocusRing = [responder isKindOfClass:[CPTableView class]],
found;
while (!(found = (responder === self)) && responder)
responder = [responder superview];
if (found && shouldAddFocusRing)
[self setThemeState:CPThemeStateFirstResponder];
else
[self unsetThemeState:CPThemeStateFirstResponder];
}
@end
#pragma mark -
var CPScrollViewContentViewKey = @"CPScrollViewContentView",
CPScrollViewHeaderClipViewKey = @"CPScrollViewHeaderClipViewKey",
+19 -9
View File
@@ -226,6 +226,7 @@ CPThemeStateScrollerKnobDark = CPThemeState("scroller-knob-dark");
if (_style === CPScrollerStyleLegacy)
{
_allowFadingOut = NO;
[self fadeIn];
[self setThemeState:CPThemeStateScrollViewLegacy];
}
@@ -380,9 +381,10 @@ 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);
@@ -409,9 +411,10 @@ 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);
@@ -460,9 +463,6 @@ CPThemeStateScrollerKnobDark = CPThemeState("scroller-knob-dark");
*/
- (void)fadeOut
{
if ([self hasThemeState:CPThemeStateScrollViewLegacy])
return;
[_animationScroller startAnimation];
}
@@ -759,15 +759,25 @@ CPThemeStateScrollerKnobDark = CPThemeState("scroller-knob-dark");
if ([self isHidden] || ![self isEnabled] || !_isMouseOver)
return;
_allowFadingOut = YES;
_allowFadingOut = (_style !== CPScrollerStyleLegacy);
_isMouseOver = NO;
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];
}
- (float)scrollerWidth
{
if (_style == CPScrollerStyleLegacy)
return [self valueForThemeAttribute:@"scroller-width" inState:CPThemeStateScrollViewLegacy];
return [self currentValueForThemeAttribute:@"scroller-width"];
}
#pragma mark -
#pragma mark Delegates
+143 -36
View File
@@ -73,10 +73,20 @@ var CPAutosavedRecentsChangedNotification = @"CPAutosavedRecentsChangedNotificat
@"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)
@"image-cancel-inset" : CGInsetMake(0, 5, 0, 0),
@"search-menu-offset": CGPointMake(10, -4),
@"search-right-margin": 2
};
}
+ (Class)_binderClassForBinding:(CPString)aBinding
{
if (aBinding === CPPredicateBinding)
return [_CPSearchFieldPredicateBinder class];
return [super _binderClassForBinding:aBinding];
}
- (id)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame])
@@ -87,10 +97,6 @@ var CPAutosavedRecentsChangedNotification = @"CPAutosavedRecentsChangedNotificat
_recentsAutosaveName = nil;
[self _init];
#if PLATFORM(DOM)
_cancelButton._DOMElement.style.cursor = "default";
_searchButton._DOMElement.style.cursor = "default";
#endif
}
return self;
@@ -177,7 +183,7 @@ var CPAutosavedRecentsChangedNotification = @"CPAutosavedRecentsChangedNotificat
- (void)resetSearchButton
{
var button = [self searchButton],
searchButtonImage = (_searchMenuTemplate === nil) ? [self valueForThemeAttribute:@"image-search"] : [self valueForThemeAttribute:@"image-find"];
searchButtonImage = (_searchMenuTemplate === nil) ? [self currentValueForThemeAttribute:@"image-search"] : [self currentValueForThemeAttribute:@"image-find"];
[button setBordered:NO];
[button setImageScaling:CPImageScaleAxesIndependently];
@@ -246,8 +252,9 @@ var CPAutosavedRecentsChangedNotification = @"CPAutosavedRecentsChangedNotificat
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)
@@ -386,9 +393,9 @@ var CPAutosavedRecentsChangedNotification = @"CPAutosavedRecentsChangedNotificat
*/
- (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];
}
@@ -531,19 +538,16 @@ var CPAutosavedRecentsChangedNotification = @"CPAutosavedRecentsChangedNotificat
}
/*!
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.
@@ -568,6 +572,13 @@ var CPAutosavedRecentsChangedNotification = @"CPAutosavedRecentsChangedNotificat
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:@""];
@@ -582,20 +593,6 @@ var CPAutosavedRecentsChangedNotification = @"CPAutosavedRecentsChangedNotificat
[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;
}
@@ -608,6 +605,8 @@ var CPAutosavedRecentsChangedNotification = @"CPAutosavedRecentsChangedNotificat
countOfRecents = [_recentSearches count],
numberOfItems = [_searchMenuTemplate numberOfItems];
[menu setAutoenablesItems:NO];
for (var i = 0; i < numberOfItems; i++)
{
var item = [[_searchMenuTemplate itemAtIndex:i] copy];
@@ -631,7 +630,6 @@ var CPAutosavedRecentsChangedNotification = @"CPAutosavedRecentsChangedNotificat
var recentItem = [[CPMenuItem alloc] initWithTitle:[_recentSearches objectAtIndex:recentIndex]
action:itemAction
keyEquivalent:[item keyEquivalent]];
[recentItem setIndentationLevel:1];
[item setTarget:self];
[menu addItem:recentItem];
}
@@ -689,11 +687,12 @@ var CPAutosavedRecentsChangedNotification = @"CPAutosavedRecentsChangedNotificat
- (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 = CGPointMake(aFrame.origin.x + 10, aFrame.origin.y + aFrame.size.height - 4);
offset = [self currentValueForThemeAttribute:@"search-menu-offset"],
location = CGPointMake(aFrame.origin.x + offset.x, aFrame.origin.y + aFrame.size.height + offset.y);
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];
@@ -771,8 +770,75 @@ var CPAutosavedRecentsChangedNotification = @"CPAutosavedRecentsChangedNotificat
_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",
@@ -825,3 +891,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
+51 -47
View File
@@ -872,64 +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 = CPNotFound;
[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];
+92 -60
View File
@@ -117,6 +117,7 @@ var ShouldSuppressResizeNotifications = 1,
CPArray _DOMDividerElements;
CPString _dividerImagePath;
int _drawingDivider;
BOOL _isTracking;
CPString _autosaveName;
BOOL _shouldAutosave;
@@ -158,6 +159,7 @@ var ShouldSuppressResizeNotifications = 1,
_buttonBars = [];
_shouldAutosave = YES;
_isTracking = NO;
[self _setVertical:YES];
}
@@ -213,6 +215,9 @@ var ShouldSuppressResizeNotifications = 1,
[_subviews[index] setFrame:CGRectMake(0, ROUND((eachSize + dividerThickness) * index), frame.size.width, eachSize)];
}
if (_DOMDividerElements[_drawingDivider])
[self _setupDOMDivider];
[self setNeedsDisplay:YES];
[self _postNotificationDidResize];
@@ -363,9 +368,9 @@ var ShouldSuppressResizeNotifications = 1,
_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));
#endif
@@ -452,17 +457,26 @@ var ShouldSuppressResizeNotifications = 1,
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
@@ -473,12 +487,13 @@ var ShouldSuppressResizeNotifications = 1,
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];
}
@@ -488,59 +503,55 @@ var ShouldSuppressResizeNotifications = 1,
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 &&
[self _delegateRespondsToSplitViewCanCollapseSubview] &&
[self _delegateRespondsToSplitViewshouldCollapseSubviewForDoubleClickOnDividerAtIndex])
{
var minPosition = [self minPossiblePositionOfDividerAtIndex:i],
maxPosition = [self maxPossiblePositionOfDividerAtIndex:i],
preCollapsePosition = [_preCollapsePositions objectForKey:"" + i] || 0;
if ([self _sendDelegateSplitViewCanCollapseSubview:_subviews[i]] && [self _sendDelegateSplitViewShouldCollapseSubview:_subviews[i] forDoubleClickOnDividerAtIndex:i])
{
if ([self isSubviewCollapsed:_subviews[i]])
[self setPosition:preCollapsePosition ? preCollapsePosition : (minPosition + (maxPosition - minPosition) / 2) ofDividerAtIndex:i];
else
[self setPosition:minPosition ofDividerAtIndex:i];
}
else if ([self _sendDelegateSplitViewCanCollapseSubview:_subviews[i + 1]] && [self _sendDelegateSplitViewShouldCollapseSubview:_subviews[i + 1] forDoubleClickOnDividerAtIndex:i])
{
if ([self isSubviewCollapsed:_subviews[i + 1]])
[self setPosition:preCollapsePosition ? preCollapsePosition : (minPosition + (maxPosition - minPosition) / 2) ofDividerAtIndex:i];
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];
@@ -553,8 +564,11 @@ var ShouldSuppressResizeNotifications = 1,
- (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
@@ -1187,18 +1201,35 @@ 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
{
[self removeAllTrackingAreas];
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++)
[self addTrackingArea:[[CPTrackingArea alloc] initWithRect:[self effectiveRectOfDividerAtIndex:i]
options:options
owner:self
userInfo:nil]];
{
[_splitViewTrackingAreas addObject:[[CPTrackingArea alloc] initWithRect:[self effectiveRectOfDividerAtIndex:i]
options:options
owner:self
userInfo:nil]];
[self addTrackingArea:_splitViewTrackingAreas[i]];
}
[super updateTrackingAreas];
}
- (void)cursorUpdate:(CPEvent)anEvent
@@ -1438,6 +1469,7 @@ var CPSplitViewDelegateKey = "CPSplitViewDelegateKey",
_currentDivider = CPNotFound;
_shouldAutosave = YES;
_isTracking = NO;
_DOMDividerElements = [];
+90 -23
View File
@@ -35,6 +35,7 @@ CPNoTabsLineBorder = 5; //Has no tabs and displays a line border.
CPNoTabsNoBorder = 6; //Displays no tabs and no border.
@class _CPTabViewBox
@class _CPSegmentedControl
var CPTabViewDidSelectTabViewItemSelector = 1 << 1,
CPTabViewShouldSelectTabViewItemSelector = 1 << 2,
@@ -65,9 +66,9 @@ var CPTabViewDidSelectTabViewItemSelector = 1 << 1,
{
CPArray _items;
CPSegmentedControl _tabs;
_CPSegmentedControl _tabs;
_CPTabViewBox _box;
CPView _placeHolderView;
CPView _placeholderView @accessors;
CPTabViewItem _selectedTabViewItem;
@@ -92,8 +93,8 @@ var CPTabViewDidSelectTabViewItemSelector = 1 << 1,
- (void)_init
{
_tabs = [[CPSegmentedControl alloc] initWithFrame:CGRectMakeZero()];
[_tabs setHitTests:NO];
_tabs = [[_CPSegmentedControl alloc] initWithFrame:CGRectMakeZero()];
[_tabs setTabView:self];
[_tabs setSegments:[CPArray array]];
var height = [_tabs valueForThemeAttribute:@"min-size"].height;
@@ -106,7 +107,7 @@ var CPTabViewDidSelectTabViewItemSelector = 1 << 1,
[self addSubview:_box];
[self addSubview:_tabs];
_placeHolderView = nil;
_placeholderView = nil;
}
- (CPArray)items
@@ -131,10 +132,10 @@ var CPTabViewDidSelectTabViewItemSelector = 1 << 1,
*/
- (void)insertTabViewItem:(CPTabViewItem)aTabViewItem atIndex:(CPUInteger)anIndex
{
[self _insertTabViewItems:[aTabViewItem] atIndexes:[CPIndexSet indexSetWithIndex:anIndex]];
[self _insertTabViewItems:[aTabViewItem] atIndexes:[CPIndexSet indexSetWithIndex:anIndex] canUpdateSelectedTab:YES];
}
- (void)_insertTabViewItems:(CPArray)tabViewItems atIndexes:(CPIndexSet)indexes
- (void)_insertTabViewItems:(CPArray)tabViewItems atIndexes:(CPIndexSet)indexes canUpdateSelectedTab:(BOOL)canUpdateSelectedTab
{
var prevItemsCount = [self numberOfTabViewItems];
@@ -147,7 +148,7 @@ var CPTabViewDidSelectTabViewItemSelector = 1 << 1,
[self _sendDelegateTabViewDidChangeNumberOfTabViewItems];
// Do not allow empty selection if selection bindings are not enabled.
if (prevItemsCount == 0 && [self numberOfTabViewItems] > 0 && ![self _isSelectionBinded])
if (prevItemsCount == 0 && [self numberOfTabViewItems] > 0 && ![self _isSelectionBinded] && canUpdateSelectedTab)
[self _selectTabViewItemAtIndex:0];
}
@@ -525,14 +526,6 @@ var CPTabViewDidSelectTabViewItemSelector = 1 << 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,
@@ -617,7 +610,7 @@ var CPTabViewDidSelectTabViewItemSelector = 1 << 1,
- (CPBinder)binderForBinding:(CPString)aBinding
{
var cls = [[self class] _binderClassForBinding:aBinding]
var cls = [[self class] _binderClassForBinding:aBinding];
return [cls getBinding:aBinding forObject:self];
}
@@ -652,17 +645,17 @@ var CPTabViewDidSelectTabViewItemSelector = 1 << 1,
- (void)_displayPlaceholder:(CPString)aPlaceholder
{
if (_placeHolderView == nil)
if (_placeholderView == nil)
{
_placeHolderView = [[CPView alloc] initWithFrame:CGRectMakeZero()];
_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];
[_placeholderView addSubview:textField];
}
var textField = [_placeHolderView viewWithTag:1000];
var textField = [_placeholderView viewWithTag:1000];
[textField setStringValue:aPlaceholder];
[textField sizeToFit];
@@ -672,7 +665,7 @@ var CPTabViewDidSelectTabViewItemSelector = 1 << 1,
[textField setFrameOrigin:origin];
[self _displayItemView:_placeHolderView];
[self _displayItemView:_placeholderView];
}
#pragma mark -
@@ -803,7 +796,7 @@ var CPTabViewItemsKey = "CPTabViewItemsKey",
[_tabs setFont:_font];
var items = [aCoder decodeObjectForKey:CPTabViewItemsKey] || [CPArray array];
[self _insertTabViewItems:items atIndexes:[CPIndexSet indexSetWithIndexesInRange:CPMakeRange(0, [items count])]];
[self _insertTabViewItems:items atIndexes:[CPIndexSet indexSetWithIndexesInRange:CPMakeRange(0, [items count])] canUpdateSelectedTab:NO];
[self setDelegate:[aCoder decodeObjectForKey:CPTabViewDelegateKey]];
@@ -887,3 +880,77 @@ var CPTabViewItemsKey = "CPTabViewItemsKey",
}
@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
+2 -2
View File
@@ -287,7 +287,7 @@ CPTableColumnUserResizingMask = 1 << 1;
if (width < [self minWidth])
[self setMinWidth:width];
else if (width > [self maxWidth])
[self setMaxWidth:width]
[self setMaxWidth:width];
if (_width !== width)
[self setWidth:width];
@@ -499,7 +499,7 @@ CPTableColumnUserResizingMask = 1 << 1;
*/
- (void)setHidden:(BOOL)shouldBeHidden
{
shouldBeHidden = !!shouldBeHidden
shouldBeHidden = !!shouldBeHidden;
if (_isHidden === shouldBeHidden)
return;
+24 -7
View File
@@ -89,7 +89,7 @@
var inset = [self currentValueForThemeAttribute:@"text-inset"],
bounds = [self bounds];
[_textField setFrame:CGRectMake(inset.right, inset.top, bounds.size.width - inset.right - inset.left, bounds.size.height - inset.top - inset.bottom)];
[_textField setFrame:CGRectMake(inset.left, inset.top, bounds.size.width - inset.right - inset.left, bounds.size.height - inset.top - inset.bottom)];
[_textField setTextColor:[self currentValueForThemeAttribute:@"text-color"]];
[_textField setFont:[self currentValueForThemeAttribute:@"font"]];
[_textField setTextShadowColor:[self currentValueForThemeAttribute:@"text-shadow-color"]];
@@ -461,21 +461,38 @@ var CPTableHeaderViewResizeZone = 3.0,
@end
@implementation CPTableHeaderView (CPTrackingArea)
{
CPMutableArray _tableHeaderViewTrackingAreas;
}
- (void)updateTrackingAreas
{
[self removeAllTrackingAreas];
if (_tableHeaderViewTrackingAreas)
{
for (var i = 0, count = [_tableHeaderViewTrackingAreas count]; i < count; i++)
[self removeTrackingArea:_tableHeaderViewTrackingAreas[i]];
_tableHeaderViewTrackingAreas = nil;
}
var options = CPTrackingCursorUpdate | CPTrackingActiveInKeyWindow;
if (!_tableView)
return;
_tableHeaderViewTrackingAreas = @[];
for (var i = 0; i < _tableView._tableColumns.length; i++)
[self addTrackingArea:[[CPTrackingArea alloc] initWithRect:[self _cursorRectForColumn:i]
options:options
owner:self
userInfo:nil]];
{
[_tableHeaderViewTrackingAreas addObject:[[CPTrackingArea alloc] initWithRect:[self _cursorRectForColumn:i]
options:options
owner:self
userInfo:nil]];
[self addTrackingArea:_tableHeaderViewTrackingAreas[i]];
}
[super updateTrackingAreas];
}
- (void)cursorUpdate:(CPEvent)anEvent
@@ -533,7 +550,7 @@ var CPTableHeaderViewResizeZone = 3.0,
- (void)_autoscroll:(CPEvent)theEvent localLocation:(CGPoint)theLocation
{
// Constrain the y coordinate so we don't autoscroll vertically
var constrainedLocation = CGPointMake(theLocation.x, CGRectGetMinY([_tableView visibleRect])),
var constrainedLocation = CGPointMake(theLocation.x, CGRectGetMaxY([self frame])),
constrainedEvent = [CPEvent mouseEventWithType:CPLeftMouseDragged
location:[self convertPoint:constrainedLocation toView:nil]
modifierFlags:[theEvent modifierFlags]
+27 -16
View File
@@ -346,8 +346,8 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
+ (CPDictionary)themeAttributes
{
return @{
@"alternating-row-colors": [CPNull null],
@"grid-color": [CPNull null],
@"alternating-row-colors": @[[CPColor whiteColor], [CPColor colorWithRed:245.0 / 255.0 green:249.0 / 255.0 blue:252.0 / 255.0 alpha:1.0]],
@"grid-color": [CPColor colorWithHexString:@"dce0e2"],
@"grid-line-thickness": 1.0,
@"highlighted-grid-color": [CPNull null],
@"selection-color": [CPNull null],
@@ -368,7 +368,8 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
@"dropview-above-border-color": [CPNull null],
@"dropview-above-border-width": [CPNull null],
@"dropview-above-selected-border-color": [CPNull null],
@"dropview-above-selected-border-width": [CPNull null]
@"dropview-above-selected-border-width": [CPNull null],
@"header-view-height": 25.0
};
}
@@ -390,8 +391,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
_selectionHighlightStyle = CPTableViewSelectionHighlightStyleRegular;
[self setUsesAlternatingRowBackgroundColors:NO];
[self setAlternatingRowBackgroundColors:
[[CPColor whiteColor], [CPColor colorWithRed:245.0 / 255.0 green:249.0 / 255.0 blue:252.0 / 255.0 alpha:1.0]]];
[self setAlternatingRowBackgroundColors:[self valueForThemeAttribute:@"alternating-row-colors"]];
_tableColumns = [];
_tableColumnRanges = [];
@@ -401,10 +401,10 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
_intercellSpacing = CGSizeMake(3.0, 2.0);
_rowHeight = [self valueForThemeAttribute:@"default-row-height"];
[self setGridColor:[CPColor colorWithHexString:@"dce0e2"]];
[self setGridColor:[self valueForThemeAttribute:@"grid-color"]];
[self setGridStyleMask:CPTableViewGridNone];
[self setHeaderView:[[CPTableHeaderView alloc] initWithFrame:CGRectMake(0, 0, [self bounds].size.width, _rowHeight)]];
[self setHeaderView:[[CPTableHeaderView alloc] initWithFrame:CGRectMake(0, 0, [self bounds].size.width, [self valueForThemeAttribute:@"header-view-height"])]];
[self setCornerView:[[_CPCornerView alloc] initWithFrame:CGRectMake(0, 0, [CPScroller scrollerWidth], CGRectGetHeight([_headerView frame]))]];
_currentHighlightedTableColumn = nil;
@@ -3096,10 +3096,15 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
*/
- (CPView)dragViewForRowsWithIndexes:(CPIndexSet)theDraggedRows tableColumns:(CPArray)theTableColumns event:(CPEvent)theDragEvent offset:(CGPoint)dragViewOffset
{
var bounds = [self bounds],
var firstRowFrame = [self frameOfDataViewAtColumn:0 row:[theDraggedRows firstIndex]],
lastRowFrame = [self frameOfDataViewAtColumn:0 row:[theDraggedRows lastIndex]],
dragViewHeight = CGRectGetMaxY(lastRowFrame) - CGRectGetMinY(firstRowFrame);
var bounds = CGRectMake(0, 0, CGRectGetWidth([self bounds]), dragViewHeight),
dragView = [[CPView alloc] initWithFrame:bounds];
[dragView setAlphaValue:0.7];
// [dragView setBackgroundColor:[CPColor colorWithWhite:1 alpha:0.5]];
// We have to fetch all the data views for the selected rows and columns
// After that we can copy these add them to a transparent drag view and use that drag view
@@ -3107,7 +3112,11 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
[self _enumerateViewsInRows:theDraggedRows tableColumns:theTableColumns usingBlock:function(v, row, tableColumn, stop)
{
var column = [_tableColumns indexOfObjectIdenticalTo:tableColumn],
newDataView = [self preparedViewAtColumn:column row:row];
newDataView = [self preparedViewAtColumn:column row:row],
origin = [newDataView frame].origin;
origin.y -= CGRectGetMinY(firstRowFrame);
[newDataView setFrameOrigin:origin];
[dragView addSubview:newDataView];
}];
@@ -3145,7 +3154,7 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
// Now a view that clips the column data views, which itself is clipped to the content view
var columnVisRect = CGRectIntersection(columnRect, visibleRect);
frame = CGRectMake(0.0, CGRectGetHeight(headerFrame), CGRectGetWidth(columnVisRect), CGRectGetHeight(columnVisRect));
frame = CGRectMake(0.0, CGRectGetHeight(headerFrame), CGRectGetWidth(columnRect), CGRectGetHeight(columnVisRect));
var columnClipView = [[CPView alloc] initWithFrame:frame];
@@ -3180,6 +3189,7 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
// While dragging, the column is deselected in the table view
[_selectedColumnIndexes removeIndex:columnIndex];
[self setNeedsDisplay:YES];
return dragView;
}
@@ -3751,7 +3761,7 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
{
if (!dataViewsForRow)
{
dataViewsForRow = {}
dataViewsForRow = {};
_dataViewsForRows[row] = dataViewsForRow;
}
@@ -4600,7 +4610,9 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
}
var bounds = [view bounds],
viewLocation = CGPointMake(aPoint.x - CGRectGetWidth(bounds) / 2 + offset.x, aPoint.y - CGRectGetHeight(bounds) / 2 + offset.y);
firstRowFrame = [self frameOfDataViewAtColumn:0 row:[_draggedRowIndexes firstIndex]],
viewLocation = CGPointMake(aPoint.x - CGRectGetWidth(bounds) / 2 + offset.x, aPoint.y - CGRectGetHeight(bounds) / 2 + offset.y + CGRectGetMinY(firstRowFrame));
[self dragView:view at:viewLocation offset:CGPointMakeZero() event:[CPApp currentEvent] pasteboard:pboard source:self slideBack:YES];
_startTrackingPoint = nil;
@@ -4896,7 +4908,7 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
row = _retargetedDropRow;
if (row === nil)
var row = [self _proposedRowAtPoint:location];
row = [self _proposedRowAtPoint:location];
return [self _sendDataSourceAcceptDrop:sender row:row dropOperation:operation];
}
@@ -5128,7 +5140,7 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
{
[super viewWillMoveToWindow:aWindow];
[self _stopObservingFirstResponderForWindow:aWindow];
[self _stopObservingFirstResponderForWindow:[self window]];
if (aWindow)
[self _startObservingFirstResponderForWindow:aWindow];
@@ -6107,7 +6119,6 @@ var CPTableViewDataSourceKey = @"CPTableViewDataSourceKey",
CPTableViewGridStyleMaskKey = @"CPTableViewGridStyleMaskKey",
CPTableViewUsesAlternatingBackgroundKey = @"CPTableViewUsesAlternatingBackgroundKey",
CPTableViewAlternatingRowColorsKey = @"CPTableViewAlternatingRowColorsKey",
CPTableViewHeaderViewKey = @"CPTableViewHeaderViewKey",
CPTableViewCornerViewKey = @"CPTableViewCornerViewKey",
CPTableViewAutosaveNameKey = @"CPTableViewAutosaveNameKey",
CPTableViewArchivedReusableViewsKey = @"CPTableViewArchivedReusableViewsKey";
@@ -6358,7 +6369,7 @@ var CPTableViewDataSourceKey = @"CPTableViewDataSourceKey",
if (tableView._draggedColumnIsSelected)
{
CGContextSetFillColor(context, [tableView selectionHighlightColor]);
CGContextSetFillColor(context, [tableView _isFocused] ? [tableView selectionHighlightColor] : [tableView unfocusedSelectionHighlightColor]);
CGContextFillRect(context, bounds);
}
else
+8
View File
@@ -33,11 +33,14 @@
@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;
@@ -175,6 +178,11 @@ CPKernAttributeName = @"CPKernAttributeName";
return stringForPasting;
}
- (BOOL)_shouldUseSmartPasting
{
return parseInt([[CPPasteboard generalPasteboard] stringForType:_CPSmartPboardType], 10) > 0 || NO;
}
- (void)paste:(id)sender
{
var stringForPasting = [self _stringForPasting];
+48 -12
View File
@@ -331,7 +331,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
[CPTextFieldInputOwner keyUp:cappEvent];
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
}
};
CPTextFieldDOMPasswordInputElement.oninput = CPTextFieldInputFunction;
CPTextFieldDOMPasswordInputElement.onblur = CPTextFieldBlurHandler;
@@ -873,12 +873,18 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
if (!CPTextFieldInputDidBlur)
CPTextFieldBlurHandler();
CPTextFieldInputDidBlur = NO;
CPTextFieldInputResigning = NO;
if (element.parentNode == _DOMElement)
element.parentNode.removeChild(element);
// 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.
CPTextFieldInputDidBlur = NO;
CPTextFieldInputResigning = NO;
CPTextFieldInputIsActive = NO;
if (document.attachEvent)
@@ -1034,7 +1040,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
[[self window] platformWindow]._DOMBodyElement.ondrag = CPTextFieldCachedDragFunction;
[[self window] platformWindow]._DOMBodyElement.onselectstart = CPTextFieldCachedSelectStartFunction;
CPTextFieldCachedSelectStartFunction = nil
CPTextFieldCachedSelectStartFunction = nil;
CPTextFieldCachedDragFunction = nil;
}
@@ -1237,7 +1243,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
return;
if (_implementedDelegateMethods & CPTextFieldDelegate_controlTextDidBeginEditing_)
[_delegate controlTextDidBeginEditing:[[CPNotification alloc] initWithName:CPControlTextDidBeginEditingNotification object:self userInfo:@{"CPFieldEditor": [note object]}]]
[_delegate controlTextDidBeginEditing:[[CPNotification alloc] initWithName:CPControlTextDidBeginEditingNotification object:self userInfo:@{"CPFieldEditor": [note object]}]];
[super textDidBeginEditing:note];
}
@@ -1784,7 +1790,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
_implementedDelegateMethods = 0;
if ([_delegate respondsToSelector:@selector(control:didFailToFormatString:errorDescription:)])
_implementedDelegateMethods |= CPTextFieldDelegate_control_didFailToFormatString_errorDescription_
_implementedDelegateMethods |= CPTextFieldDelegate_control_didFailToFormatString_errorDescription_;
if ([_delegate respondsToSelector:@selector(controlTextDidBeginEditing:)])
_implementedDelegateMethods |= CPTextFieldDelegate_controlTextDidBeginEditing_;
@@ -2177,21 +2183,32 @@ var CPTextFieldIsEditableKey = "CPTextFieldIsEditableKey",
@end
@implementation CPTextField (CPTrackingArea)
{
CPTrackingArea _textFieldTrackingArea;
}
- (void)updateTrackingAreas
{
[self removeAllTrackingAreas];
if (_textFieldTrackingArea)
{
[self removeTrackingArea:_textFieldTrackingArea];
_textFieldTrackingArea = nil;
}
if ([self isEnabled] && (_isEditable || _isSelectable))
{
var myBounds = CGRectMakeCopy([self bounds]),
contentInset = [self currentValueForThemeAttribute:@"content-inset"];
_textFieldTrackingArea = [[CPTrackingArea alloc] initWithRect:CGRectInsetByInset(myBounds, contentInset)
options:CPTrackingCursorUpdate | CPTrackingActiveInKeyWindow
owner:self
userInfo:nil];
[self addTrackingArea:[[CPTrackingArea alloc] initWithRect:CGRectInsetByInset(myBounds, contentInset)
options:CPTrackingMouseEnteredAndExited | CPTrackingCursorUpdate | CPTrackingActiveInKeyWindow
owner:self
userInfo:nil]];
[self addTrackingArea:_textFieldTrackingArea];
}
[super updateTrackingAreas];
}
- (void)cursorUpdate:(CPEvent)anEvent
@@ -2200,3 +2217,22 @@ var CPTextFieldIsEditableKey = "CPTextFieldIsEditableKey",
}
@end
#pragma mark -
@implementation CPTextField (TableDataView)
// We overide here _CPObject+Theme setValue:forThemeAttribute as CPTextField can be used as tableView data view
// So, when outside a table data view, setValue:forThemeAttribute should store the value with the CPThemeStateNormal (default behavior)
// When inside a table data view, it should store the value with the CPThemeStateTableDataView. If not, the value won't be used if the
// theme defined a value for this attribute for state CPThemeStateTableDataView
- (void)setValue:(id)aValue forThemeAttribute:(CPString)aName
{
[super setValue:aValue forThemeAttribute:aName];
[super setValue:aValue forThemeAttribute:aName inState:CPThemeStateTableDataView];
}
@end
+1 -1
View File
@@ -412,7 +412,7 @@ var _availableTraits= [@"Normal", @"Italic", @"Bold", @"Bold Italic"],
return [_availableFonts count];
if (aBrowser === _traitBrowser)
return [_availableTraits count]
return [_availableTraits count];
return [_availableSizes count]
}
+1 -1
View File
@@ -1179,7 +1179,7 @@ var _objectsInRange = function(aList, aRange)
for (var i = 0; i < count; i++)
{
_glyphsFrames[i] = CGRectMake(origin.x, origin.y, someAdvancements[i].width, height);
_glyphsFrames[i]._descent = someAdvancements[i].descent
_glyphsFrames[i]._descent = someAdvancements[i].descent;
_glyphsOffsets[i] = height - someAdvancements[i].height;
origin.x += someAdvancements[i].width;
}
+2 -5
View File
@@ -80,7 +80,7 @@ CPLineMovesUp = 4;
@implementation CPTextContainer : CPObject
{
float _lineFragmentPadding @accessors(property=lineFragmentPadding);
CGSize _size @accessors(property=containerSize)
CGSize _size @accessors(property=containerSize);
CPLayoutManager _layoutManager @accessors(property=layoutManager);
CPTextView _textView @accessors(property=textView);
BOOL _inResizing;
@@ -168,10 +168,7 @@ CPLineMovesUp = 4;
- (void)setTextView:(CPTextView)aTextView
{
if (_textView)
{
[self _removeAllLines];
[_textView setTextContainer:nil];
}
_textView = aTextView;
@@ -252,4 +249,4 @@ var CPTextContainerSizeKey = @"CPTextContainerSizeKey",
[aCoder encodeObject:_layoutManager forKey:CPTextContainerLayoutManagerKey];
}
@end
@end
+208 -92
View File
@@ -43,6 +43,7 @@
@protocol CPTextViewDelegate <CPTextDelegate>
@optional
- (BOOL)textView:(CPTextView)aTextView doCommandBySelector:(SEL)aSelector;
- (BOOL)textView:(CPTextView)aTextView shouldChangeTextInRange:(CPRange)affectedCharRange replacementString:(CPString)replacementString;
- (CPDictionary)textView:(CPTextView)textView shouldChangeTypingAttributes:(CPDictionary)oldTypingAttributes toAttributes:(CPDictionary)newTypingAttributes;
@@ -94,13 +95,16 @@ CPSelectByWord = 1;
CPSelectByParagraph = 2;
var kDelegateRespondsTo_textShouldBeginEditing = 1 << 0,
kDelegateRespondsTo_textView_doCommandBySelector = 1 << 1,
kDelegateRespondsTo_textView_willChangeSelectionFromCharacterRange_toCharacterRange = 1 << 2,
kDelegateRespondsTo_textView_shouldChangeTextInRange_replacementString = 1 << 3,
kDelegateRespondsTo_textView_shouldChangeTypingAttributes_toAttributes = 1 << 4,
kDelegateRespondsTo_textView_textDidChange = 1 << 5,
kDelegateRespondsTo_textView_didChangeSelection = 1 << 6,
kDelegateRespondsTo_textView_didChangeTypingAttributes = 1 << 7;
kDelegateRespondsTo_textShouldEndEditing = 1 << 1,
kDelegateRespondsTo_textView_doCommandBySelector = 1 << 2,
kDelegateRespondsTo_textView_willChangeSelectionFromCharacterRange_toCharacterRange = 1 << 3,
kDelegateRespondsTo_textView_shouldChangeTextInRange_replacementString = 1 << 4,
kDelegateRespondsTo_textView_shouldChangeTypingAttributes_toAttributes = 1 << 5,
kDelegateRespondsTo_textView_textDidChange = 1 << 6,
kDelegateRespondsTo_textView_didChangeSelection = 1 << 7,
kDelegateRespondsTo_textView_didChangeTypingAttributes = 1 << 8,
kDelegateRespondsTo_textView_textDidBeginEditing = 1 << 9,
kDelegateRespondsTo_textView_textDidEndEditing = 1 << 10;
@class _CPCaret;
@@ -128,7 +132,6 @@ var kDelegateRespondsTo_textShouldBeginEditing
CPSelectionGranularity _selectionGranularity @accessors(property=selectionGranularity);
CPSelectionGranularity _previousSelectionGranularity; // private
CPSelectionGranularity _copySelectionGranularity; // private
CPTextContainer _textContainer @accessors(property=textContainer);
CPTextStorage _textStorage @accessors(getter=textStorage);
@@ -153,6 +156,10 @@ var kDelegateRespondsTo_textShouldBeginEditing
CPTimer _scrollingTimer;
CPString _placeholderString;
BOOL _firstResponderButNotEditingYet;
CPRange _mouseDownOldSelection;
}
+ (Class)_binderClassForBinding:(CPString)aBinding
@@ -234,7 +241,7 @@ var kDelegateRespondsTo_textShouldBeginEditing
_selectedTextAttributes = [CPMutableDictionary new];
_caret = [[_CPCaret alloc] initWithTextView:self];
[_caret setRect:CGRectMake(0, 0, 1, 11)]
[_caret setRect:CGRectMake(0, 0, 1, 11)];
var pboardTypes = [CPStringPboardType, CPColorDragType];
@@ -265,6 +272,7 @@ var kDelegateRespondsTo_textShouldBeginEditing
[super _removeObservers];
[self _setObserveWindowKeyNotifications:NO];
[self _removeDelegateObservers];
}
- (void)_addObservers
@@ -275,7 +283,53 @@ var kDelegateRespondsTo_textShouldBeginEditing
[super _addObservers];
[self _setObserveWindowKeyNotifications:YES];
[self _startObservingClipView];
[self _addDelegateObservers];
}
- (void)_addDelegateObservers
{
if (!_delegate) return;
var nc = [CPNotificationCenter defaultCenter];
if (_delegateRespondsToSelectorMask & kDelegateRespondsTo_textView_textDidBeginEditing)
[nc addObserver:_delegate selector:@selector(textDidBeginEditing:) name:CPTextDidBeginEditingNotification object:self];
if (_delegateRespondsToSelectorMask & kDelegateRespondsTo_textView_textDidChange)
[nc addObserver:_delegate selector:@selector(textDidChange:) name:CPTextDidChangeNotification object:self];
if (_delegateRespondsToSelectorMask & kDelegateRespondsTo_textView_textDidEndEditing)
[nc addObserver:_delegate selector:@selector(textDidEndEditing:) name:CPTextDidEndEditingNotification object:self];
if (_delegateRespondsToSelectorMask & kDelegateRespondsTo_textView_didChangeSelection)
[nc addObserver:_delegate selector:@selector(textViewDidChangeSelection:) name:CPTextViewDidChangeSelectionNotification object:self];
if (_delegateRespondsToSelectorMask & kDelegateRespondsTo_textView_didChangeTypingAttributes)
[nc addObserver:_delegate selector:@selector(textViewDidChangeTypingAttributes:) name:CPTextViewDidChangeTypingAttributesNotification object:self];
}
- (void)_removeDelegateObservers
{
if (!_delegate) return;
var nc = [CPNotificationCenter defaultCenter];
if (_delegateRespondsToSelectorMask & kDelegateRespondsTo_textView_textDidBeginEditing)
[nc removeObserver:_delegate name:CPTextDidBeginEditingNotification object:self];
if (_delegateRespondsToSelectorMask & kDelegateRespondsTo_textView_textDidChange)
[nc removeObserver:_delegate name:CPTextDidChangeNotification object:self];
if (_delegateRespondsToSelectorMask & kDelegateRespondsTo_textView_textDidEndEditing)
[nc removeObserver:_delegate name:CPTextDidEndEditingNotification object:self];
if (_delegateRespondsToSelectorMask & kDelegateRespondsTo_textView_didChangeSelection)
[nc removeObserver:_delegate name:CPTextViewDidChangeSelectionNotification object:self];
if (_delegateRespondsToSelectorMask & kDelegateRespondsTo_textView_didChangeTypingAttributes)
[nc removeObserver:_delegate name:CPTextViewDidChangeTypingAttributesNotification object:self];
}
- (void)_startObservingClipView
{
if (!_observedClipView)
@@ -359,7 +413,7 @@ var kDelegateRespondsTo_textShouldBeginEditing
- (void)_windowDidResignKey:(CPNotification)aNotification
{
if (![[self window] isKeyWindow])
[self resignFirstResponder];
[self _resignFirstResponder];
}
- (void)_windowDidBecomeKey:(CPNotification)aNotification
@@ -373,7 +427,6 @@ var kDelegateRespondsTo_textShouldBeginEditing
- (void)copy:(id)sender
{
_copySelectionGranularity = _previousSelectionGranularity;
[super copy:sender];
if (![self isRichText])
@@ -387,6 +440,7 @@ var kDelegateRespondsTo_textShouldBeginEditing
[pasteboard declareTypes:[CPStringPboardType, CPRTFPboardType] owner:nil];
[pasteboard setString:stringForPasting._string forType:CPStringPboardType];
[pasteboard setString:richData forType:CPRTFPboardType];
[pasteboard setString:_previousSelectionGranularity + '' forType:_CPSmartPboardType];
}
- (void)_pasteString:(id)stringForPasting
@@ -394,7 +448,9 @@ var kDelegateRespondsTo_textShouldBeginEditing
if (!stringForPasting)
return;
if (_copySelectionGranularity > 0 && _selectionRange.location > 0)
var shouldUseSmartPasting = [self _shouldUseSmartPasting];
if (shouldUseSmartPasting && _selectionRange.location > 0)
{
if (!_isWhitespaceCharacter([[_textStorage string] characterAtIndex:_selectionRange.location - 1]) &&
_selectionRange.location != [_layoutManager numberOfCharacters])
@@ -403,29 +459,9 @@ var kDelegateRespondsTo_textShouldBeginEditing
}
}
if (_copySelectionGranularity == CPSelectByParagraph)
{
var peekStr = stringForPasting,
i = 0;
if (![stringForPasting isKindOfClass:[CPString class]])
peekStr = stringForPasting._string;
while (_isWhitespaceCharacter([peekStr characterAtIndex:i]))
i++;
if (i)
{
if ([stringForPasting isKindOfClass:[CPString class]])
stringForPasting = [stringForPasting stringByReplacingCharactersInRange:CPMakeRange(0, i) withString:''];
else
[stringForPasting replaceCharactersInRange:CPMakeRange(0, i) withString:''];
}
}
[self insertText:stringForPasting];
if (_copySelectionGranularity > 0)
if (shouldUseSmartPasting)
{
if (!_isWhitespaceCharacter([[_textStorage string] characterAtIndex:CPMaxRange(_selectionRange)]) &&
!_isNewlineCharacter([[_textStorage string] characterAtIndex:MAX(0, _selectionRange.location - 1)]) &&
@@ -471,17 +507,33 @@ var kDelegateRespondsTo_textShouldBeginEditing
- (BOOL)becomeFirstResponder
{
[super becomeFirstResponder];
_firstResponderButNotEditingYet = YES;
[self _becomeFirstResponder];
return YES;
}
- (BOOL)resignFirstResponder
- (void)_resignFirstResponder
{
[self _reverseSetBinding];
[_caret stopBlinking];
[self setNeedsDisplay:YES];
[_CPNativeInputManager cancelCurrentInputSessionIfNeeded];
}
- (BOOL)resignFirstResponder
{
if (_firstResponderButNotEditingYet)
_firstResponderButNotEditingYet = NO;
else
{
if ([self _sendDelegateTextShouldEndEditing])
[[CPNotificationCenter defaultCenter] postNotificationName:CPTextDidEndEditingNotification object:self];
else
return NO;
}
[self _resignFirstResponder];
return YES;
}
@@ -498,6 +550,8 @@ var kDelegateRespondsTo_textShouldBeginEditing
if (aDelegate === _delegate)
return;
[self _removeDelegateObservers];
_delegateRespondsToSelectorMask = 0;
_delegate = aDelegate;
@@ -512,12 +566,21 @@ var kDelegateRespondsTo_textShouldBeginEditing
if ([_delegate respondsToSelector:@selector(textViewDidChangeTypingAttributes:)])
_delegateRespondsToSelectorMask |= kDelegateRespondsTo_textView_didChangeTypingAttributes;
if ([_delegate respondsToSelector:@selector(textDidBeginEditing:)])
_delegateRespondsToSelectorMask |= kDelegateRespondsTo_textView_textDidBeginEditing;
if ([_delegate respondsToSelector:@selector(textDidEndEditing:)])
_delegateRespondsToSelectorMask |= kDelegateRespondsTo_textView_textDidEndEditing;
if ([_delegate respondsToSelector:@selector(textView:doCommandBySelector:)])
_delegateRespondsToSelectorMask |= kDelegateRespondsTo_textView_doCommandBySelector;
if ([_delegate respondsToSelector:@selector(textShouldBeginEditing:)])
_delegateRespondsToSelectorMask |= kDelegateRespondsTo_textShouldBeginEditing;
if ([_delegate respondsToSelector:@selector(textShouldEndEditing:)])
_delegateRespondsToSelectorMask |= kDelegateRespondsTo_textShouldEndEditing;
if ([_delegate respondsToSelector:@selector(textView:willChangeSelectionFromCharacterRange:toCharacterRange:)])
_delegateRespondsToSelectorMask |= kDelegateRespondsTo_textView_willChangeSelectionFromCharacterRange_toCharacterRange;
@@ -526,6 +589,9 @@ var kDelegateRespondsTo_textShouldBeginEditing
if ([_delegate respondsToSelector:@selector(textView:shouldChangeTypingAttributes:toAttributes:)])
_delegateRespondsToSelectorMask |= kDelegateRespondsTo_textView_shouldChangeTypingAttributes_toAttributes;
if (_superview)
[self _addDelegateObservers];
}
}
@@ -662,9 +728,21 @@ var kDelegateRespondsTo_textShouldBeginEditing
- (void)didChangeText
{
[[CPNotificationCenter defaultCenter] postNotificationName:CPTextDidChangeNotification object:self];
}
if (_delegateRespondsToSelectorMask & kDelegateRespondsTo_textView_textDidChange)
[_delegate textDidChange:[[CPNotification alloc] initWithName:CPTextDidChangeNotification object:self userInfo:nil]];
- (BOOL)_didBeginEditing
{
if (_firstResponderButNotEditingYet)
{
if ([self _sendDelegateTextShouldBeginEditing])
{
[[CPNotificationCenter defaultCenter] postNotificationName:CPTextDidBeginEditingNotification object:self];
_firstResponderButNotEditingYet = NO;
} else
return NO;
}
return YES;
}
- (BOOL)shouldChangeTextInRange:(CPRange)aRange replacementString:(CPString)aString
@@ -672,7 +750,7 @@ var kDelegateRespondsTo_textShouldBeginEditing
if (![self isEditable])
return NO;
return [self _sendDelegateTextShouldBeginEditing] && [self _sendDelegateShouldChangeTextInRange:aRange replacementString:aString];
return [self _sendDelegateShouldChangeTextInRange:aRange replacementString:aString];
}
@@ -704,7 +782,7 @@ var kDelegateRespondsTo_textShouldBeginEditing
var isAttributed = [aString isKindOfClass:CPAttributedString],
string = isAttributed ? [aString string]:aString;
if (![self shouldChangeTextInRange:CPMakeRangeCopy(_selectionRange) replacementString:string])
if (![self _didBeginEditing] || ![self shouldChangeTextInRange:CPMakeRangeCopy(_selectionRange) replacementString:string])
return;
if (!isAttributed)
@@ -806,53 +884,80 @@ var kDelegateRespondsTo_textShouldBeginEditing
}
}
/*!
Sets the selection to a range of characters in response to user action.
@param range The range of characters to select. This range must begin and end on glyph boundaries and not split base glyphs and their nonspacing marks.
*/
- (void)setSelectedRange:(CPRange)range
{
[_CPNativeInputManager cancelCurrentInputSessionIfNeeded];
[self setSelectedRange:range affinity:0 stillSelecting:NO];
}
/*!
Sets the selection to a range of characters in response to user action.
@param range The range of characters to select. This range must begin and end on glyph boundaries and not split base glyphs and their nonspacing marks.
@param affinity The selection affinity for the selection. See selectionAffinity for more information about how affinities work.
@param selecting YES to behave appropriately for a continuing selection where the user is still dragging the mouse, NO otherwise. If YES, the receiver doesnt send notifications or remove the marking from its marked text. If NO, the receiver posts an NSTextViewDidChangeSelectionNotification to the default notification center and removes the marking from marked text if the new selection is greater than the marked region.
*/
- (void)setSelectedRange:(CPRange)range affinity:(CPSelectionAffinity)affinity stillSelecting:(BOOL)selecting
{
[self _setSelectedRange:range affinity:affinity stillSelecting:selecting overwriteTypingAttributes:YES];
}
/*!
Sets the selection to a range of characters in response to user action.
@param range The range of characters to select. This range must begin and end on glyph boundaries and not split base glyphs and their nonspacing marks.
@param affinity The selection affinity for the selection. See selectionAffinity for more information about how affinities work.
@param selecting YES to behave appropriately for a continuing selection where the user is still dragging the mouse, NO otherwise. If YES, the receiver doesnt send notifications or remove the marking from its marked text. If NO, the receiver posts an NSTextViewDidChangeSelectionNotification to the default notification center and removes the marking from marked text if the new selection is greater than the marked region.
@param doOverwrite YES to override typing attributes. NO to not override.
*/
- (void)_setSelectedRange:(CPRange)range affinity:(CPSelectionAffinity)affinity stillSelecting:(BOOL)selecting overwriteTypingAttributes:(BOOL)doOverwrite
{
var maxRange = CPMakeRange(0, [_layoutManager numberOfCharacters]);
var maxRange = CPMakeRange(0, [_layoutManager numberOfCharacters]),
newSelectionRange;
range = CPIntersectionRange(maxRange, range);
if (!selecting && [self _delegateRespondsToWillChangeSelectionFromCharacterRangeToCharacterRange])
{
_selectionRange = [self _sendDelegateWillChangeSelectionFromCharacterRange:_selectionRange toCharacterRange:range];
newSelectionRange = [self _sendDelegateWillChangeSelectionFromCharacterRange:_selectionRange toCharacterRange:range];
}
else
{
_selectionRange = CPMakeRangeCopy(range);
_selectionRange = [self selectionRangeForProposedRange:_selectionRange granularity:[self selectionGranularity]];
newSelectionRange = [self selectionRangeForProposedRange:range granularity:[self selectionGranularity]];
}
if (_selectionRange.length)
[_layoutManager invalidateDisplayForGlyphRange:_selectionRange];
var isNewSelection = !CPEqualRanges(newSelectionRange, _selectionRange);
if (isNewSelection)
_selectionRange = newSelectionRange;
if (newSelectionRange.length)
{
if (isNewSelection)
[_layoutManager invalidateDisplayForGlyphRange:newSelectionRange];
}
else
[self setNeedsDisplay:YES];
if (!selecting)
{
if ([self _isFirstResponder])
[self updateInsertionPointStateAndRestartTimer:((_selectionRange.length === 0) && ![_caret isBlinking])];
[self updateInsertionPointStateAndRestartTimer:((newSelectionRange.length === 0) && ![_caret isBlinking])];
if (doOverwrite && _placeholderString === nil)
// If there is no new selection but the pervious mouseDown has saved a selection we check against the saved selection instead
if (!isNewSelection && _mouseDownOldSelection)
isNewSelection = !CPEqualRanges(newSelectionRange, _mouseDownOldSelection);
if (doOverwrite && _placeholderString === nil && isNewSelection)
[self setTypingAttributes:[_textStorage attributesAtIndex:CPMaxRange(range) effectiveRange:nil]];
[[CPNotificationCenter defaultCenter] postNotificationName:CPTextViewDidChangeSelectionNotification object:self];
if (_delegateRespondsToSelectorMask & kDelegateRespondsTo_textView_didChangeSelection)
[_delegate textViewDidChangeSelection:[[CPNotification alloc] initWithName:CPTextViewDidChangeSelectionNotification object:self userInfo:nil]];
}
if (!selecting && _selectionRange.length > 0)
if (!selecting && newSelectionRange.length > 0)
[_CPNativeInputManager focusForClipboardOfTextView:self];
}
@@ -936,18 +1041,18 @@ var kDelegateRespondsTo_textShouldBeginEditing
{
var fraction = [],
point = [self convertPoint:point fromView:nil];
// convert to container coordinate
point.x -= _textContainerOrigin.x;
point.y -= _textContainerOrigin.y;
var index = [_layoutManager glyphIndexForPoint:point inTextContainer:_textContainer fractionOfDistanceThroughGlyph:fraction];
if (index === CPNotFound)
index = [_layoutManager numberOfCharacters];
else if (fraction[0] > 0.5)
index++;
return index;
}
- (CGPoint)_characterIndexFromEvent:(CPEvent)event
@@ -970,9 +1075,9 @@ var kDelegateRespondsTo_textShouldBeginEditing
[_CPNativeInputManager cancelCurrentInputSessionIfNeeded];
[_caret setVisibility:NO];
_startTrackingLocation = [self _characterIndexFromEvent:event];
var granularities = [CPNotFound, CPSelectByCharacter, CPSelectByWord, CPSelectByParagraph];
[self setSelectionGranularity:granularities[[event clickCount]]];
@@ -985,20 +1090,20 @@ var kDelegateRespondsTo_textShouldBeginEditing
placeholderFrame = CGRectIntersection([_layoutManager boundingRectForGlyphRange:placeholderRange inTextContainer:_textContainer], _frame),
rangeToHide = CPMakeRange(0, _selectionRange.location - lineBeginningIndex),
dragPlaceholder;
// hide the left part of the first line of the selection that is not included
[placeholderString addAttribute:CPForegroundColorAttributeName
value:[CPColor colorWithRed:1 green:1 blue:1 alpha:0]
range:rangeToHide];
_movingSelection = CPMakeRange(_startTrackingLocation, 0);
dragPlaceholder = [[CPTextView alloc] initWithFrame:placeholderFrame];
[dragPlaceholder._textStorage replaceCharactersInRange:CPMakeRange(0, 0) withAttributedString:placeholderString];
[dragPlaceholder setBackgroundColor:[CPColor colorWithRed:1 green:1 blue:1 alpha:0]];
[dragPlaceholder setAlphaValue:0.5];
var stringForPasting = [_textStorage attributedSubstringFromRange:CPMakeRangeCopy(_selectionRange)],
richData = [_CPRTFProducer produceRTF:stringForPasting documentAttributes:@{}],
draggingPasteboard = [CPPasteboard pasteboardWithName:CPDragPboard];
@@ -1013,17 +1118,19 @@ var kDelegateRespondsTo_textShouldBeginEditing
pasteboard:draggingPasteboard
source:self
slideBack:YES];
return;
}
var setRange = CPMakeRange(_startTrackingLocation, 0);
if ([event modifierFlags] & CPShiftKeyMask)
setRange = _MakeRangeFromAbs(_startTrackingLocation < _MidRange(_selectionRange) ? CPMaxRange(_selectionRange) : _selectionRange.location, _startTrackingLocation);
else
_scrollingTimer = [CPTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(_supportScrolling:) userInfo:nil repeats:YES]; // fixme: only start if we are in the scrolling areas
// Save old selection so we can only send textViewDidChangeTypingAttribute notification when selection is changed on mouse up.
_mouseDownOldSelection = _selectionRange;
[self setSelectedRange:setRange affinity:0 stillSelecting:YES];
}
@@ -1039,7 +1146,7 @@ var kDelegateRespondsTo_textShouldBeginEditing
if (_movingSelection)
return;
var oldRange = [self selectedRange],
index = [self _characterIndexFromEvent:event];
@@ -1066,6 +1173,7 @@ var kDelegateRespondsTo_textShouldBeginEditing
_previousSelectionGranularity = [self selectionGranularity];
[self setSelectionGranularity:CPSelectByCharacter];
[self setSelectedRange:[self selectedRange] affinity:0 stillSelecting:NO];
_mouseDownOldSelection = nil;
var point = [_layoutManager locationForGlyphAtIndex:[self selectedRange].location];
_stickyXLocation = point.x;
@@ -1478,7 +1586,7 @@ var kDelegateRespondsTo_textShouldBeginEditing
- (void)moveWordLeft:(id)sender
{
if ([self isSelectable])
[self _moveSelectionIntoDirection:-1 granularity:CPSelectByWord]
[self _moveSelectionIntoDirection:-1 granularity:CPSelectByWord];
}
- (void)moveRight:(id)sender
@@ -1489,7 +1597,7 @@ var kDelegateRespondsTo_textShouldBeginEditing
- (void)_deleteForRange:(CPRange)changedRange
{
if (![self shouldChangeTextInRange:changedRange replacementString:@""])
if (![self _didBeginEditing] || ![self shouldChangeTextInRange:changedRange replacementString:@""])
return;
changedRange = CPIntersectionRange(CPMakeRange(0, [_layoutManager numberOfCharacters]), changedRange);
@@ -1506,6 +1614,7 @@ var kDelegateRespondsTo_textShouldBeginEditing
[self didChangeText];
[_layoutManager _validateLayoutAndGlyphs];
[self sizeToFit];
[self scrollRangeToVisible:CPMakeRange(changedRange.location, 0)];
_stickyXLocation = _caret._rect.origin.x;
}
@@ -1514,7 +1623,7 @@ var kDelegateRespondsTo_textShouldBeginEditing
[_CPNativeInputManager cancelCurrentInputSessionIfNeeded]; // handle ESC during native input
}
- (void)deleteBackward:(id)sender ignoreSmart:(BOOL)ignoreFlag
- (void)deleteBackward:(id)sender handleSmart:(BOOL)handleSmart
{
var changedRange;
@@ -1524,7 +1633,7 @@ var kDelegateRespondsTo_textShouldBeginEditing
changedRange = _selectionRange;
// smart delete
if (!ignoreFlag && _copySelectionGranularity > 0 &&
if (handleSmart &&
changedRange.location > 0 && _isWhitespaceCharacter([[_textStorage string] characterAtIndex:_selectionRange.location - 1]) &&
changedRange.location < [[self string] length] && _isWhitespaceCharacter([[_textStorage string] characterAtIndex:CPMaxRange(changedRange)]))
changedRange.length++;
@@ -1535,8 +1644,7 @@ var kDelegateRespondsTo_textShouldBeginEditing
- (void)deleteBackward:(id)sender
{
_copySelectionGranularity = _previousSelectionGranularity; // smart delete
[self deleteBackward:self ignoreSmart:_selectionRange.length > 0? NO:YES];
[self deleteBackward:self handleSmart:[self _shouldUseSmartPasting] && _selectionRange.length > 0];
}
- (void)deleteForward:(id)sender
@@ -1559,12 +1667,14 @@ var kDelegateRespondsTo_textShouldBeginEditing
return;
[self copy:sender];
[self deleteBackward:sender ignoreSmart:NO];
[self deleteBackward:sender handleSmart:_previousSelectionGranularity];
}
- (void)insertLineBreak:(id)sender
{
[self insertText:@"\n"];
// make sure that the return key is "swallowed" and the default button not triggered as is the case in cocoa
[[self window] _temporarilyDisableKeyEquivalentForDefaultButton];
}
- (void)insertTab:(id)sender
@@ -1612,11 +1722,11 @@ var kDelegateRespondsTo_textShouldBeginEditing
[self _enrichEssentialTypingAttributes:_typingAttributes];
}
[[CPNotificationCenter defaultCenter] postNotificationName:CPTextViewDidChangeTypingAttributesNotification
object:self];
[[CPNotificationCenter defaultCenter] postNotificationName:CPTextViewDidChangeTypingAttributesNotification object:self];
if (_delegateRespondsToSelectorMask & kDelegateRespondsTo_textView_didChangeTypingAttributes)
[_delegate textViewDidChangeTypingAttributes:[[CPNotification alloc] initWithName:CPTextViewDidChangeTypingAttributesNotification object:self userInfo:nil]];
// We always clear the saved selection range from the last mouse down event here.
// This is normally done in mouseUp: but this is if that event was never sent.
_mouseDownOldSelection = nil;
}
- (CPDictionary)_attributesForFontPanel
@@ -1759,7 +1869,7 @@ var kDelegateRespondsTo_textShouldBeginEditing
- (void)underline:(id)sender
{
if (![self shouldChangeTextInRange:_selectionRange replacementString:nil])
if (![self _didBeginEditing] || ![self shouldChangeTextInRange:_selectionRange replacementString:nil])
return;
if (!CPEmptyRange(_selectionRange))
@@ -1999,7 +2109,7 @@ var kDelegateRespondsTo_textShouldBeginEditing
- (BOOL)shouldDrawInsertionPoint
{
return (_selectionRange.length === 0 && [self _isFocused]);
return (_selectionRange.length === 0 && [self _isFocused] && !_placeholderString);
}
- (void)updateInsertionPointStateAndRestartTimer:(BOOL)flag
@@ -2060,7 +2170,7 @@ var kDelegateRespondsTo_textShouldBeginEditing
{
var point = [info draggingLocation],
location = [self _characterIndexFromRawPoint:CGPointCreateCopy(point)];
_movingSelection = CPMakeRange(location, 0);
[_caret _drawCaretAtLocation:_movingSelection.location];
[_caret setVisibility:YES];
@@ -2073,11 +2183,11 @@ var kDelegateRespondsTo_textShouldBeginEditing
{
var location = [self convertPoint:[aSender draggingLocation] fromView:nil],
pasteboard = [aSender draggingPasteboard];
if ([pasteboard availableTypeFromArray:[CPRTFPboardType, CPStringPboardType]])
{
[_caret setVisibility:NO];
if (CPLocationInRange(_movingSelection.location, _selectionRange))
{
[self setSelectedRange:_movingSelection];
@@ -2102,7 +2212,7 @@ var kDelegateRespondsTo_textShouldBeginEditing
[self insertText:dataForPasting];
}, 0);
}
if ([pasteboard availableTypeFromArray:[CPColorDragType]])
[self setTextColor:[CPKeyedUnarchiver unarchiveObjectWithData:[pasteboard dataForType:CPColorDragType]] range:_selectionRange];
}
@@ -2142,7 +2252,8 @@ var kDelegateRespondsTo_textShouldBeginEditing
[[self class] _binderClassForBinding:CPValueBinding],
theBinding = [binderClass getBinding:CPAttributedStringBinding forObject:self] || [binderClass getBinding:CPValueBinding forObject:self];
[theBinding reverseSetValueFor:@"objectValue"];
if (theBinding && [self isEditable])
[theBinding reverseSetValueFor:@"objectValue"];
}
@end
@@ -2176,6 +2287,14 @@ var kDelegateRespondsTo_textShouldBeginEditing
return [_delegate textShouldBeginEditing:self];
}
- (BOOL)_sendDelegateTextShouldEndEditing
{
if (!(_delegateRespondsToSelectorMask & kDelegateRespondsTo_textShouldEndEditing))
return YES;
return [_delegate textShouldEndEditing:self];
}
- (BOOL)_sendDelegateShouldChangeTextInRange:(CPRange)aRange replacementString:(CPString)aString
{
if (!(_delegateRespondsToSelectorMask & kDelegateRespondsTo_textView_shouldChangeTextInRange_replacementString))
@@ -2186,7 +2305,7 @@ var kDelegateRespondsTo_textShouldBeginEditing
- (CPDictionary)_sendDelegateShouldChangeTypingAttributes:(CPDictionary)typingAttributes toAttributes:(CPDictionary)attributes
{
if (!(_delegateRespondsToSelectorMask & kDelegateRespondsTo_textView_doCommandBySelector))
if (!(_delegateRespondsToSelectorMask & kDelegateRespondsTo_textView_shouldChangeTypingAttributes_toAttributes))
return [CPDictionary dictionary];
return [_delegate textView:self shouldChangeTypingAttributes:typingAttributes toAttributes:attributes];
@@ -2275,7 +2394,7 @@ var CPTextViewAllowsUndoKey = @"CPTextViewAllowsUndoKey",
{
DOMElement _selectionBoxDOM;
CGRect _rect;
CPColor _color
CPColor _color;
CPTextView _textView;
}
@@ -2419,13 +2538,13 @@ var CPTextViewAllowsUndoKey = @"CPTextViewAllowsUndoKey",
_caretTimer = nil;
}
}
- (void)_drawCaretAtLocation:(int)aLoc
{
var rect = [_textView._layoutManager boundingRectForGlyphRange:CPMakeRange(aLoc, 1) inTextContainer:_textView._textContainer];
if (aLoc >= [_textView._layoutManager numberOfCharacters])
rect.origin.x = CGRectGetMaxX(rect)
rect.origin.x = CGRectGetMaxX(rect);
[self setRect:rect];
}
@@ -2606,7 +2725,7 @@ var _CPCopyPlaceholder = '-';
isPlain = YES;
// this is the rich chrome / FF codepath (where we can use RTF directly)
if ((richtext = nativeClipboard.getData('text/rtf')) && !(!!window.event.shiftKey) && !isPlain)
if ((richtext = nativeClipboard.getData('text/rtf')) && !(!!(e.originalEvent || e).shiftKey) && !isPlain)
{
e.preventDefault();
@@ -2634,7 +2753,7 @@ var _CPCopyPlaceholder = '-';
}, 20);
return false;
}
};
if (CPBrowserIsEngine(CPGeckoBrowserEngine))
{
@@ -2650,7 +2769,7 @@ var _CPCopyPlaceholder = '-';
e.clipboardData.setData('text/plain', stringForPasting);
return false;
}
};
_CPNativeInputField.oncut = function(e)
{
@@ -2752,6 +2871,3 @@ var _CPCopyPlaceholder = '-';
}
@end
+3 -3
View File
@@ -173,7 +173,7 @@ var CPSystemTypesetterFactory,
rect = CGRectMake(lineOrigin.x, lineOrigin.y, _lineWidth, _lineHeight),
containerSize = aContainer._size;
[_layoutManager _appendNewLineFragmentInTextContainer:_currentTextContainer forGlyphRange:lineRange]
[_layoutManager _appendNewLineFragmentInTextContainer:_currentTextContainer forGlyphRange:lineRange];
var fragment = [_layoutManager._lineFragments lastObject];
fragment._isLast = !sameLine;
@@ -293,8 +293,8 @@ var CPSystemTypesetterFactory,
if (!currentFont)
currentFont = [_textStorage font] || [CPFont systemFontOfSize:12.0];
ascent = [currentFont ascender]
descent = [currentFont descender]
ascent = [currentFont ascender];
descent = [currentFont descender];
leading = (ascent - descent) * 0.2; // FAKE leading
currentFontLineHeight = ascent - descent + leading;
+6 -6
View File
@@ -113,13 +113,13 @@ var hexTable = [];
- (CPNumber)script
{
return [CPNumber numberWithInt: script];
return [CPNumber numberWithInt:script];
}
- (CPNumber)underline
{
if (underline != 0)
return [CPNumber numberWithInteger: underline];
return [CPNumber numberWithInt:underline];
else
return nil;
}
@@ -127,7 +127,7 @@ var hexTable = [];
- (CPNumber)strikethrough
{
if (strikethrough != 0)
return [CPNumber numberWithInteger: strikethrough];
return [CPNumber numberWithInt:strikethrough];
else
return nil;
}
@@ -657,7 +657,7 @@ var kRgsymRtf = {
}
- (CPAttributedString)parseRTF:(CPString)rtf
{
rtf = rtf.replace(/\\\n/g, "\\par\n")
rtf = rtf.replace(/\\\n/g, "\\par\n");
if (rtf.length == 0)
return '';
@@ -718,7 +718,7 @@ var kRgsymRtf = {
_freename = "";
}
[self _flushCurrentRun]
[self _flushCurrentRun];
break;
case "\\":
@@ -751,7 +751,7 @@ var kRgsymRtf = {
if (hexTable && hexTable[hex.toUpperCase()] !== undefined)
temp = parseInt(hexTable[hex.toUpperCase()], 16);
[self _appendPlainString: String.fromCharCode(temp)]
[self _appendPlainString: String.fromCharCode(temp)];
hex = '';
}
}
+4 -6
View File
@@ -1,5 +1,5 @@
/*
RTFProducer.j
_CPRTFProducer.j
Serialize CPAttributedString to a RTF String
@@ -189,11 +189,9 @@ function _points2twips(a) { return (a) * 20.0; }
if (val)
{
var size = [val sizeValue];
detail = [CPString stringWithFormat:@"\\paperw%d \\paperh%d",
_points2twips(size.width),
_points2twips(size.height)];
_points2twips(val.width),
_points2twips(val.height)];
result += detail;
}
@@ -612,4 +610,4 @@ function _points2twips(a) { return (a) * 20.0; }
output += trailerString;
return output;
}
@end
@end
+129 -34
View File
@@ -24,9 +24,12 @@
@import <Foundation/CPMutableArray.j>
@import <Foundation/CPString.j>
@import <Foundation/CPKeyedUnarchiver.j>
@import <Foundation/CPBundle.j>
@class CPView
@class _CPThemeAttribute
@class CPImage
@class CPColor
var CPThemesByName = { },
CPThemeDefaultTheme = nil,
@@ -313,6 +316,71 @@ var CPThemeNameKey = @"CPThemeNameKey",
@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 CPColor and CPImage with CSS components and adapt low level UI components to
// support this new kind of CPColor/CPImage. See CPImageView, CPView and _CPImageAndTextView.
//
// To be considered and treated as CSS based, a theme must set to YES the attribute "css-based" for CPView
// in the theDescriptor (default value is NO), like in the example below :
//
// + (CPView)themedView
// {
// var view = [[CPView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
//
// [self registerThemeValues:[[@"css-based", YES]] forView:view];
//
// return view;
// }
//
// You can use the method -(BOOL)isCSSBased on a theme to determine how to cope with it in your own code.
//
// The method -(void)setCSSResourcesPath is meant to be used only by CPThemeBlend during theme loading in order to
// replace the special path "%%" in CSS components (like in url(%%packed.png) ) with the path to the theme blend resources folder.
@implementation CPTheme (CSSTheming)
- (void)setCSSResourcesPath:(CPString)pathToResources
{
[_attributes enumerateKeysAndObjectsUsingBlock:function(aKey, anObject, stop)
{
[anObject enumerateKeysAndObjectsUsingBlock:function(aKey2, anObject2, stop2)
{
// anObject2 is now a _CPThemeAttribute
[[anObject2 values] enumerateKeysAndObjectsUsingBlock:function(aKey3, anObject3, stop3)
{
if (anObject3.isa && ([anObject3 isKindOfClass:CPImage] || [anObject3 isKindOfClass:CPColor]) && [anObject3 cssDictionary])
{
// We have a CSS defined image or color
[self _fixPathInCSSDictionary:[anObject3 cssDictionary] withPathToResources:pathToResources];
[self _fixPathInCSSDictionary:[anObject3 cssBeforeDictionary] withPathToResources:pathToResources];
[self _fixPathInCSSDictionary:[anObject3 cssAfterDictionary] withPathToResources:pathToResources];
}
}];
}];
}];
}
- (void)_fixPathInCSSDictionary:(CPDictionary)aDictionary withPathToResources:(CPString)pathToResources
{
[aDictionary enumerateKeysAndObjectsUsingBlock:function(aKey, anObject, stop)
{
[aDictionary setObject:[anObject stringByReplacingOccurrencesOfString:@"%%" withString:pathToResources] forKey:aKey];
}];
}
- (BOOL)isCSSBased
{
return !![self valueForAttributeWithName:@"css-based" forClass:[CPView class]];
}
@end
#pragma mark -
/*!
* ThemeStates are immutable objects representing a particular ThemeState. Applications should never be creating
* ThemeStates directly but should instead use the CPThemeState function.
@@ -659,6 +727,7 @@ CPThemeStateNormalString = String(CPThemeStateNormal);
- (id)valueForState:(ThemeState)aState
{
// First, search in cache.
var stateName = String(aState),
value = _cache[stateName];
@@ -666,50 +735,76 @@ CPThemeStateNormalString = String(CPThemeStateNormal);
if (value !== undefined)
return value;
// Not in cache. OK, search in values.
value = [_values objectForKey:stateName];
if (value === undefined || value === nil)
if ((value !== undefined) && (value !== nil))
return _cache[stateName] = value;
// No direct match in values.
// If this is a composite state, find the closest partial subset match.
if (aState._stateNameCount > 1)
{
// If this is a composite state, find the closest partial subset match.
if (aState._stateNameCount > 1)
var largestThemeState = [self largestThemeStateMatchForState:aState returnedValue:@ref(value)];
if ((value !== undefined) && (value !== nil))
return _cache[stateName] = value;
}
// Still don't have a value? OK, let's use the normal value.
value = [_values objectForKey:String(CPThemeStateNormal)];
if ((value !== undefined) && (value !== nil))
return _cache[stateName] = value;
// No normal value, try asking _themeDefaultAttribute
value = [_themeDefaultAttribute valueForState:aState];
if ((value !== undefined) && (value !== nil))
return _cache[stateName] = value;
// Well, last option, use default value
value = _defaultValue;
// Class theme attributes cannot use nil because it's a dictionary.
// So transform CPNull into nil.
if (value === [CPNull null])
value = nil;
return _cache[stateName] = value;
}
- (CPInteger)largestThemeStateMatchForState:(ThemeState)aState returnedValue:(id)valueRef
{
var stateName = String(aState),
value,
states = [_values allKeys],
count = states ? states.length : 0,
largestThemeState = 0;
while (count--)
{
var stateObject = CPThemeState(states[count]);
if (stateObject.isSubsetOf(aState) && stateObject._stateNameCount > largestThemeState)
{
var states = [_values allKeys],
count = states ? states.length : 0,
largestThemeState = 0;
while (count--)
{
var stateObject = CPThemeState(states[count]);
if (stateObject.isSubsetOf(aState) && stateObject._stateNameCount > largestThemeState)
{
value = [_values objectForKey:states[count]];
largestThemeState = stateObject._stateNameCount;
}
}
value = [_values objectForKey:states[count]];
largestThemeState = stateObject._stateNameCount;
}
// Still don't have a value? OK, let's use the normal value.
if (value === undefined || value === nil)
value = [_values objectForKey:String(CPThemeStateNormal)];
}
if (value === undefined || value === nil)
value = [_themeDefaultAttribute valueForState:aState];
// _themeDefaultAttribute may have a larger theme state match. If so, we have to take it. If not, we take our closest match.
var defaultAttributeFoundValue,
defaultAttributeMatchLength = [_themeDefaultAttribute largestThemeStateMatchForState:aState returnedValue:@ref(defaultAttributeFoundValue)];
if (value === undefined || value === nil)
if (defaultAttributeMatchLength > largestThemeState)
{
value = _defaultValue;
// Class theme attributes cannot use nil because it's a dictionary.
// So transform CPNull into nil.
if (value === [CPNull null])
value = nil;
value = defaultAttributeFoundValue;
largestThemeState = defaultAttributeMatchLength;
}
_cache[stateName] = value;
return value;
@deref(valueRef) = value;
return largestThemeState;
}
- (_CPThemeAttribute)attributeBySettingParentAttribute:(_CPThemeAttribute)anAttribute
@@ -769,7 +864,7 @@ var ParentAttributeForCoder = nil;
if ([aCoder containsValueForKey:@"state"])
state = [aCoder decodeObjectForKey:@"state"];
else
state = CPThemeStateNormalString
state = CPThemeStateNormalString;
[_values setObject:[aCoder decodeObjectForKey:"value"] forKey:state];
}
+11
View File
@@ -95,6 +95,17 @@
[unarchiver finishDecoding];
}
// CSS Theming
for (var i = 0, nb = [_themes count], allThemes = [self themeNames], aThemeName, aTheme; i < nb; i++)
{
aThemeName = allThemes[i];
aTheme = [CPTheme themeNamed:aThemeName];
if ([aTheme isCSSBased])
[aTheme setCSSResourcesPath:[aBundle resourcePath]];
}
[_loadDelegate blendDidFinishLoading:self];
}
+14 -6
View File
@@ -523,17 +523,25 @@ CPTokenFieldDeleteButtonType = 1;
var element = [self _inputElement];
CPTokenFieldInputResigning = YES;
element.blur();
if (CPTokenFieldInputIsActive)
element.blur();
if (!CPTokenFieldInputDidBlur)
CPTokenFieldBlurHandler();
CPTokenFieldInputDidBlur = NO;
CPTokenFieldInputResigning = NO;
if (element.parentNode == [_tokenScrollView documentView]._DOMElement)
element.parentNode.removeChild(element);
// Previosly, we unflagged CPTokenFieldInputDidBlur and CPTokenFieldInputResigning before
// the call to removeChild. This may result 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 CPTokenFieldInputDidBlur and CPTokenFieldInputResigning
// only after removing the element.
CPTokenFieldInputDidBlur = NO;
CPTokenFieldInputResigning = NO;
CPTokenFieldInputIsActive = NO;
if (document.attachEvent)
@@ -541,7 +549,7 @@ CPTokenFieldDeleteButtonType = 1;
CPTokenFieldCachedSelectStartFunction = nil;
CPTokenFieldCachedDragFunction = nil;
document.body.ondrag = CPTokenFieldCachedDragFunction
document.body.ondrag = CPTokenFieldCachedDragFunction;
document.body.onselectstart = CPTokenFieldCachedSelectStartFunction
}
@@ -1239,7 +1247,7 @@ CPTokenFieldDeleteButtonType = 1;
var scrollToToken = _shouldScrollTo;
if (scrollToToken === CPScrollDestinationLeft)
scrollToToken = tokens[_selectedRange.location]
scrollToToken = tokens[_selectedRange.location];
else if (scrollToToken === CPScrollDestinationRight)
scrollToToken = tokens[MAX(0, CPMaxRange(_selectedRange) - 1)];
[self _scrollTokenViewToVisible:scrollToToken];
+2 -2
View File
@@ -153,7 +153,7 @@ var CPToolbarsByIdentifier = nil,
if (!toolbarsSharingIdentifier)
{
toolbarsSharingIdentifier = []
toolbarsSharingIdentifier = [];
[CPToolbarsByIdentifier setObject:toolbarsSharingIdentifier forKey:identifier];
}
@@ -588,7 +588,7 @@ var CPToolbarIdentifierKey = @"CPToolbarIdentifierKey",
[aCoder encodeBool:_showsBaselineSeparator forKey:CPToolbarShowsBaselineSeparatorKey];
[aCoder encodeBool:_allowsUserCustomization forKey:CPToolbarAllowsUserCustomizationKey];
[aCoder encodeBool:_isVisible forKey:CPToolbarIsVisibleKey];
[aCoder encodeInt:_sizeMode forKey:CPToolbarSizeModeKey]
[aCoder encodeInt:_sizeMode forKey:CPToolbarSizeModeKey];
[aCoder encodeObject:_identifiedItems forKey:CPToolbarIdentifiedItemsKey];
[aCoder encodeObject:_defaultItems forKey:CPToolbarDefaultItemsKey];
+64 -28
View File
@@ -129,7 +129,8 @@ var DOMElementPrototype = nil,
BackgroundVerticalThreePartImage = 1,
BackgroundHorizontalThreePartImage = 2,
BackgroundNinePartImage = 3,
BackgroundTransparentColor = 4;
BackgroundTransparentColor = 4,
BackgroundCSSStyling = 5;
#endif
var CPViewFlags = { },
@@ -195,6 +196,10 @@ var CPViewHighDPIDrawingEnabled = YES;
CPArray _DOMImageSizes;
unsigned _backgroundType;
// CSS styling
CPArray _cssStylePreviousState;
DOMElement _cssStyleNode;
#endif
CGRect _dirtyRect;
@@ -320,6 +325,18 @@ var CPViewHighDPIDrawingEnabled = YES;
return nil;
}
+ (CPString)defaultThemeClass
{
return @"view";
}
+ (CPDictionary)themeAttributes
{
return @{
@"css-based": NO
};
}
- (void)_setupViewFlags
{
var theClass = [self class],
@@ -399,6 +416,8 @@ var CPViewHighDPIDrawingEnabled = YES;
_DOMImageParts = [];
_DOMImageSizes = [];
_cssStylePreviousState = @[];
#endif
_animator = nil;
@@ -409,7 +428,12 @@ var CPViewHighDPIDrawingEnabled = YES;
_inhibitDOMUpdates = NO;
_forceUpdates = NO;
}
// We force here an updateTrackingAreas in order to let the view install its own tracking areas
// in the case where an externally owned tracking area is installed on this view before putting
// it in the view hierarchy.
[self updateTrackingAreas];
}
return self;
}
@@ -449,7 +473,7 @@ var CPViewHighDPIDrawingEnabled = YES;
return;
if (!_toolTipFunctionIn)
_toolTipFunctionIn = function(e) { [_CPToolTip scheduleToolTipForView:self]; }
_toolTipFunctionIn = function(e) { [_CPToolTip scheduleToolTipForView:self]; };
if (!_toolTipFunctionOut)
_toolTipFunctionOut = function(e) { [_CPToolTip invalidateCurrentToolTipIfNeeded]; };
@@ -1954,15 +1978,25 @@ var CPViewHighDPIDrawingEnabled = YES;
_backgroundColor = aColor;
#if PLATFORM(DOM)
if (_backgroundType === BackgroundCSSStyling)
[_backgroundColor restorePreviousCSSState:@ref(_cssStylePreviousState) forDOMElement:_DOMElement];
var patternImage = [_backgroundColor patternImage],
colorExists = _backgroundColor && ([_backgroundColor patternImage] || [_backgroundColor alphaComponent] > 0.0),
colorHasAlpha = colorExists && [_backgroundColor alphaComponent] < 1.0,
supportsRGBA = CPFeatureIsCompatible(CPCSSRGBAFeature),
colorNeedsDOMElement = colorHasAlpha && !supportsRGBA,
amount = 0,
slices;
slices,
// For CSS theming
isCSSBasedColor = [_backgroundColor isCSSBased];
if ([patternImage isThreePartImage])
if (isCSSBasedColor)
{
_backgroundType = BackgroundCSSStyling;
amount = -_DOMImageParts.length;
}
else if ([patternImage isThreePartImage])
{
_backgroundType = [patternImage isVertical] ? BackgroundVerticalThreePartImage : BackgroundHorizontalThreePartImage;
amount = 3;
@@ -2025,7 +2059,14 @@ var CPViewHighDPIDrawingEnabled = YES;
_DOMElement.removeChild(_DOMImageParts.pop());
}
if (_backgroundType === BackgroundTrivialColor || _backgroundType === BackgroundTransparentColor)
if (_backgroundType === BackgroundCSSStyling)
{
_cssStyleNode = [_backgroundColor applyCSSColorForView:self
onDOMElement:_DOMElement
styleNode:_cssStyleNode
previousState:@ref(_cssStylePreviousState)];
}
else if (_backgroundType === BackgroundTrivialColor || _backgroundType === BackgroundTransparentColor)
{
var colorCSS = colorExists ? [_backgroundColor cssString] : "";
@@ -2983,7 +3024,7 @@ setBoundsOrigin:
*/
- (BOOL)inLiveResize
{
return _inLiveResize;
return [self window] && [[self window] _inLiveResize];
}
/*!
@@ -3434,6 +3475,17 @@ setBoundsOrigin:
@end
@implementation CPView (CSSTheming)
- (void)setDOMClassName:(CPString)aClassName
{
#if PLATFORM(DOM)
_DOMElement.className = aClassName;
#endif
}
@end
@implementation CPView (Appearance)
@@ -3553,11 +3605,12 @@ setBoundsOrigin:
/*!
Invoked automatically when the views geometry changes such that its tracking areas need to be recalculated.
You should override this method to remove out of date tracking areas and add recomputed tracking areas;
You should override this method to remove out of date tracking areas, add recomputed tracking areas and then call super;
Cocoa calls this on every view, whereas they have tracking area(s) or not.
Cappuccino behaves differently :
- updateTrackingAreas is called when placing a view in the view hierarchy (that is in a window)
- updateTrackingAreas is called during initWithFrame
- updateTrackingAreas is also called when placing a view in the view hierarchy (that is in a window)
- if you have only CPTrackingInVisibleRect tracking areas attached to a view, it will not be called again (until you move the view in the hierarchy)
- if you have at least one non-CPTrackingInVisibleRect tracking area attached, it will be called every time the view geometry could be modified
You don't have to touch to CPTrackingInVisibleRect tracking areas, they will be automatically updated
@@ -3571,25 +3624,6 @@ setBoundsOrigin:
}
/*!
This utility method is intended for CPView subclasses overriding updateTrackingAreas
Typical use would be :
- (void)updateTrackingAreas
{
[self removeAllTrackingAreas];
... add your specific updated tracking areas ...
}
*/
- (void)removeAllTrackingAreas
{
while (_trackingAreas.length > 0)
[self _removeTrackingArea:_trackingAreas[0]];
}
// Internal methods
- (void)_removeTrackingArea:(CPTrackingArea)trackingArea
@@ -3749,6 +3783,8 @@ var CPViewAutoresizingMaskKey = @"CPViewAutoresizingMask",
// DOM SETUP
#if PLATFORM(DOM)
_cssStylePreviousState = @[];
_DOMImageParts = [];
_DOMImageSizes = [];
+129 -26
View File
@@ -54,6 +54,7 @@
@class CPToolbar
@class CPWindowController
@class _CPWindowFrameAnimation
@class _CPWindowFrameAnimationDelegate
@global CPApp
@global _CPPlatformWindowWillCloseNotification
@@ -178,7 +179,7 @@ var CPWindowActionMessageKeys = [
BOOL _isVisible;
BOOL _hasBeenOrderedIn @accessors;
BOOL _isMiniaturized;
BOOL _isAnimating;
BOOL _isAnimating @accessors(setter=_setAnimating:);
BOOL _hasShadow;
BOOL _isMovableByWindowBackground;
BOOL _isMovable;
@@ -237,6 +238,7 @@ var CPWindowActionMessageKeys = [
CPButton _defaultButton;
BOOL _defaultButtonEnabled;
BOOL _defaultButtonDisabledTemporarily;
BOOL _autorecalculatesKeyViewLoop;
BOOL _keyViewLoopIsDirty;
@@ -261,6 +263,7 @@ var CPWindowActionMessageKeys = [
CPWindow _parentView;
BOOL _isSheet;
_CPWindowFrameAnimation _frameAnimation;
_CPWindowFrameAnimationDelegate _frameAnimationDelegate;
}
+ (Class)_binderClassForBinding:(CPString)aBinding
@@ -336,6 +339,8 @@ CPTexturedBackgroundWindowMask
_isSheet = NO;
_sheetContext = nil;
_parentView = nil;
_frameAnimation = nil;
_frameAnimationDelegate = nil;
// Set up our window number.
_windowNumber = [CPApp._windows count];
@@ -398,6 +403,7 @@ CPTexturedBackgroundWindowMask
_autorecalculatesKeyViewLoop = NO;
_defaultButtonEnabled = YES;
_defaultButtonDisabledTemporarily = NO;
_keyViewLoopIsDirty = NO;
_hasBecomeKeyWindow = NO;
@@ -742,7 +748,7 @@ CPTexturedBackgroundWindowMask
{
[_frameAnimation stopAnimation];
_frameAnimation = [[_CPWindowFrameAnimation alloc] initWithWindow:self targetFrame:frame];
[_frameAnimation setDelegate:[self _frameAnimationDelegate]];
[_frameAnimation startAnimation];
}
else
@@ -802,6 +808,13 @@ CPTexturedBackgroundWindowMask
[_platformWindow setContentRect:aFrame];
}
- (id)_frameAnimationDelegate
{
if (_frameAnimationDelegate == nil)
_frameAnimationDelegate = [[_CPWindowFrameAnimationDelegate alloc] initWithWindow:self];
return _frameAnimationDelegate;
}
/*
Constrain a frame so that the window remains at least partially visible on screen,
moving or resizing the frame as necessary.
@@ -979,6 +992,9 @@ CPTexturedBackgroundWindowMask
[self makeMainWindow];
[_platformWindow _setShouldUpdateContentRect:YES];
if ([self attachedSheet])
[_platformWindow order:CPWindowAbove window:[self attachedSheet] relativeTo:nil];
}
/*
@@ -1840,16 +1856,12 @@ CPTexturedBackgroundWindowMask
// CPLeftMouseDown is needed for window moving and resizing to work.
// CPMouseMoved is needed for rollover effects on title bar buttons.
if (sheet)
if (sheet && _sheetContext["isAttached"])
{
switch (type)
{
case CPLeftMouseDown:
// This is needed when a doubleClick occurs when the sheet is closing or opening
if (!_parentWindow)
return;
[_windowView mouseDown:anEvent];
// -dw- if the window is clicked, the sheet should come to front, and become key,
@@ -1892,7 +1904,7 @@ CPTexturedBackgroundWindowMask
// Make sure the browser doesn't try to do its own tab handling.
// This is important or the browser might blur the shared text field or token field input field,
// even that we just moved it to a new first responder.
[[[anEvent window] platformWindow] _propagateCurrentDOMEvent:NO]
[[[anEvent window] platformWindow] _propagateCurrentDOMEvent:NO];
#endif
return;
}
@@ -1906,7 +1918,7 @@ CPTexturedBackgroundWindowMask
// Make sure the browser doesn't try to do its own tab handling.
// This is important or the browser might blur the shared text field or token field input field,
// even that we just moved it to a new first responder.
[[[anEvent window] platformWindow] _propagateCurrentDOMEvent:NO]
[[[anEvent window] platformWindow] _propagateCurrentDOMEvent:NO];
#endif
}
@@ -1920,8 +1932,7 @@ CPTexturedBackgroundWindowMask
[[self firstResponder] keyDown:anEvent];
// Trigger the default button if needed
// FIXME: Is this only applicable in a sheet? See isse: #722.
if (![self disableKeyEquivalentForDefaultButton])
if (_defaultButtonEnabled && !_defaultButtonDisabledTemporarily)
{
var defaultButton = [self defaultButton],
keyEquivalent = [defaultButton keyEquivalent],
@@ -1931,6 +1942,8 @@ CPTexturedBackgroundWindowMask
[[self defaultButton] performClick:self];
}
_defaultButtonDisabledTemporarily = NO;
return;
case CPScrollWheel:
@@ -1972,7 +1985,7 @@ CPTexturedBackgroundWindowMask
var theWindow = [anEvent window],
selector = type == CPRightMouseDown ? @selector(rightMouseDown:) : @selector(mouseDown:);
if ([theWindow isKeyWindow] || ([theWindow becomesKeyOnlyIfNeeded] && ![_leftMouseDownView needsPanelToBecomeKey]))
if (([theWindow _isFrontmostWindow] && [theWindow isKeyWindow]) || ([theWindow becomesKeyOnlyIfNeeded] && ![_leftMouseDownView needsPanelToBecomeKey]))
return [_leftMouseDownView performSelector:selector withObject:anEvent];
else
{
@@ -1998,13 +2011,13 @@ CPTexturedBackgroundWindowMask
if (type == CPRightMouseDragged)
{
selector = @selector(rightMouseDragged:)
selector = @selector(rightMouseDragged:);
if (![_leftMouseDownView respondsToSelector:selector])
selector = nil;
}
if (!selector)
selector = @selector(mouseDragged:)
selector = @selector(mouseDragged:);
return [_leftMouseDownView performSelector:selector withObject:anEvent];
@@ -2018,6 +2031,25 @@ CPTexturedBackgroundWindowMask
}
}
- (void)_startLiveResize
{
[[CPNotificationCenter defaultCenter]
postNotificationName:CPWindowWillStartLiveResizeNotification
object:self];
}
- (void)_endLiveResize
{
[[CPNotificationCenter defaultCenter]
postNotificationName:CPWindowDidEndLiveResizeNotification
object:self];
}
- (BOOL)_inLiveResize
{
return [_windowView _isTracking];
}
/*!
Returns the window's number in the desktop's screen list
*/
@@ -2076,6 +2108,28 @@ CPTexturedBackgroundWindowMask
return (_styleMask & CPTitledWindowMask) || [self isFullPlatformWindow] || _isSheet;
}
/* @ignore */
- (BOOL)_isFrontmostWindow
{
if ([self isFullBridge])
return YES;
var orderedWindows = [CPApp orderedWindows];
if ([orderedWindows count] == 0)
return YES;
if ([orderedWindows objectAtIndex:0] === self)
return YES;
// this is necessary, because the CPMainMenuWindow is always the first object in orderedWindows, even if another window is in front of it
if ([[orderedWindows objectAtIndex:0] level] === CPMainMenuWindowLevel &&
[orderedWindows count] > 1 && [orderedWindows objectAtIndex:1] === self)
return YES;
return NO;
}
/*!
Returns \c YES if the window is the key window.
*/
@@ -3388,6 +3442,11 @@ CPTexturedBackgroundWindowMask
_defaultButtonEnabled = NO;
}
- (void)_temporarilyDisableKeyEquivalentForDefaultButton
{
_defaultButtonDisabledTemporarily = YES;
}
/*!
Removes the key equivalent for the default button.
Note: this method is deprecated. Use disableKeyEquivalentForDefaultButton instead.
@@ -3578,6 +3637,20 @@ var keyViewComparator = function(lhs, rhs, context)
return [CPPlatform isBrowser] ? [self convertBaseToPlatformWindow:aPoint] : [self convertBaseToScreen:aPoint];
}
/*!
@ignore
get the scroll offset (if any) from native scroll bars (can happen when the platform window shrinks below minSize)
*/
- (CGPoint)_nativeScrollOffset
{
#if PLATFORM(DOM)
return CGPointMake(_windowView._DOMElement.scrollLeft, _windowView._DOMElement.scrollTop);
#else
CGPointMake(0, 0);
#endif
}
/*!
Converts aPoint from the global coordinate system to the window coordinate system.
*/
@@ -3594,9 +3667,10 @@ var keyViewComparator = function(lhs, rhs, context)
if ([self _sharesChromeWithPlatformWindow])
return CGPointMakeCopy(aPoint);
var origin = [self frame].origin;
var origin = [self frame].origin,
scrollOffset = [self _nativeScrollOffset];
return CGPointMake(aPoint.x + origin.x, aPoint.y + origin.y);
return CGPointMake(aPoint.x + origin.x - scrollOffset.x, aPoint.y + origin.y - scrollOffset.y);
}
/*!
@@ -3607,9 +3681,10 @@ var keyViewComparator = function(lhs, rhs, context)
if ([self _sharesChromeWithPlatformWindow])
return CGPointMakeCopy(aPoint);
var origin = [self frame].origin;
var origin = [self frame].origin,
scrollOffset = [self _nativeScrollOffset];
return CGPointMake(aPoint.x - origin.x, aPoint.y - origin.y);
return CGPointMake(aPoint.x - origin.x + scrollOffset.x, aPoint.y - origin.y + scrollOffset.y);
}
- (CGPoint)convertScreenToBase:(CGPoint)aPoint
@@ -3768,13 +3843,6 @@ var interpolate = function(fromValue, toValue, progress)
return self;
}
- (void)startAnimation
{
[super startAnimation];
_window._isAnimating = YES;
}
- (void)setCurrentProgress:(float)aProgress
{
[super setCurrentProgress:aProgress];
@@ -3782,7 +3850,7 @@ var interpolate = function(fromValue, toValue, progress)
var value = [self currentValue];
if (value == 1.0)
_window._isAnimating = NO;
[_window _setAnimating:NO];
var newFrame = CGRectMake(
interpolate(CGRectGetMinX(_startFrame), CGRectGetMinX(_targetFrame), value),
@@ -3795,6 +3863,41 @@ var interpolate = function(fromValue, toValue, progress)
@end
@implementation _CPWindowFrameAnimationDelegate : CPObject
{
CPWindow _window;
}
- (id)initWithWindow:(CPWindow)aWindow
{
self = [super init];
_window = aWindow;
return self;
}
- (BOOL)animationShouldStart:(CPAnimation)animation
{
[_window _setAnimating:YES];
[_window _startLiveResize];
return YES;
}
- (void)animationDidStop:(CPAnimation)animation
{
[_window _setAnimating:NO];
[_window _endLiveResize];
}
- (void)animationDidEnd:(CPAnimation)animation
{
[_window _setAnimating:NO];
[_window _endLiveResize];
}
@end
@implementation CPWindow (CPDraggingAdditions)
+2
View File
@@ -176,6 +176,8 @@ CPWindowDidEndSheetNotification = @"CPWindowDidEndSheetNotificat
CPWindowDidMiniaturizeNotification = @"CPWindowDidMiniaturizeNotification";
CPWindowWillMiniaturizeNotification = @"CPWindowWillMiniaturizeNotification";
CPWindowDidDeminiaturizeNotification = @"CPWindowDidDeminiaturizeNotification";
CPWindowWillStartLiveResizeNotification = @"CPWindowWillStartLiveResizeNotification";
CPWindowDidEndLiveResizeNotification = @"CPWindowDidEndLiveResizeNotification";
_CPWindowDidChangeFirstResponderNotification = @"_CPWindowDidChangeFirstResponderNotification";
@@ -29,7 +29,7 @@
+ (CPString)defaultThemeClass
{
return @"bordeless-bridge-window-view";
return @"borderless-bridge-window-view";
}
+ (CPDictionary)themeAttributes
@@ -81,4 +81,19 @@
[_toolbarBackgroundView setFrame:frame];
}
- (void)setFrameSize:(CGSize)aFrameSize
{
[super setFrameSize:aFrameSize];
var theWindow = [self window];
if (_frame.size.width < theWindow._minSize.width || _frame.size.height < theWindow._minSize.height)
[theWindow._contentView setFrameSize:CGSizeMake(MAX(_frame.size.width, theWindow._minSize.width), MAX(_frame.size.height, theWindow._minSize.height))];
#if PLATFORM(DOM)
_DOMElement.style.overflowX = (_frame.size.width < theWindow._minSize.width)? "scroll":"hidden";
_DOMElement.style.overflowY = (_frame.size.height < theWindow._minSize.height)? "scroll":"hidden";
#endif
}
@end
+1 -1
View File
@@ -183,7 +183,7 @@
if (_styleMask & CPClosableWindowMask)
{
[_closeButton setFrameOrigin:[self valueForThemeAttribute:@"close-image-origin"]];
[_closeButton setFrameSize:[self valueForThemeAttribute:@"close-image-size"]]
[_closeButton setFrameSize:[self valueForThemeAttribute:@"close-image-size"]];
[_closeButton setImage:[self valueForThemeAttribute:@"close-image"]];
[_closeButton setAlternateImage:[self valueForThemeAttribute:@"close-active-image"]];
}
+23 -6
View File
@@ -64,6 +64,8 @@ _CPWindowViewResizeSlop = 3;
CGRect _cachedScreenFrame;
CPView _sheetShadowView;
BOOL _isTracking @accessors(getter=_isTracking);
}
+ (CGRect)contentRectForFrameRect:(CGRect)aFrameRect
@@ -148,6 +150,7 @@ _CPWindowViewResizeSlop = 3;
_styleMask = aStyleMask;
_resizeIndicatorOffset = CGSizeMakeZero();
_toolbarOffset = CGSizeMakeZero();
_isTracking = NO;
}
return self;
@@ -458,6 +461,8 @@ _CPWindowViewResizeSlop = 3;
if (type === CPLeftMouseUp)
{
_cachedScreenFrame = nil;
_isTracking = NO;
[_window _endLiveResize];
return;
}
@@ -474,6 +479,12 @@ _CPWindowViewResizeSlop = 3;
}
else if (type === CPLeftMouseDragged)
{
if (!_isTracking)
{
_isTracking = YES;
[_window _startLiveResize];
}
var deltaX = globalLocation.x - _mouseDraggedPoint.x,
deltaY = globalLocation.y - _mouseDraggedPoint.y,
startX = CGRectGetMinX(_cachedFrame),
@@ -973,16 +984,22 @@ _CPWindowViewResizeSlop = 3;
@end
@implementation _CPWindowView (TrackingAreaAdditions)
{
CPTrackingArea _windowViewTrackingArea;
}
- (void)updateTrackingAreas
{
[self removeAllTrackingAreas];
if (_windowViewTrackingArea)
[self removeTrackingArea:_windowViewTrackingArea];
[self addTrackingArea:[[CPTrackingArea alloc] initWithRect:[self contentRectForFrameRect:[self frame]]
options:CPTrackingCursorUpdate | CPTrackingActiveInActiveApp
owner:self
userInfo:nil]];
_windowViewTrackingArea = [[CPTrackingArea alloc] initWithRect:[self contentRectForFrameRect:[self frame]]
options:CPTrackingCursorUpdate | CPTrackingActiveInActiveApp
owner:self
userInfo:nil];
[self addTrackingArea:_windowViewTrackingArea];
[super updateTrackingAreas];
}
@end
+1 -1
View File
@@ -364,7 +364,7 @@
{
[viewControllerView removeFromSuperview];
[viewControllerView setFrame:[contentView frame]];
[viewControllerView setAutoresizingMask:[contentView autoresizingMask]]
[viewControllerView setAutoresizingMask:[contentView autoresizingMask]];
[[self window] setContentView:viewControllerView];
}
else
+25
View File
@@ -222,3 +222,28 @@ var _CPCibCustomResourceClassNameKey = @"_CPCibCustomResourceClassNameKey",
}
@end
@implementation _CPCibCustomResource (CSSTheming)
- (BOOL)isCSSBased
{
return NO;
}
- (BOOL)hasCSSDictionary
{
return NO;
}
- (BOOL)hasCSSBeforeDictionary
{
return NO;
}
- (BOOL)hasCSSAfterDictionary
{
return NO;
}
@end
+1 -1
View File
@@ -230,7 +230,7 @@ var _CPCibObjectDataNamesKeysKey = @"_CPCibObjectDataNamesKeysKey
if ([object respondsToSelector:@selector(_cibInstantiate)])
{
var instantiatedObject = [object _cibInstantiate];
instantiatedObject = [object _cibInstantiate];
if (instantiatedObject !== object)
{
+1 -1
View File
@@ -522,7 +522,7 @@ var CALayerRegisteredRunLoopUpdates = nil;
if (USE_BUFFER)
{
if (_delegateRespondsToDisplayLayerSelector)
return [_delegate displayInLayer:self];
return [_delegate displayLayer:self];
if (CGRectGetWidth(_backingStoreFrame) == 0.0 || CGRectGetHeight(_backingStoreFrame) == 0.0)
return;
+54 -26
View File
@@ -66,16 +66,6 @@ var _CPAnimationContextStack = nil,
return self;
}
- (id)copy
{
var context = [[CPAnimationContext alloc] init];
[context setDuration:[self duration]];
[context setTimingFunction:[self timingFunction]];
[context setCompletionHandler:[self completionHandler]];
return context;
}
+ (void)_scheduleAnimationContextStackFlush
{
if (!_animationFlushingObserver)
@@ -90,16 +80,13 @@ var _CPAnimationContextStack = nil,
+ (void)beginGrouping
{
var newContext;
var newContext = [[CPAnimationContext alloc] init];
if ([_CPAnimationContextStack count])
{
var currentContext = [_CPAnimationContextStack lastObject];
newContext = [currentContext copy];
}
else
{
newContext = [[CPAnimationContext alloc] init];
[newContext setDuration:[currentContext duration]];
[newContext setTimingFunction:[currentContext timingFunction]];
}
[_CPAnimationContextStack addObject:newContext];
@@ -155,9 +142,6 @@ var _CPAnimationContextStack = nil,
duration = [animation duration] || [self duration];
needsPeriodicFrameUpdates = [[anObject animator] needsPeriodicFrameUpdatesForKeyPath:aKeyPath];
if (_completionHandlerAgent)
_completionHandlerAgent.increment();
var animatorClass = [[anObject class] animatorClass];
var completionFunction = function()
@@ -221,7 +205,12 @@ var _CPAnimationContextStack = nil,
if (_animationsByObject.size == 0)
{
if (_completionHandlerAgent)
{
#if (DEBUG)
CPLog.debug("No animations are scheduled. Firing completion handler");
#endif
_completionHandlerAgent.fire();
}
}
else
[self _startAnimations];
@@ -242,8 +231,23 @@ var _CPAnimationContextStack = nil,
_animationsByObject.clear();
var k = timers.length,
n = cssAnimations.length;
if (_completionHandlerAgent)
{
if (n == 0)
{
#if (DEBUG)
CPLog.debug("Animations are not needed. Firing completion handler");
#endif
_completionHandlerAgent.fire();
}
else
_completionHandlerAgent.increment(n);
}
// start timers
var k = timers.length;
while(k--)
{
#if (DEBUG)
@@ -253,7 +257,6 @@ var _CPAnimationContextStack = nil,
}
// start css animations
var n = cssAnimations.length;
while(n--)
{
#if (DEBUG)
@@ -360,9 +363,24 @@ var _CPAnimationContextStack = nil,
- (void)setCompletionHandler:(Function)aCompletionHandler
{
if (_completionHandlerAgent)
_completionHandlerAgent.invalidate();
{
if (aCompletionHandler === _completionHandlerAgent._completionHandler)
return;
_completionHandlerAgent = aCompletionHandler ? (new CompletionHandlerAgent(aCompletionHandler)) : nil;
_completionHandlerAgent.invalidate();
}
if (aCompletionHandler)
{
_completionHandlerAgent = new CompletionHandlerAgent(aCompletionHandler);
#if (DEBUG)
CPLog.debug("created a new completion Agent with id " + _completionHandlerAgent.id);
#endif
}
else
{
_completionHandlerAgent = nil;
}
}
- (void)completionHandler
@@ -465,11 +483,14 @@ var _CPAnimationContextStack = nil,
@end
var COMPLETION_AGENT_ID = 0;
var CompletionHandlerAgent = function(aCompletionHandler)
{
this._completionHandler = aCompletionHandler;
this.total = 0;
this.valid = true;
this.id = COMPLETION_AGENT_ID++;
};
CompletionHandlerAgent.prototype.completionHandler = function()
@@ -479,12 +500,17 @@ CompletionHandlerAgent.prototype.completionHandler = function()
CompletionHandlerAgent.prototype.fire = function()
{
this._completionHandler();
if (this.valid)
{
this._completionHandler();
this.valid = false;
this.total = 0;
}
};
CompletionHandlerAgent.prototype.increment = function()
CompletionHandlerAgent.prototype.increment = function(inc)
{
this.total++;
this.total += inc;
};
CompletionHandlerAgent.prototype.decrement = function()
@@ -503,6 +529,8 @@ CompletionHandlerAgent.prototype.decrement = function()
CompletionHandlerAgent.prototype.invalidate = function()
{
this.valid = false;
this.total = 0;
this._completionHandler = null;
};
var _animationFlushingObserverCallback = function()
+17 -12
View File
@@ -214,7 +214,7 @@ var transformSizeToHeight = function(start, current)
var CSSStringFromCGAffineTransform = function(anAffineTransform)
{
return "matrix(" + anAffineTransform.a + ", " + anAffineTransform.b + ", " + anAffineTransform.c + ", " + anAffineTransform.d + ", " + anAffineTransform.tx + (CPBrowserIsEngine(CPGeckoBrowserEngine) ? "px, " : ", ") + anAffineTransform.ty + (CPBrowserIsEngine(CPGeckoBrowserEngine) ? "px)" : ")");
return [CPString stringWithFormat:@"matrix(%d,%d,%d,%d,%d,%d)", anAffineTransform.a, anAffineTransform.b, anAffineTransform.c, anAffineTransform.d, anAffineTransform.tx, anAffineTransform.ty];
};
var frameOriginToCSSTransformMatrix = function(start, current)
@@ -408,20 +408,25 @@ var createUpdateFrame = function(aView, aKeyPath)
{
[aView _setInhibitDOMUpdates:YES];
var matrix = style[transformProperty].split('(')[1].split(')')[0].split(','),
x = ROUND(initialOrigin.x + parseFloat(matrix[4])),
y = ROUND(initialOrigin.y + parseFloat(matrix[5]));
var matrix_value = style[transformProperty];
if (aKeyPath === "frame")
if (matrix_value && matrix_value !== 'none')
{
var width = getCSSPropertyValue("width"),
height = getCSSPropertyValue("height");
var matrix_array = matrix_value.split('(')[1].split(')')[0].split(','),
x = ROUND(initialOrigin.x + parseFloat(matrix_array[4])),
y = ROUND(initialOrigin.y + parseFloat(matrix_array[5]));
[aView setFrame:CGRectMake(x, y, width, height)];
}
else
{
[aView setFrameOrigin:CGPointMake(x, y)];
if (aKeyPath === "frame")
{
var width = getCSSPropertyValue("width"),
height = getCSSPropertyValue("height");
[aView setFrame:CGRectMake(x, y, width, height)];
}
else
{
[aView setFrameOrigin:CGPointMake(x, y)];
}
}
[aView _setInhibitDOMUpdates:NO];
+1 -1
View File
@@ -20,7 +20,7 @@ var _supportsCSSAnimations = null;
id <CPAnimatablePropertyContainer> _target;
}
+ (BOOL)initialize
+ (void)initialize
{
if ([self class] !== [_CPObjectAnimator class])
return;
+2 -2
View File
@@ -557,14 +557,14 @@ CGContextConcatCTM = function(aContext, anAffineTransform)
b = VT.b;
c = VT.c;
d = VT.d;
scale_rotate(a, b, c, d)
scale_rotate(a, b, c, d);
S.a *= sx;
S.d *= sy;
a = U.a;
b = U.b;
c = U.c;
d = U.d;
rotate_scale(a, b, c, d)
rotate_scale(a, b, c, d);
sx = S.a * sx;
sy = S.d * sy;
}
+1 -1
View File
@@ -242,7 +242,7 @@ function CGContextDrawPath(aContext, aMode)
vml.push("\">");
if (gState.gradient)
vml.push(gState.gradient)
vml.push(gState.gradient);
else if (fill)
{
+1 -4
View File
@@ -132,9 +132,6 @@ function CGPathAddArc(aPath, aTransform, x, y, aRadius, aStartAngle, anEndAngle,
}
else
{
var arcStartX = x + aRadius * COS(aStartAngle),
arcStartY = y + aRadius * SIN(aStartAngle);
aPath.start = CGPointMake(arcStartX, arcStartY);
}
@@ -274,7 +271,7 @@ function CGPathAddQuadCurveToPoint(aPath, aTransform, cpx, cpy, x, y)
end = CGPointApplyAffineTransform(end, aTransform);
}
aPath.elements[aPath.count++] = { type:kCGPathElementAddQuadCurveToPoint, cpx:cp.x, cpy:cp.y, x:end.x, y:end.y }
aPath.elements[aPath.count++] = { type:kCGPathElementAddQuadCurveToPoint, cpx:cp.x, cpy:cp.y, x:end.x, y:end.y };
aPath.current = end;
}
+1 -1
View File
@@ -37,7 +37,7 @@ appKitTask = framework ("AppKit", function(appKitTask)
appKitTask.setCompilerFlags("-O2 " + INCLUDES);
}
else
appKitTask.setCompilerFlags("-DDEBUG -g " + INCLUDES);
appKitTask.setCompilerFlags("-DDEBUG -g -S --inline-msg-send " + INCLUDES);
});
$BUILD_CJS_CAPPUCCINO_APPKIT = FILE.join($BUILD_CJS_CAPPUCCINO_FRAMEWORKS, "AppKit");
+1 -24
View File
@@ -224,18 +224,10 @@ var PrimaryPlatformWindow = NULL;
- (void)deminiaturize:(id)sender
{
#if PLATFORM(DOM)
if (_DOMWindow && typeof _DOMWindow["cpDeminiaturize"] === "function")
_DOMWindow.cpDeminiaturize();
#endif
}
- (void)miniaturize:(id)sender
{
#if PLATFORM(DOM)
if (_DOMWindow && typeof _DOMWindow["cpMiniaturize"] === "function")
_DOMWindow.cpMiniaturize();
#endif
}
- (void)moveWindow:(CPWindow)aWindow fromLevel:(int)fromLevel toLevel:(int)toLevel
@@ -255,31 +247,16 @@ var PrimaryPlatformWindow = NULL;
- (void)setLevel:(CPInteger)aLevel
{
_level = aLevel;
#if PLATFORM(DOM)
if (_DOMWindow && _DOMWindow.cpSetLevel)
_DOMWindow.cpSetLevel(aLevel);
#endif
}
- (void)setHasShadow:(BOOL)shouldHaveShadow
{
_hasShadow = shouldHaveShadow;
#if PLATFORM(DOM)
if (_DOMWindow && _DOMWindow.cpSetHasShadow)
_DOMWindow.cpSetHasShadow(shouldHaveShadow);
#endif
}
- (void)setShadowStyle:(int)aStyle
{
_shadowStyle = aStyle;
#if PLATFORM(DOM)
if (_DOMWindow && _DOMWindow.cpSetShadowStyle)
_shadowStyle.cpSetShadowStyle(aStyle);
#endif
}
- (BOOL)supportsFullPlatformWindows
@@ -308,7 +285,7 @@ var PrimaryPlatformWindow = NULL;
- (BOOL)_canUpdateContentRect
{
// We onyl update the contentRect with the frame of the bridgeless window if we have initialized the platform with the method initWithWindow:
// We only update the contentRect with the frame of the bridgeless window if we have initialized the platform with the method initWithWindow:
return _shouldUpdateContentRect && _hasInitializeInstanceWithWindow;
}
+2 -2
View File
@@ -469,7 +469,7 @@ Return true if the event may be a copy and paste event, but the target is not an
// By default we'll stop the native handling of the event since we're handling it ourselves. However, we need to
// stop it before we send the event so that the event can overrule our choice. CPTextField for instance wants the
// default handling when focused (which is to insert into the field).
[platformWindow _propagateCurrentDOMEvent:NO]
[platformWindow _propagateCurrentDOMEvent:NO];
[CPApp sendEvent:anEvent];
@@ -492,7 +492,7 @@ Return true if the event may be a copy and paste event, but the target is not an
SUPPRESS_CAPPUCCINO_CUT_FOR_EVENT(anEvent);
[platformWindow _propagateCurrentDOMEvent:NO]
[platformWindow _propagateCurrentDOMEvent:NO];
// Let the app react through copy: and cut: actions.
[CPApp sendEvent:anEvent];
+61 -45
View File
@@ -205,6 +205,9 @@ var resizeTimer = nil;
var PreventScroll = true;
var blurTimer = nil;
var touchStartingPointX,
touchStartingPointY;
_CPPlatformWindowWillCloseNotification = @"_CPPlatformWindowWillCloseNotification";
@@ -244,9 +247,6 @@ _CPPlatformWindowWillCloseNotification = @"_CPPlatformWindowWillCloseNotificatio
if (!_DOMWindow)
return [self contentRect];
if (_DOMWindow.cpFrame)
return _DOMWindow.cpFrame();
var contentRect = CGRectMakeZero();
if (window.screenTop)
@@ -275,9 +275,6 @@ _CPPlatformWindowWillCloseNotification = @"_CPPlatformWindowWillCloseNotificatio
if (!_DOMWindow)
return;
if (typeof _DOMWindow["cpSetFrame"] === "function")
return _DOMWindow.cpSetFrame([self contentRect]);
var origin = [self contentRect].origin,
nativeOrigin = [self nativeContentRect].origin;
@@ -430,10 +427,10 @@ _CPPlatformWindowWillCloseNotification = @"_CPPlatformWindowWillCloseNotificatio
theDocument.addEventListener("keydown", keyEventCallback, NO);
theDocument.addEventListener("keypress", keyEventCallback, NO);
theDocument.addEventListener("touchstart", touchEventCallback, NO);
theDocument.addEventListener("touchend", touchEventCallback, NO);
theDocument.addEventListener("touchmove", touchEventCallback, NO);
theDocument.addEventListener("touchcancel", touchEventCallback, NO);
theDocument.addEventListener("touchstart", touchEventCallback, {passive: false});
theDocument.addEventListener("touchend", touchEventCallback, {passive: false});
theDocument.addEventListener("touchmove", touchEventCallback, {passive: false});
theDocument.addEventListener("touchcancel", touchEventCallback, {passive: false});
_DOMWindow.addEventListener("DOMMouseScroll", scrollEventCallback, NO);
_DOMWindow.addEventListener("wheel", scrollEventCallback, NO);
@@ -573,22 +570,12 @@ _CPPlatformWindowWillCloseNotification = @"_CPPlatformWindowWillCloseNotificatio
[PlatformWindows addObject:self];
// FIXME: cpSetFrame?
_DOMWindow.document.write('<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"></head><body style="background-color:transparent; overflow:hidden"></body></html>');
_DOMWindow.document.close();
if (self != [CPPlatformWindow primaryPlatformWindow])
_DOMWindow.document.title = _title;
if (![CPPlatform isBrowser])
{
_DOMWindow.cpWindowNumber = [self._only windowNumber];
_DOMWindow.cpSetFrame(_contentRect);
_DOMWindow.cpSetLevel(_level);
_DOMWindow.cpSetHasShadow(_hasShadow);
_DOMWindow.cpSetShadowStyle(_shadowStyle);
}
[self registerDOMWindow];
_DOMBodyElement.style.cursor = [[CPCursor currentCursor] _cssString];
@@ -666,7 +653,8 @@ _CPPlatformWindowWillCloseNotification = @"_CPPlatformWindowWillCloseNotificatio
}
else if (type === "dragend")
{
var dropEffect = aDOMEvent.dataTransfer.dropEffect;
var dropEffect = aDOMEvent.dataTransfer.dropEffect,
dragOperation;
if (dropEffect === "move")
dragOperation = CPDragOperationMove;
@@ -944,8 +932,7 @@ _CPPlatformWindowWillCloseNotification = @"_CPPlatformWindowWillCloseNotificatio
if (!theWindow)
return;
var windowNumber = [theWindow windowNumber];
windowNumber = [theWindow windowNumber];
location = [theWindow convertBridgeToBase:location];
var event = [CPEvent mouseEventWithType:CPScrollWheel location:location modifierFlags:modifierFlags
@@ -1152,10 +1139,26 @@ _CPPlatformWindowWillCloseNotification = @"_CPPlatformWindowWillCloseNotificatio
- (void)touchEvent:(DOMEvent)aDOMEvent
{
var newEvent = {},
touch = aDOMEvent.touches.length ? aDOMEvent.touches[0] : aDOMEvent.changedTouches[0];
newEvent.timestamp = [CPEvent currentTimestamp];
newEvent.target = aDOMEvent.target;
newEvent.shiftKey = newEvent.ctrlKey = newEvent.altKey = newEvent.metaKey = false;
newEvent.clientX = touch.clientX;
/*
Normally the document can't scroll in Cappuccino: our body element has top:0 and bottom:0 with absolute positioning. So it should always be exactly the height of the viewport. The below handles a special case. iOS scrolls the document when the virtual keyboard is present and it needs to move a text input upwards visually to avoid covering the input with the keyboard. For most purposes we can ignore this, except here. In theory I think we could always apply this (scrollTop should always be 0 on every other device and situation) but let's be defensive and only apply it for touch events to minimise the risk of surprises.
*/
newEvent.clientY = _DOMWindow.document.body.scrollTop + touch.clientY;
newEvent.preventDefault = function() { if (aDOMEvent.preventDefault) aDOMEvent.preventDefault() };
newEvent.stopPropagation = function() { if (aDOMEvent.stopPropagation) aDOMEvent.stopPropagation() };
// single finger event-> simulate a simple mouse-click
if (aDOMEvent.touches && (aDOMEvent.touches.length == 1 || (aDOMEvent.touches.length == 0 && aDOMEvent.changedTouches.length == 1)))
{
var newEvent = {};
switch (aDOMEvent.type)
{
case CPDOMEventTouchStart: newEvent.type = CPDOMEventMouseDown;
@@ -1168,36 +1171,49 @@ _CPPlatformWindowWillCloseNotification = @"_CPPlatformWindowWillCloseNotificatio
break;
}
var touch = aDOMEvent.touches.length ? aDOMEvent.touches[0] : aDOMEvent.changedTouches[0];
newEvent.clientX = touch.clientX;
/*
Normally the document can't scroll in Cappuccino: our body element has top:0 and bottom:0 with absolute positioning. So it should always be exactly the height of the viewport. The below handles a special case. iOS scrolls the document when the virtual keyboard is present and it needs to move a text input upwards visually to avoid covering the input with the keyboard. For most purposes we can ignore this, except here. In theory I think we could always apply this (scrollTop should always be 0 on every other device and situation) but let's be defensive and only apply it for touch events to minimise the risk of surprises.
*/
newEvent.clientY = _DOMWindow.document.body.scrollTop + touch.clientY;
newEvent.timestamp = [CPEvent currentTimestamp];
newEvent.target = aDOMEvent.target;
newEvent.shiftKey = newEvent.ctrlKey = newEvent.altKey = newEvent.metaKey = false;
newEvent.preventDefault = function() { if (aDOMEvent.preventDefault) aDOMEvent.preventDefault() };
newEvent.stopPropagation = function() { if (aDOMEvent.stopPropagation) aDOMEvent.stopPropagation() };
[self mouseEvent:newEvent];
return;
}
else
{
// two fingers->simulate scrolling events
if (aDOMEvent.touches && aDOMEvent.touches.length == 2)
{
if (aDOMEvent.preventDefault)
aDOMEvent.preventDefault();
if (aDOMEvent.stopPropagation)
aDOMEvent.stopPropagation();
switch (aDOMEvent.type)
{
case CPDOMEventTouchStart:
touchStartingPointX = touch.pageX;
touchStartingPointY = touch.pageY;
break;
case CPDOMEventTouchMove:
newEvent._hasPreciseScrollingDeltas = YES;
newEvent.deltaX = touchStartingPointX - touch.pageX;
newEvent.deltaY = touchStartingPointY - touch.pageY;
newEvent.type = CPDOMEventScrollWheel;
[self scrollEvent:newEvent];
touchStartingPointX = touch.pageX;
touchStartingPointY = touch.pageY;
return;
}
}
// cancel other touch cases preventively
if (aDOMEvent.preventDefault)
aDOMEvent.preventDefault();
if (aDOMEvent.stopPropagation)
aDOMEvent.stopPropagation();
}
// handle touch cases specifically
}
- (void)mouseEvent:(DOMEvent)aDOMEvent
@@ -1422,7 +1438,7 @@ _CPPlatformWindowWillCloseNotification = @"_CPPlatformWindowWillCloseNotificatio
var insertionIndex = 0;
if (middle !== undefined)
insertionIndex = _windowLevels[middle] > aLevel ? middle : middle + 1
insertionIndex = _windowLevels[middle] > aLevel ? middle : middle + 1;
[_windowLevels insertObject:aLevel atIndex:insertionIndex];
layer._DOMElement.style.zIndex = aLevel + 1; // adding one avoids negative zIndices. These have been causing issues in Chrome
@@ -1821,7 +1837,7 @@ var _CPEventFromNativeMouseEvent = function(aNativeEvent, anEventType, aPoint, m
var CLICK_SPACE_DELTA = 5.0,
CLICK_TIME_DELTA = (typeof document != "undefined" && document.addEventListener) ? 0.55 : 1.0;
var CPDOMEventGetClickCount = function(aComparisonEvent, aTimestamp, aLocation)
CPDOMEventGetClickCount = function(aComparisonEvent, aTimestamp, aLocation)
{
if (!aComparisonEvent)
return 1;
Binary file not shown.

Before

Width:  |  Height:  |  Size: 317 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 422 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 409 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 333 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 432 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 418 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 76 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 102 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 102 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 84 B

After

Width:  |  Height:  |  Size: 92 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 171 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 168 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 95 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 75 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 96 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 167 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 77 B

After

Width:  |  Height:  |  Size: 85 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 161 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 349 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 426 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 396 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 313 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 433 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 388 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 78 B

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 81 B

After

Width:  |  Height:  |  Size: 3.6 KiB

+20 -28
View File
@@ -508,9 +508,7 @@ var themedButtonValues = nil,
orientation: PatternIsVertical
}),
trackColorLegacy = PatternColor("scroller-legacy-vertical-track-center.png", 14.0, 1.0),
incrementColorLegacy = PatternColor("scroller-legacy-vertical-track-bottom.png", 14.0, 11.0),
decrementColorLegacy = PatternColor("scroller-legacy-vertical-track-top.png", 14.0, 11.0),
trackColorLegacy = PatternColor("scroller-legacy-vertical-track-center.png", 14.0, 1.0),
knobColor = PatternColor(
"scroller-vertical-knob{style}{position}.png",
@@ -535,8 +533,8 @@ var themedButtonValues = nil,
[@"minimum-knob-length", 21.0, CPThemeStateVertical],
// Overlay
[@"scroller-width", 9.0, CPThemeStateVertical],
[@"knob-inset", CGInsetMake(2.0, 0.0, 0.0, 0.0), CPThemeStateVertical],
[@"scroller-width", 14.0, CPThemeStateVertical],
[@"knob-inset", CGInsetMake(0.0, 0.0, 0.0, 0.0), CPThemeStateVertical],
[@"track-inset", CGInsetMake(2.0, 0.0, 2.0, 0.0), CPThemeStateVertical],
[@"track-border-overlay", 12.0, CPThemeStateVertical],
[@"knob-slot-color", [CPNull null], CPThemeStateVertical],
@@ -553,7 +551,7 @@ var themedButtonValues = nil,
// Legacy
[@"scroller-width", 14.0, [CPThemeStateVertical, CPThemeStateScrollViewLegacy]],
[@"knob-inset", CGInsetMake(0.0, 0.0, 0.0, 0.0), [CPThemeStateVertical, CPThemeStateScrollViewLegacy]],
[@"knob-inset", CGInsetMake(0.0, 2.0, 0.0, 2.0), [CPThemeStateVertical, CPThemeStateScrollViewLegacy]],
[@"track-inset", CGInsetMake(0.0, 0.0, 0.0, 0.0), [CPThemeStateVertical, CPThemeStateScrollViewLegacy]],
[@"track-border-overlay", 0.0, [CPThemeStateVertical, CPThemeStateScrollViewLegacy]],
[@"knob-slot-color", trackColorLegacy, [CPThemeStateVertical, CPThemeStateScrollViewLegacy]],
@@ -562,13 +560,11 @@ var themedButtonValues = nil,
[@"knob-slot-color", trackColorLegacy, [CPThemeStateVertical, CPThemeStateScrollViewLegacy, CPThemeStateSelected, CPThemeStateScrollerKnobDark]],
[@"knob-slot-color", trackColorLegacy, [CPThemeStateVertical, CPThemeStateScrollViewLegacy, CPThemeStateScrollerKnobDark]],
[@"knob-slot-color", trackColorLegacy, [CPThemeStateVertical, CPThemeStateScrollViewLegacy, CPThemeStateScrollerKnobLight]],
[@"knob-color", knobColorLegacy, [CPThemeStateVertical, CPThemeStateScrollViewLegacy]],
[@"knob-color", knobColorLegacy, [CPThemeStateVertical, CPThemeStateScrollViewLegacy, CPThemeStateScrollerKnobLight]],
[@"knob-color", knobColorLegacy, [CPThemeStateVertical, CPThemeStateScrollViewLegacy, CPThemeStateScrollerKnobDark]],
[@"increment-line-color", incrementColorLegacy, [CPThemeStateVertical, CPThemeStateScrollViewLegacy]],
[@"decrement-line-color", decrementColorLegacy, [CPThemeStateVertical, CPThemeStateScrollViewLegacy]],
[@"decrement-line-size", CGSizeMake(14.0, 11.0), [CPThemeStateVertical, CPThemeStateScrollViewLegacy]],
[@"increment-line-size", CGSizeMake(14.0, 11.0), [CPThemeStateVertical, CPThemeStateScrollViewLegacy]]
[@"knob-color", knobColor["dark"], [CPThemeStateVertical, CPThemeStateScrollViewLegacy]],
[@"increment-line-color", [CPNull null], [CPThemeStateVertical, CPThemeStateScrollViewLegacy]],
[@"decrement-line-color", [CPNull null], [CPThemeStateVertical, CPThemeStateScrollViewLegacy]],
[@"decrement-line-size", CGSizeMakeZero(), [CPThemeStateVertical, CPThemeStateScrollViewLegacy]],
[@"increment-line-size", CGSizeMakeZero(), [CPThemeStateVertical, CPThemeStateScrollViewLegacy]]
];
[self registerThemeValues:themedVerticalScrollerValues forView:scroller];
@@ -588,9 +584,7 @@ var themedButtonValues = nil,
orientation: PatternIsHorizontal
}),
trackColorLegacy = PatternColor("scroller-legacy-horizontal-track-center.png", 1.0, 14.0),
incrementColorLegacy = PatternColor("scroller-legacy-horizontal-track-right.png", 11.0, 14.0),
decrementColorLegacy = PatternColor("scroller-legacy-horizontal-track-left.png", 11.0, 14.0),
trackColorLegacy = PatternColor("scroller-legacy-horizontal-track-center.png", 1.0, 14.0),
knobColor = PatternColor(
"scroller-horizontal-knob{style}{position}.png",
@@ -616,7 +610,7 @@ var themedButtonValues = nil,
// Overlay
[@"scroller-width", 9.0],
[@"knob-inset", CGInsetMake(0.0, 0.0, 0.0, 2.0)],
[@"knob-inset", CGInsetMake(0.0, 0.0, 0.0, 0.0)],
[@"track-inset", CGInsetMake(0.0, 2.0, 0.0, 2.0)],
[@"track-border-overlay", 12.0],
[@"knob-slot-color", [CPNull null]],
@@ -631,20 +625,18 @@ var themedButtonValues = nil,
// Legacy
[@"scroller-width", 14.0, CPThemeStateScrollViewLegacy],
[@"knob-inset", CGInsetMake(0.0, 0.0, 0.0, 0.0), CPThemeStateScrollViewLegacy],
[@"knob-inset", CGInsetMake(2.0, 0.0, 2.0, 0.0), CPThemeStateScrollViewLegacy],
[@"track-inset", CGInsetMake(0.0, 0.0, 0.0, 0.0), CPThemeStateScrollViewLegacy],
[@"track-border-overlay", 0.0, CPThemeStateScrollViewLegacy],
[@"knob-slot-color", trackColorLegacy, CPThemeStateScrollViewLegacy],
[@"knob-slot-color", trackColorLegacy, [CPThemeStateScrollViewLegacy, CPThemeStateSelected]],
[@"knob-slot-color", trackColorLegacy, [CPThemeStateScrollViewLegacy, CPThemeStateScrollerKnobLight]],
[@"knob-slot-color", trackColorLegacy, [CPThemeStateScrollViewLegacy, CPThemeStateScrollerKnobDark]],
[@"knob-color", knobColorLegacy, CPThemeStateScrollViewLegacy],
[@"knob-color", knobColorLegacy, [CPThemeStateScrollViewLegacy, CPThemeStateScrollerKnobLight]],
[@"knob-color", knobColorLegacy, [CPThemeStateScrollViewLegacy, CPThemeStateScrollerKnobDark]],
[@"increment-line-color", incrementColorLegacy, CPThemeStateScrollViewLegacy],
[@"decrement-line-color", decrementColorLegacy, CPThemeStateScrollViewLegacy],
[@"decrement-line-size", CGSizeMake(11.0, 14.0), CPThemeStateScrollViewLegacy],
[@"increment-line-size", CGSizeMake(11.0, 14.0), CPThemeStateScrollViewLegacy]
[@"knob-color", knobColor["@"], CPThemeStateScrollViewLegacy],
[@"knob-color", knobColor["light"], [CPThemeStateScrollViewLegacy, CPThemeStateScrollerKnobLight]],
[@"knob-color", knobColor["dark"], [CPThemeStateScrollViewLegacy, CPThemeStateScrollerKnobDark]],
[@"decrement-line-size", CGSizeMakeZero(), CPThemeStateScrollViewLegacy],
[@"increment-line-size", CGSizeMakeZero(), CPThemeStateScrollViewLegacy]
];
[self registerThemeValues:themedHorizontalScrollerValues forView:scroller];
@@ -2877,7 +2869,7 @@ var themedButtonValues = nil,
+ (_CPBorderlessBridgeWindowView)themedBorderlessBridgeWindowView
{
var bordelessBridgeWindowView = [[_CPBorderlessBridgeWindowView alloc] initWithFrame:CGRectMake(0,0,0,0)],
var borderlessBridgeWindowView = [[_CPBorderlessBridgeWindowView alloc] initWithFrame:CGRectMake(0,0,0,0)],
toolbarBackgroundColor = PatternColor(
[
@@ -2891,9 +2883,9 @@ var themedButtonValues = nil,
[@"toolbar-background-color", toolbarBackgroundColor]
];
[self registerThemeValues:themeValues forView:bordelessBridgeWindowView inherit:themedWindowViewValues];
[self registerThemeValues:themeValues forView:borderlessBridgeWindowView inherit:themedWindowViewValues];
return bordelessBridgeWindowView;
return borderlessBridgeWindowView;
}
+ (_CPToolbarView)themedToolbarView

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