Compare commits

...
398 Commits
Author SHA1 Message Date
Alexander Ljungberg 0036f329f5 Fixed: in recent builds, WithBindingsTest failed with a "CPScroller does not contain theme attribute 'scroller-width'" error. 2011-11-16 12:57:01 +00:00
Alexander Ljungberg 15af54efda Fixed with CPTokenField: quickly entered tokens would be ignored.
If the autocomplete state had not been set yet, tokens could not be finished using the token separator, return or tab. Instead the user typed text remained in its 'non token' state.
2011-11-16 12:52:27 +00:00
Alexander Ljungberg 07966bb7fe Fixed with CPTokenField: crash if added to a window in a unit test. 2011-11-16 12:50:05 +00:00
Alexander Ljungberg e7d9b0503b Fixes #1398. Fixed with CPTokenField: deleting tokens in front of selected tokens would shift the selection to the right. 2011-11-16 12:04:03 +00:00
Alexander Ljungberg 072b43d178 Fixes #1397. Fixed with CPTokenField: make sure selection is initialised when loading from cib. 2011-11-16 11:55:38 +00:00
Alexander Ljungberg 281d2295ae Code formatting. 2011-11-15 23:47:56 +00:00
Alexander Ljungberg 79cf4370b4 Update bootstrap to 0.9.5 as well. 2011-11-14 18:49:30 +00:00
Alexander Ljungberg 6217fc8459 Given the large number of changes, this will be Cappuccino 0.9.5 instead. 2011-11-14 18:37:00 +00:00
Alexander Ljungberg f1fd3d170a Merge branch '0.9.2b' of github.com:cappuccino/cappuccino into 0.9.2b 2011-11-14 18:27:08 +00:00
Antoine Mercadal 4e410f8a81 Merge remote-tracking branch 'upstream/0.9.2b' into 0.9.2b 2011-11-14 16:46:36 +01:00
Antoine Mercadal 7a1b273d8d simplify the ignored path matching 2011-11-13 23:34:49 +01:00
Antoine Mercadal 820531342d fix during tidying shadow files 2011-11-13 21:58:45 +01:00
Antoine Mercadal 353db3277a fix file level mode deactivated, fix auto ignore not working 2011-11-13 21:36:52 +01:00
Antoine Mercadal 82f37549ae reactivate 10.7 file level API 2011-11-13 20:28:11 +01:00
Alexander Ljungberg 09e1bd6bf1 The 0.9.2 GM will be tagged v0.9.2 simply. 2011-11-11 16:52:48 +00:00
Alexander Ljungberg 44f3abf262 Don't mention "steam" in TOOLS-README. 2011-11-11 16:45:43 +00:00
Antoine Mercadal 8c09af5013 Merge remote-tracking branch 'upstream/master' 2011-11-10 14:11:12 +01:00
Antoine Mercadal 0781e932c6 Merge branch 'xcc-improvments' 2011-11-10 14:10:45 +01:00
Alexander Ljungberg 3cee00323c Don't separate statements by commas. 2011-11-10 12:31:16 +00:00
Alexander Ljungberg b1f6f3ddfa Missing semicolons. 2011-11-10 12:30:05 +00:00
Alexander Ljungberg 7147266ddf objjc option to compile to plain JavaScript (suitable for linting). 2011-11-10 11:59:26 +00:00
Alexander Ljungberg 357212bff7 Missing semicolons. 2011-11-10 11:34:26 +00:00
Alexander Ljungberg ed4fc3b20f objjc compile to stdout, argument parsing, --help. 2011-11-10 10:37:46 +00:00
Alexander Ljungberg 7e8b71dd52 Semicolons. 2011-11-10 10:36:47 +00:00
Alexander Ljungberg 267f00bfe1 Put spaces around = in [name] = function... generated JS to reduce lint warnings. 2011-11-10 09:41:21 +00:00
Alexander Ljungberg 8f90dbce99 Allow almost anything as a key equivalent unless a text field is the first responder.
After testing in Cocoa, even unexpected keys such as tab can be used when a text field isn't selected. Some keys such as the arrow keys and escape act like key equivalents even with a text field active.
2011-11-10 00:52:38 +00:00
Alexander Ljungberg 00485dba89 Refs #1019. Clean up. 2011-11-10 00:12:48 +00:00
Alexander Ljungberg 8fd4f5e4b6 Merge branch 'master' of github.com:cappuccino/cappuccino 2011-11-09 23:36:47 +00:00
Scott RiceandAlexander Ljungberg e7e69b3fd4 Fixed issue #1019 in IE 2011-11-10 07:35:50 +08:00
Alexander Ljungberg 2463c1dc05 IE compatibility. 2011-11-09 23:02:31 +00:00
Alexander Ljungberg bc590286f2 Missing semicolons. 2011-11-09 22:55:11 +00:00
Aparajita Fishman 8c83816ec8 Made [CPMenu -removeAllItems] KVO compliant
Fixes https://github.com/cappuccino/cappuccino/issues/1395
2011-11-09 14:50:52 -08:00
Alexander Ljungberg 699069ce8f Typo fix. 2011-11-09 20:48:01 +00:00
Alexander Ljungberg ec0cd22c1d Merge pull request #1382 from kjamieson/cappuccino
---

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

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

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

adding autoreconf to fix issues reported at [1]

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

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

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

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

This patch makes CPScrollView acts like Lions NSScrollView.

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

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

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

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

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

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

Cocoa compliance.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

this allows to do:

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

this allow to do:

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

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

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

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

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

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

For reference on key handling code, I consulted this:

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

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

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

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

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

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

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

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

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

- sendAction:to: should return a BOOL.

- Support for CPFormatter -editingStringForObjectValue.

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

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

- Removed a few extra blank lines.

- Changed NULL to nil.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Reviewed.
2011-06-08 01:11:02 -07:00
Gustaf Lindqvist d6244f090e Fix white spaces in path for system() 2011-06-08 09:10:28 +02:00
Aparajita Fishman 1c44dc1052 Removed unused variable, fixed typo 2011-06-03 18:09:57 -07:00
Aparajita Fishman 4f7fbdc344 Use Menlo if Consolas is not available 2011-06-01 18:22:57 -07:00
Derek Hammer c5f37e665b Adding OJTest installation to the bootstrap.sh file. Also added the
cappuccino/objective-j packages back to the file.
2011-05-31 03:05:24 -07:00
Aparajita Fishman 99180ba001 Enable escape as key equivalent. 2011-05-30 23:20:06 -07:00
Aparajita Fishman 9377cf9128 Test app and unit test to validate pinned ranges in beginsWith/endsWith predicate comparison. 2011-05-26 14:31:20 -07:00
Aparajita Fishman e17d8ca302 Pin ranges to valid values. 2011-05-26 14:31:13 -07:00
Aparajita Fishman acbaa1eec4 Restored space, backspace and escape as key equivalents, but only if the first responder is not a CPTextField. Updated test app to show clearly the effect of this change. 2011-05-23 16:31:52 -07:00
Aparajita Fishman 65b6ff6ecc Fixed set of keys that can be considered a key equivalent, removed redundant call to performKeyEquivalent, test app 2011-05-22 18:05:48 -07:00
Antoine Mercadal df7aa30267 include xcodecapp-cocoa in the Cappuccino build process. 2011-05-21 00:39:50 +02:00
Antoine Mercadal 0f4aab926e add Jakefile to build xcodecapp-cocoa 2011-05-21 00:24:10 +02:00
Antoine Mercadal 7f3512d22c update .gitignore 2011-05-21 00:23:47 +02:00
Antoine Mercadal a6b5ed22b0 make parse.j LGPLv3 2011-05-21 00:02:22 +02:00
Antoine Mercadal e843b31287 update license of xcodecapp-cocoa 2011-05-20 23:39:13 +02:00
Antoine Mercadal 06a5aa45ba Merge remote branch 'xcodecapp-cocoa/master' into xcodecapp-cocoa-merge 2011-05-20 23:34:07 +02:00
Antoine Mercadal 45a5eed62f Merge xcodecapp-cocoa 2011-05-20 23:32:17 +02:00
Antoine Mercadal 188e27e931 update status bar icon 2011-05-20 23:05:41 +02:00
Aparajita Fishman f7a7f06c67 Use CPLog instead of console.log 2011-05-20 08:12:37 -07:00
Antoine Mercadal ed560ed489 display ... when actually doing some jobs 2011-05-20 12:13:28 +02:00
Antoine Mercadal 186eb66f52 Make XCodeCapp-Cocoa a status bar application
+ fix bash_profile, thanks to @natemartinsf
 + add gitignore
2011-05-20 11:59:43 +02:00
Aparajita Fishman 860f0d5846 CPColor and CPImage enhancements
- Enhanced -description method of CPImage and CPColor to show the exact content, especially for pattern colors.

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

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

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

Test: added delegate methods to the top-left scroll view in CPScrollView example and log.
2011-03-19 10:17:12 +01:00
cacaodev f60a92d2c4 CPViewAnimation: current frame based on -currentValue. CPAnimation: early return in -currentValue if linear 2011-01-24 20:24:19 +01:00
335 changed files with 28756 additions and 2240 deletions
+1
View File
@@ -9,3 +9,4 @@ WebSite
*.xcodeproj/*.perspectivev3
xcuserdata/
!*.xcodeproj/project.pbxproj
*.xCodeSupport/
+1
View File
@@ -66,6 +66,7 @@
@import "CPOutlineView.j"
@import "CPPanel.j"
@import "CPPasteboard.j"
@import "CPPopover.j"
@import "CPPopUpButton.j"
@import "CPPredicateEditor.j"
@import "CPPredicateEditorRowTemplate.j"
+4 -4
View File
@@ -117,7 +117,7 @@ CPCriticalAlertStyle = 2;
*/
+ (CPAlert)alertWithMessageText:(CPString)aMessage defaultButton:(CPString)defaultButtonTitle alternateButton:(CPString)alternateButtonTitle otherButton:(CPString)otherButtonTitle informativeTextWithFormat:(CPString)informativeText
{
var alert = [[CPAlert alloc] init];
var alert = [[self alloc] init];
[alert setMessageText:aMessage];
[alert addButtonWithTitle:defaultButtonTitle];
@@ -142,7 +142,7 @@ CPCriticalAlertStyle = 2;
*/
+ (CPAlert)alertWithError:(CPString)anErrorMessage
{
var alert = [[CPAlert alloc] init];
var alert = [[self alloc] init];
[alert setMessageText:anErrorMessage];
[alert setAlertStyle:CPCriticalAlertStyle];
@@ -371,8 +371,8 @@ CPCriticalAlertStyle = 2;
[_informativeLabel setAlignment:[self currentValueForThemeAttribute:@"informative-text-alignment"]];
[_informativeLabel setLineBreakMode:CPLineBreakByWordWrapping];
informativeLabelWidth = CGRectGetWidth([[_window contentView] frame]) - inset.left - inset.right,
informativeLabelOriginY = [_messageLabel frameOrigin].y + [_messageLabel frameSize].height + defaultElementsMargin,
informativeLabelWidth = CGRectGetWidth([[_window contentView] frame]) - inset.left - inset.right;
informativeLabelOriginY = [_messageLabel frameOrigin].y + [_messageLabel frameSize].height + defaultElementsMargin;
informativeLabelTextSize = [[_informativeLabel stringValue] sizeWithFont:[_informativeLabel font] inWidth:informativeLabelWidth];
[_informativeLabel setFrame:CGRectMake(inset.left, informativeLabelOriginY, informativeLabelTextSize.width, informativeLabelTextSize.height + sizeWithFontCorrection)];
+3
View File
@@ -306,6 +306,9 @@ ACTUAL_FRAME_RATE = 0;
if ([_delegate respondsToSelector:@selector(animation:valueForProgress:)])
return [_delegate animation:self valueForProgress:t];
if (_animationCurve == CPAnimationLinear)
return t;
var c1 = [],
c2 = [];
+4 -4
View File
@@ -338,7 +338,7 @@ CPRunContinuesResponse = -1002;
Copyright - Human readable copyright information.
</pre>
If you choose not the include any of the above keys, they will default
If you choose not the include any of the above keys, they will default
to the following respective keys in your info.plist file.
<pre>
@@ -1003,7 +1003,7 @@ CPRunContinuesResponse = -1002;
}
/*!
Sets the arguments of your application.
Sets the arguments of your application.
That is, set the slash seperated values of an array as the window location hash.
For example if you pass an array:
@@ -1340,8 +1340,8 @@ var _CPAppBootstrapperActions = nil;
[editMenu addItem:undoMenuItem];
[editMenu addItem:redoMenuItem];
[editMenu addItem:[[CPMenuItem alloc] initWithTitle:@"Cut" action:@selector(cut:) keyEquivalent:@"x"]],
[editMenu addItem:[[CPMenuItem alloc] initWithTitle:@"Copy" action:@selector(copy:) keyEquivalent:@"c"]],
[editMenu addItem:[[CPMenuItem alloc] initWithTitle:@"Cut" action:@selector(cut:) keyEquivalent:@"x"]];
[editMenu addItem:[[CPMenuItem alloc] initWithTitle:@"Copy" action:@selector(copy:) keyEquivalent:@"c"]];
[editMenu addItem:[[CPMenuItem alloc] initWithTitle:@"Paste" action:@selector(paste:) keyEquivalent:@"v"]];
[editMenuItem setSubmenu:editMenu];
+24 -12
View File
@@ -564,8 +564,9 @@
- (BOOL)setSelectionIndexes:(CPIndexSet)indexes
{
[self _selectionWillChange]
[self __setSelectionIndexes:indexes];
var r = [self __setSelectionIndexes:indexes];
[self _selectionDidChange];
return r;
}
/*
@@ -574,7 +575,7 @@
*/
- (BOOL)__setSelectionIndex:(int)theIndex
{
[self __setSelectionIndexes:[CPIndexSet indexSetWithIndex:theIndex]];
return [self __setSelectionIndexes:[CPIndexSet indexSetWithIndex:theIndex]];
}
/*
@@ -583,28 +584,38 @@
*/
- (BOOL)__setSelectionIndexes:(CPIndexSet)indexes
{
if (!indexes)
indexes = [CPIndexSet indexSet];
var newIndexes = indexes;
if (![indexes count])
if (!newIndexes)
newIndexes = [CPIndexSet indexSet];
if (![newIndexes count])
{
if (_avoidsEmptySelection && [[self arrangedObjects] count])
indexes = [CPIndexSet indexSetWithIndex:0];
newIndexes = [CPIndexSet indexSetWithIndex:0];
}
else
{
var objectsCount = [[self arrangedObjects] count];
// Don't trash the input - the caller might depend on it or we might have been
// given _selectionIndexes as the input in which case the equality test below
// would always succeed despite our change below.
newIndexes = [newIndexes copy];
// Remove out of bounds indexes.
[indexes removeIndexesInRange:CPMakeRange(objectsCount, [indexes lastIndex] + 1)];
[newIndexes removeIndexesInRange:CPMakeRange(objectsCount, [newIndexes lastIndex] + 1)];
// When avoiding empty selection and the deleted selection was at the bottom, select the last item.
if (![indexes count] && _avoidsEmptySelection && objectsCount)
indexes = [CPIndexSet indexSetWithIndex:objectsCount - 1];
if (![newIndexes count] && _avoidsEmptySelection && objectsCount)
newIndexes = [CPIndexSet indexSetWithIndex:objectsCount - 1];
}
if ([_selectionIndexes isEqualToIndexSet:indexes])
if ([_selectionIndexes isEqualToIndexSet:newIndexes])
return NO;
_selectionIndexes = [indexes copy];
// If we haven't already created our own index instance, make sure to copy it here so that
// the copy the user sent in is decoupled from our internal copy.
_selectionIndexes = indexes === newIndexes ? [indexes copy] : newIndexes;
// Push back the new selection to the model for selectionIndexes if we have one.
// There won't be an infinite loop because of the equality check above.
@@ -636,10 +647,11 @@
[self willChangeValueForKey:@"selectionIndexes"];
[self _selectionWillChange];
[self __setSelectedObjects:objects];
var r = [self __setSelectedObjects:objects];
[self didChangeValueForKey:@"selectionIndexes"];
[self _selectionDidChange];
return r;
}
/*
+1
View File
@@ -61,6 +61,7 @@ CPGrooveBorder = 3;
var box = [[self alloc] initWithFrame:CGRectMakeZero()],
enclosingView = [aView superview];
[box setAutoresizingMask:[aView autoresizingMask]];
[box setFrameFromContentFrame:[aView frame]];
[enclosingView replaceSubview:aView with:box];
+99 -6
View File
@@ -27,6 +27,7 @@
@import "CPCompatibility.j"
@import "CPImage.j"
/// @cond IGNORE
var _redComponent = 0,
_greenComponent = 1,
@@ -54,6 +55,66 @@ var cachedBlackColor,
cachedShadowColor,
cachedClearColor;
/// @endcond
/*!
Orientation to use with \c CPColorPattern for vertical patterns.
*/
CPColorPatternIsVertical = YES;
/*!
Orientation to use with \c CPColorPattern for horizontal patterns.
*/
CPColorPatternIsHorizontal = NO;
/*!
To create a simple color with a pattern image:
<code>CPColorWithImages(name, width, height{, bundle})</code>
To create a color with a three part pattern image:
<code>CPColorWithImages(slices{, orientation})</code>
where slices is an array of three [name, width, height{, bundle}] arrays,
and orientation is \c CPColorPatternIsVertical or \ref CPColorPatternIsHorizontal.
If orientatation is not passed, it defaults to \ref CPColorPatternIsHorizontal.
To create a color with a nine part pattern image:
<code>CPColorWithImages(slices);</code>
where slices is an array of nine [name, width, height{, bundle}] arrays.
*/
function CPColorWithImages()
{
if (arguments.length < 3)
{
var slices = arguments[0],
imageSlices = [];
for (var i = 0; i < slices.length; ++i)
{
var slice = slices[i];
imageSlices.push(slice ? CPImageInBundle(slice[0], CGSizeMake(slice[1], slice[2]), slice[3]) : nil);
}
if (imageSlices.length === 3)
return [CPColor colorWithPatternImage:[[CPThreePartImage alloc] initWithImageSlices:imageSlices isVertical:arguments[1] || CPColorPatternIsHorizontal]];
else
return [CPColor colorWithPatternImage:[[CPNinePartImage alloc] initWithImageSlices:imageSlices]];
}
else if (arguments.length === 3 || arguments.length === 4)
{
return [CPColor colorWithPatternImage:CPImageInBundle(arguments[0], CGSizeMake(arguments[1], arguments[2]), arguments[3])];
}
else
{
return nil;
}
}
/*!
@ingroup appkit
@@ -633,7 +694,36 @@ url("data:image/png;base64,BASE64ENCODEDDATA") // if there is a pattern image
- (CPString)description
{
return [super description]+" "+[self cssString];
var description = [super description],
patternImage = [self patternImage];
if (!patternImage)
return description + " " + [self cssString];
description += " {\n";
if ([patternImage isThreePartImage] || [patternImage isNinePartImage])
{
var slices = [patternImage imageSlices];
if ([patternImage isThreePartImage])
description += " orientation: " + ([patternImage isVertical] ? "vertical" : "horizontal") + ",\n";
description += " patternImage (" + slices.length + " part): [\n";
for (var i = 0; i < slices.length; ++i)
{
var imgDescription = [slices[i] description];
description += imgDescription.replace(/^/mg, " ") + ",\n";
}
description = description.substr(0, description.length - 2) + "\n ]\n}";
}
else
description += [patternImage description].replace(/^/mg, " ") + "\n}";
return description;
}
@end
@@ -678,8 +768,10 @@ url("data:image/png;base64,BASE64ENCODEDDATA") // if there is a pattern image
@end
/// @cond IGNORE
var CPColorComponentsKey = @"CPColorComponentsKey",
CPColorPatternImageKey = @"CPColorPatternImageKey";
/// @endcond
@implementation CPColor (CPCoding)
@@ -710,13 +802,12 @@ var CPColorComponentsKey = @"CPColorComponentsKey",
@end
/// @cond IGNORE
var hexCharacters = "0123456789ABCDEF";
/*!
Used for the CPColor \c +colorWithHexString: implementation
@ignore
@class CPColor
@return an array of rgb components
/*
Used for the CPColor +colorWithHexString: implementation.
Returns an array of rgb components.
*/
var hexToRGB = function(hex)
{
@@ -754,3 +845,5 @@ var byteToHex = function(n)
return hexCharacters.charAt((n - n % 16) / 16) +
hexCharacters.charAt(n % 16);
};
/// @endcond
+1 -1
View File
@@ -51,7 +51,7 @@ CPWheelColorPickerMode = 1;
*/
CPSliderColorPickerMode = 2;
CPColorPickerViewWidth = 265,
CPColorPickerViewWidth = 265;
CPColorPickerViewHeight = 370;
/*!
+41 -8
View File
@@ -20,6 +20,9 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#import "../Foundation/Ref.h"
@import "../Foundation/CPFormatter.j"
@import "CPFont.j"
@import "CPShadow.j"
@import "CPView.j"
@@ -82,6 +85,7 @@ var CPControlBlackColor = [CPColor blackColor];
@implementation CPControl : CPView
{
id _value;
CPFormatter _formatter @accessors(property=formatter);
// Target-Action Support
id _target;
@@ -221,10 +225,11 @@ var CPControlBlackColor = [CPColor blackColor];
@param anAction the action to send
@param anObject the object to which the action will be sent
*/
- (void)sendAction:(SEL)anAction to:(id)anObject
- (BOOL)sendAction:(SEL)anAction to:(id)anObject
{
[self _reverseSetBinding];
[CPApp sendAction:anAction to:anObject from:self];
return [CPApp sendAction:anAction to:anObject from:self];
}
- (int)sendActionOn:(int)mask
@@ -502,15 +507,46 @@ var CPControlBlackColor = [CPColor blackColor];
*/
- (CPString)stringValue
{
if (_formatter && _value !== undefined && _value !== nil)
{
var formattedValue = [self hasThemeState:CPThemeStateEditing] ? [_formatter editingStringForObjectValue:_value] : [_formatter stringForObjectValue:_value];
if (formattedValue !== nil && formattedValue !== undefined)
return formattedValue;
}
return (_value === undefined || _value === nil) ? "" : String(_value);
}
/*!
Sets the receiver's string value.
*/
- (void)setStringValue:(CPString)anObject
- (void)setStringValue:(CPString)aString
{
[self setObjectValue:anObject];
// Cocoa raises an invalid parameter assertion and returns if you pass nil.
if (aString === nil || aString === undefined)
{
CPLog.warn("nil sent to CPControl -setStringValue");
return;
}
var value;
if (_formatter)
{
value = nil;
if ([_formatter getObjectValue:AT_REF(value) forString:aString errorDescription:nil] === NO)
{
// If the given string is non-empty and doesn't work, Cocoa tries an empty string.
if (!aString || [_formatter getObjectValue:AT_REF(value) forString:@"" errorDescription:nil] === NO)
value = undefined; // Means the value is invalid
}
}
else
value = aString;
[self setObjectValue:value];
}
- (void)takeDoubleValueFrom:(id)sender
@@ -526,21 +562,18 @@ var CPControlBlackColor = [CPColor blackColor];
[self setFloatValue:[sender floatValue]];
}
- (void)takeIntegerValueFrom:(id)sender
{
if ([sender respondsToSelector:@selector(integerValue)])
[self setIntegerValue:[sender integerValue]];
}
- (void)takeIntValueFrom:(id)sender
{
if ([sender respondsToSelector:@selector(intValue)])
[self setIntValue:[sender intValue]];
}
- (void)takeObjectValueFrom:(id)sender
{
if ([sender respondsToSelector:@selector(objectValue)])
@@ -882,7 +915,7 @@ var __Deprecated__CPImageViewImageKey = @"CPImageViewImageKey";
if (_target !== nil)
[aCoder encodeConditionalObject:_target forKey:CPControlTargetKey];
if (_action !== NULL)
if (_action !== nil)
[aCoder encodeObject:_action forKey:CPControlActionKey];
[aCoder encodeInt:_sendActionOn forKey:CPControlSendActionOnKey];
+16 -21
View File
@@ -571,31 +571,27 @@ var _CPEventPeriodicEventPeriod = 0,
if (_modifierFlags & (CPCommandKeyMask | CPControlKeyMask))
return YES;
// Cocoa allows almost any key as a key equivalent unless the first responder is a
// text field (presumably a subclass of NSText.)
var firstResponderIsText = [[_window firstResponder] isKindOfClass:[CPTextField class]];
// Some keys are accepted as key equivalents even if the first responder is a text
// field.
for (var i = 0; i < characterCount; i++)
{
switch (_characters.charAt(i))
var c = _characters.charAt(i);
if ((c >= CPUpArrowFunctionKey && c <= CPModeSwitchFunctionKey) ||
c === CPEnterCharacter ||
c === CPNewlineCharacter ||
c === CPCarriageReturnCharacter ||
c === CPEscapeFunctionKey)
{
case CPBackspaceCharacter:
case CPDeleteCharacter:
case CPDeleteFunctionKey:
case CPTabCharacter:
case CPCarriageReturnCharacter:
case CPNewlineCharacter:
case CPSpaceFunctionKey:
case CPEscapeFunctionKey:
case CPPageUpFunctionKey:
case CPPageDownFunctionKey:
case CPLeftArrowFunctionKey:
case CPUpArrowFunctionKey:
case CPRightArrowFunctionKey:
case CPDownArrowFunctionKey:
case CPEndFunctionKey:
case CPHomeFunctionKey:
return YES;
return YES;
}
}
// FIXME: More cases?
return NO;
return !firstResponderIsText;
}
/*!
@@ -651,4 +647,3 @@ function _CPEventFromNativeMouseEvent(aNativeEvent, anEventType, aPoint, modifie
return aNativeEvent;
}
+20 -1
View File
@@ -44,7 +44,8 @@ CPImageNameColorPanel = @"CPImageNameColorPanel";
CPImageNameColorPanelHighlighted = @"CPImageNameColorPanelHighlighted";
var imagesForNames = { },
AppKitImageForNames = { };
AppKitImageForNames = { },
ImageDescriptionFormat = "%s {\n filename: \"%s\",\n size: { width:%f, height:%f }\n}";
AppKitImageForNames[CPImageNameColorPanel] = CGSizeMake(26.0, 29.0);
AppKitImageForNames[CPImageNameColorPanelHighlighted] = CGSizeMake(26.0, 29.0);
@@ -324,6 +325,24 @@ function CPAppKitImage(aFilename, aSize)
return NO;
}
- (CPString)description
{
var filename = [self filename],
size = [self size];
if (filename.indexOf("data:") === 0)
{
var index = filename.indexOf(",");
if (index > 0)
filename = [CPString stringWithFormat:@"%s,%s...%s", filename.substr(0, index), filename.substr(index + 1, 10), filename.substr(filename.length - 10)];
else
filename = "data:<unknown type>";
}
return [CPString stringWithFormat:ImageDescriptionFormat, [super description], filename, size.width, size.height];
}
/* @ignore */
- (void)_derefFromImage
{
+3 -3
View File
@@ -311,10 +311,10 @@ var CPBindingOperationAnd = 0,
- (void)bind:(CPString)aBinding toObject:(id)anObject withKeyPath:(CPString)aKeyPath options:(CPDictionary)options
{
if (!anObject || !aKeyPath)
return CPLog.error("Invalid object or path on "+self+" for "+aBinding);
return CPLog.error("Invalid object or path on " + self + " for " + aBinding);
//if (![[self exposedBindings] containsObject:aBinding])
// CPLog.warn("No binding exposed on "+self+" for "+aBinding);
// CPLog.warn("No binding exposed on " + self + " for " + aBinding);
var binderClass = [[self class] _binderClassForBinding:aBinding];
@@ -518,4 +518,4 @@ CPValueTransformerBindingOption = @"CPValueTransformer";
CPIsControllerMarker = function(/*id*/anObject)
{
return anObject === CPMultipleValuesMarker || anObject === CPNoSelectionMarker || anObject === CPNotApplicableMarker || anObject === CPNullMarker;
}
}
+2 -2
View File
@@ -149,9 +149,9 @@ var _CPLevelIndicatorBezelColor = nil,
var filledColor = _CPLevelIndicatorSegmentNormalColor,
value = [self doubleValue];
if (value < _criticalValue)
if (value <= _criticalValue)
filledColor = _CPLevelIndicatorSegmentCriticalColor;
else if (value < _warningValue)
else if (value <= _warningValue)
filledColor = _CPLevelIndicatorSegmentWarningColor;
for (var i = 0; i < segmentCount; i++)
+35 -13
View File
@@ -352,8 +352,12 @@ var _CPMenuBarVisible = NO,
while (count--)
[_items[count] setMenu:nil];
_items = [CPMutableArray array];
_highlightedIndex = CPNotFound;
// Because we are changing _items directly, be sure to notify KVO
[self willChangeValueForKey:@"items"];
_items = [CPMutableArray array];
[self didChangeValueForKey:@"items"];
}
/*!
@@ -622,11 +626,11 @@ var _CPMenuBarVisible = NO,
var validator = [CPApp targetForAction:[item action] to:[item target] from:item];
if (!validator || ![validator respondsToSelector:[item action]])
[item _setEnabled:NO];
[item setEnabled:NO];
else if ([validator respondsToSelector:@selector(validateMenuItem:)])
[item _setEnabled:[validator validateMenuItem:item]];
[item setEnabled:[validator validateMenuItem:item]];
else if ([validator respondsToSelector:@selector(validateUserInterfaceItem:)])
[item _setEnabled:[validator validateUserInterfaceItem:item]];
[item setEnabled:[validator validateUserInterfaceItem:item]];
}
[[_menuWindow _menuView] tile];
@@ -711,10 +715,7 @@ var _CPMenuBarVisible = NO,
if (aView && !theWindow)
throw "In call to popUpMenuPositioningItem:atLocation:inView:callback:, view is not in any window.";
var delegate = [self delegate];
if ([delegate respondsToSelector:@selector(menuWillOpen:)])
[delegate menuWillOpen:self];
[self _menuWillOpen];
// Convert location to global coordinates if not already in them.
if (aView)
@@ -802,10 +803,7 @@ var _CPMenuBarVisible = NO,
+ (void)popUpContextMenu:(CPMenu)aMenu withEvent:(CPEvent)anEvent forView:(CPView)aView withFont:(CPFont)aFont
{
var delegate = [aMenu delegate];
if ([delegate respondsToSelector:@selector(menuWillOpen:)])
[delegate menuWillOpen:aMenu];
[aMenu _menuWillOpen];
if (!aFont)
aFont = [CPFont systemFontOfSize:12.0];
@@ -875,7 +873,15 @@ var _CPMenuBarVisible = NO,
*/
- (CPMenuItem)highlightedItem
{
return _highlightedIndex >= 0 ? _items[_highlightedIndex] : nil;
if (_highlightedIndex < 0)
return nil;
var highlightedItem = _items[_highlightedIndex];
if ([highlightedItem isSeparatorItem])
return nil;
return highlightedItem;
}
// Managing the Delegate
@@ -890,6 +896,22 @@ var _CPMenuBarVisible = NO,
return _delegate;
}
- (void)_menuWillOpen
{
var delegate = [self delegate];
if ([delegate respondsToSelector:@selector(menuWillOpen:)])
[delegate menuWillOpen:self];
}
- (void)_menuDidClose
{
var delegate = [self delegate];
if ([delegate respondsToSelector:@selector(menuDidClose:)])
[delegate menuDidClose:self];
}
// Handling Tracking
/*!
Cancels tracking.
+28 -10
View File
@@ -1,8 +1,8 @@
@import <Foundation/CPObject.j>
_CPMenuManagerScrollingStateUp = -1,
_CPMenuManagerScrollingStateDown = 1,
_CPMenuManagerScrollingStateUp = -1;
_CPMenuManagerScrollingStateDown = 1;
_CPMenuManagerScrollingStateNone = 0;
var STICKY_TIME_INTERVAL = 500,
@@ -11,6 +11,7 @@ var STICKY_TIME_INTERVAL = 500,
@implementation _CPMenuManager: CPObject
{
CPTimeInterval _startTime;
BOOL _hasMouseGoneUpAfterStartedTracking;
int _scrollingState;
CGPoint _lastGlobalLocation;
@@ -60,6 +61,9 @@ var STICKY_TIME_INTERVAL = 500,
{
var menu = [aMenuContainer menu];
if ([menu numberOfItems] <= 0)
return;
CPApp._activeMenu = menu;
_startTime = [anEvent timestamp];//new Date();
@@ -87,6 +91,8 @@ var STICKY_TIME_INTERVAL = 500,
return [self trackMenuBarButtonEvent:anEvent];
}
_hasMouseGoneUpAfterStartedTracking = NO;
[self trackEvent:anEvent];
}
@@ -99,7 +105,7 @@ var STICKY_TIME_INTERVAL = 500,
if (type === CPAppKitDefined)
return [self completeTracking];
[CPApp setTarget:self selector:@selector(trackEvent:) forNextEventMatchingMask:CPKeyDownMask | CPPeriodicMask | CPMouseMovedMask | CPLeftMouseDraggedMask | CPLeftMouseUpMask | CPAppKitDefinedMask | CPScrollWheelMask untilDate:nil inMode:nil dequeue:YES];
[CPApp setTarget:self selector:@selector(trackEvent:) forNextEventMatchingMask:CPKeyDownMask | CPPeriodicMask | CPMouseMovedMask | CPLeftMouseDraggedMask | CPLeftMouseUpMask | CPRightMouseUpMask | CPAppKitDefinedMask | CPScrollWheelMask untilDate:nil inMode:nil dequeue:YES];
if (type === CPKeyDown)
{
@@ -221,8 +227,20 @@ var STICKY_TIME_INTERVAL = 500,
[CPEvent startPeriodicEventsAfterDelay:0.0 withPeriod:0.04];
}
}
else if (type === CPLeftMouseUp && ([anEvent timestamp] - _startTime > (STICKY_TIME_INTERVAL + [activeMenu numberOfItems] * 5)))
[trackingMenu cancelTracking];
else if (type === CPLeftMouseUp || type === CPRightMouseUp)
{
if (_hasMouseGoneUpAfterStartedTracking)
{
// Don't close the menu if the current item has a submenu
// and did not override it's default action
if ([activeItem action] === @selector(submenuAction:))
return;
[trackingMenu cancelTracking];
}
else
_hasMouseGoneUpAfterStartedTracking = YES;
}
}
// Prevent previous selected menu items from opening by stopping the timer if a
@@ -306,11 +324,7 @@ var STICKY_TIME_INTERVAL = 500,
// Hide all submenus.
[self showMenu:nil fromMenu:trackingMenu atPoint:nil];
var delegate = [trackingMenu delegate];
if ([delegate respondsToSelector:@selector(menuDidClose:)])
[delegate menuDidClose:trackingMenu];
[trackingMenu _menuDidClose];
if (_trackingCallback)
_trackingCallback([self trackingMenuContainer], trackingMenu);
@@ -379,6 +393,8 @@ var STICKY_TIME_INTERVAL = 500,
var count = _menuContainerStack.length,
index = count;
[newMenu _menuWillOpen];
// Hide all menus up to the base menu...
while (index--)
{
@@ -398,6 +414,8 @@ var STICKY_TIME_INTERVAL = 500,
[_CPMenuWindow poolMenuWindow:menuContainer];
[_menuContainerStack removeObjectAtIndex:index];
[menu _menuDidClose];
}
if (!newMenu)
+1 -8
View File
@@ -148,14 +148,6 @@ var CPMenuItemStringRepresentationDictionary = [CPDictionary dictionary];
@param isEnabled \c YES enables the item. \c NO disables it.
*/
- (void)setEnabled:(BOOL)isEnabled
{
if ([_menu autoenablesItems])
return;
[self _setEnabled:isEnabled];
}
- (void)_setEnabled:(BOOL)isEnabled
{
if (_isEnabled === isEnabled)
return;
@@ -496,6 +488,7 @@ CPOffState
if (_submenu)
{
[_submenu setSupermenu:_menu];
[_submenu setTitle:[self title]]
[self setTarget:_menu];
[self setAction:@selector(submenuAction:)];
+1 -1
View File
@@ -131,8 +131,8 @@
_contentObject = aContent;
[self didChangeValueForKey:@"contentObject"];
[self _selectionDidChange];
[self didChangeValueForKey:@"contentObject"];
}
/*!
+38
View File
@@ -1458,6 +1458,44 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
userInfo:[CPDictionary dictionaryWithObject:item forKey:"CPObject"]];
}
- (void)keyDown:(CPEvent)anEvent
{
var character = [anEvent charactersIgnoringModifiers],
modifierFlags = [anEvent modifierFlags];
// Check for the key events manually, as opposed to waiting for CPWindow to sent the actual action message
// in _processKeyboardUIKey:, because we might not want to handle the arrow events.
if (character !== CPRightArrowFunctionKey && character !== CPLeftArrowFunctionKey)
return [super keyDown:anEvent];
var rows = [self selectedRowIndexes],
indexes = [],
items = [];
[rows getIndexes:indexes maxCount:-1 inIndexRange:nil];
var i = 0,
c = [indexes count];
for (; i < c; i++)
items.push([self itemAtRow:indexes[i]]);
if (character === CPRightArrowFunctionKey)
{
for (var i = 0; i < c; i++)
[self expandItem:items[i]];
}
else if (character === CPLeftArrowFunctionKey)
{
for (var i = 0; i < c; i++)
[self collapseItem:items[i]];
}
[super keyDown:anEvent];
}
@end
// FIX ME: We're using with() here because Safari fails if we use anOutlineView._itemInfosForItems or whatever...
+2 -1
View File
@@ -86,7 +86,7 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
[self setPullsDown:shouldPullDown];
var options = CPKeyValueObservingOptionNew |CPKeyValueObservingOptionOld;/* |CPKeyValueObservingOptionInitial;*/
var options = CPKeyValueObservingOptionNew | CPKeyValueObservingOptionOld; // | CPKeyValueObservingOptionInitial;
[self addObserver:self forKeyPath:@"menu.items" options:options context:nil];
[self addObserver:self forKeyPath:@"_firstItem.changeCount" options:options context:nil];
[self addObserver:self forKeyPath:@"selectedItem.changeCount" options:options context:nil];
@@ -193,6 +193,7 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
- (void)removeAllItems
{
[[self menu] removeAllItems];
[self synchronizeTitleAndSelectedItem];
}
/*!
+325
View File
@@ -0,0 +1,325 @@
/*
* CPPopover.j
* AppKit
*
* Created by Antoine Mercadal.
* Copyright 2011 Antoine Mercadal.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import <Foundation/CPObject.j>
@import "CPButton.j"
@import "CPColor.j"
@import "CPImage.j"
@import "CPImageView.j"
@import "CPResponder.j"
@import "CPView.j"
@import "_CPAttachedWindow.j"
CPPopoverBehaviorApplicationDefined = 0;
CPPopoverBehaviorTransient = 1;
CPPopoverBehaviorSemitransient = 2;
var CPPopoverDelegate_popover_willShow_ = 1 << 0,
CPPopoverDelegate_popover_didShow_ = 1 << 1,
CPPopoverDelegate_popover_shouldClose_ = 1 << 2,
CPPopoverDelegate_popover_willClose_ = 1 << 3,
CPPopoverDelegate_popover_didClose_ = 1 << 4;
/*! @ingroup appkit
@class CPPopover
This class represent a widget that displays a attached
view relative to another one.
Delegate can implement:
popoverShouldClose:(CPPopover)aPopOver
popoverWillShow:(CPPopover)aPopOver
popoverDidShow:(CPPopover)aPopOver
popoverWillClose:(CPPopover)aPopOver
popoverDidClose:(CPPopover)aPopOver
*/
@implementation CPPopover : CPResponder
{
@outlet CPViewController _contentViewController @accessors(property=contentViewController);
@outlet id _delegate @accessors(getter=delegate);
BOOL _animates @accessors(property=animates);
BOOL _shown @accessors(getter=shown);
int _appearance @accessors(property=appearance);
int _behavior @accessors(getter=behavior);
BOOL _needsCompute;
_CPAttachedWindow _attachedWindow;
int _implementedDelegateMethods;
}
#pragma mark -
#pragma mark Initialization
/*!
Initialize the CPPopover witn default values
@returns anInitialized CPPopover
*/
- (CPPopover)init
{
if (self = [super init])
{
_animates = YES;
_appearance = CPPopoverAppearanceMinimal;
_behavior = CPPopoverBehaviorApplicationDefined;
_needsCompute = YES;
_shown = NO;
}
return self;
}
#pragma mark -
#pragma mark Getters / Setters
/*!
Returns the current rect of the popover
@return CPRect represeting the frame of the popover
*/
- (CPRect)positioningRect
{
if (!_attachedWindow || ![_attachedWindow isVisible])
return nil;
return [_attachedWindow frame];
}
/*! Sets the frame of the popover
@param aRect the desired frame
*/
- (void)setPositioningRect:(CPRect)aRect
{
if (!_attachedWindow || ![_attachedWindow isVisible])
return;
[_attachedWindow setFrame:aRect];
}
/*!
Returns the size of the popover's view
@return CPSize represeting the size of the popover's view
*/
- (CPRect)contentSize
{
if (!_attachedWindow || ![_attachedWindow isVisible])
return nil;
return [[_contentViewController view] frameSize];
}
/*!
Sets the size of of the popover's view
@param aSize the desired size
*/
- (void)setContentSize:(CPSize)aSize
{
[[_contentViewController view] setFrameSize:aSize];
}
/*!
Indicates if CPPopover is visible
@returns YES if visible
*/
- (BOOL)shown
{
if (!_attachedWindow)
return NO;
return [_attachedWindow isVisible];
}
/*!
Set the behaviour of the CPPopover. It can be
- CPPopoverBehaviorTransient: the popover will be close if another control outside the popover become the responder
- CPPopoverBehaviorApplicationDefined: (DEFAULT) the application is responsible for closing the popover
@param aBehaviour the desired behaviour
*/
- (void)setBehaviour:(int)aBehaviour
{
if (_behavior == aBehaviour)
return;
_behavior = aBehaviour;
_needsCompute = YES;
}
- (void)setDelegate:(id)aDelegate
{
if (_delegate === aDelegate)
return;
_delegate = aDelegate;
_implementedDelegateMethods = 0;
if ([_delegate respondsToSelector:@selector(popoverWillShow:)])
_implementedDelegateMethods |= CPPopoverDelegate_popover_willShow_;
if ([_delegate respondsToSelector:@selector(popoverDidShow:)])
_implementedDelegateMethods |= CPPopoverDelegate_popover_didShow_;
if ([_delegate respondsToSelector:@selector(popoverShouldClose:)])
_implementedDelegateMethods |= CPPopoverDelegate_popover_shouldClose_;
if ([_delegate respondsToSelector:@selector(popoverWillClose:)])
_implementedDelegateMethods |= CPPopoverDelegate_popover_willClose_;
if ([_delegate respondsToSelector:@selector(popoverDidClose:)])
_implementedDelegateMethods |= CPPopoverDelegate_popover_didClose_;
}
#pragma mark -
#pragma mark Positioning
/*!
Show the popover
@param positioningRect if set, the popover will be positionned to a random rect relative to the window
@param positioningView if set, the popover will be positioned relative to this view
@param preferredEdge: CPRectEdge representing the preferred positioning.
*/
- (void)showRelativeToRect:(CPRect)positioningRect ofView:(CPView)positioningView preferredEdge:(CPRectEdge)preferredEdge
{
if (_implementedDelegateMethods & CPPopoverDelegate_popover_willShow_)
[_delegate popoverWillShow:self];
if (!_contentViewController)
[CPException raise:CPInternalInconsistencyException reason:@"contentViewController must not be nil"];
if (_needsCompute || !_attachedWindow)
{
var styleMask = (_behavior == CPPopoverBehaviorTransient) ? CPClosableOnBlurWindowMask : nil;
_attachedWindow = [[_CPAttachedWindow alloc] initWithContentRect:CPRectMakeZero() styleMask:styleMask];
}
[_attachedWindow setAppearance:_appearance];
[_attachedWindow setAnimates:_animates];
[_attachedWindow setDelegate:self];
[_attachedWindow setMovableByWindowBackground:NO];
[_attachedWindow setFrame:[_attachedWindow frameRectForContentRect:[[_contentViewController view] frame]]];
[_attachedWindow setContentView:[_contentViewController view]];
if (positioningRect)
[_attachedWindow positionRelativeToRect:positioningRect preferredEdge:preferredEdge];
else if (positioningView)
[_attachedWindow positionRelativeToView:positioningView preferredEdge:preferredEdge];
else
[CPException raise:CPInvalidArgumentException reason:@"a value must be passed for positioningRect or positioningView"];
if (_implementedDelegateMethods & CPPopoverDelegate_popover_didShow_)
[_delegate popoverDidShow:self];
}
/*!
Closes the popover
*/
- (void)close
{
if (_implementedDelegateMethods & CPPopoverDelegate_popover_shouldClose_)
if (![_delegate popoverShouldClose:self])
return;
if (_implementedDelegateMethods & CPPopoverDelegate_popover_willClose_)
[_delegate popoverWillClose:self];
[_attachedWindow close];
if (_implementedDelegateMethods & CPPopoverDelegate_popover_didClose_)
[_delegate popoverDidClose:self];
}
#pragma mark -
#pragma mark Action
/*!
Close the popover
@param aSender the sender of the action
*/
- (IBAction)performClose:(id)aSender
{
[self close];
}
#pragma mark -
#pragma mark Delegates
/*! @ignore */
- (BOOL)attachedWindowShouldClose:(_CPAttachedWindow)anAttachedWindow
{
[self close];
// we return NO, because we want the CPPopover to compute
// if the attached can be close in order to send delegate messages
return NO;
}
@end
var CPPopoverNeedsComputeKey = @"CPPopoverNeedsComputeKey",
CPPopoverAppearanceKey = @"CPPopoverAppearanceKey",
CPPopoverAnimatesKey = @"CPPopoverAnimatesKey",
CPPopoverContentViewControllerKey = @"CPPopoverContentViewControllerKey",
CPPopoverDelegateKey = @"CPPopoverDelegateKey",
CPPopoverBehaviorKey = @"CPPopoverBehaviorKey";
@implementation CPPopover (CPCoding)
- (id)initWithCoder:(CPCoder)aCoder
{
self = [super initWithCoder:aCoder];
if (self)
{
_needsCompute = [aCoder decodeIntForKey:CPPopoverNeedsComputeKey];
_appearance = [aCoder decodeIntForKey:CPPopoverAppearanceKey];
_animates = [aCoder decodeBoolForKey:CPPopoverAnimatesKey];
_contentViewController = [aCoder decodeObjectForKey:CPPopoverContentViewControllerKey];
[self setDelegate:[aCoder decodeObjectForKey:CPPopoverDelegateKey]];
[self setBehaviour:[aCoder decodeIntForKey:CPPopoverBehaviorKey]];
}
return self;
}
- (void)encodeWithCoder:(CPCoder)aCoder
{
[super encodeWithCoder:aCoder];
[aCoder encodeBool:_needsCompute forKey:CPPopoverNeedsComputeKey];
[aCoder encodeInt:_appearance forKey:CPPopoverAppearanceKey];
[aCoder encodeObject:_animates forKey:CPPopoverAnimatesKey];
[aCoder encodeObject:_contentViewController forKey:CPPopoverContentViewControllerKey];
[aCoder encodeObject:_delegate forKey:CPPopoverDelegateKey];
[aCoder encodeInt:_behavior forKey:CPPopoverBehaviorKey];
}
@end
+8 -2
View File
@@ -150,6 +150,14 @@ CPRadioImageOffset = 4.0;
[_radioGroup _setSelectedRadio:self];
}
- (void)sendAction:(SEL)anAction to:(id)anObject
{
[super sendAction:anAction to:anObject];
if (_radioGroup)
[CPApp sendAction:[_radioGroup action] to:[_radioGroup target] from:_radioGroup];
}
@end
var CPRadioRadioGroupKey = @"CPRadioRadioGroupKey";
@@ -220,8 +228,6 @@ var CPRadioRadioGroupKey = @"CPRadioRadioGroupKey";
[_selectedRadio setState:CPOffState];
_selectedRadio = aRadio;
[CPApp sendAction:_action to:_target from:self];
}
- (CPRadio)selectedRadio
+2 -2
View File
@@ -200,7 +200,7 @@
if (isPopup)
{
itemArray = [[templateView itemArray] valueForKey:@"title"];
itemsCount = [itemArray count],
itemsCount = [itemArray count];
menuIndex = 0;
}
@@ -501,4 +501,4 @@ var CPPredicateTemplatesKey = @"CPPredicateTemplates";
@end
/*! @endcond */
/*! @endcond */
@@ -20,17 +20,17 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
CPUndefinedAttributeType = 0,
CPInteger16AttributeType = 100,
CPInteger32AttributeType = 200,
CPInteger64AttributeType = 300,
CPDecimalAttributeType = 400,
CPDoubleAttributeType = 500,
CPFloatAttributeType = 600,
CPStringAttributeType = 700,
CPBooleanAttributeType = 800,
CPDateAttributeType = 900,
CPBinaryDataAttributeType = 1000,
CPUndefinedAttributeType = 0;
CPInteger16AttributeType = 100;
CPInteger32AttributeType = 200;
CPInteger64AttributeType = 300;
CPDecimalAttributeType = 400;
CPDoubleAttributeType = 500;
CPFloatAttributeType = 600;
CPStringAttributeType = 700;
CPBooleanAttributeType = 800;
CPDateAttributeType = 900;
CPBinaryDataAttributeType = 1000;
CPTransformableAttributeType = 1800;
@implementation CPPredicateEditorRowTemplate : CPObject
@@ -785,4 +785,4 @@ var CPPredicateTemplateTypeKey = @"CPPredicateTemplateType",
}
@end
/*! @endcond */
/*! @endcond */
@@ -16,12 +16,12 @@ var GRADIENT_NORMAL,
{
if (CPBrowserIsEngine(CPWebKitBrowserEngine))
{
GRADIENT_NORMAL = "-webkit-gradient(linear, left top, left bottom, from(rgb(252, 252, 252)), to(rgb(223, 223, 223)))",
GRADIENT_NORMAL = "-webkit-gradient(linear, left top, left bottom, from(rgb(252, 252, 252)), to(rgb(223, 223, 223)))";
GRADIENT_HIGHLIGHTED = "-webkit-gradient(linear, left top, left bottom, from(rgb(223, 223, 223)), to(rgb(252, 252, 252)))";
}
else if (CPBrowserIsEngine(CPGeckoBrowserEngine))
{
GRADIENT_NORMAL = "-moz-linear-gradient(top, rgb(252, 252, 252), rgb(223, 223, 223))",
GRADIENT_NORMAL = "-moz-linear-gradient(top, rgb(252, 252, 252), rgb(223, 223, 223))";
GRADIENT_HIGHLIGHTED = "-moz-linear-gradient(top, rgb(223, 223, 223), rgb(252, 252, 252))";
}
}
@@ -35,7 +35,7 @@ var GRADIENT_NORMAL,
style.border = "1px solid rgb(189, 189, 189)";
style.filter = IE_FILTER;
[self setTextColor:[CPColor colorWithWhite:101/255 alpha:1]];
[self setTextColor:[CPColor colorWithWhite:101 / 255 alpha:1]];
[self setBordered:NO];
}
+938 -536
View File
File diff suppressed because it is too large Load Diff
+261 -66
View File
@@ -5,6 +5,9 @@
* Created by Francisco Tolmasky.
* Copyright 2008, 280 North, Inc.
*
* Modified to match Lion style by Antoine Mercadal 2011
* <antoine.mercadal@archipelproject.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
@@ -22,7 +25,6 @@
@import "CPControl.j"
// CPScroller Constants
CPScrollerNoPart = 0;
CPScrollerDecrementPage = 1;
@@ -54,6 +56,17 @@ NAMES_FOR_PARTS[CPScrollerKnobSlot] = @"knob-slot";
NAMES_FOR_PARTS[CPScrollerKnob] = @"knob";
CPScrollerStyleLegacy = 0;
CPScrollerStyleOverlay = 1;
CPScrollerKnobStyleDefault = 0;
CPScrollerKnobStyleDark = 1;
CPScrollerKnobStyleLight = 2;
CPThemeStateScrollViewLegacy = CPThemeState("scroller-style-legacy");
CPThemeStateScrollerKnobLight = CPThemeState("scroller-knob-light");
CPThemeStateScrollerKnobDark = CPThemeState("scroller-knob-dark");
@implementation CPScroller : CPControl
{
CPControlSize _controlSize;
@@ -68,8 +81,19 @@ NAMES_FOR_PARTS[CPScrollerKnob] = @"knob";
CPScrollerPart _trackingPart;
float _trackingFloatValue;
CGPoint _trackingStartPoint;
CPViewAnimation _animationScroller;
BOOL _allowFadingOut @accessors(getter=allowFadingOut);
int _style;
CPTimer _timerFadeOut;
BOOL _isMouseOver;
}
#pragma mark -
#pragma mark Class methods
+ (CPString)defaultThemeClass
{
return "scroller";
@@ -78,49 +102,43 @@ NAMES_FOR_PARTS[CPScrollerKnob] = @"knob";
+ (id)themeAttributes
{
return [CPDictionary dictionaryWithJSObject:{
@"scroller-width": 15.0,
@"knob-slot-color": [CPColor lightGrayColor],
@"scroller-width": 7.0,
@"knob-slot-color": [CPNull null],
@"decrement-line-color": [CPNull null],
@"increment-line-color": [CPNull null],
@"knob-color": [CPColor grayColor],
@"knob-color": [CPNull null],
@"decrement-line-size":_CGSizeMakeZero(),
@"increment-line-size":_CGSizeMakeZero(),
@"track-inset":_CGInsetMakeZero(),
@"knob-inset": _CGInsetMakeZero(),
@"minimum-knob-length":21.0
}]
@"minimum-knob-length":21.0,
@"track-border-overlay": 9.0
}];
}
// Calculating Layout
- (id)initWithFrame:(CGRect)aFrame
+ (float)scrollerWidth
{
self = [super initWithFrame:aFrame];
if (self)
{
_controlSize = CPRegularControlSize;
_partRects = [];
[self setFloatValue:0.0];
[self setKnobProportion:1.0];
_hitPart = CPScrollerNoPart;
[self _calculateIsVertical];
}
return self;
return [self scrollerWidthInStyle:CPScrollerStyleLegacy];
}
// Determining CPScroller Size
/*!
Returns the CPScroller's width for a CPRegularControlSize.
*/
+ (float)scrollerWidth
+ (float)scrollerWidthInStyle:(int)aStyle
{
return [[[CPScroller alloc] init] currentValueForThemeAttribute:@"scroller-width"];
var scroller = [[self alloc] init];
if (aStyle == CPScrollerStyleLegacy)
return [scroller valueForThemeAttribute:@"scroller-width" inState:CPThemeStateScrollViewLegacy];
return [scroller currentValueForThemeAttribute:@"scroller-width"];
}
/*!
Returns the CPScroller's overlay value.
*/
+ (float)scrollerOverlay
{
return [[[self alloc] init] currentValueForThemeAttribute:@"track-border-overlay"];
}
/*!
@@ -132,6 +150,87 @@ NAMES_FOR_PARTS[CPScrollerKnob] = @"knob";
return [self scrollerWidth];
}
#pragma mark -
#pragma mark Initialization
- (id)initWithFrame:(CGRect)aFrame
{
if (self = [super initWithFrame:aFrame])
{
_controlSize = CPRegularControlSize;
_partRects = [];
[self setFloatValue:0.0];
[self setKnobProportion:1.0];
_hitPart = CPScrollerNoPart;
_allowFadingOut = YES;
_isMouseOver = NO;
_style = CPScrollerStyleOverlay;
var paramAnimFadeOut = [CPDictionary dictionaryWithObjects:[self, CPViewAnimationFadeOutEffect]
forKeys:[CPViewAnimationTargetKey, CPViewAnimationEffectKey]];
_animationScroller = [[CPViewAnimation alloc] initWithDuration:0.2 animationCurve:CPAnimationEaseInOut];
[_animationScroller setViewAnimations:[paramAnimFadeOut]];
[_animationScroller setDelegate:self];
[self setAlphaValue:0.0];
[self _calculateIsVertical];
}
return self;
}
#pragma mark -
#pragma mark Getters / Setters
/*!
Returns the scroller's style
*/
- (void)style
{
return _style;
}
/*!
Set the scroller's control size
@param aStyle the scroller style: CPScrollerStyleLegacy or CPScrollerStyleOverlay
*/
- (void)setStyle:(id)aStyle
{
if (_style != nil && _style === aStyle)
return;
_style = aStyle;
if (_style === CPScrollerStyleLegacy)
{
[self fadeIn];
[self setThemeState:CPThemeStateScrollViewLegacy];
}
else
{
_allowFadingOut = YES;
[self unsetThemeState:CPThemeStateScrollViewLegacy];
}
[self _adjustScrollerSize];
}
- (void)setObjectValue:(id)aValue
{
[super setObjectValue:MIN(1.0, MAX(0.0, +aValue))];
}
/*!
Returns the scroller's control size
*/
- (CPControlSize)controlSize
{
return _controlSize;
}
/*!
Sets the scroller's size.
@param aControlSize the scroller's size
@@ -148,18 +247,17 @@ NAMES_FOR_PARTS[CPScrollerKnob] = @"knob";
}
/*!
Returns the scroller's control size
Return's the knob's proportion
*/
- (CPControlSize)controlSize
- (float)knobProportion
{
return _controlSize;
}
- (void)setObjectValue:(id)aValue
{
[super setObjectValue:MIN(1.0, MAX(0.0, +aValue))];
return _knobProportion;
}
/*!
Set the knob's proportion
@param aProportion the desired proportion
*/
- (void)setKnobProportion:(float)aProportion
{
_knobProportion = MIN(1.0, MAX(0.0001, aProportion));
@@ -168,25 +266,35 @@ NAMES_FOR_PARTS[CPScrollerKnob] = @"knob";
[self setNeedsLayout];
}
/*!
Return's the knob's proportion
*/
- (float)knobProportion
#pragma mark -
#pragma mark Privates
/*! @ignore */
- (void)_adjustScrollerSize
{
return _knobProportion;
var frame = [self frame],
scrollerWidth = [self currentValueForThemeAttribute:@"scroller-width"];
if ([self isVertical] && CGRectGetWidth(frame) !== scrollerWidth)
frame.size.width = scrollerWidth;
if (![self isVertical] && CGRectGetHeight(frame) !== scrollerWidth)
frame.size.height = scrollerWidth;
[self setFrame:frame];
}
- (id)currentValueForThemeAttribute:(CPString)anAttributeName
/*! @ignore */
- (void)_performFadeOut:(CPTimer)aTimer
{
var themeState = _themeState;
if (NAMES_FOR_PARTS[_hitPart] + "-color" !== anAttributeName)
themeState &= ~CPThemeStateHighlighted;
return [self valueForThemeAttribute:anAttributeName inState:themeState];
[self fadeOut];
_timerFadeOut = nil;
}
// Calculating Layout
#pragma mark -
#pragma mark Utilities
- (CGRect)rectForPart:(CPScrollerPart)aPart
{
@@ -208,6 +316,9 @@ NAMES_FOR_PARTS[CPScrollerKnob] = @"knob";
// The ordering of these tests is important. We check the knob and
// page rects first since they may overlap with the arrows.
if (![self hasThemeState:CPThemeStateSelected])
return CPScrollerNoPart;
if (CGRectContainsPoint([self rectForPart:CPScrollerKnob], aPoint))
return CPScrollerKnob;
@@ -330,7 +441,35 @@ NAMES_FOR_PARTS[CPScrollerKnob] = @"knob";
return _usableParts;
}
// Drawing the Parts
/*!
Display the scroller
*/
- (void)fadeIn
{
if (_isMouseOver && _knobProportion != 1.0)
[self setThemeState:CPThemeStateSelected];
if (_timerFadeOut)
[_timerFadeOut invalidate];
[self setAlphaValue:1.0];
}
/*!
Start the fade out anination
*/
- (void)fadeOut
{
if ([self hasThemeState:CPThemeStateScrollViewLegacy])
return;
[_animationScroller startAnimation];
}
#pragma mark -
#pragma mark Drawing
/*!
Draws the specified arrow and sets the highlight.
@param anArrow the arrow to draw
@@ -458,7 +597,8 @@ NAMES_FOR_PARTS[CPScrollerKnob] = @"knob";
[CPApp setTarget:self selector:@selector(trackKnob:) forNextEventMatchingMask:CPLeftMouseDraggedMask | CPLeftMouseUpMask untilDate:nil inMode:nil dequeue:YES];
[self sendAction:[self action] to:[self target]];
if (type === CPLeftMouseDragged)
[self sendAction:[self action] to:[self target]];
}
/*!
@@ -564,6 +704,20 @@ NAMES_FOR_PARTS[CPScrollerKnob] = @"knob";
[self setNeedsLayout];
}
#pragma mark -
#pragma mark Overrides
- (id)currentValueForThemeAttribute:(CPString)anAttributeName
{
var themeState = _themeState;
if (NAMES_FOR_PARTS[_hitPart] + "-color" !== anAttributeName)
themeState &= ~CPThemeStateHighlighted;
return [self valueForThemeAttribute:anAttributeName inState:themeState];
}
- (void)mouseDown:(CPEvent)anEvent
{
if (![self isEnabled])
@@ -582,10 +736,52 @@ NAMES_FOR_PARTS[CPScrollerKnob] = @"knob";
}
}
- (void)mouseEntered:(CPEvent)anEvent
{
[super mouseEntered:anEvent];
if (_timerFadeOut)
[_timerFadeOut invalidate];
if (![self isEnabled])
return;
_allowFadingOut = NO;
_isMouseOver = YES;
if ([self alphaValue] > 0 && _knobProportion != 1.0)
[self setThemeState:CPThemeStateSelected];
}
- (void)mouseExited:(CPEvent)anEvent
{
[super mouseExited:anEvent];
if ([self isHidden] || ![self isEnabled] || !_isMouseOver)
return;
_allowFadingOut = YES;
_isMouseOver = NO;
if (_timerFadeOut)
[_timerFadeOut invalidate];
_timerFadeOut = [CPTimer scheduledTimerWithTimeInterval:1.2 target:self selector:@selector(_performFadeOut:) userInfo:nil repeats:NO];
}
#pragma mark -
#pragma mark Delegates
- (void)animationDidEnd:(CPAnimation)animation
{
[self unsetThemeState:CPThemeStateSelected];
}
@end
var CPScrollerControlSizeKey = "CPScrollerControlSize",
CPScrollerKnobProportionKey = "CPScrollerKnobProportion";
var CPScrollerControlSizeKey = @"CPScrollerControlSize",
CPScrollerKnobProportionKey = @"CPScrollerKnobProportion",
CPScrollerStyleKey = @"CPScrollerStyleKey";
@implementation CPScroller (CPCoding)
@@ -605,20 +801,18 @@ var CPScrollerControlSizeKey = "CPScrollerControlSize",
_hitPart = CPScrollerNoPart;
_allowFadingOut = YES;
_isMouseOver = NO;
var paramAnimFadeOut = [CPDictionary dictionaryWithObjects:[self, CPViewAnimationFadeOutEffect]
forKeys:[CPViewAnimationTargetKey, CPViewAnimationEffectKey]];
_animationScroller = [[CPViewAnimation alloc] initWithDuration:0.2 animationCurve:CPAnimationEaseInOut];
[_animationScroller setViewAnimations:[paramAnimFadeOut]];
[_animationScroller setDelegate:self];
[self setAlphaValue:0.0];
[self _calculateIsVertical];
// Adjust the size of the scroller if the size from cib
// isn't equal to the scrollerWidth
var frame = [self frame],
scrollerWidth = [CPScroller scrollerWidth];
if ([self isVertical] && CGRectGetWidth(frame) !== scrollerWidth)
frame.size.width = scrollerWidth;
if (![self isVertical] && CGRectGetHeight(frame) !== scrollerWidth)
frame.size.height = scrollerWidth;
[self setFrame:frame];
[self setStyle:[aCoder decodeIntForKey:CPScrollerStyleKey]];
}
return self;
@@ -630,6 +824,7 @@ var CPScrollerControlSizeKey = "CPScrollerControlSize",
[aCoder encodeInt:_controlSize forKey:CPScrollerControlSizeKey];
[aCoder encodeFloat:_knobProportion forKey:CPScrollerKnobProportionKey];
[aCoder encodeInt:_style forKey:CPScrollerStyleKey];
}
@end
+14
View File
@@ -45,6 +45,7 @@ CPSoundPlayBackStatePause = 2;
CPString _name @accessors(property=name);
id _delegate @accessors(property=delegate);
BOOL _playRequestBeforeLoad;
HTMLAudioElement _audioTag;
int _loadStatus;
int _playBackStatus;
@@ -61,6 +62,7 @@ CPSoundPlayBackStatePause = 2;
_loops = NO;
_audioTag = document.createElement("audio");
_audioTag.preload = YES;
_playRequestBeforeLoad = NO;
_audioTag.addEventListener("canplay", function()
{
@@ -138,6 +140,12 @@ CPSoundPlayBackStatePause = 2;
- (void)_soundDidload
{
_loadStatus = CPSoundLoadStateCanBePlayed;
if (_playRequestBeforeLoad)
{
_playRequestBeforeLoad = NO;
[self play];
}
}
/*! @ignore
@@ -167,6 +175,12 @@ CPSoundPlayBackStatePause = 2;
*/
- (BOOL)play
{
if (_loadStatus === CPSoundLoadStateLoading)
{
_playRequestBeforeLoad = YES;
return YES;
}
if ((_loadStatus !== CPSoundLoadStateCanBePlayed)
|| (_playBackStatus === CPSoundPlayBackStatePlay))
return NO;
+256 -33
View File
@@ -20,16 +20,43 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "../Foundation/Foundation.h"
@import "CPButtonBar.j"
@import "CPImage.j"
@import "CPView.j"
#define SPLIT_VIEW_MAYBE_POST_WILL_RESIZE() \
if ((_suppressResizeNotificationsMask & DidPostWillResizeNotification) === 0) \
{ \
[self _postNotificationWillResize]; \
_suppressResizeNotificationsMask |= DidPostWillResizeNotification; \
}
#define SPLIT_VIEW_MAYBE_POST_DID_RESIZE() \
if ((_suppressResizeNotificationsMask & ShouldSuppressResizeNotifications) !== 0) \
_suppressResizeNotificationsMask |= DidSuppressResizeNotification; \
else \
[self _postNotificationDidResize];
#define SPLIT_VIEW_DID_SUPPRESS_RESIZE_NOTIFICATION() \
((_suppressResizeNotificationsMask & DidSuppressResizeNotification) !== 0)
#define SPLIT_VIEW_SUPPRESS_RESIZE_NOTIFICATIONS(shouldSuppress) \
if (shouldSuppress) \
_suppressResizeNotificationsMask |= ShouldSuppressResizeNotifications; \
else \
_suppressResizeNotificationsMask = 0;
CPSplitViewDidResizeSubviewsNotification = @"CPSplitViewDidResizeSubviewsNotification";
CPSplitViewWillResizeSubviewsNotification = @"CPSplitViewWillResizeSubviewsNotification";
var CPSplitViewHorizontalImage = nil,
CPSplitViewVerticalImage = nil;
CPSplitViewVerticalImage = nil,
ShouldSuppressResizeNotifications = 1,
DidPostWillResizeNotification = 1 << 1,
DidSuppressResizeNotification = 1 << 2;
/*!
@ingroup appkit
@@ -45,24 +72,29 @@ var CPSplitViewHorizontalImage = nil,
@implementation CPSplitView : CPView
{
id _delegate;
BOOL _isVertical;
BOOL _isPaneSplitter;
id _delegate;
BOOL _isVertical;
BOOL _isPaneSplitter;
int _currentDivider;
float _initialOffset;
float _preCollapsePosition;
int _currentDivider;
float _initialOffset;
CPDictionary _preCollapsePositions;
CPString _originComponent;
CPString _sizeComponent;
CPString _originComponent;
CPString _sizeComponent;
CPArray _DOMDividerElements;
CPString _dividerImagePath;
int _drawingDivider;
CPArray _DOMDividerElements;
CPString _dividerImagePath;
int _drawingDivider;
BOOL _needsResizeSubviews;
CPString _autosaveName;
BOOL _shouldAutosave;
BOOL _needsRestoreFromAutosave;
CPArray _buttonBars;
BOOL _needsResizeSubviews;
int _suppressResizeNotificationsMask;
CPArray _buttonBars;
}
+ (CPString)defaultThemeClass
@@ -93,11 +125,15 @@ var CPSplitViewHorizontalImage = nil,
{
if (self = [super initWithFrame:aFrame])
{
_suppressResizeNotificationsMask = 0;
_preCollapsePositions = [CPMutableDictionary new];
_currentDivider = CPNotFound;
_DOMDividerElements = [];
_buttonBars = [];
_shouldAutosave = YES;
[self _setVertical:YES];
}
@@ -412,7 +448,6 @@ var CPSplitViewHorizontalImage = nil,
{
_currentDivider = CPNotFound;
[self _updateResizeCursor:anEvent];
[self _postNotificationDidResize];
}
return;
@@ -436,7 +471,8 @@ var CPSplitViewHorizontalImage = nil,
[_delegate respondsToSelector:@selector(splitView:shouldCollapseSubview:forDoubleClickOnDividerAtIndex:)])
{
var minPosition = [self minPossiblePositionOfDividerAtIndex:i],
maxPosition = [self maxPossiblePositionOfDividerAtIndex:i];
maxPosition = [self maxPossiblePositionOfDividerAtIndex:i],
_preCollapsePosition = [_preCollapsePositions objectForKey:"" + i] || 0;
if ([_delegate splitView:self canCollapseSubview:_subviews[i]] && [_delegate splitView:self shouldCollapseSubview:_subviews[i] forDoubleClickOnDividerAtIndex:i])
{
@@ -526,20 +562,34 @@ var CPSplitViewHorizontalImage = nil,
// If we are currently tracking, keep the resize cursor active even outside of hit areas.
if (_currentDivider === i || (_currentDivider == CPNotFound && [self cursorAtPoint:point hitDividerAtIndex:i]))
{
var frame = [_subviews[i] frame],
size = frame.size[_sizeComponent],
startPosition = frame.origin[_originComponent] + size,
var frameA = [_subviews[i] frame],
sizeA = frameA.size[_sizeComponent],
startPosition = frameA.origin[_originComponent] + sizeA,
frameB = [_subviews[i + 1] frame],
sizeB = frameB.size[_sizeComponent],
canShrink = [self _realPositionForPosition:startPosition - 1 ofDividerAtIndex:i] < startPosition,
canGrow = [self _realPositionForPosition:startPosition + 1 ofDividerAtIndex:i] > startPosition,
cursor = [CPCursor arrowCursor];
if (size === 0)
if (sizeA === 0)
canGrow = YES; // Subview is collapsed.
else if (!canShrink &&
[_delegate respondsToSelector:@selector(splitView:canCollapseSubview:)] &&
[_delegate splitView:self canCollapseSubview:_subviews[i]])
canShrink = YES; // Subview is collapsible.
if (sizeB === 0)
{
// Right/lower subview is collapsed.
canGrow = NO;
// It's safe to assume it can always be uncollapsed.
canShrink = YES;
}
else if (!canGrow &&
[_delegate respondsToSelector:@selector(splitView:canCollapseSubview:)] &&
[_delegate splitView:self canCollapseSubview:_subviews[i + 1]])
canGrow = YES; // Right/lower subview is collapsible.
if (_isVertical && canShrink && canGrow)
cursor = [CPCursor resizeLeftRightCursor];
else if (_isVertical && canShrink)
@@ -597,7 +647,15 @@ var CPSplitViewHorizontalImage = nil,
{
// not sure where this should override other positions?
if ([_delegate respondsToSelector:@selector(splitView:constrainSplitPosition:ofSubviewAt:)])
position = [_delegate splitView:self constrainSplitPosition:position ofSubviewAt:dividerIndex];
{
var proposedPosition = [_delegate splitView:self constrainSplitPosition:position ofSubviewAt:dividerIndex];
// Silently ignore bad positions which could result from odd delegate responses. We don't want these
// bad results to go into the system and cause havoc with frame sizes as the split view tries to resize
// its subviews.
if (_IS_NUMERIC(proposedPosition))
position = proposedPosition;
}
var proposedMax = [self maxPossiblePositionOfDividerAtIndex:dividerIndex],
proposedMin = [self minPossiblePositionOfDividerAtIndex:dividerIndex],
@@ -605,18 +663,33 @@ var CPSplitViewHorizontalImage = nil,
actualMin = proposedMin;
if ([_delegate respondsToSelector:@selector(splitView:constrainMinCoordinate:ofSubviewAt:)])
actualMin = [_delegate splitView:self constrainMinCoordinate:proposedMin ofSubviewAt:dividerIndex];
{
var proposedActualMin = [_delegate splitView:self constrainMinCoordinate:proposedMin ofSubviewAt:dividerIndex];
if (_IS_NUMERIC(proposedActualMin))
actualMin = proposedActualMin;
}
if ([_delegate respondsToSelector:@selector(splitView:constrainMaxCoordinate:ofSubviewAt:)])
actualMax = [_delegate splitView:self constrainMaxCoordinate:proposedMax ofSubviewAt:dividerIndex];
{
var proposedActualMax = [_delegate splitView:self constrainMaxCoordinate:proposedMax ofSubviewAt:dividerIndex];
if (_IS_NUMERIC(proposedActualMax))
actualMax = proposedActualMax;
}
var viewA = _subviews[dividerIndex],
viewB = _subviews[dividerIndex + 1],
realPosition = MAX(MIN(position, actualMax), actualMin);
if (position < proposedMin + (actualMin - proposedMin) / 2)
// Is this position past the halfway point to collapse?
if (position < proposedMin + (actualMin - proposedMin) / 2)
if ([_delegate respondsToSelector:@selector(splitView:canCollapseSubview:)])
if ([_delegate splitView:self canCollapseSubview:viewA])
realPosition = proposedMin;
// We can also collapse to the right.
if (position > proposedMax - (proposedMax - actualMax) / 2)
if ([_delegate respondsToSelector:@selector(splitView:canCollapseSubview:)])
if ([_delegate splitView:self canCollapseSubview:viewB])
realPosition = proposedMax;
return realPosition;
}
@@ -628,6 +701,7 @@ var CPSplitViewHorizontalImage = nil,
*/
- (void)setPosition:(float)position ofDividerAtIndex:(int)dividerIndex
{
SPLIT_VIEW_SUPPRESS_RESIZE_NOTIFICATIONS(YES);
[self _adjustSubviewsWithCalculatedSize];
var realPosition = [self _realPositionForPosition:position ofDividerAtIndex:dividerIndex];
@@ -635,32 +709,59 @@ var CPSplitViewHorizontalImage = nil,
var viewA = _subviews[dividerIndex],
frameA = [viewA frame],
viewB = _subviews[dividerIndex + 1],
frameB = [viewB frame];
_preCollapsePosition = 0;
frameB = [viewB frame],
_preCollapsePosition = 0;
var preSize = frameA.size[_sizeComponent];
frameA.size[_sizeComponent] = realPosition - frameA.origin[_originComponent];
if (preSize !== 0 && frameA.size[_sizeComponent] === 0)
_preCollapsePosition = preSize;
[_subviews[dividerIndex] setFrame:frameA];
if (preSize !== frameA.size[_sizeComponent])
{
SPLIT_VIEW_MAYBE_POST_WILL_RESIZE();
[_subviews[dividerIndex] setFrame:frameA];
SPLIT_VIEW_MAYBE_POST_DID_RESIZE();
}
preSize = frameB.size[_sizeComponent];
var preOrigin = frameB.origin[_originComponent];
frameB.size[_sizeComponent] = frameB.origin[_originComponent] + frameB.size[_sizeComponent] - realPosition - [self dividerThickness];
if (preSize !== 0 && frameB.size[_sizeComponent] === 0)
_preCollapsePosition = preSize;
_preCollapsePosition = frameB.origin[_originComponent];
frameB.origin[_originComponent] = realPosition + [self dividerThickness];
[_subviews[dividerIndex + 1] setFrame:frameB];
if (preSize !== frameB.size[_sizeComponent] || preOrigin !== frameB.origin[_originComponent])
{
SPLIT_VIEW_MAYBE_POST_WILL_RESIZE();
[_subviews[dividerIndex + 1] setFrame:frameB];
SPLIT_VIEW_MAYBE_POST_DID_RESIZE();
}
if (_preCollapsePosition)
[_preCollapsePositions setObject:_preCollapsePosition forKey:"" + dividerIndex];
[self setNeedsDisplay:YES];
if (SPLIT_VIEW_DID_SUPPRESS_RESIZE_NOTIFICATION())
[self _postNotificationDidResize];
SPLIT_VIEW_SUPPRESS_RESIZE_NOTIFICATIONS(NO);
}
- (void)setFrameSize:(CGSize)aSize
{
[self _adjustSubviewsWithCalculatedSize];
if (_needsRestoreFromAutosave)
_shouldAutosave = NO;
else
[self _adjustSubviewsWithCalculatedSize];
[super setFrameSize:aSize];
if (_needsRestoreFromAutosave)
{
_needsRestoreFromAutosave = NO;
[self _restoreFromAutosave];
_shouldAutosave = YES;
}
[self setNeedsDisplay:YES];
}
@@ -672,6 +773,7 @@ var CPSplitViewHorizontalImage = nil,
return;
}
SPLIT_VIEW_MAYBE_POST_WILL_RESIZE();
[self _postNotificationWillResize];
var index = 0,
@@ -730,9 +832,10 @@ var CPSplitViewHorizontalImage = nil,
bounds.origin[_originComponent] += viewFrame.size[_sizeComponent] + dividerThickness;
[view setFrame:viewFrame];
}
[self _postNotificationDidResize];
SPLIT_VIEW_MAYBE_POST_DID_RESIZE();
}
/*!
@@ -831,6 +934,7 @@ The sum of the views and the sum of the dividers should be equal to the size of
@param CPButtonBar - The supplied button bar.
@param unsigned int - The divider index the button bar will be assigned to.
*/
// FIXME Should be renamed to setButtonBar:ofDividerAtIndex:.
- (void)setButtonBar:(CPButtonBar)aButtonBar forDividerAtIndex:(unsigned)dividerIndex
{
if (!aButtonBar)
@@ -867,15 +971,121 @@ The sum of the views and the sum of the dividers should be equal to the size of
- (void)_postNotificationDidResize
{
[self _autosave];
[[CPNotificationCenter defaultCenter] postNotificationName:CPSplitViewDidResizeSubviewsNotification object:self];
}
/*!
Set the name under which the split view divider positions is automatically saved to CPUserDefaults.
@param autosaveName the name to save under or nil to not save
*/
- (void)setAutosaveName:(CPString)autosaveName
{
if (_autosaveName == autosaveName)
return;
_autosaveName = autosaveName;
}
/*!
Get the name under which the split view divider position is automatically saved to CPUserDefaults.
@return the name to save under or nil if no auto save is active
*/
- (CPString)autosaveName
{
return _autosaveName;
}
/*!
@ignore
*/
- (void)_autosave
{
if (!_shouldAutosave)
return;
var userDefaults = [CPUserDefaults standardUserDefaults],
autosaveName = [self _framesKeyForAutosaveName:[self autosaveName]],
autosavePrecollapseName = [self _precollapseKeyForAutosaveName:[self autosaveName]],
count = [_subviews count],
positions = [CPMutableArray new],
preCollapseArray = [CPMutableArray new];
for (var i = 0; i < count; i++)
{
var frame = [_subviews[i] frame];
[positions addObject:CPStringFromRect(frame)];
[preCollapseArray addObject:[_preCollapsePositions objectForKey:"" + i]];
}
[userDefaults setObject:positions forKey:autosaveName];
[userDefaults setObject:preCollapseArray forKey:autosavePrecollapseName];
}
/*!
@ignore
*/
- (void)_restoreFromAutosave
{
if (!_autosaveName)
return;
var autosaveName = [self _framesKeyForAutosaveName:[self autosaveName]],
autosavePrecollapseName = [self _precollapseKeyForAutosaveName:[self autosaveName]],
userDefaults = [CPUserDefaults standardUserDefaults],
frames = [userDefaults objectForKey:autosaveName],
preCollapseArray = [userDefaults objectForKey:autosavePrecollapseName];
if (frames)
{
var dividerThickness = [self dividerThickness],
position = 0;
_shouldAutosave = NO;
for (var i = 0, count = [frames count] - 1; i < count; i++)
{
var frame = CPRectFromString(frames[i]);
position += frame.size[_sizeComponent];
[self setPosition:position ofDividerAtIndex:i];
position += dividerThickness;
}
_shouldAutosave = YES;
}
if (preCollapseArray)
{
_preCollapsePositions = [CPMutableDictionary new];
for (var i = 0, count = [preCollapseArray count]; i < count; i++)
[_preCollapsePositions setObject:preCollapseArray[i] forKey:i + ""];
}
}
/*!
@ignore
*/
- (CPString)_framesKeyForAutosaveName:(CPString)theAutosaveName
{
return @"CPSplitView Subview Frames " + theAutosaveName;
}
/*!
@ignore
*/
- (CPString)_precollapseKeyForAutosaveName:(CPString)theAutosaveName
{
return @"CPSplitView Subview Precollapse Positions " + theAutosaveName;
}
@end
var CPSplitViewDelegateKey = "CPSplitViewDelegateKey",
CPSplitViewIsVerticalKey = "CPSplitViewIsVerticalKey",
CPSplitViewIsPaneSplitterKey = "CPSplitViewIsPaneSplitterKey",
CPSplitViewButtonBarsKey = "CPSplitViewButtonBarsKey";
CPSplitViewButtonBarsKey = "CPSplitViewButtonBarsKey",
CPSplitViewAutosaveNameKey = "CPSplitViewAutosaveNameKey";
@implementation CPSplitView (CPCoding)
@@ -889,7 +1099,11 @@ var CPSplitViewDelegateKey = "CPSplitViewDelegateKey",
if (self)
{
_suppressResizeNotificationsMask = 0;
_preCollapsePositions = [CPMutableDictionary new];
_currentDivider = CPNotFound;
_shouldAutosave = YES;
_DOMDividerElements = [];
@@ -899,6 +1113,13 @@ var CPSplitViewDelegateKey = "CPSplitViewDelegateKey",
_isPaneSplitter = [aCoder decodeBoolForKey:CPSplitViewIsPaneSplitterKey];
[self _setVertical:[aCoder decodeBoolForKey:CPSplitViewIsVerticalKey]];
[self setAutosaveName:[aCoder decodeObjectForKey:CPSplitViewAutosaveNameKey]];
// We have to wait until we know our frame size before restoring, or the frame resize later will throw
// away the restored size.
if (_autosaveName)
_needsRestoreFromAutosave = YES;
}
return self;
@@ -919,6 +1140,8 @@ var CPSplitViewDelegateKey = "CPSplitViewDelegateKey",
[aCoder encodeBool:_isVertical forKey:CPSplitViewIsVerticalKey];
[aCoder encodeBool:_isPaneSplitter forKey:CPSplitViewIsPaneSplitterKey];
[aCoder encodeObject:_autosaveName forKey:CPSplitViewAutosaveNameKey];
}
@end
+44 -25
View File
@@ -25,11 +25,11 @@
@import <AppKit/CPTextField.j>
var CPStepperButtonsSize = CPSizeMake(19, 13);
/*! CPStepper is an implementation of Cocoa NSStepper.
/*!
CPStepper is an implementation of Cocoa NSStepper.
This control display a two part button that can be used to increase or decrease a value with a given interval.
This control displays a two part button that can be used to increase or decrease a value with a given interval.
*/
@implementation CPStepper: CPControl
{
@@ -45,7 +45,8 @@ var CPStepperButtonsSize = CPSizeMake(19, 13);
#pragma mark -
#pragma mark Initialization
/*! Initializes a CPStepper with given values
/*!
Initializes a CPStepper with given values.
@param aValue the initial value of the CPStepper
@param minValue the minimal acceptable value of the stepper
@param maxValue the maximal acceptable value of the stepper
@@ -53,7 +54,7 @@ var CPStepperButtonsSize = CPSizeMake(19, 13);
*/
+ (CPStepper)stepperWithInitialValue:(float)aValue minValue:(float)aMinValue maxValue:(float)aMaxValue
{
var stepper = [[CPStepper alloc] initWithFrame:CPRectMake(0, 0, 19, 25)];
var stepper = [[CPStepper alloc] initWithFrame:_CGRectMake(0, 0, 19, 25)];
[stepper setDoubleValue:aValue];
[stepper setMinValue:aMinValue];
[stepper setMaxValue:aMaxValue];
@@ -61,10 +62,12 @@ var CPStepperButtonsSize = CPSizeMake(19, 13);
return stepper;
}
/*! Initializes a CPStepper with default values:
/*!
Initializes a CPStepper with default values:
- minValue = 0.0
- maxValue = 59.0
- value = 0.0
@return Initialized CPStepper
*/
+ (CPStepper)stepper
@@ -72,7 +75,8 @@ var CPStepperButtonsSize = CPSizeMake(19, 13);
return [CPStepper stepperWithInitialValue:0.0 minValue:0.0 maxValue:59.0];
}
/*! Initializes the CPStepper
/*!
Initializes a CPStepper.
@param aFrame the frame of the control
@return initialized CPStepper
*/
@@ -87,14 +91,14 @@ var CPStepperButtonsSize = CPSizeMake(19, 13);
[self setDoubleValue:0.0];
_buttonUp = [[CPButton alloc] initWithFrame:CPRectMake(aFrame.size.width - CPStepperButtonsSize.width, 0, CPStepperButtonsSize.width, CPStepperButtonsSize.height)];
_buttonUp = [[CPButton alloc] initWithFrame:_CGRectMakeZero()];
[_buttonUp setContinuous:YES];
[_buttonUp setTarget:self];
[_buttonUp setAction:@selector(_buttonDidClick:)];
[_buttonUp setAutoresizingMask:CPViewNotSizable];
[self addSubview:_buttonUp];
_buttonDown = [[CPButton alloc] initWithFrame:CPRectMake(aFrame.size.width - CPStepperButtonsSize.width, CPStepperButtonsSize.height, CPStepperButtonsSize.width, CPStepperButtonsSize.height - 1)];
_buttonDown = [[CPButton alloc] initWithFrame:_CGRectMakeZero()];
[_buttonDown setContinuous:YES];
[_buttonDown setTarget:self];
[_buttonDown setAction:@selector(_buttonDidClick:)];
@@ -110,7 +114,8 @@ var CPStepperButtonsSize = CPSizeMake(19, 13);
#pragma mark -
#pragma mark Superclass overrides
/*! set if the CPStepper is enabled or not
/*!
Set if the CPStepper is enabled or not.
@param shouldEnabled BOOL that define if stepper is enabled or not.
*/
- (void)setEnabled:(BOOL)shouldEnabled
@@ -121,19 +126,30 @@ var CPStepperButtonsSize = CPSizeMake(19, 13);
[_buttonDown setEnabled:shouldEnabled];
}
/*! set the frame of the CPStepper and check if width is not smaller than theme min-size
@param aFrame the frame
*/
- (void)setFrame:(CGRect)aFrame
{
if (aFrame.size.width >= CGRectGetWidth(aFrame))
[super setFrame:aFrame];
var upSize = [self valueForThemeAttribute:@"up-button-size"],
downSize = [self valueForThemeAttribute:@"down-button-size"],
minSize = _CGSizeMake(upSize.width, upSize.height + downSize.height),
frame = _CGRectMakeCopy(aFrame);
frame.size.width = Math.max(minSize.width, frame.size.width);
frame.size.height = Math.max(minSize.height, frame.size.height);
[super setFrame:frame];
}
/*! @ignore
*/
/*! @ignore */
- (void)layoutSubviews
{
var aFrame = [self frame],
upSize = [self valueForThemeAttribute:@"up-button-size"],
downSize = [self valueForThemeAttribute:@"down-button-size"],
upFrame = _CGRectMake(aFrame.size.width - upSize.width, 0, upSize.width, upSize.height),
downFrame = _CGRectMake(aFrame.size.width - downSize.width, upSize.height, downSize.width, downSize.height);
[_buttonUp setFrame:upFrame];
[_buttonDown setFrame:downFrame];
[_buttonUp setValue:[self valueForThemeAttribute:@"bezel-color-up-button" inState:CPThemeStateBordered] forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered];
[_buttonUp setValue:[self valueForThemeAttribute:@"bezel-color-up-button" inState:CPThemeStateBordered | CPThemeStateDisabled] forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered | CPThemeStateDisabled];
[_buttonUp setValue:[self valueForThemeAttribute:@"bezel-color-up-button" inState:CPThemeStateBordered | CPThemeStateHighlighted] forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered | CPThemeStateHighlighted];
@@ -142,7 +158,8 @@ var CPStepperButtonsSize = CPSizeMake(19, 13);
[_buttonDown setValue:[self valueForThemeAttribute:@"bezel-color-down-button" inState:CPThemeStateBordered | CPThemeStateHighlighted] forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered | CPThemeStateHighlighted];
}
/*! set if CPStepper should autorepeat
/*!
Set if CPStepper should autorepeat.
@param shouldAutoRepeat if YES, the first mouse down does one increment (decrement) and, after each delay of 0.5 seconds
*/
- (void)setAutorepeat:(BOOL)shouldAutoRepeat
@@ -151,7 +168,8 @@ var CPStepperButtonsSize = CPSizeMake(19, 13);
[_buttonDown setContinuous:shouldAutoRepeat];
}
/*! set the current value of the stepper
/*!
Set the current value of the stepper.
@param aValue a float containing the value
*/
- (void)setDoubleValue:(float)aValue
@@ -167,8 +185,7 @@ var CPStepperButtonsSize = CPSizeMake(19, 13);
#pragma mark -
#pragma mark Actions
/*! @ignore
*/
/*! @ignore */
- (IBAction)_buttonDidClick:(id)aSender
{
if (![self isEnabled])
@@ -183,7 +200,8 @@ var CPStepperButtonsSize = CPSizeMake(19, 13);
[self sendAction:_action to:_target];
}
/*! @perform a programatic click on up button
/*!
Perform a programatic click on up button.
@param aSender sender of the action
*/
- (IBAction)performClickUp:(id)aSender
@@ -191,7 +209,8 @@ var CPStepperButtonsSize = CPSizeMake(19, 13);
[_buttonUp performClick:aSender];
}
/*! @perform a programatic click on down button
/*!
Perform a programatic click on down button.
@param aSender sender of the action
*/
- (IBAction)performClickDown:(id)aSender
@@ -210,8 +229,8 @@ var CPStepperButtonsSize = CPSizeMake(19, 13);
+ (id)themeAttributes
{
return [CPDictionary dictionaryWithObjects:[[CPNull null], [CPNull null]]
forKeys:[@"bezel-color-up-button", @"bezel-color-down-button"]];
return [CPDictionary dictionaryWithObjects:[[CPNull null], [CPNull null], _CGSizeMakeZero(), _CGSizeMakeZero()]
forKeys:[@"bezel-color-up-button", @"bezel-color-down-button", @"up-button-size", @"down-button-size"]];
}
@end
+17 -2
View File
@@ -132,7 +132,7 @@ CPTableColumnUserResizingMask = 1 << 1;
{
var min = [self minWidth],
max = [self maxWidth],
newWidth = MIN(MAX(width, min), max);
newWidth = ROUND(MIN(MAX(width, min), max));
[self setWidth:newWidth];
@@ -594,7 +594,22 @@ CPTableColumnUserResizingMask = 1 << 1;
[super bind:aBinding toObject:anObject withKeyPath:aKeyPath options:options];
if (![aBinding isEqual:@"someListOfExceptedBindings(notAcceptedBindings)"])
[[self tableView] _establishBindingsIfUnbound:anObject];
{
// Bind the table to the array controller this column is bound to.
// Note that anObject might not be the array controller. E.g. the keypath could be something like
// somePathTo.anArrayController.arrangedObjects.aKey. Cocoa doesn't support this but it is consistent
// and it makes sense.
var acIndex = aKeyPath.lastIndexOf("arrangedObjects."),
arrayController = anObject;
if (acIndex > 1)
{
var firstPart = aKeyPath.substring(0, acIndex - 1);
arrayController = [anObject valueForKeyPath:firstPart];
}
[[self tableView] _establishBindingsIfUnbound:arrayController];
}
}
/*!
+11 -6
View File
@@ -509,6 +509,11 @@ NOT YET IMPLEMENTED
_objectValues = { };
_cachedRowHeights = [];
// Otherwise, if we have a row marked as group with a
// index greater than the new number or rows
// it keeps the the graphical group style.
[_groupRows removeAllIndexes];
// This updates the size too.
[self noteNumberOfRowsChanged];
@@ -1984,7 +1989,7 @@ NOT YET IMPLEMENTED
// so we should size the last resized to fit
// find the last visisble column
while (count-- && [_tableColumns[count] isHidden]) ;
while (count-- && [_tableColumns[count] isHidden]);
// find the max x, but subtract a single pixel since the spacing isn't applicable here.
var delta = superviewWidth - _CGRectGetMaxX([self rectOfColumn:count]) - ([self intercellSpacing].width || 1),
@@ -2770,7 +2775,7 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
*/
- (BOOL)canDragRowsWithIndexes:(CPIndexSet)rowIndexes atPoint:(CGPoint)mouseDownPoint
{
return YES;
return [rowIndexes count] > 0 && [self numberOfRows] > 0;
}
/*!
@@ -3544,16 +3549,16 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
}
var exposedRows = [self _unboundedRowsInRect:aRect],
firstRow = FLOOR(exposedRows.location / colorCount) * colorCount,
lastRow = CPMaxRange(exposedRows),
colorIndex = 0,
groupRowRects = [],
row = exposedRows.location;
groupRowRects = [];
//loop through each color so we only draw once for each color
while (colorIndex < colorCount)
{
CGContextBeginPath(context);
for (var row = colorIndex; row <= lastRow; row += colorCount)
for (var row = firstRow + colorIndex; row <= lastRow; row += colorCount)
{
// if it's not a group row draw it otherwise we draw it later
if (![_groupRows containsIndex:row])
@@ -4609,7 +4614,7 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
}
_wasSelectionBroken = true;
}
else if (_wasSelectionBroken && ((shouldGoUpward && i !== [selectedIndexes firstIndex]) || (!shouldGoUpward && i !== [selectedIndexes lastindex])))
else if (_wasSelectionBroken && ((shouldGoUpward && i !== [selectedIndexes firstIndex]) || (!shouldGoUpward && i !== [selectedIndexes lastIndex])))
{
shouldGoUpward ? i = [selectedIndexes firstIndex] - 1 : i = [selectedIndexes lastIndex];
_wasSelectionBroken = false;
+189 -73
View File
@@ -1,4 +1,3 @@
/*
* CPTextField.j
* AppKit
@@ -21,13 +20,15 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#import "../Foundation/Ref.h"
@import "CPControl.j"
@import "CPStringDrawing.j"
@import "CPCompatibility.j"
@import "_CPImageAndTextView.j"
CPTextFieldSquareBezel = 0; /*! A textfield bezel with a squared corners. */
CPTextFieldSquareBezel = 0; /*! A textfield bezel with squared corners. */
CPTextFieldRoundedBezel = 1; /*! A textfield bezel with rounded corners. */
CPTextFieldDidFocusNotification = @"CPTextFieldDidFocusNotification";
@@ -83,12 +84,11 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
CPColor _textFieldBackgroundColor;
id _placeholderString;
CPString _placeholderString;
CPString _stringValue;
id _delegate;
CPString _textDidChangeValue;
// NS-style Display Properties
CPTextFieldBezelStyle _bezelStyle;
BOOL _isBordered;
@@ -481,17 +481,17 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
[self setNeedsLayout];
_isEditing = NO;
_stringValue = [self stringValue];
#if PLATFORM(DOM)
var string = [self stringValue],
element = [self _inputElement],
var element = [self _inputElement],
font = [self currentValueForThemeAttribute:@"font"];
// generate the font metric
[font _getMetrics];
element.value = string;
element.value = _stringValue;
element.style.color = [[self currentValueForThemeAttribute:@"text-color"] cssString];
element.style.font = [font cssString];
element.style.zIndex = 1000;
@@ -548,8 +548,6 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
CPTextFieldInputOwner = self;
}, 0.0);
element.value = [self stringValue];
[[[self window] platformWindow] _propagateCurrentDOMEvent:YES];
CPTextFieldInputIsActive = YES;
@@ -572,17 +570,39 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
{
[self unsetThemeState:CPThemeStateEditing];
#if PLATFORM(DOM)
var element = [self _inputElement],
newValue = element.value,
error = @"";
if (newValue !== _stringValue)
{
[self _setStringValue:newValue];
}
// If there is a formatter, always give it a chance to reject the resignation,
// even if the value has not changed.
if ([self _valueIsValid:newValue] === NO)
{
[self setThemeState:CPThemeStateEditing];
element.focus();
return NO;
}
#endif
// Cache the formatted string
_stringValue = [self stringValue];
_willBecomeFirstResponderByClick = NO;
[self _updatePlaceholderState];
[self setNeedsLayout];
#if PLATFORM(DOM)
var element = [self _inputElement];
if ([self stringValue] !== element.value)
[self _setStringValue:element.value];
CPTextFieldInputResigning = YES;
if (CPTextFieldInputIsActive)
@@ -610,7 +630,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
#endif
//post CPControlTextDidEndEditingNotification
// post CPControlTextDidEndEditingNotification
if (_isEditing)
{
_isEditing = NO;
@@ -625,6 +645,28 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
return YES;
}
- (BOOL)_valueIsValid:(CPString)aValue
{
#if PLATFORM(DOM)
var error = @"";
if ([self _setStringValue:aValue isNewValue:NO errorDescription:AT_REF(error)] === NO)
{
var acceptInvalidValue = NO;
if ([_delegate respondsToSelector:@selector(control:didFailToFormatString:errorDescription:)])
acceptInvalidValue = [_delegate control:self didFailToFormatString:[self _inputElement] errorDescription:error];
if (acceptInvalidValue === NO)
return NO;
}
#endif
return YES;
}
/*!
Text fields require panels to become key window, so this returns \c YES.
*/
@@ -685,11 +727,14 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
- (void)keyUp:(CPEvent)anEvent
{
var oldValue = [self stringValue];
[self _setStringValue:[self _inputElement].value];
#if PLATFORM(DOM)
if (oldValue !== [self stringValue])
var newValue = [self _inputElement].value;
if (newValue !== _stringValue)
{
[self _setStringValue:newValue];
if (!_isEditing)
{
_isEditing = YES;
@@ -699,14 +744,13 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
[self textDidChange:[CPNotification notificationWithName:CPControlTextDidChangeNotification object:self userInfo:nil]];
}
#endif
[[[self window] platformWindow] _propagateCurrentDOMEvent:YES];
}
- (void)keyDown:(CPEvent)anEvent
{
if ([anEvent _couldBeKeyEquivalent] && [self performKeyEquivalent:anEvent])
return;
// CPTextField uses an HTML input element to take the input so we need to
// propagate the dom event so the element is updated. This has to be done
// before interpretKeyEvents: though so individual commands have a chance
@@ -735,45 +779,60 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
- (void)insertNewline:(id)sender
{
if (_isEditing)
var newValue = [self _inputElement].value;
if (newValue !== _stringValue)
{
_isEditing = NO;
[self textDidEndEditing:[CPNotification notificationWithName:CPControlTextDidEndEditingNotification object:self userInfo:nil]];
[self _setStringValue:newValue];
}
[self sendAction:[self action] to:[self target]];
[self selectText:nil];
if ([self _valueIsValid:_stringValue])
{
// If _isEditing == YES then the target action can also be called via
// resignFirstResponder, and it is possible that the target action
// itself will change this textfield's responder status, so start by
// setting the _isEditing flag to NO to prevent the target action being
// called twice (once below and once from resignFirstResponder).
if (_isEditing)
{
_isEditing = NO;
[self textDidEndEditing:[CPNotification notificationWithName:CPControlTextDidEndEditingNotification object:self userInfo:nil]];
}
// If there is no target action, or the sendAction call returns
// success.
if (![self action] || [self sendAction:[self action] to:[self target]])
{
[self selectAll:nil];
}
}
[[[self window] platformWindow] _propagateCurrentDOMEvent:NO];
}
- (void)insertNewlineIgnoringFieldEditor:(id)sender
{
var oldValue = [self stringValue];
[self _inputElement].value += CPNewlineCharacter;
[self _setStringValue:[self _inputElement].value];
if (oldValue !== [self stringValue])
{
if (!_isEditing)
{
_isEditing = YES;
[self textDidBeginEditing:[CPNotification notificationWithName:CPControlTextDidBeginEditingNotification object:self userInfo:nil]];
}
[self textDidChange:[CPNotification notificationWithName:CPControlTextDidChangeNotification object:self userInfo:nil]];
}
[self _insertCharacterIgnoringFieldEditor:CPNewlineCharacter];
}
- (void)insertTabIgnoringFieldEditor:(id)sender
{
var oldValue = [self stringValue];
[self _insertCharacterIgnoringFieldEditor:CPTabCharacter];
}
[self _inputElement].value += CPTabCharacter;
[self _setStringValue:[self _inputElement].value];
- (void)_insertCharacterIgnoringFieldEditor:(CPString)aCharacter
{
#if PLATFORM(DOM)
if (oldValue !== [self stringValue])
var oldValue = _stringValue,
range = [self selectedRange],
element = [self _inputElement];
element.value = [element.value stringByReplacingCharactersInRange:[self selectedRange] withString:aCharacter];
[self _setStringValue:element.value];
// NOTE: _stringValue is now the current input element value
if (oldValue !== _stringValue)
{
if (!_isEditing)
{
@@ -783,6 +842,8 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
[self textDidChange:[CPNotification notificationWithName:CPControlTextDidChangeNotification object:self userInfo:nil]];
}
#endif
}
- (void)textDidBlur:(CPNotification)note
@@ -813,15 +874,8 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
[super textDidChange:note];
}
- (void)sendAction:(SEL)anAction to:(id)anObject
{
[self _reverseSetBinding];
[CPApp sendAction:anAction to:anObject from:self];
}
/*!
Returns the string the text field.
Returns the string in the text field.
*/
- (id)objectValue
{
@@ -830,24 +884,84 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
/*
@ignore
Sets the internal string value without updating the value in the input element
Sets the internal string value without updating the value in the input element.
This should only be invoked when the underlying text element's value has changed.
*/
- (void)_setStringValue:(id)aValue
- (BOOL)_setStringValue:(CPString)aValue
{
[self willChangeValueForKey:@"objectValue"];
[super setObjectValue:String(aValue)];
[self _updatePlaceholderState];
[self didChangeValueForKey:@"objectValue"];
return [self _setStringValue:aValue isNewValue:YES errorDescription:nil];
}
/*
@ignore
Sets the internal string value without updating the value in the input element.
If there is a formatter and formatting fails, returns NO. Otherwise returns YES.
*/
- (BOOL)_setStringValue:(CPString)aValue isNewValue:(BOOL)isNewValue errorDescription:(CPStringRef)anError
{
_stringValue = aValue;
var objectValue = aValue,
formatter = [self formatter],
result = YES;
if (formatter)
{
var object = nil;
if ([formatter getObjectValue:AT_REF(object) forString:aValue errorDescription:anError])
objectValue = object;
else
{
objectValue = undefined; // Mark the value as invalid
result = NO;
}
isNewValue |= objectValue !== [super objectValue];
}
if (isNewValue)
{
[self willChangeValueForKey:@"objectValue"];
[super setObjectValue:objectValue];
[self _updatePlaceholderState];
[self didChangeValueForKey:@"objectValue"];
}
return result;
}
- (void)setObjectValue:(id)aValue
{
[super setObjectValue:aValue];
var formatter = [self formatter];
if (formatter)
{
// If there is a formatter, make sure the object value can be formatted successfully
var formattedString = [self hasThemeState:CPThemeStateEditing] ? [formatter editingStringForObjectValue:aValue] : [formatter stringForObjectValue:aValue];
if (formattedString === nil)
{
var value = nil;
// Formatting failed, get an "empty" object by formatting an empty string.
// If that fails, the value is undefined.
if ([formatter getObjectValue:AT_REF(value) forString:@"" errorDescription:nil] === NO)
value = undefined;
[super setObjectValue:value];
}
}
_stringValue = [self stringValue];
#if PLATFORM(DOM)
if (CPTextFieldInputOwner === self || [[self window] firstResponder] === self)
[self _inputElement].value = aValue;
[self _inputElement].value = _stringValue;
#endif
[self _updatePlaceholderState];
@@ -855,9 +969,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
- (void)_updatePlaceholderState
{
var string = [self stringValue];
if ((!string || string.length === 0) && ![self hasThemeState:CPThemeStateEditing])
if ((!_stringValue || _stringValue.length === 0) && ![self hasThemeState:CPThemeStateEditing])
[self setThemeState:CPTextFieldStatePlaceholder];
else
[self unsetThemeState:CPTextFieldStatePlaceholder];
@@ -910,7 +1022,6 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
However, since you don't know how tall it needs to be if you change the font, sizeToFit will still be
useful for making the textfield an appropriate height.
*/
- (void)sizeToFit
{
[self setFrameSize:[self _minimumFrameSize]];
@@ -923,7 +1034,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
minSize = [self currentValueForThemeAttribute:@"min-size"],
maxSize = [self currentValueForThemeAttribute:@"max-size"],
lineBreakMode = [self lineBreakMode],
text = ([self stringValue] || @" "),
text = (_stringValue || @" "),
textSize = _CGSizeMakeCopy(frameSize),
font = [self currentValueForThemeAttribute:@"font"];
@@ -994,8 +1105,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
return;
var pasteboard = [CPPasteboard generalPasteboard],
stringValue = [self stringValue],
stringForPasting = [stringValue substringWithRange:selectedRange];
stringForPasting = [_stringValue substringWithRange:selectedRange];
[pasteboard declareTypes:[CPStringPboardType] owner:nil];
[pasteboard setString:stringForPasting forType:CPStringPboardType];
@@ -1025,9 +1135,8 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
[self deleteBackward:sender];
var selectedRange = [self selectedRange],
stringValue = [self stringValue],
pasteString = [pasteboard stringForType:CPStringPboardType],
newValue = [stringValue stringByReplacingCharactersInRange:selectedRange withString:pasteString];
newValue = [_stringValue stringByReplacingCharactersInRange:selectedRange withString:pasteString];
[self setStringValue:newValue];
[self setSelectedRange:CPMakeRange(selectedRange.location + pasteString.length, 0)];
@@ -1041,6 +1150,8 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
if ([[self window] firstResponder] !== self)
return CPMakeRange(0, 0);
#if PLATFORM(DOM)
// we wrap this in try catch because firefox will throw an exception in certain instances
try
{
@@ -1067,6 +1178,8 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
// fall through to the return
}
#endif
return CPMakeRange(0, 0);
}
@@ -1075,6 +1188,8 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
if (![[self window] firstResponder] === self)
return;
#if PLATFORM(DOM)
var inputElement = [self _inputElement];
try
@@ -1103,6 +1218,8 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
catch (e)
{
}
#endif
}
- (void)selectAll:(id)sender
@@ -1120,8 +1237,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
selectedRange.location += 1;
selectedRange.length -= 1;
var stringValue = [self stringValue],
newValue = [stringValue stringByReplacingCharactersInRange:selectedRange withString:""];
var newValue = [_stringValue stringByReplacingCharactersInRange:selectedRange withString:""];
[self setStringValue:newValue];
[self setSelectedRange:CPMakeRange(selectedRange.location, 0)];
@@ -1274,7 +1390,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
string = [self placeholderString];
else
{
string = [self stringValue];
string = _stringValue;
if ([self isSecure])
string = secureStringForString(string);
+137 -56
View File
@@ -97,61 +97,66 @@ var CPThemeStateAutoCompleting = @"CPThemeStateAutoCompleting",
{
if (self = [super initWithFrame:frame])
{
_selectedRange = CPMakeRange(0, 0);
_tokenScrollView = [[CPScrollView alloc] initWithFrame:CGRectMakeZero()];
[_tokenScrollView setHasHorizontalScroller:NO];
[_tokenScrollView setHasVerticalScroller:NO];
[_tokenScrollView setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
var contentView = [[CPView alloc] initWithFrame:CGRectMakeZero()];
[contentView setAutoresizingMask:CPViewWidthSizable];
[_tokenScrollView setDocumentView:contentView];
[self addSubview:_tokenScrollView];
_tokenIndex = 0;
_cachedCompletions = [];
_completionDelay = [CPTokenField defaultCompletionDelay];
_tokenizingCharacterSet = [[self class] defaultTokenizingCharacterSet];
_autocompleteContainer = [[CPView alloc] initWithFrame:CPRectMake(0.0, 0.0, frame.size.width, 92.0)];
[_autocompleteContainer setBackgroundColor:[_CPMenuWindow backgroundColorForBackgroundStyle:_CPMenuWindowPopUpBackgroundStyle]];
_autocompleteScrollView = [[CPScrollView alloc] initWithFrame:CPRectMake(1.0, 1.0, frame.size.width - 2.0, 90.0)];
[_autocompleteScrollView setAutohidesScrollers:YES];
[_autocompleteScrollView setHasHorizontalScroller:NO];
[_autocompleteContainer addSubview:_autocompleteScrollView];
_autocompleteView = [[CPTableView alloc] initWithFrame:CPRectMakeZero()];
var tableColumn = [[CPTableColumn alloc] initWithIdentifier:CPTokenFieldTableColumnIdentifier];
[tableColumn setResizingMask:CPTableColumnAutoresizingMask];
[_autocompleteView addTableColumn:tableColumn];
[_autocompleteView setDataSource:self];
[_autocompleteView setDelegate:self];
[_autocompleteView setAllowsMultipleSelection:NO];
[_autocompleteView setHeaderView:nil];
[_autocompleteView setCornerView:nil];
[_autocompleteView setRowHeight:30.0];
[_autocompleteView setGridStyleMask:CPTableViewSolidHorizontalGridLineMask];
[_autocompleteView setBackgroundColor:[CPColor clearColor]];
[_autocompleteView setGridColor:[CPColor colorWithRed:242.0 / 255.0 green:243.0 / 255.0 blue:245.0 / 255.0 alpha:1.0]];
[_autocompleteScrollView setDocumentView:_autocompleteView];
[self setBezeled:YES];
[self _init];
[self setObjectValue:[]];
[self setNeedsLayout];
}
return self;
}
- (void)_init
{
_selectedRange = CPMakeRange(0, 0);
var frame = [self frame];
_tokenScrollView = [[CPScrollView alloc] initWithFrame:CGRectMakeZero()];
[_tokenScrollView setHasHorizontalScroller:NO];
[_tokenScrollView setHasVerticalScroller:NO];
[_tokenScrollView setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
var contentView = [[CPView alloc] initWithFrame:CGRectMakeZero()];
[contentView setAutoresizingMask:CPViewWidthSizable];
[_tokenScrollView setDocumentView:contentView];
[self addSubview:_tokenScrollView];
_cachedCompletions = [];
_autocompleteContainer = [[CPView alloc] initWithFrame:CPRectMake(0.0, 0.0, frame.size.width, 92.0)];
[_autocompleteContainer setBackgroundColor:[_CPMenuWindow backgroundColorForBackgroundStyle:_CPMenuWindowPopUpBackgroundStyle]];
_autocompleteScrollView = [[CPScrollView alloc] initWithFrame:CPRectMake(1.0, 1.0, frame.size.width - 2.0, 90.0)];
[_autocompleteScrollView setAutohidesScrollers:YES];
[_autocompleteScrollView setHasHorizontalScroller:NO];
[_autocompleteContainer addSubview:_autocompleteScrollView];
_autocompleteView = [[CPTableView alloc] initWithFrame:CPRectMakeZero()];
var tableColumn = [[CPTableColumn alloc] initWithIdentifier:CPTokenFieldTableColumnIdentifier];
[tableColumn setResizingMask:CPTableColumnAutoresizingMask];
[_autocompleteView addTableColumn:tableColumn];
[_autocompleteView setDataSource:self];
[_autocompleteView setDelegate:self];
[_autocompleteView setAllowsMultipleSelection:NO];
[_autocompleteView setHeaderView:nil];
[_autocompleteView setCornerView:nil];
[_autocompleteView setRowHeight:30.0];
[_autocompleteView setGridStyleMask:CPTableViewSolidHorizontalGridLineMask];
[_autocompleteView setBackgroundColor:[CPColor clearColor]];
[_autocompleteView setGridColor:[CPColor colorWithRed:242.0 / 255.0 green:243.0 / 255.0 blue:245.0 / 255.0 alpha:1.0]];
[_autocompleteScrollView setDocumentView:_autocompleteView];
}
// ===============
// = CONVENIENCE =
// ===============
@@ -159,7 +164,7 @@ var CPThemeStateAutoCompleting = @"CPThemeStateAutoCompleting",
{
var indexOfSelectedItem = 0;
_cachedCompletions = [self tokenField:self completionsForSubstring:[self _inputElement].value indexOfToken:_tokenIndex indexOfSelectedItem:indexOfSelectedItem];
_cachedCompletions = [self tokenField:self completionsForSubstring:[self _inputElement].value indexOfToken:0 indexOfSelectedItem:indexOfSelectedItem];
[_autocompleteView selectRowIndexes:[CPIndexSet indexSetWithIndex:indexOfSelectedItem] byExtendingSelection:NO];
[_autocompleteView reloadData];
@@ -167,19 +172,20 @@ var CPThemeStateAutoCompleting = @"CPThemeStateAutoCompleting",
- (void)_autocompleteWithDOMEvent:(JSObject)DOMEvent
{
if (!_cachedCompletions || ![self hasThemeState:CPThemeStateAutoCompleting])
if (![self _inputElement].value && (!_cachedCompletions || ![self hasThemeState:CPThemeStateAutoCompleting]))
return;
[self _hideCompletions];
var token = _cachedCompletions[[_autocompleteView selectedRow]],
var token = _cachedCompletions ? _cachedCompletions[[_autocompleteView selectedRow]] : nil,
shouldRemoveLastObject = token !== @"" && [self _inputElement].value !== @"";
if (!token)
token = [self _inputElement].value;
// Make sure the user typed an actual token to prevent the previous token from being emptied
// If the input area is empty, we want to fallback to the normal behavior, resigning first responder or select the next or previous key view
// If the input area is empty, we want to fall back to the normal behavior, resigning first
// responder or selecting the next or previous key view.
if (!token || token === @"")
{
if (DOMEvent && DOMEvent.keyCode === CPTabKeyCode)
@@ -194,7 +200,6 @@ var CPThemeStateAutoCompleting = @"CPThemeStateAutoCompleting",
return;
}
var objectValue = [self objectValue];
// Remove the uncompleted token and add the token string.
@@ -202,10 +207,25 @@ var CPThemeStateAutoCompleting = @"CPThemeStateAutoCompleting",
if (shouldRemoveLastObject)
[objectValue removeObjectAtIndex:_selectedRange.location];
[objectValue insertObject:token atIndex:_selectedRange.location];
// Give the delegate a chance to confirm, replace or add to the list of tokens being added.
var delegateApprovedObjects = [self tokenField:self shouldAddObjects:[CPArray arrayWithObject:token] atIndex:_selectedRange.location],
delegateApprovedObjectsCount = [delegateApprovedObjects count];
if (delegateApprovedObjects)
{
for (var i = 0; i < delegateApprovedObjectsCount; i++)
{
[objectValue insertObject:[delegateApprovedObjects objectAtIndex:i] atIndex:_selectedRange.location + i];
}
}
// Put the cursor after the last inserted token.
var location = _selectedRange.location;
[self setObjectValue:objectValue];
_selectedRange = CPMakeRange(location + 1, 0);
if (delegateApprovedObjectsCount)
location += delegateApprovedObjectsCount;
_selectedRange = CPMakeRange(location, 0);
[self _inputElement].value = @"";
[self setNeedsLayout];
@@ -250,8 +270,13 @@ var CPThemeStateAutoCompleting = @"CPThemeStateAutoCompleting",
var indexOfToken = [[self _tokens] indexOfObject:token],
objectValue = [self objectValue];
// If the token was selected, deselect it for selection preservation.
[self _deselectToken:token];
// If the selection was to the right of the deleted token, move it to the left. If the deleted token was
// selected, deselect it.
if (indexOfToken < _selectedRange.location)
_selectedRange.location--;
else
[self _deselectToken:token];
// Preserve selection.
var selection = CPCopyRange(_selectedRange);
[objectValue removeObjectAtIndex:indexOfToken];
@@ -291,6 +316,14 @@ var CPThemeStateAutoCompleting = @"CPThemeStateAutoCompleting",
[self _controlTextDidChange];
}
- (void)_updatePlaceholderState
{
if (([[self _tokens] count] === 0) && ![self hasThemeState:CPThemeStateEditing])
[self setThemeState:CPTextFieldStatePlaceholder];
else
[self unsetThemeState:CPTextFieldStatePlaceholder];
}
// =============
// = RESPONDER =
// =============
@@ -575,14 +608,16 @@ var CPThemeStateAutoCompleting = @"CPThemeStateAutoCompleting",
{
}
// ========
// = VIEW =
// ========
- (void)viewDidMoveToWindow
{
[[[self window] contentView] addSubview:_autocompleteContainer];
#if PLATFORM(DOM)
_autocompleteContainer._DOMElement.style.zIndex = 1000; // Anything else doesn't seem to work
#endif
}
- (void)removeFromSuperview
@@ -1123,7 +1158,7 @@ var CPThemeStateAutoCompleting = @"CPThemeStateAutoCompleting",
{
if ([[self delegate] respondsToSelector:@selector(tokenField:completionsForSubstring:indexOfToken:indexOfSelectedItem:)])
{
return [[self delegate] tokenField:tokenField completionsForSubstring:substring indexOfToken:_tokenIndex indexOfSelectedItem:selectedIndex];
return [[self delegate] tokenField:tokenField completionsForSubstring:substring indexOfToken:tokenIndex indexOfSelectedItem:selectedIndex];
}
return [];
@@ -1149,7 +1184,19 @@ var CPThemeStateAutoCompleting = @"CPThemeStateAutoCompleting",
// // return an array of represented objects you want to add.
// // If you want to reject the add, return an empty array.
// // returning nil will cause an error.
// - (NSArray *)tokenField:(NSTokenField *)tokenField shouldAddObjects:(NSArray *)tokens atIndex:(NSUInteger)index;
- (CPArray)tokenField:(CPTokenField)tokenField shouldAddObjects:(CPArray)tokens atIndex:(int)index
{
var delegate = [self delegate];
if ([delegate respondsToSelector:@selector(tokenField:shouldAddObjects:atIndex:)])
{
var approvedObjects = [delegate tokenField:tokenField shouldAddObjects:tokens atIndex:index];
if (approvedObjects !== nil)
return approvedObjects;
}
return tokens;
}
//
// // If you return nil or don't implement these delegate methods, we will assume
// // editing string = display string = represented object
@@ -1292,3 +1339,37 @@ var CPThemeStateAutoCompleting = @"CPThemeStateAutoCompleting",
}
@end
var CPTokenFieldTokenizingCharacterSetKey = "CPTokenFieldTokenizingCharacterSetKey",
CPTokenFieldCompletionDelayKey = "CPTokenFieldCompletionDelay";
@implementation CPTokenField (CPCoding)
- (id)initWithCoder:(CPCoder)aCoder
{
self = [super initWithCoder:aCoder];
if (self)
{
_tokenizingCharacterSet = [aCoder decodeObjectForKey:CPTokenFieldTokenizingCharacterSetKey] || [[self class] defaultTokenizingCharacterSet];
_completionDelay = [aCoder decodeDoubleForKey:CPTokenFieldCompletionDelayKey] || [[self class] defaultCompletionDelay];
[self _init];
[self setNeedsLayout];
[self setNeedsDisplay:YES];
}
return self;
}
- (void)encodeWithCoder:(CPCoder)aCoder
{
[super encodeWithCoder:aCoder];
[aCoder encodeInt:_tokenizingCharacterSet forKey:CPTokenFieldTokenizingCharacterSetKey];
[aCoder encodeDouble:_completionDelay forKey:CPTokenFieldCompletionDelayKey];
}
@end
+1 -1
View File
@@ -1015,7 +1015,7 @@ var TOP_MARGIN = 5.0,
_labelSize = [_labelField frame].size;
_minSize = CGSizeMake(MAX(_labelSize.width, minSize.width), _labelSize.height + minSize.height + LABEL_MARGIN + TOP_MARGIN);
_maxSize = CGSizeMake(MIN(_labelSize.width, maxSize.width), 100000000.0);
_maxSize = CGSizeMake(MAX(_labelSize.width, maxSize.width), 100000000.0);
[_toolbar tile];
}
+8 -7
View File
@@ -111,7 +111,8 @@ CPViewAnimationFadeOutEffect = @"CPViewAnimationFadeOutEffect";
view = [self _targetView:dictionary],
startFrame = [self _startFrame:dictionary],
endFrame = [self _endFrame:dictionary],
differenceFrame = _CGRectMakeZero();
differenceFrame = _CGRectMakeZero(),
value = [super currentValue];
differenceFrame.origin.x = endFrame.origin.x - startFrame.origin.x;
differenceFrame.origin.y = endFrame.origin.y - startFrame.origin.y;
@@ -119,19 +120,19 @@ CPViewAnimationFadeOutEffect = @"CPViewAnimationFadeOutEffect";
differenceFrame.size.height = endFrame.size.height - startFrame.size.height;
var intermediateFrame = _CGRectMakeZero();
intermediateFrame.origin.x = startFrame.origin.x + differenceFrame.origin.x * progress;
intermediateFrame.origin.y = startFrame.origin.y + differenceFrame.origin.y * progress;
intermediateFrame.size.width = startFrame.size.width + differenceFrame.size.width * progress;
intermediateFrame.size.height = startFrame.size.height + differenceFrame.size.height * progress;
intermediateFrame.origin.x = startFrame.origin.x + differenceFrame.origin.x * value;
intermediateFrame.origin.y = startFrame.origin.y + differenceFrame.origin.y * value;
intermediateFrame.size.width = startFrame.size.width + differenceFrame.size.width * value;
intermediateFrame.size.height = startFrame.size.height + differenceFrame.size.height * value;
[view setFrame:intermediateFrame];
// Update the view's alpha value
var effect = [self _effect:dictionary];
if (effect === CPViewAnimationFadeInEffect)
[view setAlphaValue:1.0 * progress];
[view setAlphaValue:1.0 * value];
else if (effect === CPViewAnimationFadeOutEffect)
[view setAlphaValue:1.0 + ( 0.0 - 1.0 ) * progress];
[view setAlphaValue:1.0 + ( 0.0 - 1.0 ) * value];
if (progress === 1.0)
[self _targetView:view setHidden:_CGRectIsNull(endFrame) || [view alphaValue] === 0.0];
+83 -12
View File
@@ -271,6 +271,7 @@ var CPWindowActionMessageKeys = [
BOOL _isAnimating;
BOOL _hasShadow;
BOOL _isMovableByWindowBackground;
BOOL _isMovable;
unsigned _shadowStyle;
BOOL _showsResizeIndicator;
@@ -404,6 +405,7 @@ CPTexturedBackgroundWindowMask
_registeredDraggedTypesArray = [];
_isSheet = NO;
_acceptsMouseMovedEvents = YES;
_isMovable = YES;
// Set up our window number.
_windowNumber = [CPApp._windows count];
@@ -426,6 +428,7 @@ CPTexturedBackgroundWindowMask
// Create a generic content view.
[self setContentView:[[CPView alloc] initWithFrame:CGRectMakeZero()]];
[self setInitialFirstResponder:[self contentView]];
_firstResponder = self;
@@ -480,6 +483,7 @@ CPTexturedBackgroundWindowMask
[self close];
_platformWindow = aPlatformWindow;
[_platformWindow _setTitle:_title window:self];
if (wasVisible)
[self orderFront:self];
@@ -949,6 +953,12 @@ CPTexturedBackgroundWindowMask
var bounds = CGRectMake(0.0, 0.0, CGRectGetWidth(_frame), CGRectGetHeight(_frame));
// During init the initial first responder is set to the contentView
// if it hasn't changed in the mean time we need to update that reference
// to the new contentView
if ([self initialFirstResponder] === _contentView)
[self setInitialFirstResponder:aView];
_contentView = aView;
[_contentView setFrame:[self contentRectForFrameRect:bounds]];
@@ -1273,17 +1283,17 @@ CPTexturedBackgroundWindowMask
- (BOOL)acceptsFirstResponder
{
return YES;
return NO;
}
- (id)initialFirstResponder
- (CPView)initialFirstResponder
{
return _initialFirstResponder;
}
- (void)setInitialFirstResponder:(id)aResponder
- (void)setInitialFirstResponder:(CPView)aView
{
_initialFirstResponder = aResponder;
_initialFirstResponder = aView;
}
/*!
@@ -1359,6 +1369,7 @@ CPTexturedBackgroundWindowMask
_title = aTitle;
[_windowView setTitle:aTitle];
[_platformWindow _setTitle:_title window:self];
[self _synchronizeMenuBarTitleWithWindowTitle];
}
@@ -1429,6 +1440,23 @@ CPTexturedBackgroundWindowMask
return _isMovableByWindowBackground;
}
/*!
Sets whether the window can be moved.
@param shouldBeMovable \c YES makes the window movable.
*/
- (void)setMovable:(BOOL)shouldBeMovable
{
_isMovable = shouldBeMovable;
}
/*!
Returns \c YES if the window can be moved.
*/
- (void)isMovable
{
return _isMovable;
}
/*!
Sets the window location to be the center of the screen
*/
@@ -2485,30 +2513,70 @@ CPTexturedBackgroundWindowMask
- (void)selectNextKeyView:(id)sender
{
if (_keyViewLoopIsDirty && [self autorecalculatesKeyViewLoop])
[self recalculateKeyViewLoop];
var nextValidKeyView = nil;
if ([_firstResponder isKindOfClass:[CPView class]])
[self selectKeyViewFollowingView:_firstResponder];
nextValidKeyView = [_firstResponder nextValidKeyView];
if (!nextValidKeyView)
{
var initialFirstResponder = [self initialFirstResponder];
if ([initialFirstResponder acceptsFirstResponder])
nextValidKeyView = initialFirstResponder;
else
nextValidKeyView = [initialFirstResponder nextValidKeyView];
}
[self makeFirstResponder:nextValidKeyView];
}
- (void)selectPreviousKeyView:(id)sender
{
if (_keyViewLoopIsDirty && [self autorecalculatesKeyViewLoop])
[self recalculateKeyViewLoop];
var previousValidKeyView = nil;
if ([_firstResponder isKindOfClass:[CPView class]])
[self selectKeyViewPrecedingView:_firstResponder];
previousValidKeyView = [_firstResponder previousValidKeyView];
if (!previousValidKeyView)
{
var initialFirstResponder = [self initialFirstResponder];
if ([initialFirstResponder acceptsFirstResponder])
previousValidKeyView = initialFirstResponder;
else
previousValidKeyView = [initialFirstResponder previousValidKeyView];
}
[self makeFirstResponder:previousValidKeyView];
}
- (void)selectKeyViewFollowingView:(CPView)aView
{
if (_keyViewLoopIsDirty)
if (_keyViewLoopIsDirty && [self autorecalculatesKeyViewLoop])
[self recalculateKeyViewLoop];
[self makeFirstResponder:[aView nextValidKeyView]];
var nextValidKeyView = [aView nextValidKeyView];
if ([nextValidKeyView isKindOfClass:[CPView class]])
[self makeFirstResponder:nextValidKeyView];
}
- (void)selectKeyViewPrecedingView:(CPView)aView
{
if (_keyViewLoopIsDirty)
if (_keyViewLoopIsDirty && [self autorecalculatesKeyViewLoop])
[self recalculateKeyViewLoop];
[self makeFirstResponder:[aView previousValidKeyView]];
var previousValidKeyView = [aView previousValidKeyView];
if ([previousValidKeyView isKindOfClass:[CPView class]])
[self makeFirstResponder:previousValidKeyView];
}
/*!
@@ -2596,9 +2664,11 @@ CPTexturedBackgroundWindowMask
var allViews = function(aWindow)
{
var views = [[aWindow contentView] subviews],
index = 0;
var views = [CPArray arrayWithObject:[aWindow contentView]];
[views addObjectsFromArray:[[aWindow contentView] subviews]];
var index = 0;
for (; index < views.length; ++index)
views = views.concat([views[index] subviews]);
@@ -2928,5 +2998,6 @@ CPCustomWindowShadowStyle = 3;
@import "_CPHUDWindowView.j"
@import "_CPBorderlessWindowView.j"
@import "_CPBorderlessBridgeWindowView.j"
@import "_CPAttachedWindowView.j"
@import "CPDragServer.j"
@import "CPView.j"
+300
View File
@@ -0,0 +1,300 @@
/*
* _CPAttachedWindowView.j
* AppKit
*
* Created by Antoine Mercadal
* Copyright 2011 <primalmotion@archipelproject.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "_CPWindowView.j"
/*!
@ignore
A custom CPWindowView that manage border and cursor
*/
@implementation _CPAttachedWindowView : _CPWindowView
{
BOOL _mouseDownPressed @accessors(getter=isMouseDownPressed, setter=setMouseDownPressed:);
float _arrowOffsetX @accessors(property=arrowOffsetX);
float _arrowOffsetY @accessors(property=arrowOffsetY);
int _appearance @accessors(property=appearance);
unsigned _preferredEdge @accessors(property=preferredEdge);
CPSize _cursorSize;
}
/*!
Compute the contentView frame from a given window frame
@param aFrameRect the window frame
*/
- (CGRect)contentRectForFrameRect:(CGRect)aFrameRect
{
var contentRect = CGRectMakeCopy(aFrameRect);
// @todo change border art and remove this pixel perfect adaptation
// return CGRectInset(contentRect, 20, 20);
contentRect.origin.x += 18;
contentRect.origin.y += 17;
contentRect.size.width -= 35;
contentRect.size.height -= 37;
return contentRect;
}
/*!
Compute the window frame from a given contentView frame
@param aContentRect the contentView frame
*/
+ (CGRect)frameRectForContentRect:(CGRect)aContentRect
{
var frameRect = CGRectMakeCopy(aContentRect);
// @todo change border art and remove this pixel perfect adaptation
//return CGRectOffset(frameRect, 20, 20);
frameRect.origin.x -= 18;
frameRect.origin.y -= 17;
frameRect.size.width += 35;
frameRect.size.height += 37;
return frameRect;
}
/*!
Initialize the _CPWindowView
*/
- (id)initWithFrame:(CPRect)aFrame styleMask:(unsigned)aStyleMask
{
if (self = [super initWithFrame:aFrame styleMask:aStyleMask])
{
var bundle = [CPBundle bundleForClass:[self class]];
_arrowOffsetX = 0.0;
_arrowOffsetY = 0.0;
// @TODO: make this themable
_useGlowingEffect = YES;
_appearance = CPPopoverAppearanceMinimal;
_cursorSize = CPSizeMake(15, 10);
}
return self;
}
/*!
Hide the cursor
*/
- (void)hideCursor
{
_cursorSize = CPSizeMakeZero();
[self setNeedsDisplay:YES];
}
/*!
Show the cursor
*/
- (void)showCursor
{
_cursorSize = CPSizeMake(15, 10);
[self setNeedsDisplay:YES];
_mouseDownPressed = NO;
}
/*!
Draw the view
*/
- (void)drawRect:(CGRect)aRect
{
[super drawRect:aRect];
var context = [[CPGraphicsContext currentContext] graphicsPort],
radius = 5,
arrowWidth = _cursorSize.width,
arrowHeight = _cursorSize.height,
strokeWidth = 1,
strokeColor,
shadowColor = [[CPColor blackColor] colorWithAlphaComponent:.2],
shadowSize = CGSizeMake(0, 7),
shadowBlur = 15,
gradient;
if (_appearance == CPPopoverAppearanceMinimal)
{
gradient = CGGradientCreateWithColorComponents(CGColorSpaceCreateDeviceRGB(), [(254.0 / 255), (254.0 / 255), (254.0 / 255), 0.93,
(231.0 / 255), (231.0 / 255), (231.0 / 255), 0.93], [0,1], 2);
strokeColor = [CPColor colorWithHexString:@"B8B8B8"];
}
else
{
gradient = CGGradientCreateWithColorComponents(CGColorSpaceCreateDeviceRGB(), [(38.0 / 255), (38.0 / 255), (38.0 / 255), 0.93,
(18.0 / 255), (18.0 / 255), (18.0 / 255), 0.93], [0,1], 2);
strokeColor = [CPColor colorWithHexString:@"222222"];
}
// fix rect to take care of stroke and shadow
aRect.origin.x += strokeWidth + shadowBlur;
aRect.origin.y += strokeWidth + (shadowBlur + shadowSize.height / 2);
aRect.size.width -= (strokeWidth * 2) + (shadowBlur * 2);
aRect.size.height -= (strokeWidth * 2) + (shadowBlur * 2 + shadowSize.height);
CGContextSetStrokeColor(context, strokeColor);
CGContextSetLineWidth(context, strokeWidth);
CGContextBeginPath(context);
CGContextSetShadowWithColor(context, shadowSize, shadowBlur, shadowColor);
CGContextDrawLinearGradient(context, gradient, CGPointMake(CPRectGetMidX(aRect), 0.0), CGPointMake(CPRectGetMidX(aRect), aRect.size.height), 0);
var xMin = _CGRectGetMinX(aRect),
xMax = _CGRectGetMaxX(aRect),
yMin = _CGRectGetMinY(aRect),
yMax = _CGRectGetMaxY(aRect);
// draw!
switch (_preferredEdge)
{
case CPMinXEdge:
// origin ne
CGContextMoveToPoint(context, xMin + radius, yMin);
// ne
CGContextAddLineToPoint(context, xMax - radius, yMin);
CGContextAddCurveToPoint(context, xMax - radius, yMin, xMax, yMin, xMax, yMin + radius);
// arrow CPMinXEdge
CGContextAddLineToPoint(context, xMax, (aRect.size.height / 2) + aRect.origin.y + _arrowOffsetY - (arrowHeight - 2));
CGContextAddLineToPoint(context, aRect.size.width + arrowHeight + aRect.origin.x + _arrowOffsetX, (aRect.size.height / 2) + aRect.origin.y + _arrowOffsetY);
CGContextAddLineToPoint(context, aRect.size.width + aRect.origin.x + _arrowOffsetX, (aRect.size.height / 2 + (arrowWidth / 2)) + aRect.origin.y + _arrowOffsetY);
// se
CGContextAddLineToPoint(context, xMax, yMax - radius);
CGContextAddCurveToPoint(context, xMax, yMax - radius, xMax, yMax, xMax - radius, yMax);
// sw
CGContextAddLineToPoint(context, xMin + radius, yMax);
CGContextAddCurveToPoint(context, xMin + radius, yMax, xMin, yMax, xMin, yMax - radius);
// nw
CGContextAddLineToPoint(context, xMin, yMin + radius);
CGContextAddCurveToPoint(context, xMin, yMin + radius, xMin, yMin, xMin + radius, yMin);
break;
case CPMaxXEdge:
// origin ne
CGContextMoveToPoint(context, xMin + radius, yMin);
// ne
CGContextAddLineToPoint(context, xMax - radius, yMin);
CGContextAddCurveToPoint(context, xMax - radius, yMin, xMax, yMin, xMax, yMin + radius);
// se
CGContextAddLineToPoint(context, xMax, yMax - radius);
CGContextAddCurveToPoint(context, xMax, yMax - radius, xMax, yMax, xMax - radius, yMax);
// sw
CGContextAddLineToPoint(context, xMin + radius, yMax);
CGContextAddCurveToPoint(context, xMin + radius, yMax, xMin, yMax, xMin, yMax - radius);
// arrow CPMaxXEdge
CGContextAddLineToPoint(context, xMin, (aRect.size.height / 2 + (arrowWidth / 2) + aRect.origin.y + _arrowOffsetY));
CGContextAddLineToPoint(context, aRect.origin.x - arrowHeight + _arrowOffsetX, (aRect.size.height / 2) + aRect.origin.y + _arrowOffsetY);
CGContextAddLineToPoint(context, aRect.origin.x + _arrowOffsetX, (aRect.size.height / 2 - (arrowWidth / 2) + aRect.origin.y + _arrowOffsetY));
// nw
CGContextAddLineToPoint(context, xMin, yMin + radius);
CGContextAddCurveToPoint(context, xMin, yMin + radius, xMin, yMin, xMin + radius, yMin);
break;
case CPMaxYEdge:
// origin nw
CGContextMoveToPoint(context, xMin, yMin + yMin);
// nw
CGContextAddLineToPoint(context, xMin, yMin + radius);
CGContextAddCurveToPoint(context, xMin, yMin + radius, xMin, yMin, xMin + radius, yMin);
// arrow CPMaxYEdge
CGContextAddLineToPoint(context, (aRect.size.width / 2) + aRect.origin.x + _arrowOffsetX - (arrowWidth / 2), yMin);
CGContextAddLineToPoint(context, (aRect.size.width / 2) + aRect.origin.x + _arrowOffsetX, aRect.origin.y - arrowHeight + _arrowOffsetY);
CGContextAddLineToPoint(context, (aRect.size.width / 2) + (arrowWidth / 2) + aRect.origin.x + _arrowOffsetX, aRect.origin.y + _arrowOffsetY);
// ne
CGContextAddLineToPoint(context, xMax - radius, yMin);
CGContextAddCurveToPoint(context, xMax - radius, yMin, xMax, yMin, xMax, yMin + radius);
// se
CGContextAddLineToPoint(context, xMax, yMax - radius);
CGContextAddCurveToPoint(context, xMax, yMax - radius, xMax, yMax, xMax - radius, yMax);
// sw
CGContextAddLineToPoint(context, xMin + radius, yMax);
CGContextAddCurveToPoint(context, xMin + radius, yMax, xMin, yMax, xMin, yMax - radius);
break;
case CPMinYEdge:
// origin nw
CGContextMoveToPoint(context, xMin, yMin + yMin);
// nw
CGContextAddLineToPoint(context, xMin, yMin + radius);
CGContextAddCurveToPoint(context, xMin, yMin + radius, xMin, yMin, xMin + radius, yMin);
// ne
CGContextAddLineToPoint(context, xMax - radius, yMin);
CGContextAddCurveToPoint(context, xMax - radius, yMin, xMax, yMin, xMax, yMin + radius);
// se
CGContextAddLineToPoint(context, xMax, yMax - radius);
CGContextAddCurveToPoint(context, xMax, yMax - radius, xMax, yMax, xMax - radius, yMax);
// arrow CPMinYEdge
CGContextAddLineToPoint(context, (aRect.size.width / 2) + (arrowWidth / 2) + aRect.origin.x + _arrowOffsetX , yMax);
CGContextAddLineToPoint(context, (aRect.size.width / 2) + aRect.origin.x + _arrowOffsetX, aRect.size.height + aRect.origin.y + arrowHeight + _arrowOffsetY);
CGContextAddLineToPoint(context, (aRect.size.width / 2) - (arrowWidth / 2) + aRect.origin.x + _arrowOffsetX, aRect.size.height + aRect.origin.y + _arrowOffsetY);
// sw
CGContextAddLineToPoint(context, xMin + radius, yMax);
CGContextAddCurveToPoint(context, xMin + radius, yMax, xMin, yMax, xMin, yMax - radius);
break;
default:
// no computed edge means standard rounded rect
CGContextAddPath(context, CGPathWithRoundedRectangleInRect(aRect, radius, radius, YES, YES, YES, YES));
}
CGContextClosePath(context);
//Draw it
CGContextStrokePath(context);
CGContextFillPath(context);
}
- (void)mouseDown:(CPEvent)anEvent
{
_mouseDownPressed = YES;
[super mouseDown:anEvent];
}
- (void)mouseUp:(CPEvent)anEvent
{
_mouseDownPressed = NO;
[super mouseUp:anEvent];
}
@end
+4 -1
View File
@@ -111,7 +111,7 @@ var _CPWindowViewResizeIndicatorImage = nil;
return [self trackResizeWithEvent:anEvent];
}
if ([theWindow isMovableByWindowBackground])
if ([theWindow isMovable] && [theWindow isMovableByWindowBackground])
[self trackMoveWithEvent:anEvent];
else
@@ -174,6 +174,9 @@ var _CPWindowViewResizeIndicatorImage = nil;
- (void)trackMoveWithEvent:(CPEvent)anEvent
{
if (![[self window] isMovable])
return;
var type = [anEvent type];
if (type === CPLeftMouseUp)
+3 -3
View File
@@ -34,9 +34,9 @@
@import "_CPCibWindowTemplate.j"
CPCibOwner = @"CPCibOwner",
CPCibTopLevelObjects = @"CPCibTopLevelObjects",
CPCibReplacementClasses = @"CPCibReplacementClasses",
CPCibOwner = @"CPCibOwner";
CPCibTopLevelObjects = @"CPCibTopLevelObjects";
CPCibReplacementClasses = @"CPCibReplacementClasses";
CPCibExternalObjects = @"CPCibExternalObjects";
var CPCibObjectDataKey = @"CPCibObjectDataKey";
+4 -3
View File
@@ -108,7 +108,7 @@ function CGColorCreateCopy(aColor)
*/
function CGColorCreateGenericGray(gray, alpha)
{
return CGColorCreate(CGColorSpaceCreateDeviceRGB(), [gray,gray,gray, alpha]);
return CGColorCreate(CGColorSpaceCreateDeviceRGB(), [gray, gray, gray, alpha]);
}
/*!
@@ -137,7 +137,7 @@ function CGColorCreateGenericRGB(red, green, blue, alpha)
*/
function CGColorCreateGenericCMYK(cyan, magenta, yellow, black, alpha)
{
return CGColorCreate(CGColorSpaceCreateDeviceCMYK(),
return CGColorCreate(CGColorSpaceCreateDeviceCMYK(),
[cyan, magenta, yellow, black, alpha]);
}
@@ -150,7 +150,8 @@ function CGColorCreateGenericCMYK(cyan, magenta, yellow, black, alpha)
*/
function CGColorCreateCopyWithAlpha(aColor, anAlpha)
{
if ( !aColor ) return aColor; // Avoid error null pointer in next line
if (!aColor)
return aColor; // Avoid error null pointer in next line
var components = aColor.components.slice();
+9
View File
@@ -42,7 +42,16 @@
#include "DOM/CPPlatformString.j"
#else
@implementation CPPlatformString : CPBasePlatformString
+ (CGSize)sizeOfString:(CPString)aString withFont:(CPFont)aFont forWidth:(float)aWidth
{
return _CGSizeMakeZero();
}
+ (CPDictionary)metricsOfFont:(CPFont)aFont
{
return [CPDictionary dictionaryWithObjectsAndKeys:0, @"ascender", 0, @"descender", 0, @"lineHeight"];
}
@end
#endif
+17
View File
@@ -32,6 +32,7 @@ var PrimaryPlatformWindow = NULL;
CPInteger _level;
BOOL _hasShadow;
unsigned _shadowStyle;
CPString _title;
#if PLATFORM(DOM)
DOMWindow _DOMWindow;
@@ -258,6 +259,22 @@ var PrimaryPlatformWindow = NULL;
return [CPPlatform isBrowser];
}
- (void)_setTitle:(CPString)aTitle window:(CPWindow)aWindow
{
_title = aTitle;
#if PLATFORM(DOM)
if (_DOMWindow && _DOMWindow.document
&& (aWindow === [CPApp mainWindow] || [aWindow platformWindow] !== [CPPlatformWindow primaryPlatformWindow]))
_DOMWindow.document.title = _title;
#endif
}
- (CPString)title
{
return _title;
}
@end
#if PLATFORM(BROWSER)
+5 -2
View File
@@ -534,13 +534,15 @@ var ModifierKeyCodes = [
if (_DOMWindow)
return _DOMWindow.focus();
_DOMWindow = window.open("", "_blank", "menubar=no,location=no,resizable=yes,scrollbars=no,status=no,left=" + _CGRectGetMinX(_contentRect) + ",top=" + _CGRectGetMinY(_contentRect) + ",width=" + _CGRectGetWidth(_contentRect) + ",height=" + _CGRectGetHeight(_contentRect));
_DOMWindow = window.open("about:blank", "_blank", "menubar=no,location=no,resizable=yes,scrollbars=no,status=no,left=" + _CGRectGetMinX(_contentRect) + ",top=" + _CGRectGetMinY(_contentRect) + ",width=" + _CGRectGetWidth(_contentRect) + ",height=" + _CGRectGetHeight(_contentRect));
[PlatformWindows addObject:self];
// FIXME: cpSetFrame?
_DOMWindow.document.write("<!DOCTYPE html><html lang='en'><head></head><body style='background-color:transparent;'></body></html>");
_DOMWindow.document.close();
if (self != [CPPlatformWindow primaryPlatformWindow])
_DOMWindow.document.title = _title;
if (![CPPlatform isBrowser])
{
@@ -706,7 +708,8 @@ var ModifierKeyCodes = [
var characters;
// Handle key codes for which String.fromCharCode won't work.
if (aDOMEvent.which === 0 || aDOMEvent.charCode === 0)
// Refs #1036: In Internet Explorer, both 'which' and 'charCode' are undefined for special keys.
if (aDOMEvent.which === 0 || aDOMEvent.charCode === 0 || (aDOMEvent.which === undefined && aDOMEvent.charCode === undefined))
characters = KeyCodesToUnicodeMap[_keyCode];
if (!characters)
Binary file not shown.

Before

Width:  |  Height:  |  Size: 161 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 146 B

After

Width:  |  Height:  |  Size: 123 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 162 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 155 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 154 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 436 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 452 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 444 B

After

Width:  |  Height:  |  Size: 205 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 158 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 157 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 460 B

After

Width:  |  Height:  |  Size: 208 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 147 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 147 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 185 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 179 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 145 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 220 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 158 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 218 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 147 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 123 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 158 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 157 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 145 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 285 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 301 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 153 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 123 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 157 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 310 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 302 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 423 B

After

Width:  |  Height:  |  Size: 189 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 136 B

After

Width:  |  Height:  |  Size: 119 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 119 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 163 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 421 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 143 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 424 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 154 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 154 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 433 B

After

Width:  |  Height:  |  Size: 186 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 213 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 145 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 194 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 145 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 178 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 220 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 154 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 B

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