Compare commits

...
820 Commits
Author SHA1 Message Date
Francisco Ryan Tolmasky I 5be4fb7642 Updating version strings to 0.7.1.
Reviewed by me.
2009-06-13 11:42:23 -07:00
Francisco Ryan Tolmasky I f78c341a11 Fix for capitalization issue with circular slider images.
Reviewed by me.
2009-06-13 11:42:23 -07:00
Francisco Ryan Tolmasky I 4d907f2a88 Fix for window returning a direct reference to its frame instead of a copy.
Reviewed by me.
2009-06-13 11:42:23 -07:00
Francisco Ryan Tolmasky I c028092bcd Fix for dragged types not working on decoded views.
Reviewed by me.
2009-06-13 11:42:23 -07:00
Francisco Ryan Tolmasky I 82411047e1 Made CPImageView accept image drag and drop.
Reviewed by me.

Conflicts:

	AppKit/CPPasteboard.j
2009-06-13 11:42:23 -07:00
Francisco Ryan Tolmasky I 3b04b027f8 Fix for image views in toolbar items not displaying their images.
Reviewed by me.
2009-06-13 11:42:23 -07:00
Francisco Ryan Tolmasky I 2beebd4c1e Made class swapping more robust.
Reviewed by me.
2009-06-13 11:42:22 -07:00
Francisco Ryan Tolmasky I 3b9e73faba Added support for custom classes on non-customviews in nib2cib.
Reviewed by me.
2009-06-13 11:42:22 -07:00
Francisco Ryan Tolmasky I 38273e4dab Fix for -description in CPArray containing null or undefined values.
Reviewed by me.
2009-06-13 11:42:22 -07:00
Tom RobinsonandFrancisco Ryan Tolmasky I 787e0c8afd Update to use JSON.{parse,stringify} 2009-06-13 11:42:22 -07:00
Tom RobinsonandFrancisco Ryan Tolmasky I 774ea99319 Update JSON support to json2.js, added in Objective-J. Deprecate CPJSObjectCreateJSON and CPJSObjectCreateWithJSON. 2009-06-13 11:42:22 -07:00
Ross BoucherandFrancisco Ryan Tolmasky I 0ca573c7e6 Update the documentation of methods define with the BRIDGE macro 2009-06-13 11:42:21 -07:00
Ross BoucherandFrancisco Ryan Tolmasky I 751b89237f Fix for VML paths 2009-06-13 11:42:21 -07:00
Ross BoucherandFrancisco Ryan Tolmasky I 41eeb69485 Fix for KAPPA missing in CGPath. Looks like it was auto-merged out. 2009-06-13 11:42:21 -07:00
Francisco Ryan Tolmasky I 18a0e7f0d2 Fix for providing too many image slices breaking CPView.
Reviewed by me.
2009-05-31 13:45:58 -07:00
Nicholas SmallandFrancisco Ryan Tolmasky I ef9053f1ba Fix for undefined key handling.
Reviewed by me.
2009-05-31 01:35:51 -07:00
Francisco Ryan Tolmasky I 8a9b9d4821 Fix for nib2cib's separator menu items not showing up.
Reviewed by me.
2009-05-31 01:35:43 -07:00
Francisco Ryan Tolmasky I 6afaff6d2f Support for new CPEvent mechanism.
Reviewed by me.
2009-05-30 23:19:27 -07:00
Francisco Ryan Tolmasky I 95f594131b Coat tailed CPEvents on native DOM events if they exist, saving the creation of many objects.
Reviewed by me.
2009-05-30 23:17:59 -07:00
Tom RobinsonandFrancisco Ryan Tolmasky I de9ab95b55 Rename plutil back to cputil. Oops. 2009-05-30 13:34:14 -07:00
Tom RobinsonandFrancisco Ryan Tolmasky I ce0c3a9b6e Fixed incorrect variables in regexp-rhino-patch 2009-05-30 13:34:05 -07:00
Tom RobinsonandFrancisco Ryan Tolmasky I 380b0d0e5d Bring back the Rhino regex patch to use native Java regex. 2009-05-30 13:33:54 -07:00
Francisco Ryan Tolmasky I 90e7508700 Fix for Unicode chars being mangled when building.
Closes #146.

Reviewed by me.
2009-05-27 01:36:10 -07:00
Francisco Ryan Tolmasky I fc7b5a86ef Further work on theme showcase.
Reviewed by me.
2009-05-25 15:31:52 -07:00
tlrobinsonandFrancisco Ryan Tolmasky I 26ebd6bf64 When loading modules escape "+" in case they're converted to spaces later.
Updated to latest Narwhal and Jack
2009-05-25 15:31:35 -07:00
Francisco Ryan Tolmasky I 28b387554f Added Demos, Aristo, and WebSite to .gitignore so they can be checked out together and eventually built together.
Reviewed by me.
2009-05-24 16:11:15 -07:00
Francisco Ryan Tolmasky I c4c9528af6 Organized BlendKit classes into their own files and added licensing info.
Reviewed by me.
2009-05-24 15:01:22 -07:00
Francisco Ryan Tolmasky I a90e9c83f4 Fix for typos in CPButton.j.
Closes #139.

Reviewed by me.
2009-05-24 14:27:55 -07:00
Francisco Ryan Tolmasky I 25c145e490 Fix Info.plist name for Aristo blend.
Reviewed by me.
2009-05-24 12:49:25 -07:00
Francisco Ryan Tolmasky I 44dc4f6595 Fix for scroll wheel not working in Firefox 3 and up.
Closes #102.

Reviewed by me.
2009-05-24 12:45:51 -07:00
Francisco Ryan Tolmasky I 83bceaa867 Fix for HUD button misrendered in Aristo theme gallery until pressed for first time.
Closes #141.

Reviewed by me.
2009-05-23 13:04:29 -07:00
Francisco Ryan Tolmasky I f6a731ff91 Updated loading page and removed some unused resources from Aristo blend.
Reviewed by me.
2009-05-23 12:55:20 -07:00
Francisco Ryan Tolmasky I 354fddf6b2 Updated template theme project to use new theme gallery.
Reviewed by me.
2009-05-23 12:43:35 -07:00
Francisco Ryan Tolmasky I aebbdbe0a3 Fixed a few graphics bugs and made the automatically generated theme gallery nicer.
Reviewed by me.
2009-05-23 12:33:24 -07:00
Francisco Ryan Tolmasky I 15bff97388 Fix for MainMenu.cib not displaying images.
Closes #140.

Reviewed by me.
2009-05-22 03:23:08 -07:00
Francisco Ryan Tolmasky I ffab4bdf56 README/Download fix.
Reviewed by me.
2009-05-21 16:38:59 -07:00
Francisco Ryan Tolmasky I fff40499cc Fix for CPPopUpButton being broken in nib2cib.
Reviewed by me.
2009-05-21 14:11:21 -07:00
Francisco Ryan Tolmasky I 0b24bf8fe8 Automate NibApplication for Starter package.
Reviewed by me.
2009-05-20 12:34:14 -07:00
Ross Boucher 429dd80409 updated documentatino for CPTextField 2009-05-20 12:15:55 -07:00
Francisco Ryan Tolmasky I bee5d36fbf Merge branch 'master' of git@github.com:280north/cappuccino 2009-05-20 12:14:39 -07:00
Francisco Ryan Tolmasky I 8428edad37 Fix for menus not being clickable until you resize the browser window in NibApplication.
Reviewed by me.
2009-05-20 12:13:54 -07:00
Thomas BalthazarandRoss Boucher 2ba2bb8115 readme file updated (issue tracker + system requirements) 2009-05-20 09:38:55 -07:00
Tom Robinson b8be5d3bf5 Fix zipping to *not* follow symlinks. Breaks narwhal. 2009-05-20 02:05:28 -07:00
Tom Robinson b99ba2c25e Update Starter and Tools READMEs for 0.7 2009-05-20 02:04:35 -07:00
Francisco Ryan Tolmasky I 289a21156c Fix for Tools Rakefile: nib2cib should be built before capp.
Reviewd by me.
2009-05-19 23:53:29 -07:00
Tom Robinson 66ca70acd2 "Save for web" then pngcrush images to prevent color profile problems 2009-05-19 16:08:24 -07:00
Francisco Ryan Tolmasky I 578113d557 Updated version strings on products.
Reviewed by me.
2009-05-19 15:04:25 -07:00
Francisco Ryan Tolmasky I 79c9a2781f Fix for right scrollbar button not showing up completely.
Reviewed by me.
2009-05-19 13:18:00 -07:00
Francisco Ryan Tolmasky I fd7436527d Merge branch '0.7b' of git@github.com:280north/cappuccino into 0.7b 2009-05-19 13:04:29 -07:00
Francisco Ryan Tolmasky I 20f128b9c3 Added easy creation methods for textfields and labels and touched up sizeToFit in CPTextField.
Reviewed by me.
2009-05-19 13:03:41 -07:00
Ross Boucher e6a1370ae5 Update the default cib app to make the window full bridge 2009-05-19 12:48:05 -07:00
Francisco Ryan Tolmasky I 4758154014 Fix for mis-sized sizeToFit in CPButton.
Reviewed by me.
2009-05-19 12:22:15 -07:00
Ross Boucher a7ed62a108 Remove references to NSArray 2009-05-19 12:10:06 -07:00
Francisco Ryan Tolmasky I 8f8e2343a0 Merge branch '0.7b' of git@github.com:280north/cappuccino into 0.7b 2009-05-19 12:03:13 -07:00
Francisco Ryan Tolmasky I 6d8e1705b8 Cleaned up button's sizeToFit.
Reviewed by me.
2009-05-19 12:02:10 -07:00
Ross Boucher a84bc49540 pngcrushed image files 2009-05-19 11:41:59 -07:00
Ross Boucher fe56cbb77f update alerts to 0.7 2009-05-19 10:02:24 -07:00
tlrobinson ac9b6af56a Update browserjs to fix XHR not decoding responseText as UTF-8 2009-05-19 06:40:07 -07:00
tlrobinson 4ff99126d6 In objj module, ensure we read Objective-J as UTF-8 2009-05-19 06:36:41 -07:00
Francisco Ryan Tolmasky I 3e4763df68 Merge branch '0.7b' of git@github.com:280north/cappuccino into 0.7b 2009-05-19 05:37:49 -07:00
Francisco Ryan Tolmasky I f3fdcf327d Scroller fix.
Reviewed by me.
2009-05-19 05:37:03 -07:00
Tom Robinson e5dd36d807 Add --force to capp gen 2009-05-19 05:05:16 -07:00
Francisco Tolmasky ad03ab01e2 Temporary fix for gif/UTF 8 issue.
Reviewed by me.
2009-05-19 04:01:30 -07:00
Francisco Tolmasky be72a3ff47 Allow fully building capp apps with Rake, and added to template Rakefiles.
Reviewed by me.
2009-05-19 03:54:54 -07:00
Francisco Tolmasky d8b2946fb5 Updated themes so Rakefile will build your theme.
Reviewed by me.
2009-05-19 02:48:21 -07:00
Francisco Tolmasky aa3e049565 Merge branch '0.7b' of git@github.com:280north/cappuccino into 0.7b 2009-05-19 00:42:11 -07:00
Francisco Tolmasky bf49d7b766 Fix for intermittent failures with nib2cib and checkboxes.
Reviewed by me.
2009-05-19 00:41:13 -07:00
Ross Boucher b9cbf8274e Make url connection delegate methods optional 2009-05-19 00:35:51 -07:00
Francisco Tolmasky 07ec530442 Fix for repeating checkboxes/radio buttons.
Reviewed by me.
2009-05-19 00:12:36 -07:00
Francisco Tolmasky 12cbbcd485 Fixed some remaining __Product__ references in capp templates.
Reviewed by me.
2009-05-18 23:53:46 -07:00
Francisco Tolmasky d2be23e354 Aristo HUD resources.
Reviewed by me.
2009-05-18 22:58:14 -07:00
Francisco Tolmasky ea1783504d Added HUD to Aristo.
Reviewed by me.
2009-05-18 22:57:39 -07:00
Francisco Tolmasky 8391f593d9 Various unicode fixes.
Reviewed by me.
2009-05-18 21:24:46 -07:00
Francisco Tolmasky dc3ffdff08 Fix for cibed menus not opening.
Closes #94.

Reviewed by me.
2009-05-18 20:18:05 -07:00
Francisco Tolmasky ef6cf18aaa Merge branch '0.7b' of git@github.com:280north/cappuccino into 0.7b 2009-05-18 19:45:08 -07:00
Francisco Tolmasky a31c8891ba Fix for NibApplication template being broken.
Reviewed by me.
2009-05-18 19:44:32 -07:00
Francisco Tolmasky 36b65f3f30 Partial fix for NibApplication no longer containing a valid .cib.
Reviewed by me.
2009-05-18 19:13:08 -07:00
Ross Boucher dff2a5656f Merge branch '0.7b' of git@github.com:280north/cappuccino into 0.7b 2009-05-18 18:55:08 -07:00
Ross Boucher 5507855bee update to default template, doxygen config file 2009-05-18 18:54:30 -07:00
Francisco Tolmasky 7266821eae Some minor theme fixes.
Reviewed by me.
2009-05-18 16:44:07 -07:00
Francisco Tolmasky 27e79c2222 Fix for geming breaking install.
Reviewed by me.
2009-05-18 16:24:05 -07:00
Francisco Tolmasky d3f67947ef Merge branch '0.7b' of git@github.com:280north/cappuccino into 0.7b 2009-05-18 15:58:09 -07:00
Francisco Tolmasky a0cd03caa4 Added config option to capp and default Rakefiles for new projects.
Reviewed by me.
2009-05-18 15:57:39 -07:00
Ross Boucher 850125b8ab Add documentation groups 2009-05-18 15:43:36 -07:00
Ross Boucher 6b9b9b544b Add support for building docs and download files 2009-05-18 14:30:18 -07:00
Francisco Tolmasky 45e3f776cf Fix for quoted params in objj programs.
Reviewed by me.
2009-05-18 13:36:03 -07:00
Ross Boucher 1a00998357 Temporarily disable the gem subrake until it can be repaired 2009-05-18 11:14:13 -07:00
Ross Boucher ac02592c13 Merge branch '0.7b' of git@github.com:280north/cappuccino into 0.7b 2009-05-18 10:41:34 -07:00
Ross Boucher 52d3115ad6 update the doc config to exclude themes 2009-05-18 10:41:11 -07:00
tlrobinson 97492fcb29 Update narwal external to fix arguments grouping 2009-05-18 02:37:17 -07:00
Tom Robinson 1d39235a45 Added support for app: protocol in CPURLConnection, for use with Titanium 2009-05-18 01:07:05 -07:00
Francisco Tolmasky 15dc89fe2f Only build Objective-J gem when installing or creating the tools download.
Reviewed by me.
2009-05-18 00:11:33 -07:00
Ross Boucher e27e4309da Merge branch '0.7b' of git@github.com:280north/cappuccino into 0.7b 2009-05-18 00:09:11 -07:00
Francisco Tolmasky 7f733fdf34 Building Cappuccino apps with rake now automatically nib2cibs all .nibs and .xibs in the project.
Reviewed by me.
2009-05-18 00:02:18 -07:00
Ross Boucher e190ba82b4 Merge branch '0.7b' of git@github.com:280north/cappuccino into 0.7b 2009-05-17 22:31:31 -07:00
Tom Robinson f2f99833a6 Fix absolute path in instal-tools 2009-05-17 22:30:44 -07:00
Ross Boucher 5daf874f6c Merge branch '0.7b' of git@github.com:280north/cappuccino into 0.7b 2009-05-17 21:55:17 -07:00
Ross Boucher 8beb7848a2 Adjust highlight color for CPMenu 2009-05-17 21:54:39 -07:00
Tom Robinson c7313f519f Merge branch '0.7b' of git@github.com:280north/cappuccino into 0.7b 2009-05-17 21:27:00 -07:00
Tom Robinson 43a3e6d984 Add objective-j gem to Tools distro and instal scripts 2009-05-17 21:26:24 -07:00
Ross Boucher 0bafdfd43a Merge branch '0.7b' of git@github.com:280north/cappuccino into 0.7b 2009-05-17 20:59:39 -07:00
Ross Boucher 3fc7b7573d New loading page for Cappuccino templates 2009-05-17 20:58:04 -07:00
Francisco Tolmasky 8fc213a134 Forgot to check in NSMatrix.j
Reviewed by me.
2009-05-17 20:05:40 -07:00
Francisco Tolmasky eb96d48230 Merge branch '0.7b' of git@github.com:280north/cappuccino into 0.7b 2009-05-17 20:04:24 -07:00
Francisco Tolmasky 4ff6590e74 Added support for NSMatrix of radio buttons.
Reviewed by me.
2009-05-17 20:03:36 -07:00
Tom Robinson b8cac31e85 Updated to lastest External repos 2009-05-17 19:50:11 -07:00
Francisco Tolmasky c3d698bcac Merge branch '0.7b' of git@github.com:280north/cappuccino into 0.7b 2009-05-17 18:47:23 -07:00
Francisco Tolmasky 28da8ccacf Prelminary support for radio buttons and checkboxes in nib2cib.
Reviewed by me.
2009-05-17 18:46:28 -07:00
Ross Boucher 00b1d893e2 Merge branch '0.7b' of git@github.com:280north/cappuccino into 0.7b 2009-05-17 16:51:33 -07:00
Ross Boucher 4a1630b7ba Add IE7 compatibility meta tag to new project templates. For now. 2009-05-17 16:50:54 -07:00
Tom Robinson 7ea048f5bd Fix root submodules task and for older versions of git 2009-05-17 15:18:48 -07:00
Ross Boucher bd3895e6c1 make windows not white by default 2009-05-17 13:00:06 -07:00
Ross Boucher 71200ca5f3 Update to the ciruclar slider images 2009-05-16 22:34:33 -07:00
Tom Robinson 00456fe62c Fixed press. Added --platforms option. 2009-05-16 19:42:31 -07:00
Francisco Tolmasky 269b61d6c4 Merge branch '0.7b' of git@github.com:280north/cappuccino into 0.7b 2009-05-16 17:40:18 -07:00
Francisco Tolmasky b23d62190d Further cleanup of encoding/decoding for AppKit classes.
Reviewed by me.
2009-05-16 17:39:22 -07:00
Tom Robinson 113131a2b3 Merge branch '0.7b' of git@github.com:280north/cappuccino into 0.7b 2009-05-16 17:37:47 -07:00
Tom Robinson d4436acea3 Switch browser.js to browserjs. Fix External build problems 2009-05-16 17:37:09 -07:00
Ross Boucher fc581e3d3d Merge branch '0.7b' of git@github.com:280north/cappuccino into 0.7b 2009-05-16 16:51:24 -07:00
Ross Boucher 83cdbec1d3 Fix for broken cgcontext (stroke/fill ellipse) 2009-05-16 16:51:05 -07:00
Francisco Tolmasky 9f237c2d1a Automatically update submodules when building.
Reviewed by me.
2009-05-16 16:21:48 -07:00
Ross Boucher cfed10bbac Add bezier path to appkit.j, fix slight code bug 2009-05-16 16:18:26 -07:00
Francisco Tolmasky 67cfe69f38 Forgot to include these files in the last commit.
Reviewed by me.
2009-05-16 15:55:07 -07:00
Francisco Tolmasky 94f83a92b7 Added Radio and checkbox classes.
Remaining works:
- Fix artwork issue
- nib2cib support

Closes #77.

Reviewed by me.
2009-05-16 15:53:49 -07:00
Francisco Tolmasky 738d9186a6 Merge branch '0.7b-integration' into 0.7b 2009-05-16 15:33:23 -07:00
Francisco Tolmasky 1b494389a6 Fixed crash when selecting "About New Application..." in nib app. About panel still not implemented, but at least it no longer crashes.
Reviewed by me.
2009-05-15 22:33:39 -07:00
Francisco Tolmasky 4588d1db08 Further CPView/CPMenuItem cleanup.
Reviewed by me.
2009-05-15 22:16:15 -07:00
Francisco Tolmasky 8c1f6f3014 CPButton cleanup from residual pre-theme code.
Reviewed by me.
2009-05-15 21:40:11 -07:00
Seth BuntinandRoss Boucher abb49664f9 add prefix arg to 'rake install' 2009-05-15 14:55:58 -07:00
Ross Boucher c0fc298082 Update the new app template. 2009-05-15 12:30:17 -07:00
Ross Boucher 32af35492d Style fix. 2009-05-15 11:49:33 -07:00
Martin HäckerandRoss Boucher ad58952a32 Allows to leave of the suffix .cib from the filenames of cib files (just like cocoa does and states in the documentation). 2009-05-15 11:47:43 -07:00
Ross Boucher e05816419e Some documentation enhancements. 2009-05-14 22:48:42 -07:00
Ross Boucher 3b0feec801 Closes 113. 2009-05-14 22:16:06 -07:00
Ross Boucher 688fd5725d Missing scroller images. 2009-05-14 22:10:02 -07:00
Ross Boucher 9c7f07979b Add CPBezierPath, clean up some of CGPath and CGContext 2009-05-14 19:06:58 -07:00
Ross Boucher 22f7985d20 Fix for unicode characters being screwed up by shrinksafe 2009-05-14 16:39:36 -07:00
Ross Boucher 675b9df44c fix usage printout for nib2cib 2009-05-14 11:02:55 -07:00
tlrobinson af0b06ff28 Merge branch '0.7b' of git@github.com:280north/cappuccino into tlr0.7b 2009-05-13 18:40:20 -07:00
Ross Boucher a71a984a03 Accidentally committed logs to CPSegmentedContorl 2009-05-13 18:28:18 -07:00
Ross Boucher f4231dd890 Fix for closing an already not visible window causing app to break. 2009-05-13 18:19:41 -07:00
tlrobinson cfaf2d26a5 Update jack submodule 2009-05-13 17:58:47 -07:00
tlrobinson 43197b3099 Update capp to use CAPP_BUILD if present, falling back to STEAM_BUILD, erroring if neither. 2009-05-13 17:57:00 -07:00
tlrobinson 3c30a2fc3d Merge commit 'origin/0.7b' into tlr0.7b 2009-05-13 17:51:24 -07:00
Ross Boucher 4c31b25110 A couple minor segmented control changes. Still needs work. 2009-05-13 12:46:18 -07:00
Ross Boucher a5ef85c676 Mistake 2009-05-13 11:48:22 -07:00
Ross Boucher b747cd339a Closes 123. 2009-05-13 11:33:44 -07:00
Ross Boucher 8e7ce7c814 Merge branch '0.7b' of git@github.com:280north/cappuccino into 0.7b 2009-05-13 11:33:34 -07:00
Thomas BalthazarandRoss Boucher a4b75b0132 CPURLConnection calls didFailWithError instead of didReceiveResponse for successful HTTP responses other than 200 2009-05-12 16:12:07 -07:00
Ross Boucher 453845dd20 Merge branch '0.7b' of git@github.com:280north/cappuccino into 0.7-integration 2009-05-12 16:11:25 -07:00
tlrobinson 33ff286635 Fix "rake install" task 2009-05-11 18:06:49 -07:00
tlrobinson a45c3efa38 Add Jack submodule to External 2009-05-11 18:06:34 -07:00
tlrobinson 0925d41db6 Start migrating press to Narwhal 2009-05-11 16:22:53 -07:00
tlrobinson c63f92d1ea Force symlinks to prevent "File exists" errors 2009-05-11 16:22:28 -07:00
tlrobinson e249937457 Merge branch '0.7b' of git@github.com:280north/cappuccino into tlr0.7b 2009-05-11 16:14:45 -07:00
Francisco Tolmasky 645affad93 Fixed a few issues with nib2cib and hiding scrollers.
Reviewed by me.
2009-05-11 13:45:09 -07:00
Francisco Tolmasky 77c2ab3822 Fix for webview being broken (-window returnign domwindow isntead of cpwindow).
Reviewed by me.
2009-05-11 03:20:05 -07:00
tlrobinson 6aa4940e2b Merge branch '0.7b' of git@github.com:280north/cappuccino into tlr0.7b 2009-05-11 00:04:59 -07:00
Ross Boucher 78ec4046cc bug in nib2cib segmented controls 2009-05-10 21:20:14 -07:00
Ross Boucher 5604fa23a8 Merge branch '0.7b' of git@github.com:280north/cappuccino into 0.7b
Conflicts:
	AppKit/CPSegmentedControl.j
2009-05-10 21:13:23 -07:00
Ross Boucher 41f3146c47 Segmented controls with improved theming and nib2cibing 2009-05-10 21:06:22 -07:00
Francisco Tolmasky e395d6e0e0 Merge branch '0.7b-integration' into 0.7b 2009-05-10 18:46:29 -07:00
Francisco Tolmasky 99c29c5e61 Fix for subclasses not inherting themes, as well as finalizing theme API.
Closes #36.
Closes #109.

Reviewed by me.
2009-05-10 18:44:23 -07:00
Francisco Tolmasky 862af9cbae First stab at fixing Themeing API.
Reviewed by me.
2009-05-10 13:04:02 -07:00
tlrobinson 6c0a281ac2 Remove importClass for java.io.File 2009-05-10 03:56:13 -07:00
tlrobinson dcec480f08 Synced narwhal 2009-05-10 03:40:57 -07:00
tlrobinson 6e11a66cb0 Updated all Rakefiles and tools to work with Narwhal 2009-05-10 03:35:31 -07:00
tlrobinson b31abab595 Sync ojunit 2009-05-10 02:23:01 -07:00
tlrobinson ff23f320ac Add submodules for narwhal, ojtest and browser.js 2009-05-10 01:16:44 -07:00
Ross Boucher 2d55fb3443 Cache CPNumber and CPData class objects 2009-05-09 21:53:21 -07:00
Ross Boucher 9f3a1f1e7e Remove the need to call Function.apply for most objj_msgSends 2009-05-09 21:52:49 -07:00
Ross Boucher a8394baa1a Make debug mode name functions again 2009-05-09 21:52:30 -07:00
Ross Boucher 0533ddcc3e Some fixes for secure text fields in IE 2009-05-08 17:05:22 -07:00
Ross Boucher 2825560c1f keep key view loops established in interface builder 2009-05-08 14:37:31 -07:00
Ross Boucher 1497944eff Removing CPLog's from cibs. 2009-05-08 12:35:17 -07:00
Francisco Ryan Tolmasky I bda437985e Fix for Objective-J build breaking with the removal of resolve_flags.
Closes #117.

Reviewed by me.
2009-05-08 12:07:06 -07:00
Ross Boucher 4f024a0974 Merge branch '0.7b' of git@github.com:280north/cappuccino into 0.7b 2009-05-07 15:59:27 -07:00
Ross Boucher 3d2cf3f6b4 Add segmented controls to Aristo 2009-05-07 15:58:53 -07:00
Francisco Tolmasky 0cd33120cf Fix for Cappuccino no longer being compressed in release builds.
Closes #33.

Reviewed by me.
2009-05-07 00:47:28 -07:00
Francisco Tolmasky c5f4e0a268 Cleanup code for nib2cib.
Reviewed by me.
2009-05-06 23:57:21 -07:00
Ross Boucher aaafb59976 removing comment 2009-05-06 23:55:17 -07:00
Ross Boucher 06e3221c0f Massive hack for VML gradients in 280 Slides.
Conflicts:

	AppKit/CoreGraphics/CGContextVML.j
2009-05-06 23:53:37 -07:00
Francisco Tolmasky 120768c74b Merge branch '0.7b-integration' into 0.7b 2009-05-06 01:37:45 -07:00
Francisco Tolmasky 864c62b6e0 Fix for replacementObjectForKeyedArchiver: not working properly (incorrect decoding class).
Closes #111.

Reviewed by me.
2009-05-06 01:34:00 -07:00
nciagraandRoss Boucher 854d1c0afa CGContextDrawLinearGradient() now works in CGContextVML. 2009-05-05 23:50:06 -07:00
Ross Boucher ae8fd0c2d4 add size to fit for buttons. Closes #34. 2009-05-05 22:10:00 -07:00
Ross Boucher 81d23aafab Fix for broken image resources in Aristo Menus 2009-05-05 21:32:57 -07:00
Ross Boucher 7bc26d5e40 Merge branch '0.7b' of git@github.com:280north/cappuccino into 0.7b 2009-05-05 21:09:34 -07:00
Ross Boucher fedf0ef7ce Fix for highlight state on default menu bar 2009-05-05 21:07:26 -07:00
Francisco Tolmasky bfefe5e80f Merge branch '0.7b' into 0.7b-integration 2009-05-05 14:26:22 -07:00
Francisco Tolmasky f76b14dd83 Fix for rake sometimes not picking up on file changes.
Closes #108.

Reviewed by me.
2009-05-05 14:24:53 -07:00
Ross Boucher 06947ef9d3 Fix for controlTextDidChange not firing. Closes 35. 2009-05-05 13:51:35 -07:00
Ross Boucher 8dc8d6f367 Add an index-debug to the nibapp template 2009-05-05 13:30:50 -07:00
Ross Boucher 31ed6254db Fix for null values in CPJSObjectCreateWithJSON. Closes #19
.
2009-05-05 13:20:35 -07:00
Ross Boucher 88d8a409bb Enable text selection for CPTextField in Internet Explorer 2009-05-05 12:23:36 -07:00
Ross Boucher c976557346 Fixes text field regressions in Firefox and IE 2009-05-05 12:12:17 -07:00
Ross Boucher 6cd92e1278 Force windows to stay within the bounds of the browser window 2009-05-04 21:54:02 -07:00
Ross Boucher dd41c319ee Merge branch '0.7b' of git@github.com:280north/cappuccino into 0.7b 2009-05-04 18:08:16 -07:00
Ross Boucher 0501f12017 Add support for clear color. Closes #60. 2009-05-04 18:07:16 -07:00
Vladimir PouzanovandFrancisco Tolmasky 2176785370 Fix for adding initWithObjectsAndKeys: and dictionaryWithObjectsAndKeys: to CPDictionary.
Made a few minor changes for speed to Vladimir's commit.

Closes #38.

Reviewed by me.
2009-05-03 16:52:56 -07:00
Martin HäckerandFrancisco Tolmasky ad866e44f5 Fix for CPMutableDictionary not existing.
Closes #13.

Reviewed by me.
2009-05-03 16:18:19 -07:00
Thomas BalthazarandFrancisco Tolmasky b28146aa47 Fix for typo in CPTableView.
Reviewed by me.
2009-05-03 16:11:44 -07:00
Francisco Tolmasky 390cf2c16c Fix for MainMenu.cib needing to be loaded manually in cib apps.
Closes #9.

Reviewed by me.
2009-05-02 22:47:42 -07:00
Francisco Tolmasky 586a1e347d Fix for track no longer stretching in vertical sliders.
Closes #8.

Reviewed by me.
2009-05-01 02:00:50 -07:00
Francisco Ryan Tolmasky I 08b4bdada1 Fix for placeholder strings showing up as bullets in CPSecureTextField.
Closes #7.

Reviewed by me.
2009-04-30 16:32:57 -07:00
Francisco Ryan Tolmasky I 0f357c24a7 Fix for Cappuccino sometimes failing to build on Mac OS X.
Thanks to Josh Wilson for tracking this down!

Closes #6.

Reviewed by me.
2009-04-30 13:47:22 -07:00
Francisco Tolmasky f887aca66f Fix for menu bars created in Interface Builder not showing up with nib2cib.
Closes #5.

Reviewed by me.
2009-04-28 09:51:20 -07:00
tlrobinson ff6487caf3 import -> @import in Tests and NibApp 2009-04-27 20:32:59 -07:00
tlrobinson aa146613ac Added missing "var"s to various parts of Objective-J 2009-04-27 19:31:36 -07:00
tlrobinson dadabd899d Improved subrake missing WARNING 2009-04-26 16:34:25 -07:00
Francisco Tolmasky 2f790c6503 Fix for file evaluation showing up as "(anonymous)" in Safari profiler.
Closes #4.

Reviewed by me.
2009-04-23 04:38:59 -07:00
Ross Boucher 120dcdac54 A few changes to the xcode lang spec 2009-04-22 12:21:05 -07:00
Alex KarahaliosandRoss Boucher a95aae22ab Initial commit of Xcode editor integration 2009-04-22 12:05:56 -07:00
Ross Boucher 64010672eb Merge branch '0.7b' of git@github.com:280north/cappuccino into 0.7b 2009-04-22 12:05:10 -07:00
Ross Boucher f9640fb99e Make sliders work with nib2cib again 2009-04-22 12:04:47 -07:00
Francisco Tolmasky 1614855353 Forgot to add this in the last commit. 2009-04-22 11:47:37 -07:00
Francisco Tolmasky f9a1fb8d3f Fix for CPSecureTextField not being in nib2cib.
Closes #2.

Reviewed by me.
2009-04-22 11:20:26 -07:00
Ross Boucher 2e32688ad6 Add support for x-requested-with in CPURLConnection [#231 state:resolved milestone:0.7] 2009-04-19 13:54:01 -07:00
Thomas BalthazarandRoss Boucher b24011cd6c [#262 state:resolved] Typo in CAAnimation 2009-04-19 12:09:15 -07:00
Ross Boucher 1cf40a7d7a Temporary fix for #269 2009-04-17 12:23:31 -07:00
Ross Boucher 6d8d4b59cc Add an opacity slider to the color panel 2009-04-16 22:51:47 -07:00
Ross Boucher f4e329f5de CPSlider was going counter clockwise in circular mode 2009-04-16 20:02:34 -07:00
Francisco Tolmasky 0eb86fd4b6 Removed unecessary _sliderType ivar.
Reviewed by me.
2009-04-16 19:09:56 -07:00
Ross Boucher a284275ffe Update the color panel to use the new attribute name for track-color 2009-04-16 18:09:23 -07:00
Ross Boucher a8317177c6 Typo 2009-04-16 18:07:00 -07:00
Ross Boucher df7fab7e03 Add CPCircularSlider to CPSlider 2009-04-16 17:47:33 -07:00
Ross Boucher 7d0d01211b bug in color panel 2009-04-16 12:18:43 -07:00
Ross Boucher 8b9ae1c1b8 Fix CPTextField + nib2cib 2009-04-15 16:20:39 -07:00
Francisco Tolmasky 844919cfda Combined brightness bar and slider.
Reviewed by me.
2009-04-15 00:57:43 -07:00
Ross Boucher d01bc09b5b Add focus rings for CPTextFields 2009-04-15 00:32:34 -07:00
Ross Boucher e55de4bf8d Missing method in CPResponder 2009-04-14 22:21:45 -07:00
Ross Boucher b6b3e7f492 Make setting initial first responder in IB work 2009-04-14 22:20:22 -07:00
Ross Boucher 4ce0bbe1c0 run recalculateKeyViewLoop automatically when a window is created 2009-04-14 22:10:50 -07:00
Ross Boucher d2b5a7362e support for autorecalculateskeyviewloop 2009-04-14 20:42:44 -07:00
nciagraandRoss Boucher 66e3c90655 Fix for infinite loop in CPView -enclosingMenuItem. 2009-04-14 18:43:36 -07:00
Ross Boucher b508ccab08 Fix placeholder strings with new text field code 2009-04-14 17:04:52 -07:00
Ross Boucher a138e9bde4 Merge branch '0.7b' of git@github.com:280north/cappuccino into 0.7b 2009-04-14 16:19:48 -07:00
Ross Boucher 822a4310cd Add support for key views and tabbing 2009-04-14 16:11:51 -07:00
Francisco TolmaskyandRoss Boucher d0399eb902 Fixed a bug where placeholder state was not updated correctly.
Reviewed by me.
2009-04-14 16:11:51 -07:00
Tom Robinson 86b780aa2e Add Build to gitignore 2009-04-14 15:55:41 -07:00
Ross Boucher db6c70215a Next key view support, plus text field support 2009-04-14 15:40:12 -07:00
Francisco Tolmasky c55e1ac99c Fixed a bug where placeholder state was not updated correctly.
Reviewed by me.
2009-04-14 15:29:37 -07:00
Ross Boucher a60ce80141 Merge branch '0.7b' of git@github.com:280north/cappuccino into 0.7b 2009-04-14 01:32:58 -07:00
Ross Boucher acb1929b49 Add default button style 2009-04-14 01:32:14 -07:00
Francisco Tolmasky 1ab9170a9b Merge branch '0.7b' into 0.7b-integration 2009-04-14 00:26:05 -07:00
Francisco Tolmasky 0e8e725f59 Fix for all ObjJ methods showing up as anonymous functions in Safari profiler.
[#266 state:resolved]

Reviewed by me.
2009-04-14 00:21:16 -07:00
Ross Boucher 0c63a5aba4 Add defaultButton to CPWindow, set up default key bindings 2009-04-13 21:22:32 -07:00
Ross Boucher 831bbef9e1 First take of new CPSecureTextField. Known issues in IE. 2009-04-13 14:33:27 -07:00
Ross Boucher 6b7c610676 Fix a bug in CPColorPanel where the color would jump around on the wheel picker. 2009-04-09 18:01:31 -07:00
Ross Boucher 092a6b922e disabled this performance test for the moment, to fix the build. 2009-04-09 15:07:39 -07:00
Ross Boucher f2ced978c9 methodForSelector: should return the implementation, not the method object (per Cocoa docs). 2009-04-09 15:07:19 -07:00
Ross Boucher 213c70e00d Modify CPAttributedString test to treat undefined and null as equal. I believe it must work this way, worth verifying. 2009-04-09 15:00:00 -07:00
Ross Boucher dc014e9b1d Print the test output if the build fails 2009-04-09 13:18:04 -07:00
Ross Boucher 417f5c3f0f Add failing builds when tests fail 2009-04-09 13:11:41 -07:00
Ross Boucher 5365d1d1fd a few UI tweaks in the color panel 2009-04-07 01:12:02 -07:00
nciagraandRoss Boucher 9c0777991b Added CPMenuBarHighlightColor, CPMenuBarHighlightTextColor and CPMenuBarHighlightTextShadowColor to CPMenuBarAttributes. 2009-04-07 00:54:12 -07:00
nciagraandRoss Boucher c61ba5f050 Added setActivateColor: and setActivateShadowColor: to _CPMenuItemView. 2009-04-07 00:54:03 -07:00
nciagraandRoss Boucher e10445807c Fix for CPTabView not having its bezel drawn before being added as a subview. 2009-04-06 22:26:25 -07:00
nciagraandRoss Boucher 3bc50c1c3b Allow _CPWindowView to set its own toolbarItem labelShadowColor. 2009-04-06 21:19:46 -07:00
Ross Boucher 15b383886e Adding support for shadows in the title bar. 2009-04-05 16:00:42 -07:00
Ross Boucher 91d1ba6713 Additional fix for hasVerticalScroller. 2009-04-05 13:54:10 -07:00
Rich CollinsandRoss Boucher 4cb516d8b1 deref CPImage from dom image to prevent memory leak 2009-04-04 22:44:21 -07:00
nciagraandRoss Boucher ecee86cc6d Added allowsEmptySelection to CPCollectionView. 2009-04-04 22:43:08 -07:00
Thomas BalthazarandRoss Boucher 5500792ed3 [#243 state:resolved] : Error in CPTabView.indexOfTabViewItemWithIdentifier 2009-04-04 22:41:12 -07:00
Ross Boucher 51b0231f68 Cached +color returned colors so we create fewer objects in most apps. 2009-04-04 22:34:59 -07:00
Ross Boucher b55140d50a Add isEqual: to CPColor. 2009-04-04 22:34:42 -07:00
Ross Boucher 43af999d41 Add autoscroll: support to CPView, CPClipView, and the dragging server (which may not be generic enough) 2009-04-04 22:16:24 -07:00
Jesse RossandRoss Boucher 64b41ffb8e Added initial documentation for CPFlashMovie 2009-04-04 16:13:19 -07:00
Ross Boucher 0e8bf56284 Removing git submodules. 2009-04-04 16:10:54 -07:00
Ross Boucher f2c9719c23 Merge branch '0.7b' of git@github.com:280north/cappuccino into 0.7 2009-04-04 15:44:25 -07:00
Ross Boucher fb3ddb035c Typo in objj_dictionary exposes accidental global. 2009-04-04 15:43:52 -07:00
Francisco Tolmasky 390208d16a Fixed a bug where registerForDraggedTypes: replaced current drag types instead of appending to them.
Reviewed by me.
2009-03-27 17:32:53 -07:00
Ross Boucher 4963f8401a Merge branch '0.7b' of git@github.com:280north/cappuccino into 0.7 2009-03-27 17:02:21 -07:00
Francisco Tolmasky 9ce20d50ac Fix for drag and drop being broken.
Reviewed by me.
2009-03-27 15:29:53 -07:00
Ross Boucher 717781655f Support CPImageOverlaps mode for _CPImageAndTextView 2009-03-27 11:27:08 -07:00
Tom Robinson 4ffed5edf2 CPTableView binary search fixes 2009-03-26 17:35:52 -07:00
Francisco Tolmasky 21ab1b7e06 Textfields are a little better -- still more work required for Firefox/IE.
Reviewed by me.
2009-03-26 13:17:26 -07:00
tlrobinson e07c98b418 nib2cib NSColor colorspace 3 and 4 fix 2009-03-26 12:54:46 -07:00
Ross Boucher 20eaf1455d Change the color panel to use the standard window theme. 2009-03-26 02:14:47 -07:00
Ross Boucher 6e75a13a90 Print detailed usage on capp 2009-03-25 21:03:47 -07:00
tlrobinson d970bd5830 Update ojunit 2009-03-25 18:19:32 -07:00
tlrobinson 2652ece827 Submodules task and subrake check 2009-03-25 18:17:14 -07:00
tlrobinson 5b95ff5ff3 Added ojunit as a submodule 2009-03-25 17:02:29 -07:00
Ross Boucher 50ed22c63c [#247 state:resolved milestone:0.7] 2009-03-25 02:59:53 -07:00
Ross Boucher e0af565824 [#218 state:resolved milestone:0.7] 2009-03-25 02:56:53 -07:00
Ross Boucher b96285a56c Merge branch '0.7b' of git@github.com:280north/cappuccino into 0.7 2009-03-25 02:52:55 -07:00
Ross Boucher 49accf9fc8 Fix for CPAttributedString bug #245 [#245 state:resolved milestone:0.7] 2009-03-25 02:51:54 -07:00
Tom RobinsonandRoss Boucher 932aa87d87 Cleanup of shell scripts, change shebang to bash, etc 2009-03-25 02:51:54 -07:00
Tom Robinson c1c5c67b36 Merge branch '0.7b' of git@github.com:280north/cappuccino into 0.7b 2009-03-25 02:35:18 -07:00
Tom Robinson a5a622cf92 Cleanup of shell scripts, change shebang to bash, etc 2009-03-25 02:34:34 -07:00
stephenandRoss Boucher f04a199f4c Documentation for CPAttributedString 2009-03-25 01:37:43 -07:00
Ross Boucher 70da3e287d Replace removed __Product__. 2009-03-25 01:35:47 -07:00
Ross Boucher 57d0e12b1f Merge branch '0.7b' of git@github.com:280north/cappuccino into 0.7 2009-03-25 01:16:08 -07:00
Tom RobinsonandRoss Boucher e2eefe350d require rubygems in case it isn't automatically 2009-03-25 00:59:08 -07:00
Tom RobinsonandRoss Boucher e5b0094f7d Remove unecessary header.txt reference 2009-03-25 00:59:08 -07:00
Tom RobinsonandRoss Boucher 3fe872c125 Delete old blend and nib2cib directories 2009-03-25 00:59:08 -07:00
Tom Robinson 3739710fba require rubygems in case it isn't automatically 2009-03-25 00:57:23 -07:00
Ross Boucher 65593c5200 Update styles for noscript section of index.html 2009-03-25 00:57:10 -07:00
Tom Robinson 46cc218694 Remove unecessary header.txt reference 2009-03-25 00:56:45 -07:00
Tom Robinson c08ec3e52a Delete old blend and nib2cib directories 2009-03-25 00:56:01 -07:00
Nabil ElisaandRoss Boucher 9420c22298 changed Javascript to JavaScript in all natural-language references. 2009-03-25 00:11:06 -07:00
Nabil ElisaandRoss Boucher a05e116ceb see issue #114 2009-03-25 00:10:56 -07:00
Tom Robinson 99b04827d1 Fix for renamed header.txt in Objective-J 2009-03-24 21:28:15 -07:00
Francisco Tolmasky 40027c2266 Fix for case sensitive issues with Ubuntu.
Reviewed by me.
2009-03-24 14:52:59 -07:00
Francisco Ryan Tolmasky I 6db2aa5354 Fix for capp not respecting '-f' option.
Reviewed by me.
2009-03-22 20:41:03 -07:00
Francisco Ryan Tolmasky I 9d8a4f14e3 Merge branch '0.7b' of git@github.com:280north/cappuccino into tolmasky 2009-03-22 20:31:26 -07:00
Francisco Ryan Tolmasky I 6b1180caa4 Added principal_class support to Rake task. Fixed loading bundles with new platform-aware code.
Reviewed by me.
2009-03-22 20:30:31 -07:00
Francisco Tolmasky e5ea6b242d Fixed Aristo affecting unbordered pop up buttons.
Reviewed by me.
2009-03-22 12:40:06 -07:00
Francisco Tolmasky 0638de200b Use visibleFrame for full bridge windows, not contentBounds.
Reviewed by me.
2009-03-22 12:20:18 -07:00
nciagraand280 North, Inc. 8dc6500649 Fix for setting toolbar on bridge window losing its origin.
Signed-off-by: 280 North, Inc. <admin+280north@280north.com>
2009-03-23 02:47:25 +08:00
nciagraand280 North, Inc. bb2697a1d8 Fix to make CPMenuItem send itself as the sender with its action.
Signed-off-by: 280 North, Inc. <admin+280north@280north.com>
2009-03-23 02:47:24 +08:00
Francisco Ryan Tolmasky I 65d9df9c54 Removed stray Application folder in NibApplication template.
Reviewed by me.
2009-03-22 11:35:05 -07:00
Francisco Ryan Tolmasky I 14d91c6bec Added bundle type to BlendKit.
Reviewed by me.
2009-03-22 08:16:09 -07:00
Francisco Ryan Tolmasky I 3bd28b28ab Fixed nib2cib importing of external custom frameworks and added bundle types.
Reviewed by me.
2009-03-22 08:12:54 -07:00
Francisco Ryan Tolmasky I f1601d01ea Got rid of ant specific jars that we no longer needs.
Reviewed by me.
2009-03-21 18:46:05 -07:00
Francisco Ryan Tolmasky I c27cc7ddf1 Building should be significantly faster.
Reviewed by me.
2009-03-21 18:23:27 -07:00
Francisco Ryan Tolmasky I f58940d92d Fixed a bug in the build system where Aristo would sometimes not build on the first run.
Reviewed by me.
2009-03-21 17:03:16 -07:00
Francisco Tolmasky a1b680b722 Updated README to reflect new build instructions.
Reviewed by me.
2009-03-21 07:42:02 -07:00
Francisco Tolmasky 56364d187a Deleted some remaining build.xml files.
Reviewed by me.
2009-03-21 07:35:02 -07:00
Francisco Tolmasky 0023c5753a Got rid of remaining old ant stuff and added TODO's to current Rakefile.
Reviewed by me.
2009-03-21 07:31:47 -07:00
Francisco Tolmasky 436c466e2d Fixed typos Tools README and updated to reflect new tools.
[#240 state:resolved]

Reviewed by me.
2009-03-21 06:58:35 -07:00
Francisco Tolmasky ffe1f9c7a4 Fix for infinite loop in isHiddenOrHasHiddenAncestors.
[#235 state:resolved]

Reviewed by me.
2009-03-21 06:35:45 -07:00
Francisco Tolmasky 0b4701f96d Made error message a bit better.
Reviewed by me.
2009-03-20 16:58:07 -07:00
Francisco Tolmasky 93ea03972b Added NibApplication template.
Reviewed by me.
2009-03-20 06:19:11 -07:00
Francisco Tolmasky c9fcc22875 Added auto installing of plist gem.
Reviewed by me.
2009-03-20 01:07:44 -07:00
Francisco Tolmasky 32e302b1b6 Got rid of a lot of the old build.xml files.
Reviewed by me.
2009-03-19 21:58:09 -07:00
Francisco Tolmasky 844d8fbe08 Added install task.
Reviewed by me.
2009-03-19 21:45:30 -07:00
Francisco Tolmasky b60a99008e Added READMEs.
Reviewed by me.
2009-03-19 20:03:02 -07:00
Francisco Tolmasky 4c6959191d Added Editors to Tools download.
Reviewed by me.
2009-03-19 18:46:58 -07:00
Francisco Tolmasky 4a50eb2e05 No longer need the NewApplication Tools folder (we simply use capp to generate the app).
Reviewed by me.
2009-03-19 18:26:54 -07:00
Francisco Tolmasky 661fd3446d Added beginnings of downlaods task.
Reviewed by me.
2009-03-19 18:25:25 -07:00
Francisco Tolmasky 02a997e28c Added shorthands:
all
debug
release

clean-debug, cleandebug
clean-release, cleanrelease
clean-all, cleanall

clobber-debug, clobberdebug
clobber-release, clobberrelease
clobber-all, clobberall

Reviewed by me.
2009-03-19 07:17:54 -07:00
Francisco Tolmasky 221b4329c6 Added clean/clobber to current tasks.
Reviewed by me.
2009-03-19 06:54:48 -07:00
Francisco Tolmasky 6930357351 Added clean/clobber to Objective-J.
Reviewed by me.
2009-03-19 06:36:07 -07:00
Francisco Tolmasky 28ebace7c6 Began supporting non-framework bundles in gem. 2009-03-19 04:06:21 -07:00
Tom Robinson 486d0ae25a Reverting AppKit/Info.plist 2009-03-19 03:40:23 -07:00
Tom Robinson 41ba12b1d7 Update press for new build system. Also fixed bug that was supposedly fixed previously (hasOwnProperty) 2009-03-19 03:25:02 -07:00
Tom Robinson b525be4680 Merge branch 'master' of git@github.com:tolmasky/cappuccino into tolmasky 2009-03-19 00:51:57 -07:00
Francisco Tolmasky 87389c7ca6 Began moving over press to new build system.
Reviewed by me.
2009-03-19 00:38:22 -07:00
Francisco Tolmasky f372e7ae11 Beginning to move over bake.
Reviewed by me.
2009-03-19 00:30:14 -07:00
Francisco Tolmasky 018fe182d3 Fixed bug in setting clip view.
Reviewed by me.
2009-03-18 23:48:25 -07:00
Tom Robinson d0b437bc74 Merge branch 'master' of git@github.com:tolmasky/cappuccino into tolmasky 2009-03-18 23:39:04 -07:00
Francisco Tolmasky 50a5abe321 Added Aristo Theme Project.
Reviewed by me.
2009-03-18 23:30:58 -07:00
Francisco Tolmasky 9dcdf84824 Gemed up Objective-J rake stuff.
Reviewed by me.
2009-03-18 23:29:26 -07:00
Francisco Tolmasky 880e4dfb3a Merge branch 'master' into tolmasky
Conflicts:
	AppKit/CPControl.j
	AppKit/CPTextField.j
2009-03-18 17:41:17 -07:00
Francisco Tolmasky c6e266b08f Name changes.
Reviewed by me.
2009-03-18 16:53:00 -07:00
Francisco Tolmasky 3eed879fd2 More name changes.
Reviewed by me.
2009-03-18 16:51:01 -07:00
Francisco Tolmasky 07b6f54990 Name change.
Reviewed by me.
2009-03-18 16:48:44 -07:00
Francisco Tolmasky bd07c5338a Name changes
Reviewed by me.
2009-03-18 16:41:42 -07:00
Francisco Tolmasky 31279a0cdc Fix for copy bug and added capp changes.
Reviewed by me.
2009-03-18 16:37:06 -07:00
Francisco Tolmasky 487bf288e5 Moved all editing modes to one folder.
Reviewed by me.
2009-03-17 19:28:12 -07:00
Francisco Tolmasky ad93ad55cc Fixed some build bugs and moved capp to new build system.
Reviewed by me.
2009-03-17 19:19:08 -07:00
tlrobinson 9e7ca719d8 Merge branch 'master' of git@github.com:280north/cappuccino 2009-03-17 18:38:47 -07:00
tlrobinson b7b0ca40b0 Fixed CPString pathComponents and lastPathComponent to match Cocoa. Added tests. 2009-03-17 18:38:14 -07:00
Francisco Tolmasky 1dcc6db079 Moved BlendKit to new build system.
Reviewd by me.
2009-03-17 00:33:22 -07:00
Francisco Tolmasky 10422caa92 Moved nib2cib to new build system.
Reviewed by me.
2009-03-17 00:22:09 -07:00
Francisco Tolmasky 319127f88a Cleaned up build scripts.
Reviewed by me.
2009-03-16 23:39:16 -07:00
Francisco Tolmasky b4cf1ba041 Added altIncrementValue/setAltIncrementValue:.
Reviewed by me.
2009-03-16 18:07:20 -07:00
Francisco Tolmasky 0a32d13cb0 Support for blends.
Reviewed by me.
2009-03-16 17:00:02 -07:00
Francisco Tolmasky 6d34f53e43 Fix for platform stuff.
Reviewed by me.
2009-03-16 14:50:45 -07:00
Francisco Tolmasky b3cc75fe46 Added significantly improved platform support.
Reviewed by me.
2009-03-16 07:10:42 -07:00
Francisco Tolmasky 409fab31e6 Added beginnings of bundle app.
Reviewed by me.
2009-03-16 00:39:28 -07:00
Francisco Tolmasky df6ec644e9 Started moving blend over.
Reviewed by me.
2009-03-15 19:36:24 -07:00
Francisco Tolmasky 101cf4db2c Further Tools changes.
Reviewed by me.
2009-03-15 15:32:29 -07:00
Francisco Tolmasky 9c3c239162 Added rakefile to cplutil.
Reviewed by me.
2009-03-15 02:54:55 -07:00
Francisco Tolmasky b22d1837be Added cplutil to rake.
Reviewed by me.
2009-03-15 02:54:09 -07:00
Tom Robinson 7ed2efd584 Merge branch 'master' of git@github.com:tolmasky/cappuccino into tolmasky 2009-03-15 02:44:49 -07:00
Francisco Tolmasky eaa9003aea Added common file for rake use.
Reviewed by me.
2009-03-15 02:28:48 -07:00
Francisco Tolmasky 9c4d4ccb70 Started moving build system to rake.
Reviewed by me.
2009-03-15 02:25:23 -07:00
Ross Boucher 9f8ca93a57 Collection views should be selectable by default. 2009-03-13 15:51:54 -07:00
Tom Robinson 3aa97c7e0f Merge branch 'master' of git@github.com:tolmasky/cappuccino into tolmasky 2009-03-12 13:25:43 -07:00
Ross Boucher 38d72bc672 Respect _isSelectable on CPCollectionView 2009-03-10 23:18:43 -07:00
Francisco Ryan Tolmasky I 229d814866 Fix for using unbuilt blend.
Reviewed by me.
2009-03-10 16:06:24 -07:00
Francisco Ryan Tolmasky I 5cc1ef9609 Fix commented code.
Reviewed by me.
2009-03-10 15:26:13 -07:00
Francisco Ryan Tolmasky I 8913ef8929 Make Debug use Debug blend.
Reviewed by me.
2009-03-10 15:25:17 -07:00
Francisco Tolmasky 71ee5f6b4b Java to JS string.
Reviewed by me.
2009-03-10 14:59:59 -07:00
Francisco Tolmasky 07000fd86f Changes.
Reviewed by me.
2009-03-10 14:59:07 -07:00
Ross Boucher 19d26f148f Reverting the tooltip change, fixes bug in CPToolbar. 2009-03-10 11:50:31 -07:00
Francisco Tolmasky 47c20911c3 Updated build stuff.
Reviewed by me.
2009-03-09 16:01:34 -07:00
Francisco Tolmasky a07211253c Making CPThemedAttribute more robust.
Reviewed by me.
2009-03-09 15:07:29 -07:00
Thomas BalthazarandRoss Boucher 2f85a417d6 [#239 state:resolved] : typo in CPNotificationCenter 2009-03-09 11:27:14 -07:00
Francisco Tolmasky ee3b7deb07 Removed old art.
Reviewed by me.
2009-03-08 21:01:14 -07:00
Francisco Tolmasky 2664e30a8b A number of changes.
Reviewed by me.
2009-03-08 20:40:11 -07:00
Ross Boucher 3268081d1f CPDictionary should check for isa's before calling isEqual: in isEqualToDictionary: 2009-03-07 21:54:39 -08:00
Ross Boucher 88035429bb Fix in CPString setPlaceholderString
[#238 state:resolved]
2009-03-07 21:05:18 -08:00
Tom Robinson 25c7d98d2c Fix cplutil using "arguments" instead of "args" 2009-03-07 19:35:14 -08:00
Tom Robinson 4422530fe4 Fixed press bug (hasOwnProperty to lookup dependencies) and cleaned up output 2009-03-07 19:34:24 -08:00
Tom Robinson 17b3fc044d Might as well commit these, tolmasky branch is useless without Aristo anyway 2009-03-07 18:16:30 -08:00
Vladimir PouzanovandRoss Boucher bbe1b58437 Added more api docs to CPObject 2009-03-05 14:57:50 -08:00
cacaodevandRoss Boucher 546c95bdf6 Fixed typos in CPArray+KVO ; added suport for *objects:atIndexes: 2009-03-05 14:48:48 -08:00
cacaodevandRoss Boucher faac82287f Fixed bug in previous commit of setToolTip: 2009-03-05 14:46:25 -08:00
Ross Boucher 0fdfd8919f Remove the tabs. 2009-03-05 14:45:34 -08:00
M ESCOandRoss Boucher 55fa6024db Added tooltip support 2009-03-05 14:40:56 -08:00
cacaodevandRoss Boucher a1e3feda4f Fixed typo 2009-03-05 14:39:45 -08:00
Ross Boucher 46a975b966 Updated CPObject's instancesRespondToSelector to return BOOL 2009-03-05 14:30:38 -08:00
stephenandRoss Boucher 0508c54799 Defgroups must go at end of comment otherwise previous obj-j statements
become part of the group name.
2009-03-05 14:21:25 -08:00
stephenandRoss Boucher 89e776281f Added @mainpage for doxygen that simply includes the README and LiCENSE
docs. Also added groups for appkit and foundation classes.
2009-03-05 14:20:39 -08:00
tlrobinson 1188da3c21 Much improved but still unbearable CPTableView 2009-03-02 20:07:52 -08:00
Ross Boucher d81c944e45 minor fix to the objective-j mode. 2009-03-02 15:59:58 -08:00
Ross Boucher 6750b90671 Fixes for some new CPString tests. 2009-02-26 21:30:54 -08:00
Russell MullandRoss Boucher 723c9ae556 improved CPStringTest 2009-02-26 21:00:58 -08:00
Thomas BalthazarandRoss Boucher 1d38ca64c7 ticket 220 fixed http://cappuccino.lighthouseapp.com:80/projects/16499/tickets/220-typo-in-cppopupbutton-indexofitemwithrepresentedobject#ticket-220-1 2009-02-26 17:46:41 -08:00
Leif SingerandRoss Boucher 547ed38855 Modified CPColor's hexToRGB to also accept hex colors with only three characters, as is possible in CSS. E.g., 'ccc' will expand to 'cccccc', etc. 2009-02-26 17:24:34 -08:00
Ross Boucher 8da7b0ee91 Fix some spacing/style issues in CPDate. 2009-02-26 17:21:40 -08:00
Landon FullerandRoss Boucher 1da9e93241 Implement support for UNIX epoch initialization.
Add support for the +[CPDate dateWithTimeIntervalSince1970:]
and -[CPDate initWithTimeIntervalSince1970].
2009-02-26 17:13:37 -08:00
tlrobinson 3200f1c6ca Merge branch 'master' of git@github.com:tolmasky/cappuccino into tolmasky 2009-02-23 20:38:37 -08:00
Francisco Tolmasky a25ffe0899 Temporary fix for webview white background.
Reviewed by me.
2009-02-23 20:34:13 -08:00
Francisco Tolmasky 7b04023f54 bleh.
Reviewed by me.
2009-02-23 19:10:41 -08:00
Ross Boucherandtlrobinson 1c79db2303 Stop propagation for all events, not just single finger ones. 2009-02-22 17:18:15 -08:00
Ross Boucherandtlrobinson b1fc23af08 Make mouseUp work with the "touch" bridge. 2009-02-22 17:18:05 -08:00
Ross Boucherandtlrobinson 4280c3513a Remove the callout from iPhone on touch and hold. 2009-02-22 17:17:51 -08:00
Ross Boucherandtlrobinson 9eab840f37 Add mouse simulation using native touch events 2009-02-22 17:17:42 -08:00
Francisco Tolmasky ce31353a7a Updated menu images.
Reviewed by me.
2009-02-22 02:06:21 -08:00
Francisco Tolmasky f22684b5e8 I need to commit this?
Reviewed by me.
2009-02-22 02:04:47 -08:00
Francisco Tolmasky 12459aae1e Minor changes.
Reviewed by me.
2009-02-22 02:04:00 -08:00
Tom Robinson fd0a0de4b2 Table View "correctly" purge cells 2009-02-22 01:45:38 -08:00
Tom Robinson 0e3ead62fb CPWebView resize fixes (sorta) 2009-02-21 21:57:53 -08:00
Tom Robinson 8b36cddd9c Init _isFullBridge and cast too BOOL in setFullBridge: 2009-02-21 21:56:24 -08:00
Francisco Tolmasky 415e826a73 Major CPScroller nib2cib fixes.
Reviewed by me.
2009-02-21 18:15:37 -08:00
Francisco Tolmasky 6a0958f9c1 Some scroll view nib fixes.
Reviewed by me.
2009-02-21 17:17:29 -08:00
Francisco Tolmasky 2788af6922 Fix for setValue:forThemedAttributeName: not updating display like inControlState:.
Reviewed by me.
2009-02-21 04:31:13 -08:00
Tom Robinson 49e4e8e2fd Auto select scrollbar mode in CPWebView 2009-02-21 01:48:48 -08:00
Tom Robinson 63585dfea6 Merge branch 'master' of git@github.com:tolmasky/cappuccino into tolmasky 2009-02-21 01:34:36 -08:00
Francisco Tolmasky 27035770d7 Fix for adding awakeFromCib.
Reviewed by me.
2009-02-21 01:37:28 -08:00
Tom Robinson f2a70194c8 Merge branch 'master' of git@github.com:tolmasky/cappuccino into tolmasky 2009-02-21 01:23:57 -08:00
Tom Robinson 8bdd8258be CPWebView support for CPScrollView scrollbars 2009-02-21 01:23:08 -08:00
Francisco Tolmasky aa0135515c Forgot to add this file.
Reviewed by me.
2009-02-20 19:01:05 -08:00
Francisco Tolmasky 9a0fe44acc Better placeholder string support.
Reviewed by me.
2009-02-20 15:36:09 -08:00
Francisco Tolmasky b74b382e30 Fix for resize indicator always showing up.
Reviewed by me.
2009-02-20 14:47:34 -08:00
Francisco Tolmasky 180c42b9d5 Added setFullBridge:/isFullBridge.
Reviewed by me.
2009-02-19 22:56:07 -08:00
Tom Robinson ec3dcaa287 Delete the stupid debug.txt file after building documentation. 2009-02-19 04:32:15 -08:00
Tom Robinson ac6260bf0d CPException CPCoding bug fixes 2009-02-19 04:19:22 -08:00
Francisco Tolmasky 1f54d5de0e Some cleanup.
Reviewed by me.
2009-02-18 23:28:13 -08:00
Tom Robinson 2c335e37b0 Merge branch 'master' of git@github.com:tolmasky/cappuccino into tolmasky 2009-02-18 19:45:34 -08:00
Francisco Tolmasky 4afed0067e Fix for CPSlider not encoding/decoding its value correctly.
Reviewed by me.
2009-02-18 19:19:05 -08:00
Tom Robinson 49719a2e8c Merge branch 'master' of git@github.com:tolmasky/cappuccino into tolmasky 2009-02-18 18:43:18 -08:00
Tom Robinson 197bdf8228 CPTableView doubleAction, clickedRow, clickedColumn methods 2009-02-18 18:42:43 -08:00
Tom Robinson 9890fbd57a CPDictionary dictionaryWithJSObject methods 2009-02-18 18:41:43 -08:00
Francisco Tolmasky 72ae296db0 Fix for new textfield encoding/decoding.
Reviewed by me.
2009-02-18 17:16:10 -08:00
Francisco Tolmasky 51ad4b2b06 Further work on CPTextField.
Reviewed by me.
2009-02-18 13:06:56 -08:00
Francisco Tolmasky 80bc3e3455 Typo.
Reviewed by me.
2009-02-18 04:04:45 -08:00
Tom Robinson 0fe9de4f09 Merge branch 'master' of git@github.com:tolmasky/cappuccino into tolmasky 2009-02-18 04:01:12 -08:00
Francisco Tolmasky 958d17831c Fixed remaining reference to CPThemedValue.
Reviewed by me.
2009-02-18 03:52:27 -08:00
Tom Robinson 6b6991bf6a Merge branch 'master' of git@github.com:tolmasky/cappuccino into tolmasky 2009-02-18 03:49:39 -08:00
Tom Robinson bc9b36165c Merge branch 'master' of git@github.com:tolmasky/cappuccino into tolmasky 2009-02-18 03:45:17 -08:00
Tom Robinson 5fdf39edb3 Better Rhino exception messages for objj 2009-02-18 03:44:37 -08:00
Tom Robinson 00c6a8905d Various CPTableView improvements and nib2cib support 2009-02-18 03:43:49 -08:00
Francisco Tolmasky 6ad037e469 Fix for major theme state bug.
Reviewed by me.
2009-02-18 02:22:10 -08:00
Tom Robinson aaa56f7c02 Merge branch 'master' of git@github.com:tolmasky/cappuccino into tolmasky 2009-02-17 17:05:21 -08:00
Francisco Tolmasky f6c0d93c47 Merged from master.
Reviewed by me.
2009-02-17 14:46:40 -08:00
Francisco Tolmasky cd3b5b7cea It's easier if I just commit this.
Reviewed by me.
2009-02-17 14:27:44 -08:00
Francisco Tolmasky 2bdb0575ad == to ===.
Reviewed by me.
2009-02-17 14:23:25 -08:00
Francisco Tolmasky e095b245e2 Fix for resizing scrollviews when scrollers is scrolled all the way down.
Reviewed by me.
2009-02-17 14:08:54 -08:00
Ross Boucher b7f2f315e2 Bugfix for new splitview resze behavior. 2009-02-17 02:37:26 -08:00
Ross Boucher 0bd543b57b Added support for autoresizing inner split view subviews. 2009-02-17 02:37:16 -08:00
Tom Robinson 7c4b1daed6 Merge branch 'master' of git@github.com:tolmasky/cappuccino into tolmasky 2009-02-16 16:16:57 -08:00
Francisco Tolmasky 66203b0685 Fixed a bug where we were posting frame changed notifications before autoresizing -- causing autoresizing to happen in reverse order.
Reviewed by me.
2009-02-16 14:53:51 -08:00
Tom Robinson a5f23035ae Added Frameworks to .gitignore 2009-02-15 22:54:29 -08:00
Tom Robinson 0ff64751e8 Include previous $CLASSPATH in objj's $CLASSPATH 2009-02-15 03:30:05 -08:00
Francisco Tolmasky 670ebee06d A number of Cib improvments.
Reviewed by me.
2009-02-15 01:11:57 -08:00
Francisco Tolmasky 53aadde343 Added class_replaceMethod.
Reviewed by me.
2009-02-15 01:08:44 -08:00
Francisco Tolmasky 699550c879 Fixes to Cib support.
Reviewed by me.
2009-02-13 14:45:18 -08:00
Francisco Tolmasky 58111b3ba1 Better CPTextField, still not completed.
Reviewed by me.
2009-02-13 01:51:34 -08:00
Francisco Tolmasky 44d837c1eb A number of improvements to theming and bug fixes.
Reviewed by me.
2009-02-13 01:48:44 -08:00
Francisco Tolmasky 689dd72363 Fix for typo that broke copying of CPSets.
Reviewed by me.
2009-02-12 19:38:23 -08:00
Francisco Tolmasky 0f34966f43 Updated CPTextField.
Reviewed by me.
2009-02-10 02:41:38 -08:00
Francisco Tolmasky 50baf5fd50 Further improvements.
Reviewed by me.
2009-02-10 01:12:34 -08:00
Ross Boucher 48fb8f00ca Add convenience methods for full screen. 2009-02-09 23:34:49 -08:00
Francisco Tolmasky a30e91052e Removed themability from title and image in CPButton.
Reviewed by me.
2009-02-07 20:21:03 -08:00
Francisco Tolmasky abd86c676b Theming for CPScroller.
Reviewed by me.
2009-02-07 18:38:34 -08:00
Francisco Tolmasky df5f6c692f Additional theme changes.
Reviewed by me.
2009-02-05 21:17:59 -08:00
Ross Boucher 3f410ea688 Add missing _delegate to CAAnimation.j 2009-02-04 23:11:00 -07:00
Ross Boucher c29b5f2fef Use cached math library functions in UUID. 2009-02-04 14:37:48 -07:00
nciagraandRoss Boucher 471f6cb5e5 Added setTitle: accessors to CPAlert. 2009-02-04 14:33:03 -07:00
nciagraandRoss Boucher 1758e18bd2 Added UUID generator method to CPString. 2009-02-04 14:27:30 -07:00
Marc ChungandRoss Boucher 40def352d9 Removing borking characters from CPURLResponse.j 2009-02-04 11:26:33 -07:00
Ross Boucher 0e965f73b7 Return type was incorrect on "center" 2009-02-04 09:17:45 -07:00
Ross Boucher ecaab49c08 In addition to setting the center of a view's frame, now you can query it. 2009-02-04 08:52:18 -07:00
Ross Boucher f671b89da5 Add "setCenter:" to CPView, which takes a point and moves the center of the view's frame to that point. 2009-02-04 08:11:46 -07:00
Francisco Ryan Tolmasky I e4b2988864 Added more customizability.
Reviewed by me.
2009-02-03 22:47:02 -08:00
Francisco Ryan Tolmasky I 8ea3963f62 Fix for typo.
Reviewed by me.
2009-02-02 17:58:15 -08:00
Francisco Ryan Tolmasky I 99b192c4bc Removed Acidentaly committed Frameworks/ 2009-02-02 17:56:18 -08:00
Ross Boucher 94c838dfde Various fixes. 2009-02-02 18:24:06 -07:00
Ross Boucher a9034de9cd Fix for textfield placeholders being completely broken. 2009-02-02 18:16:23 -07:00
Francisco Ryan Tolmasky I 69833f3d72 Fix for circular dependency stuff.
Reviewed by me.
2009-02-02 17:10:12 -08:00
Francisco Ryan Tolmasky I 6671414da5 Added better templating support.
Reviewed by me.
2009-02-02 12:46:21 -08:00
Francisco Ryan Tolmasky I a4a075655d Forgot to add build.xml.
Reviewed by me.
2009-02-02 02:00:27 -08:00
Francisco Ryan Tolmasky I 9aad67ae04 Added create-frameworks to steam, and began adding Templating system.
Reviewed by me.
2009-02-02 01:59:50 -08:00
Francisco Ryan Tolmasky I 63f813d8ad Typo fixes, deprecating, minor fixes to CPSlider.
Reviewed by me.
2009-02-02 00:09:10 -08:00
Francisco Ryan Tolmasky I e35c4b1461 Added setNeedsLayout and layoutSubviews. Changed CPSlider to use them.
Reviewed by me.
2009-02-01 17:36:22 -08:00
Francisco Ryan Tolmasky I 9ec781fb41 Improved support for resources in nib2cib.
Reviewed by me.
2009-02-01 14:51:12 -08:00
Francisco Ryan Tolmasky I 064a554985 Fix for steam build file.
Reviewed by me.
2009-02-01 01:14:36 -08:00
Francisco Ryan Tolmasky I 8aef955c77 Temporary circular dependency fix.
Reviewed by me.
2009-02-01 00:56:49 -08:00
Francisco Ryan Tolmasky I 492f4b6480 First pass at themes in Cappuccino.
Reviewed by me.
2009-02-01 00:19:50 -08:00
nciagraandRoss Boucher 69cf9b34b1 Some refactoring of CPAlert to allow setting window style. 2009-01-29 21:15:52 -08:00
nciagraandRoss Boucher d2b11a9ba4 Updated CPAlert code and window style 2009-01-29 20:51:41 -08:00
nciagraandRoss Boucher 66bbfbbb3c Added verticalMargin accessor to CPCollectionView. 2009-01-29 20:26:22 -08:00
nciagraandRoss Boucher 9295e2436d Fix to automatically reload arguments when they've changed 2009-01-29 13:51:33 -08:00
nciagraandRoss Boucher 615383e665 Possible changeset for [CPApp setArguments:]. Please review 2009-01-29 13:51:25 -08:00
Nicholas SmallandFrancisco Ryan Tolmasky I d1977f148e Added numberOfRows and numberOfColumns to CPCollectionView.
Reviewed by me.
2009-01-29 11:30:53 -08:00
Francisco Ryan Tolmasky I 9d70c6ad9c Removed menu color change until we have a better API to control it.
Reviewed by me.
2009-01-28 23:23:58 -08:00
Francisco Ryan Tolmasky I c8101d481e Fix spacing issues in CPPopUpButton.
Reviewed by me.
2009-01-28 17:20:29 -08:00
Francisco Ryan Tolmasky I 3ac6b3c1fb Fixed it so that pop ups are properly placed over their buttons.
Reviewed by me.
2009-01-28 16:43:24 -08:00
Francisco Ryan Tolmasky I d0db80335b Fixed bug where buttons wouldn't shrink after sizeToFitting.
Reviewed by me.
2009-01-28 12:38:55 -08:00
Francisco Ryan Tolmasky I f0defa1799 Fix for exception in IE with new imageandtextview code.
Reviewed by me.
2009-01-28 00:10:37 -08:00
Francisco Ryan Tolmasky I f73c569f9a Merge branch 'master' of git@github.com:280north/cappuccino 2009-01-27 19:30:44 -08:00
Francisco Ryan Tolmasky I 6819743850 Fix for issues with new pop up menu code.
Reviewed by me.
2009-01-27 19:21:47 -08:00
Francisco Ryan Tolmasky I f28f2c6e8c Performance improvements to pop up menus.
Reviewed by me.
2009-01-27 16:57:46 -08:00
Francisco Ryan Tolmasky I 10b34965bd Added support for cross-browser text shadows in _CPImageAndTextView.
Reviewed by me.
2009-01-27 15:41:32 -08:00
Francisco Ryan Tolmasky I 9e7fd7f74f Began integrating new imageandtextview into CPButton.
Reviewed by me.
2009-01-27 01:06:21 -08:00
Francisco Ryan Tolmasky I b0d5ca2830 Added vertical alignment support to _CPImageAndTextView.
Reviewed by me.
2009-01-26 22:35:01 -08:00
Francisco Ryan Tolmasky I 6273929184 Added -init to CPMenu, which just calls initWithTitle: with empty string.
Reviewed by me.
2009-01-24 09:14:19 -08:00
Francisco Ryan Tolmasky I 9e9266712a Changed _CPImageAndTitleView to _CPImageAndTextView.
Reviewed by me.
2009-01-23 18:01:05 -08:00
Francisco Ryan Tolmasky I 6acb074993 Moved all text and image dom element operations to drawRect:.
Reviewed by me.
2009-01-23 13:59:32 -08:00
Francisco Ryan Tolmasky I 986a8815ff Moved tiling to drawRect: in _CPDOMImageAndTitleView.
Reviewed by me.
2009-01-23 13:18:28 -08:00
Francisco Ryan Tolmasky I add96e9c04 First pass at removing CPTextField from _CPImageAndTitleView.
Reviewed by me.
2009-01-23 12:13:34 -08:00
Francisco Ryan Tolmasky I 289d0cac63 Added close button to standard window look.
Reviewed by me.
2009-01-23 10:10:56 -08:00
Francisco Ryan Tolmasky I 90389996d1 Fixed a DOM protection issue in CPWindow.
Reviewed by me.
2009-01-23 09:59:29 -08:00
Francisco Ryan Tolmasky I d28bfee704 Fix for fonts not working in nib2cib and performance improvement for adding views.
Reviewed by me.
2009-01-22 17:30:56 -08:00
Francisco Ryan Tolmasky I cc32844a9c Fixed a missing DOM protection guard.
Reviewed by me.
2009-01-22 14:40:26 -08:00
Francisco Ryan Tolmasky I 6f3a0bdc55 Fixed a few minor issues in steam.
Reviewed by me.
2009-01-22 13:47:33 -08:00
Ross Boucher 06601ba5df Error in the CPCountedSet archiving code. Removing for now, will reattack later. 2009-01-22 00:46:39 -08:00
Ross Boucher 928be8d8e7 Add CPCountedSet and fix a few CPSet errors. 2009-01-22 00:33:10 -08:00
Rich CollinsandFrancisco Ryan Tolmasky I 7fabb182f1 Fix for typo in CPPopUpButton.
[#189 state:resolved].

Reviewed by me.
2009-01-22 00:18:22 -08:00
Francisco Ryan Tolmasky I 815e12be66 Added support for new tracking in CPTextField and CPImageView.
Reviewed by me.
2009-01-21 15:07:41 -08:00
Francisco Ryan Tolmasky I 7c2e6875c6 Fixed a slight typo.
Reviewed by me.
2009-01-21 11:50:49 -08:00
Francisco Ryan Tolmasky I 8de321c780 Final fix for buttons not working when disabled.
[#188 state:resolved]

Reviewed by me.
2009-01-21 11:43:45 -08:00
Thomas BalthazarandFrancisco Ryan Tolmasky I 99f6492f29 work in progress
Signed-off-by: Francisco Ryan Tolmasky I <francisco@280north.com>
2009-01-22 00:59:35 +08:00
Francisco Ryan Tolmasky I bb135f041a Changed CPArray_KVO.j to CPArray+KVO.j.
Reviewed by me.
2009-01-21 07:27:14 -08:00
Tom Robinson a45869be49 Fixed various press bugs. 2009-01-21 01:45:24 -08:00
Tom Robinson 26b7d5fa8b Removed awful Rhino hack (fixed in Rhino 1.7) https://bugzilla.mozilla.org/show_bug.cgi?id=374918 2009-01-21 01:44:23 -08:00
Tom Robinson 9ef4a92613 Better stack trace reporting in objj 2009-01-21 01:39:34 -08:00
Tom Robinson 86cc38cd69 Rhino now supports DOM properties, but we need to cast to JavaScript string.
Checks type during XML plist serialization.
2009-01-21 01:38:00 -08:00
Tom Robinson 19a4140f7d Better file/line number reporting in stack traces in Rhino 2009-01-21 01:35:52 -08:00
Ross Boucher 62284c9218 Merge branch '280north/master' 2009-01-20 21:38:04 -08:00
Ross Boucher 6291804775 Support, fixes, and tests for KVC array operators. 2009-01-20 20:06:46 -08:00
Ross Boucher 0b05b4b7d8 Add KVC+KVO support for "To Many" keys (i.e. Arrays). 2009-01-20 18:51:10 -08:00
Ross Boucher 490ad97f7b Make stringWithHash: not use sprintf, for performance reasons. 2009-01-20 17:29:27 -08:00
Francisco Ryan Tolmasky I 03ec852804 Fixed a bug where changes in one toolbar affected other toolbars.
Reviewed by rossco.
2009-01-20 13:36:34 -08:00
Francisco Ryan Tolmasky I 1ef0e1c078 Modified executable loader to be much more efficient than just calling objj_import recursively.
Reviewed by me.
2009-01-20 08:26:38 -08:00
Francisco Ryan Tolmasky I b371a73644 Merge branch 'master' of git@github.com:280north/cappuccino 2009-01-19 18:17:30 -08:00
Ross Boucher e859e9efc0 Add additional support for dependent keys, some performance improvements. 2009-01-19 01:42:39 -08:00
Ross Boucher 3b82ef5fde Fix an error where we were casting CPNull to a string, forcing calls to sprintf. 2009-01-19 01:41:38 -08:00
Ross Boucher 17bb6aac05 Fix typo in CPTabView.j 2009-01-19 01:25:54 -08:00
Ross Boucher 44e4af0f02 Experimental support for dependent keys. I say experimental because it slows down KVO by nearly 2x when its used. 2009-01-18 22:09:24 -08:00
Ross Boucher 9d34f3d4e6 Remove dead code, use just in time setter replacement.
Typo fix.

Better way to replace methods, courtesy of Francisco.
2009-01-18 16:55:15 -08:00
Francisco Ryan Tolmasky I e05e8788d6 Fix for CPDocument not opening with file local URLs.
Reviewed by me.
2009-01-17 13:50:37 -08:00
Francisco Ryan Tolmasky I e926aad568 Fixed an issue where local documents could not be opened by Cappuccino's document-apps.
Reviewed by me.
2009-01-17 13:31:07 -08:00
Ross Boucher 0559bac7a9 Minor tweak to the dimensions.
[#124 state:resolved]
2009-01-15 20:27:41 -08:00
Thomas BalthazarandRoss Boucher c2ed5b68a1 solve the problem reported by Ross here :
http://groups.google.com/group/objectivej-dev/msg/02549260a9d66f27
2009-01-15 20:14:39 -08:00
Thomas BalthazarandRoss Boucher 03f1cf8ec4 Patch for : http://cappuccino.lighthouseapp.com/projects/16499/tickets/124-cptextfield-rounded-style-has-incorrect-positioning 2009-01-15 20:12:13 -08:00
Jari BakkenandRoss Boucher cc1a3ee93f Fix for CPArray -removeObjectsAtIndexes: 2009-01-15 19:59:12 -08:00
Jari BakkenandRoss Boucher 869db920a9 Add [CPArrayTest testRemoveObjectsAtIndexes] 2009-01-15 19:58:59 -08:00
Francisco Ryan Tolmasky I 6d27e5d0f8 Added DOM protections to CPControl and CPWebView.
Reviewed by me.
2009-01-14 19:22:34 -08:00
Francisco Ryan Tolmasky I 32372c68cd A few minor adjustments to CPImageView nib support.
Reviewed by me.
2009-01-09 05:33:45 -08:00
Francisco Ryan Tolmasky I fb3c43ef6a Made CPImageView nib2cib compliant.
Reviewed by me.
2009-01-09 04:38:35 -08:00
Francisco Ryan Tolmasky I 0af841cfd4 Added .gitignore.
Reviewed by me.
2009-01-08 18:37:43 -08:00
Francisco Ryan Tolmasky I 4a24923edb Fixed a number of subtle bugs introduced with the last keyed archiver change.
Reviewed by me.
2009-01-08 18:26:12 -08:00
Francisco Ryan Tolmasky I 33cd18e109 Merge branch 'master' of git@github.com:280north/cappuccino 2009-01-07 00:08:12 -08:00
Francisco Ryan Tolmasky I 84f6564cd2 Added CGContextStrokeRoundedRect.
Reviewed by me.
2009-01-07 00:05:54 -08:00
Francisco Ryan Tolmasky I f61a82d0eb Merge branch 'master' of git@github.com:280north/cappuccino 2009-01-06 23:57:34 -08:00
Tom Robinson 88f3186839 Merge branch 'integration' of git@github.com:280north/cappuccino into integration 2009-01-06 23:33:00 -08:00
Francisco Ryan Tolmasky IandTom Robinson 541b73e322 Fixed typos.
Signed-off-by: Tom Robinson <yachttom@gmail.com>
2009-01-07 15:30:33 +08:00
Francisco Ryan Tolmasky IandTom Robinson 89476fb54e Fix for tags not being encoded/decoded in CPMenuItems.
[#132 state:resolved].

Signed-off-by: Tom Robinson <yachttom@gmail.com>
2009-01-07 15:30:32 +08:00
Tom RobinsonandTom Robinson 1a56d10bef Better JSON method names.
Signed-off-by: Tom Robinson <yachttom@gmail.com>
2009-01-07 15:27:27 +08:00
Tom RobinsonandTom Robinson b3c71fef9e Simpler JSON APIs as CPString class/instance methods.
Signed-off-by: Tom Robinson <yachttom@gmail.com>
2009-01-07 15:27:24 +08:00
Francisco Ryan Tolmasky I 6696eca847 Merge branch 'master' of git@github.com:280north/cappuccino 2009-01-06 02:43:11 -08:00
Francisco Ryan Tolmasky I d942ed415b Fix for Dragging can happen across views.
Reviewed by me.
2009-01-05 23:46:57 -08:00
Francisco Ryan Tolmasky I fb7535286c Fixed typos. 2009-01-05 17:26:14 -08:00
Francisco Ryan Tolmasky I 2c51252c09 Fix for tags not being encoded/decoded in CPMenuItems.
[#132 state:resolved].
2009-01-05 17:20:14 -08:00
Francisco Ryan Tolmasky I 6a5bf822ab Fix for setIgnoresMouseEvents: in CPWindow.
[#195 state:resolved].

Reviewed by me.
2009-01-05 01:58:21 -08:00
Francisco Ryan Tolmasky I c6529f6bf7 Minor style changes to nciarga's menu changes.
Reviewed by me.
2009-01-04 16:22:22 -08:00
Francisco Ryan Tolmasky I 481cedb871 Merge branch 'integration' of git@github.com:280north/cappuccino into integration 2009-01-04 15:53:09 -08:00
nciagraand280north 78b84be3fd Further fixes for separator items
Signed-off-by: 280north <admin+280north@280north.com>
2009-01-05 07:50:49 +08:00
Nicholas Smalland280north 3235cfd288 Few fixes for previous menu commits
Signed-off-by: 280north <admin+280north@280north.com>
2009-01-05 07:50:47 +08:00
Nicholas Smalland280north 899db8fe0b Fix for disabled menu items still firing actions
Signed-off-by: 280north <admin+280north@280north.com>
2009-01-05 07:50:40 +08:00
Nicholas Smalland280north 08ba49ed46 Updated all blank key equivalents to nil, which works now
Signed-off-by: 280north <admin+280north@280north.com>
2009-01-05 07:50:34 +08:00
Nicholas Smalland280north 0a8b08ebec Fix for flash view transparency
Signed-off-by: 280north <admin+280north@280north.com>
2009-01-05 07:50:31 +08:00
Nicholas Smalland280north 78503a9380 Fix for disabled menu items still highlighting
Signed-off-by: 280north <admin+280north@280north.com>
2009-01-05 07:50:30 +08:00
Nicholas Smalland280north 67658876d5 Added menu item separators and a + menuBarHeight
Signed-off-by: 280north <admin+280north@280north.com>
2009-01-05 07:50:29 +08:00
Francisco Ryan Tolmasky I d361cffc75 Fixed a typo "_arguments" instead of "_argument".
Reviewed by me.
2009-01-04 15:38:36 -08:00
Francisco Ryan Tolmasky I b9cd78fde9 Added comment explaining the run loop business in CPScrollView.
Reviewed by me.
2009-01-04 15:37:42 -08:00
Francisco Ryan Tolmasky I 42451ece28 Merge branch 'master' into localint 2009-01-04 14:54:01 -08:00
Francisco Tolmaskyand280north f5963ecc30 Fix for CPKeyedArchiver
Signed-off-by: 280north <admin+280north@280north.com>
2009-01-05 06:42:01 +08:00
Francisco Tolmaskyand280north 74e3bfe6ce Fix for _CPCibCustomView
Signed-off-by: 280north <admin+280north@280north.com>
2009-01-05 06:42:00 +08:00
Tom Robinsonand280north 2b455ecfc3 nib2cib/archiving support for CPScrollView, CPScroller, and CPClipView
Signed-off-by: 280north <admin+280north@280north.com>
2009-01-05 06:41:59 +08:00
Tom Robinson a1802ff043 Merge branch 'master' of git@github.com:280north/cappuccino 2009-01-03 21:09:52 -08:00
Tom Robinson 5b7d6e2e1f Fixed "objectForKey:" returning undefined instead of nil.
Reviewed by tolmasky.

[#194 state:resolved responsible:tlrobinson]
2009-01-03 21:08:46 -08:00
Francisco Ryan Tolmasky I ac8ecdb7f3 A number of CPTableView improvements, still not built by default.
Reviewed by me.
2009-01-03 16:16:24 -08:00
Francisco Ryan Tolmasky I 0af5bb05fc Replacing a few instances of Math.min/max with MIN/MAX and == with ===.
Reviewed by me.
2009-01-03 15:44:29 -08:00
Francisco Ryan Tolmasky I 35fc44e183 Fixed convertPoint/rect to work across different windows.
[#193 state:resolved]

Reviewed by me.
2009-01-03 12:14:04 -08:00
Francisco Ryan Tolmasky I aabe06eb3f Fix for adding draggedViewLocation and draggedImageLocatio to CPDraggingInfo.
[#192 state:resolved]

Reviewed by me.
2009-01-03 01:11:06 -08:00
Francisco Ryan Tolmasky I ef7000a29d Fix for menus showing up under modal windows.
[#182 state:resolved].

Reviewed by me.
2008-12-29 17:53:51 -08:00
Francisco Ryan Tolmasky I bec47ec814 Added -objectEnumerator to CPSet.
[#185 state:resolved].

Reviewed by me.
2008-12-29 17:32:03 -08:00
Francisco Ryan Tolmasky I b29dc6052e Further reorg.
Reviewed by me.
2008-12-26 23:54:20 -08:00
Francisco Ryan Tolmasky I 3afd7a9a69 A bit more CPWindow code reorg.
Reviewed by me.
2008-12-26 21:35:10 -08:00
Francisco Ryan Tolmasky I 3305385311 Removed unnecesary code.
Reviewed by me.
2008-12-26 20:38:08 -08:00
Francisco Ryan Tolmasky I ce5cfca43d Fix for tag not being set on button in toolbar.
Reviewed by me.
2008-12-23 01:12:39 -08:00
Francisco Ryan Tolmasky I 08a3b64483 Fix for impropert animationCurve being set.
[#175 state:resolved].
[#176 state:resolved].

Reviewed by me.
2008-12-22 16:37:22 -08:00
Francisco Ryan Tolmasky I 9fa56531c6 Updated nib2cib to support new window styles.
Reviewed by me.
2008-12-22 15:10:20 -08:00
Francisco Ryan Tolmasky I 459316f102 Major Window Fixes/Changes.
[#65 state:resolved].
[#58 state:resolved].
[#94 state:resolved].

Reviewed by me.
2008-12-22 13:53:48 -08:00
Leif SingerandRoss Boucher 554aa77707 CPLogPopup printed [null] as log level; removed. 2008-12-22 12:18:02 -05:00
Ross Boucher 4eb1490d80 Fix for http://cappuccino.lighthouseapp.com/projects/16499/tickets/177-cpapplication-trytoperformwith-causes-infinite-recursion
Not entirely sure this is the correct implementation, but I did fix the two typos and the infinite recursion.

[#177 state:resolved milestone:0.6.5]
2008-12-22 12:14:40 -05:00
Ross Boucher 670efb196e Merge branch 'master' of git@github.com:280north/cappuccino 2008-12-22 11:48:11 -05:00
Ross Boucher 8b68729041 Fix for http://cappuccino.lighthouseapp.com/projects/16499/tickets/60-cpcolorpanel-does-not-update-color-correctly
and for http://cappuccino.lighthouseapp.com/projects/16499/tickets/59-cpcolorpanel-defaults-to-white-on-init

[#59 state:resolved milestone:0.6.5]
[#60 state:resolved milestone:0.6.5]
2008-12-22 11:46:25 -05:00
Francisco Ryan Tolmasky I 3b299aa5b4 Merge branch 'master' of git@github.com:280north/cappuccino 2008-12-19 18:45:57 -08:00
Francisco Ryan Tolmasky I 14f267da47 Fixed a problem in building nib2cib that caused way too many files to end up in the distro.
Reviewed by me.
2008-12-19 18:44:40 -08:00
Tom Robinson 059456571d plist <data> support. NSColor unarchiving for nib2cib. 2008-12-19 00:48:13 -08:00
Tom Robinson f7571f83c8 Better CPLog sprintf integration (only uses sprintf if param 0 is a string and there is more than one param) 2008-12-18 19:23:40 -08:00
Francisco Ryan Tolmasky I bd42a03cf0 Merge branch 'master' of git@github.com:280north/cappuccino 2008-12-18 18:11:24 -08:00
Francisco Ryan Tolmasky I 66c7997ed0 Fix for [CPMenu setMenuBarVisible:NO] being broken.
[#172 state:resolved].

Reviewed by me.
2008-12-18 18:10:52 -08:00
Ross Boucher 9cbefdda28 another typo. silly me. 2008-12-17 18:44:00 -08:00
Ross Boucher 389a44dfc1 typo 2008-12-17 18:39:55 -08:00
Ross Boucher bc30541b9c Add 2 missing methods on CPDictionary.
[#157 state:resolved milestone:0.6.1]
2008-12-17 18:21:29 -08:00
Ross Boucher 8fa5217318 Fix for a few errors francisco noticed. 2008-12-17 18:21:03 -08:00
Ross Boucher 7ad1c68249 incorrect method name 2008-12-17 18:11:23 -08:00
Ross Boucher ef0baea3ad Merge branch 'master' into bindings 2008-12-17 18:09:08 -08:00
Ross Boucher 69b1685280 Fix for http://cappuccino.lighthouseapp.com/projects/16499/tickets/170-appkitcptextfieldj-textfieldbackground-argreturn-types-are-incorrect
[#170 state:resolved milestone:0.6.1]
2008-12-17 18:07:37 -08:00
Bailey CarlsonandRoss Boucher 508e8b04a1 Add CPSet to Foundation. Thanks Bailey and Nabil. 2008-12-17 18:02:17 -08:00
Joubert NelandRoss Boucher 365a5f182c Fixed documentation for dragView: 2008-12-17 16:50:53 -08:00
Ross Boucher bbd632fa34 Add missing method to CPDictionary. 2008-12-17 16:49:31 -08:00
Francisco Ryan Tolmasky I 488078ac04 Merge branch 'master' of git@github.com:280north/cappuccino 2008-12-16 19:44:53 -08:00
Francisco Ryan Tolmasky I a9b57d4187 Fix for +isKindOfClass: and +isMemberOfClass: not being there.
[#171 state:resolved].

Reviewed by me.
2008-12-16 19:43:48 -08:00
Tom Robinson 2d887d0a7e Initial CPSegmentedControl archiving/nib2cib support (currently useless) 2008-12-16 16:43:00 -08:00
Tom Robinson cd9a3a68ec Spurious CPLog 2008-12-16 16:42:21 -08:00
Tom Robinson d73450d8fa CPSplitView fix for more than one splitter 2008-12-15 21:18:36 -08:00
Ross Boucher 5eb7be054e Merge branch 'master' of git@github.com:280north/cappuccino 2008-12-15 18:46:44 -08:00
Ross Boucher 70e1fe5a4b Fix for misplaced ; in CPCompatibility 2008-12-15 18:46:20 -08:00
Francisco Ryan Tolmasky I 75015ce466 Fix for making CPAnimation "pausable".
[#168 state:resolved].

Reviewed by me.
2008-12-15 18:40:33 -08:00
Francisco Ryan Tolmasky I c2b9ebd4b9 Fix for "unkown class NSObject" warnings.
[#166 state:resolved].

Reviewed by me.
2008-12-15 00:48:27 -08:00
Francisco Ryan Tolmasky I 7c117f22a7 Added support for external frameworks in nib2cib.
[#167 state:resolved].

Reviewed by me.
2008-12-15 00:47:42 -08:00
Francisco Ryan Tolmasky I f278de3a8c Fix for adding clean-all.
[#165 state:resolved]

Reviewed by me.
2008-12-15 00:45:47 -08:00
Francisco Ryan Tolmasky I b584f8bc46 Fix for _currentMousePosition errors.
[#163 state:resolved].

Reviewed by me.
2008-12-14 10:50:51 -08:00
Francisco Ryan Tolmasky I b08e98d0ab Fix for item not being ull width in non-integral collection views.
[#164 state:resolved].

Reviewed by me.
2008-12-14 10:49:38 -08:00
Francisco Ryan Tolmasky I de5d83aedd Updated nibs/xibs in NibApp project to be "MainMenu" instead of "HelloWorld" now that nib2cib doesn't always choose "MainMenu.cib".
Reviewed by me.
2008-12-12 20:22:40 -08:00
Francisco Ryan Tolmasky I 0b48863a51 Fix for nib2cib always using MainMenu.cib as output filename.
Reviewed by me.
2008-12-12 20:21:46 -08:00
Francisco Ryan Tolmasky I 5f66874d3e Fix for infinite looping with unterminated msgsends and array literals.
[#161 state:resolved]

Reviewed by me.
2008-12-12 15:59:33 -08:00
Tom Robinson 79ba2af699 Added utilities.js in Objective-J with Base64 encoding/decoding, sprintf moved from CPString. Tests for base64 and sprintf utilities. 2008-12-11 05:23:47 -08:00
Tom Robinson 2aacd3e807 Better xib/nib examples 2008-12-10 23:53:17 -08:00
Tom Robinson 1d2d37334c nib2cib installation fix. 2008-12-10 23:42:21 -08:00
Francisco Ryan Tolmasky I fbf4f426db Merge branch 'master' of git@github.com:280north/cappuccino 2008-12-10 23:41:56 -08:00
Francisco Ryan Tolmasky I 5ecb83aafa Fix for menus in IE.
Reviewed by me.
2008-12-10 23:41:25 -08:00
tlrobinson 77315d0268 Merge branch 'master' of git@github.com:280north/cappuccino 2008-12-10 19:03:03 -08:00
tlrobinson f29be2f69c CPTabView and CPTabViewItem coding and nib2cib support 2008-12-10 19:02:22 -08:00
Francisco Ryan Tolmasky I 4a9f09570e Updated SubEthaEdit syntax mode.
Reviewed by me.
2008-12-10 18:04:18 -08:00
Francisco Ryan Tolmasky I fd46487c82 Updated default bake template.
Reviewed by me.
2008-12-10 16:56:28 -08:00
Francisco Ryan Tolmasky I d92fc8c4d0 Cleaned up old deprecated documentation stuff and added documentation to deploy.
Reviewed by me.
2008-12-10 15:57:31 -08:00
Francisco Ryan Tolmasky I b87493bd5f Merge branch 'master' of git@github.com:280north/cappuccino 2008-12-10 12:06:37 -08:00
Francisco Ryan Tolmasky I 6925bfd416 RemainingBuild change.
Reviewed by me.
2008-12-10 12:06:00 -08:00
Francisco Ryan Tolmasky I 2d9d9f3e93 Fix for timer issue in firefox.
Reviewed by me.
2008-12-10 11:24:19 -08:00
Francisco Ryan Tolmasky I 87f644e5ba Forgot to commit this earlier.
Reviewed by me.
2008-12-09 15:03:41 -08:00
Francisco Ryan Tolmasky I 5c57d241ca Changed an import to @import.
Reviewed by me.
2008-12-09 14:43:18 -08:00
Francisco Tolmasky a966e7520f Added better support for debugging.
Reviewed by me.
2008-12-09 14:08:57 -08:00
tlrobinson f6b3afa75c Various nib2cib conversion improvements (sizes, autoresize, button/window styles, etc) 2008-12-09 02:00:09 -08:00
tlrobinson cfbdb1ce76 nib2cib support for CPMenu, CPMenuItem, CPPopUpButton, including MainMenu support. New test NIBs. 2008-12-09 01:58:42 -08:00
tlrobinson 39ff2b46ab Another fix for non-ASCII characters in NIBs 2008-12-09 01:54:29 -08:00
tlrobinson 29d33193cd bridge.js XMLHttpRequest force UTF-8 encoding to fix nib2cib NIBs w/ non-ASCII characters.
Possibly incorrect assumption, but nothing appears to have broken.
2008-12-09 01:47:39 -08:00
Francisco Tolmasky 5babf3708e Fix for broken steam with new build system.
Reviewed by me.
2008-12-06 15:12:05 -08:00
Francisco Tolmasky ab40761a6c Merge branch 'master' of git@github.com:280north/cappuccino 2008-12-05 20:43:17 -08:00
Francisco Tolmasky cf5fa034b9 Fix for textfields no longer working with new timers -- timers firing before one native run loop has occured.
[#154 state:resolved]

Reviewed by me.
2008-12-05 20:42:12 -08:00
Thomas Robinson 9d6ebf79cd Merge branch 'master' of git@github.com:280north/cappuccino 2008-12-05 19:38:59 -08:00
Thomas Robinson c992b61ca2 Fixed _imageScaling typos 2008-12-05 19:38:18 -08:00
Ross Boucher 3ba2f208d4 Some changes to color pickers to allow you to make your own. 2008-12-05 14:57:50 -08:00
Francisco Tolmasky 462bed7d67 Merge branch 'master' of git@github.com:280north/cappuccino 2008-12-05 09:30:20 -08:00
Francisco Tolmasky d938d39929 Fix for (At least one occurence of) the "empty menu" bug.
Reviewed by me.
2008-12-05 09:29:32 -08:00
Tom Robinson abe2e14af4 CPLog integration with sprintf. 2008-12-04 22:16:24 -08:00
Tom Robinson 3516e026d0 Improved nib2cib support for windows (min/max size, correct autoresize mask, flipped Y coordinate) 2008-12-04 22:13:41 -08:00
Tom Robinson 10db0dab7e Add %b specifier to sprintf for printing in binary. 2008-12-04 22:11:25 -08:00
Tom Robinson e0967272e7 Explicitly set radix to 10 for Ross. 2008-12-04 22:04:41 -08:00
Tom Robinson c0aa78eb76 Make CPColorWell resize correctly, and display immediately upon unarchiving. 2008-12-04 21:58:01 -08:00
Tom Robinson 09d03bf270 Merge branch 'master' of git@github.com:280north/cappuccino 2008-12-04 21:55:53 -08:00
Tom Robinson 6399ac0c95 Fixed CPStringFromRect and CPStringFromPoint 2008-12-04 21:54:50 -08:00
Francisco Tolmasky 2639b7beeb Added "all" target for building both debug and release.
Reviewed by me.
2008-12-04 21:48:00 -08:00
Francisco Tolmasky 062ff28a5c Fixed a few issues with bootstrap.
Reviewed by me.
2008-12-04 17:52:04 -08:00
Francisco Tolmasky d59403cc5b We don't need steam.xml in common.xml.
Reviewed by me.
2008-12-04 17:33:42 -08:00
Francisco Tolmasky 9565ad2cb2 Improvements to the build system.
Reviewed by me.
2008-12-04 16:29:42 -08:00
Francisco Tolmasky 72375fe1cd Fix for CPMenuItem dieing with nil keyEquivalent.
[#153 state:resolved]

Reviewed by me.
2008-12-02 18:25:29 -08:00
Francisco Tolmasky ce696a50f1 Fix for windowShouldClose: being called twice.
[#152 state:resolved]

Reviewed by me.
2008-12-02 18:08:41 -08:00
Thomas Robinson a7a4740c60 Ant task for creating docs ("ant docs") and removed absolute paths from Doxyfile. 2008-12-02 02:10:44 -08:00
Francisco Ryan Tolmasky I d0b52f7118 Replaced some imports with @imports.
Reviewed by me.
2008-11-28 11:28:20 -08:00
Francisco Ryan Tolmasky I a92243314a Fix for using transform() instead of in code calculation when available.
[#148 state:resolved]

Reviewed by me.
2008-11-24 19:42:00 -08:00
Francisco Ryan Tolmasky I 538adfeb61 Merge branch 'master' of git@github.com:280north/cappuccino 2008-11-24 17:03:42 -08:00
Francisco Ryan Tolmasky I 2dc5458e63 Fix for intervals not being clearable after one run.
[#147 state:resolved]

Reviewed by nciagra
2008-11-24 16:49:34 -08:00
Thomas Robinson 043bcc5729 gzip support in steam, removed special "cat" dependency, improved install-tools script 2008-11-21 17:24:11 -08:00
Francisco Ryan Tolmasky I 2ff51a3dbb Further press fix.
Reviewed by me.
2008-11-21 16:04:37 -08:00
Tom RobinsonandFrancisco Ryan Tolmasky I 5d8cea9ed6 Fix for press being broken.
[#143 state:resolved]

Reviewed by tolmasky.
2008-11-21 03:48:19 -08:00
Francisco Ryan Tolmasky I f3dcfbac52 Fix for hiTests always returning true in CPView.
Reviewed by me.
2008-11-20 04:39:22 -08:00
Ross Boucher 952fe0091b Compatibilty update to the whitespace commit. 2008-11-19 16:31:31 -08:00
Rich CollinsandRoss Boucher 6ea22a96ad Fix for line break bug from Rich Collins. 2008-11-19 14:19:48 -08:00
Tom Robinson b4b28cda92 Merge branch 'master' of git@github.com:280north/cappuccino 2008-11-18 20:19:56 -08:00
Tom Robinson db542fa905 objj console fix for missing file/bundle 2008-11-18 20:19:15 -08:00
Francisco Ryan Tolmasky I 30f905a253 Changed imports to @imports.
Reviewed by me.
2008-11-18 20:17:24 -08:00
Francisco Ryan Tolmasky I cc8e6e5820 Merge branch 'master' of git@github.com:280north/cappuccino 2008-11-18 20:13:05 -08:00
Francisco Ryan Tolmasky I 67ee22c6d9 Fix for nib2cib with new timeout system.
Reviewed by me.
2008-11-18 20:12:31 -08:00
Tom Robinson 20830ae349 Merge branch 'master' of git@github.com:280north/cappuccino 2008-11-18 19:42:37 -08:00
Tom Robinson 44b6f8cfc5 Objective-J backtrace prints object hash id 2008-11-18 19:38:33 -08:00
Francisco Ryan Tolmasky I 1be4ba0075 Merge branch 'master' of git@github.com:280north/cappuccino 2008-11-18 19:38:19 -08:00
Francisco Ryan Tolmasky I bbeba1e735 Fix for regression in toolbar copying behavior.
Reviewed by me.
2008-11-18 19:34:42 -08:00
Tom Robinson 3b65f460d6 Simplified stringWithHash 2008-11-18 19:28:55 -08:00
Tom Robinson fbb3959e66 Merge branch 'master' of git@github.com:280north/cappuccino 2008-11-18 18:15:29 -08:00
Francisco Ryan Tolmasky I 663f28e541 Fix for objj in the console.
Reviewed by me.
2008-11-18 18:13:39 -08:00
Tom Robinson 9321084d84 CPTimer semicolon/comma typo 2008-11-18 18:11:09 -08:00
Tom Robinson 7e352676c9 nib2cib null _superview bug fix 2008-11-18 18:10:28 -08:00
Nick TakayamaandFrancisco Ryan Tolmasky I 4c8d7b0f1c Timers.
[#116 state:resolved]

Reviewed by ross and me.
2008-11-18 02:09:35 -08:00
Francisco Ryan Tolmasky I 827e56b23f Merge branch 'master' of git@github.com:280north/cappuccino 2008-11-15 14:57:36 -08:00
Francisco Ryan Tolmasky I 04294cf8b9 Updated SubEthaEdit mode with new syntax additions.
Reviewed by me.
2008-11-15 14:57:05 -08:00
Francisco Ryan Tolmasky I 7f0aa75ba1 Fixed inconsistency in docs.
[#118 state:resolved]

Reviewed by me.
2008-11-15 14:04:08 -08:00
Francisco Ryan Tolmasky I cb7c8046e4 Fix for plist URL encoding instead of HTML entity encoding.
[#81 state:resolved]

Reviewed by me.
2008-11-15 02:57:29 -08:00
Francisco Ryan Tolmasky I ad2bf51fd9 Merge branch 'master' of git@github.com:280north/cappuccino 2008-11-14 17:56:29 -08:00
Francisco Ryan Tolmasky I 26333c3d2b A number of improvements to the parser.
Reviewed by me.
2008-11-14 17:56:04 -08:00
Thomas Robinson cbf51a6127 Removed AppKit from test task until we actually have AppKit tests 2008-11-14 04:16:03 -08:00
Tom Robinson 4dbfe1f23e Make ant test task depend on build task 2008-11-13 21:27:45 -08:00
Tom Robinson ea5221bfda Merge branch 'master' of git@github.com:280north/cappuccino 2008-11-13 21:27:29 -08:00
Ross Boucher ea0c9af0f8 Merge branch 'master' into atrstring 2008-11-13 21:25:52 -08:00
Tom Robinson ba43925f22 "ant test" now tests frameworks in $STEAM_BUILD/Release instead of installed 2008-11-13 21:06:02 -08:00
Tom Robinson e51b1cb7e1 Integrated OJUnit with build scripts ("ant test" runs tests, "ant release" now pulls OJUnit from separate repo) 2008-11-13 20:54:40 -08:00
Ross Boucher d64e55226d Add CPMutableAttributedString 2008-11-13 19:33:48 -08:00
Patrick CrosbyandFrancisco Ryan Tolmasky I 311939ecb9 Fix for indeterminate check in CPProgressIndicator.
[#140 state:resolved]

Reviewed by me.
2008-11-13 16:59:55 -08:00
Francisco Ryan Tolmasky I e1d57aac3b Fix for broken insertObjects:atIndexes: and tests and isEqual.
[#136 state:resolved]

Reviewed by me.
2008-11-13 16:55:33 -08:00
Ross Boucher 102c741ca3 Initial commit of CPAttributedString, and test cases. All test cases currently pass. 2008-11-13 11:23:00 -08:00
Francisco Ryan Tolmasky I 1a8093c314 Fix for minimizer not recognizing a var.
Reviewed by me.
2008-11-13 00:40:40 -08:00
Francisco Ryan Tolmasky I 7d8b02dd96 Fix for addSubview:positioned:relativeTo: not working with view already in the view treey.
Reviewed by me.
2008-11-13 00:21:13 -08:00
Glenn RempeandFrancisco Ryan Tolmasky I 6e15ce0c00 Some updates to NewApplication.
[#137 state:resolved]

Reviewed by me.
2008-11-12 19:24:04 -08:00
Francisco Ryan Tolmasky I 9e8eff4543 Fix for broken resources in DEBUG builds.
[#139 state:resolved]

Reviewed by me.
2008-11-12 18:25:42 -08:00
Thomas Robinson eee0338b63 Build script changes to allow a bootstrapped build with no existing installed tools 2008-11-11 17:55:40 -08:00
Ross Boucher 75bedef465 Merge branch 'master' into atrstring 2008-11-11 13:40:01 -08:00
Francisco Ryan Tolmasky I 8adaa2d3c8 Added CGContextSetAlpha VML implementation for use in IE, and fixed a bug where CGContextCanvas.j and CGContextVML.j were being added to AppKit.sj inappropriately.
Reviewed by me.
2008-11-11 12:21:33 -08:00
Tom Robinson 581a004ed0 Merge branch 'master' of git@github.com:280north/cappuccino 2008-11-11 02:30:44 -08:00
Tom Robinson 88fbecb4d3 Intial CPToolbar coding / nib2cib support (still need CPToolbarItem support) 2008-11-11 02:29:33 -08:00
Tom Robinson ac5c59f8ba Fixed incorrect viewClass/windowClass archiving keys 2008-11-11 02:27:56 -08:00
Ross Boucher add1776125 Fix for local CPURLConnection requests (file:///) 2008-11-10 23:16:29 -08:00
Ross Boucher 937865ef83 There was a missing @end in CPAlert.j 2008-11-10 11:17:39 -08:00
Ross Boucher bf72b5cd13 Merge branch 'master' into atrstring 2008-11-10 10:34:36 -08:00
Ross Boucher 88f12bad93 implement NSString compare:options:range
Thanks to Cacaodev for the ticket and initial stab at this.

[#105 state:resolved milestone:0.6]
2008-11-10 10:29:46 -08:00
Ross Boucher 9b764caf79 Fixes for CPAlert (style, cleanup, and some behavior). 2008-11-10 10:15:35 -08:00
Ross Boucher 56c2b9d755 Revert previous tools commit. 2008-11-10 10:07:50 -08:00
Ross Boucher 814696070d Merge branch 'master' into alert 2008-11-10 09:31:01 -08:00
Brian TaylorandRoss Boucher 0907f287af fix for future installs not overwriting previous installs
[#134 state:resolved milestone:0.6]
2008-11-10 09:29:24 -08:00
Francisco Ryan Tolmasky I 08c1973f11 Merge branch 'master' of git@github.com:280north/cappuccino 2008-11-09 18:51:21 -08:00
Francisco Ryan Tolmasky I 3156de3a5c Fixed bad CPNotificationCenter call.
Reviewed by me.
2008-11-09 18:50:46 -08:00
Tom Robinson 16209b3e3f press --main fix 2008-11-09 16:55:35 -08:00
Sam McDonaldandFrancisco Ryan Tolmasky I 9f9cc4c22c Fix for stringByDeletingLastPathComponent.
[#126 state:resolved]

Reviewed by tolmasky
2008-11-08 13:53:53 -08:00
Francisco Ryan Tolmasky I 9def3ba765 Added error output.
Reviewed by me.
2008-11-08 13:01:13 -08:00
Francisco Ryan Tolmasky I 5d5aa0a4d2 Fix for typo in build.xml.
Reviewed by me.
2008-11-08 12:38:11 -08:00
Tom Robinson edf463ab31 Fixed missing CPTabView and CPFlashView/Movie imports in AppKit.j
[#128 state:resolved responsible:tlrobinson]
2008-11-08 04:39:38 -08:00
Francisco Ryan Tolmasky I 7702fd9929 Merge branch 'master' of git@github.com:280north/cappuccino 2008-11-07 11:30:44 -08:00
Francisco Ryan Tolmasky I eae1dc2568 Fix for setHidden: not working in main menu bar.
[#78 state:resolved]

Reviewed by me.
2008-11-07 11:29:18 -08:00
Francisco Ryan Tolmasky I 204739e220 Merge branch 'master' of git@github.com:280north/cappuccino 2008-11-07 11:07:21 -08:00
Francisco Ryan Tolmasky I 41b3d7987a Hopefully this resolved the issues with isntalling the tools.
[#13 state:resolved]

Reviewed by me.
2008-11-07 11:06:39 -08:00
Francisco Ryan Tolmasky I f5b0542d35 Ugh, two remaining references.
Reviewed by me.
2008-11-07 03:09:37 -08:00
Francisco Ryan Tolmasky I b754d60752 Forgot to take out these references to the old arrow images.
Reviewed by me.
2008-11-07 03:04:56 -08:00
Francisco Ryan Tolmasky I edd49f222e Added a number of customization options to the main menubar.
Reviewed by me.
2008-11-06 00:12:47 -08:00
Francisco Ryan Tolmasky I 6cff27c7bb Fix for minimization in Cappuccino.
[#9 state:resolved]

Reviewed by ross.
2008-11-03 16:57:28 -08:00
Francisco Ryan Tolmasky I 54d48e9292 Fix for minimization in Cappuccino.
Need to figure out licensing for this.

[#9 state:resolved]

Reviewed by rossco.
2008-11-03 16:53:46 -08:00
Francisco Ryan Tolmasky I 07507eac1e Make press create 280North style plists instead of xml plists.
Reviewed by me.
2008-11-02 18:30:08 -08:00
Francisco Ryan Tolmasky I 912895d1ad Added cplutil app to convert between plist types.
Reviewed by me.
2008-11-02 10:42:05 -08:00
Ross Boucher 5823db8319 Fix for bug in CPKeyedArchiver (typo aNuumber). 2008-10-28 18:35:02 -07:00
Tom Robinson b9b109daf0 More comprehensive test XIB 2008-10-28 01:20:12 -07:00
Tom Robinson ed5aa5b54c CPColorWell coding and nib2cib support. 2008-10-28 01:08:07 -07:00
Tom Robinson 1457f5d1c8 Changed deprecated setValues/value to setFloatValue/floatValue. 2008-10-28 01:07:03 -07:00
Tom Robinson e8febcda15 Reverting to previous CPControl/CPSlider event system 2008-10-28 00:56:21 -07:00
Ross Boucher 5c04acf840 Make isEqual: more like Cocoa's version. 2008-10-27 19:27:37 -07:00
Tom Robinson a3ae869f1d Removed CPLogs and an extra performSelectors, cleaned up rest of string literals. 2008-10-27 16:49:18 -07:00
Tom Robinson 7a3fab1d6d Numerous improvements and nib2cib support for CPControl, CPSlider, CPTextField, CPWebView, etc.
Fixed broken @accessors preprocessing.
2008-10-27 04:54:43 -07:00
Francisco Ryan Tolmasky I 745df353c4 Fix for toolbar item's target set to null.
[#115 state:resolved]

Reviewed by me.
2008-10-27 01:51:08 -07:00
Francisco Ryan Tolmasky I f7dd436b81 Stop flash of scrollers when autohidden.
Reviewed by me.
2008-10-27 01:20:23 -07:00
Ross Boucher 80f95e4d58 Fix binary search in CPArray to allow searching for 0. 2008-10-26 23:06:23 -07:00
Ross Boucher 8fcf7581e6 Starting a test class for attributed string. 2008-10-26 14:37:54 -07:00
Francisco Ryan Tolmasky I 12b58cd938 Merge branch 'master' of git@github.com:280north/cappuccino 2008-10-26 00:49:28 -07:00
Francisco Ryan Tolmasky I 5144a5a579 Added @accessor support, @import, and fixed spacing bug with @selector.
Reviewed by ross.
2008-10-26 00:48:49 -07:00
Ross Boucher b5ad11323c Merge branch 'master' into string 2008-10-26 00:16:53 -07:00
Nick TakayamaandRoss Boucher 748d5b84bd ix for bad code in CPArray (incorrect range calculations) 2008-10-25 23:59:04 -07:00
Francisco Ryan Tolmasky I b7bba7dc7f Added @synthesize.
Reviewed by tom.
2008-10-24 17:40:30 -07:00
Nick TakayamaandFrancisco Ryan Tolmasky I 3e6fa883cf Removed Kuler Color Picker from Cappuccino.
Reviewed by tolmasky.
2008-10-24 14:07:14 -07:00
Francisco Ryan Tolmasky I 6f8a6bde62 Whitespace cleanup.
Reviewed by ross.
2008-10-24 13:59:32 -07:00
Francisco Ryan Tolmasky I 75aa1e591a Fix for bad copyright and spacing in NewApplication.
Reviewed by ross.
2008-10-24 13:57:09 -07:00
Ross Boucher 7568d91d28 Add copy method on CPDictionary 2008-10-23 15:36:03 -07:00
Ross Boucher 5023588af4 CPAttributedString necessary additions 2008-10-22 18:54:19 -07:00
Francisco Ryan Tolmasky I 98e5c0ed3e Merge branch 'master' of git@github.com:280north/cappuccino 2008-10-22 18:16:24 -07:00
Francisco Ryan Tolmasky I 2e9e38ebaf Fix for multiline string literals not working in Objective-J.
[#80 state:resolved]

Reviewed by me.
2008-10-22 18:13:44 -07:00
Tom Robinson f34265a864 nib2cib fix for multiple subviews in a Custom View 2008-10-22 18:01:54 -07:00
Tom Robinson cb53db05dc Merge branch 'master' of git@github.com:280north/cappuccino 2008-10-22 17:04:15 -07:00
Tom Robinson 88c64c5071 Temporary fix for lack of <data> tag support in PLISTs (for nib2cib) 2008-10-22 17:03:39 -07:00
Francisco Ryan Tolmasky I abebe2e081 Get rid of this.
Reviewed by me.
2008-10-22 16:33:05 -07:00
Tom Robinson fabd1df4dd Fix for missing debug variable 2008-10-22 16:22:41 -07:00
Tom Robinson abbbc6e8f0 Replaced regex literals with RegExp objects, due to bug [#117] 2008-10-22 16:00:26 -07:00
Tom Robinson a6e4712524 Cleanup of bridge.js. "correct" setTimeout and setInterval implementations. Removed extra code. 2008-10-22 01:04:31 -07:00
Tom Robinson 0798e47459 Cleanup of objj. Fixed bug preventing static code from working. 2008-10-22 01:03:58 -07:00
Tom Robinson 5c6b82c172 Missing headers 2008-10-21 22:28:02 -07:00
Tom Robinson 2c7c53084f Merge branch 'master' of git@github.com:280north/cappuccino 2008-10-21 16:26:55 -07:00
Tom Robinson 04695597b2 Coerce Java string to JS string in "switch" statement (otherwise they don't match) 2008-10-21 16:26:06 -07:00
Tom Robinson 956bc7fe14 Merge branch 'master' into experimental 2008-10-21 16:24:30 -07:00
Francisco Ryan Tolmasky I 75117d77a9 This shouldn't be in there.
Reviewed by me.
2008-10-21 15:59:28 -07:00
Ross Boucher 3190b57ad3 Merge branch 'array' 2008-10-21 15:54:30 -07:00
Ross Boucher 94ea70f4d4 Add binary search of a sorted array. 2008-10-21 15:53:42 -07:00
Tom Robinson d3a0d90ce7 "press" support for flattening to a single JavaScript file, and foundation of intelligent image sprites 2008-10-21 03:42:24 -07:00
Tom Robinson 010fe01265 CPBundle -resourcePath 2008-10-20 21:26:35 -07:00
Ross Boucher f8ee950339 Add a doxygen configuration. If you have doxygen, you should be able to build your own docs with this. 2008-10-20 16:17:29 -07:00
Ross Boucher f7aa5c15c9 New style for documentation (/*! vs. /*).
Enabled doxygen support.

Merge branch 'documentation'

Conflicts:
	AppKit/CPTextField.j
2008-10-20 16:14:09 -07:00
Ross Boucher 17ec9a0cae Add -l option to steam create 2008-10-20 16:05:43 -07:00
Ross Boucher 42a68812a9 Missing import in CPString 2008-10-20 01:56:24 -07:00
Ross Boucher 82f26fbdc0 Fix for an error in the last commit. 2008-10-20 01:17:22 -07:00
Nick TakayamaandRoss Boucher f19793f8a3 add delegate functions to CPTextField and CPControl 2008-10-20 00:57:54 -07:00
Jake MacMullinandRoss Boucher 13940ad38f Added an initial implementation of CPAlert. 2008-10-19 22:12:52 -07:00
Tom Robinson abe4dd7abc sprintf and related functions support for "%@" format specifier 2008-10-19 20:39:04 -07:00
Ross Boucher c6a2d55821 Fix for a broken exception raise in CPToolbar.
THanks terhorst for reporting the issue.

[#102 state:resolved];
2008-10-19 20:35:25 -07:00
Nick TakayamaandRoss Boucher dd56b75bd6 Better behavior for placeholder text in CPTextField.
Primarily from Nick, partially from me.

[#101 state:resolved]
2008-10-19 20:08:24 -07:00
Tom Robinson cd2a66a644 objjc now checks syntax of preprocessed code. 2008-10-18 22:42:16 -07:00
Tom Robinson 32fd299d1d Fixed encoding issue with objj console.
[#108 state:resolved responsible:tlrobinson]
2008-10-18 21:45:05 -07:00
Nick TakayamaandRoss Boucher fc9e5b3a4c implementing CPString compare: so that sorting will work with default selector 2008-10-17 14:43:43 -07:00
Francisco Ryan Tolmasky I 0ac0a84b18 Fix for CPSplitView indents its subviews by frame.origin.
[#106 state:resolved]

Reviewed by me.
2008-10-16 05:39:28 -07:00
Francisco Ryan Tolmasky I dad6d613e6 Merge branch 'master' of git@github.com:280north/cappuccino 2008-10-14 22:26:44 -07:00
Francisco Ryan Tolmasky I fd23867c93 Make sure non-static files store their fragments.
Reviewed  by me.
2008-10-14 22:23:23 -07:00
Ross Boucher 59b7c55ba2 Else protecting dom opacity access. 2008-10-13 20:11:22 -07:00
Ross Boucher 0997042dcd Performance improvement in CPView setAlphaValue: 2008-10-13 19:49:53 -07:00
Ross Boucher 847118c35b Addendum to previous commit.
Thanks to Jake MacMullin for this fix.

[#99 state:resolved]
2008-10-12 21:23:19 -07:00
Jake MacMullinandRoss Boucher 5a086243f5 Implemented missing methods on CPString:
stringByReplacingOccurrencesOfString:target withString:replacement options:options range:searchRange
stringByReplacingCharactersInRange:range withString:replacement

Signed-off-by: Jake MacMullin <jmacmullin@mac.com>
2008-10-12 21:05:56 -07:00
Ross Boucher f228934e54 Initial conversion to Doxygen style comments. 2008-10-12 15:57:01 -07:00
Ross Boucher 5404b0bbfa style guide fix 2008-10-09 23:19:00 -07:00
Ross Boucher c2b1130e23 Fix for setStringValue on CPTextField being broken if first responder.
First commit by Nick Takayama! Thanks!

[#100 state:resolved]
2008-10-09 23:15:18 -07:00
633 changed files with 43829 additions and 12432 deletions
+6
View File
@@ -0,0 +1,6 @@
.DS_Store
Frameworks
Build
Demos
Aristo
WebSite
+12
View File
@@ -0,0 +1,12 @@
[submodule "External/narwhal"]
path = External/narwhal
url = git://github.com/tlrobinson/narwhal.git
[submodule "External/jack"]
path = External/jack
url = git://github.com/tlrobinson/jack.git
[submodule "External/browserjs"]
path = External/browserjs
url = git://github.com/tlrobinson/browserjs.git
[submodule "External/ojunit"]
path = External/ojunit
url = git://github.com/280north/ojunit.git
+53 -41
View File
@@ -20,44 +20,56 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
import "CALayer.j"
import "CPAnimation.j"
import "CPApplication.j"
import "CPButton.j"
import "CPClipView.j"
import "CPCollectionView.j"
import "CPColor.j"
import "CPColorPanel.j"
import "CPColorWell.j"
import "CPCompatibility.j"
import "CPControl.j"
import "CPCookie.j"
import "CPDocument.j"
import "CPDocumentController.j"
import "CPEvent.j"
import "CPFont.j"
import "CPFontManager.j"
import "CPGeometry.j"
import "CPImage.j"
import "CPImageView.j"
import "CPMenu.j"
import "CPMenuItem.j"
import "CPPanel.j"
import "CPPasteboard.j"
import "CPPopUpButton.j"
import "CPProgressIndicator.j"
import "CPResponder.j"
import "CPScroller.j"
import "CPScrollView.j"
import "CPSecureTextField.j"
import "CPSegmentedControl.j"
import "CPShadow.j"
import "CPSlider.j"
import "CPSplitView.j"
import "CPTextField.j"
import "CPToolbar.j"
import "CPToolbarItem.j"
import "CPView.j"
import "CPWebView.j"
import "CPWindow.j"
import "CPWindowController.j"
@import "CALayer.j"
@import "CPAlert.j"
@import "CPAnimation.j"
@import "CPApplication.j"
@import "CPBezierPath.j"
@import "CPButton.j"
@import "CPButtonBar.j"
@import "CPCheckBox.j"
@import "CPCib.j"
@import "CPCibLoading.j"
@import "CPClipView.j"
@import "CPCollectionView.j"
@import "CPColor.j"
@import "CPColorPanel.j"
@import "CPColorWell.j"
@import "CPCompatibility.j"
@import "CPControl.j"
@import "CPCookie.j"
@import "CPDocument.j"
@import "CPDocumentController.j"
@import "CPEvent.j"
@import "CPFlashMovie.j"
@import "CPFlashView.j"
@import "CPFont.j"
@import "CPFontManager.j"
@import "CPGeometry.j"
@import "CPImage.j"
@import "CPImageView.j"
@import "CPMenu.j"
@import "CPMenuItem.j"
@import "CPPanel.j"
@import "CPPasteboard.j"
@import "CPPopUpButton.j"
@import "CPProgressIndicator.j"
@import "CPRadio.j"
@import "CPResponder.j"
@import "CPScrollView.j"
@import "CPScroller.j"
@import "CPSecureTextField.j"
@import "CPSegmentedControl.j"
@import "CPShadow.j"
@import "CPSlider.j"
@import "CPSplitView.j"
@import "CPTabView.j"
@import "CPTableColumn.j"
@import "CPTableView.j"
@import "CPTextField.j"
@import "CPToolbar.j"
@import "CPToolbarItem.j"
@import "CPView.j"
@import "CPWebView.j"
@import "CPWindow.j"
@import "CPWindowController.j"
-58
View File
@@ -1,58 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>name</key>
<string>AppKit</string>
<key>Targets</key>
<array>
<dict>
<key>Name</key>
<string>AppKit</string>
<key>Excluded</key>
<array>
<string>CPOutlineView.j</string>
<string>CPTableColumn.j</string>
<string>CPTableView.j</string>
</array>
<key>Flags</key>
<string>-DPLATFORM_DOM</string>
</dict>
<dict>
<key>Name</key>
<string>AppKit-Rhino</string>
<key>Excluded</key>
<array>
<string>CPOutlineView.j</string>
<string>CPTableColumn.j</string>
<string>CPTableView.j</string>
</array>
</dict>
</array>
<key>Configurations</key>
<array>
<dict>
<key>Name</key>
<string>Debug</string>
<key>Flags</key>
<string>-DDEBUG</string>
<key>Settings</key>
<dict>
<key>PREPROCESS</key>
<true/>
</dict>
</dict>
<dict>
<key>Name</key>
<string>Release</string>
<key>Settings</key>
<dict>
<key>PREPROCESS</key>
<true/>
<key>PREINTERPRET</key>
<true/>
</dict>
</dict>
</array>
</dict>
</plist>
+308
View File
@@ -0,0 +1,308 @@
/*
* CPAlert.j
* AppKit
*
* Created by Jake MacMullin.
* Copyright 2008, Jake MacMullin.
*
* 11/10/2008 Ross Boucher
* - Make it conform to style guidelines, general cleanup and ehancements
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import <Foundation/CPObject.j>
@import <Foundation/CPString.j>
@import <AppKit/CPApplication.j>
@import <AppKit/CPButton.j>
@import <AppKit/CPColor.j>
@import <AppKit/CPFont.j>
@import <AppKit/CPImage.j>
@import <AppKit/CPImageView.j>
@import <AppKit/CPPanel.j>
@import <AppKit/CPTextField.j>
/*
@global
@group CPAlertStyle
*/
CPWarningAlertStyle = 0;
/*
@global
@group CPAlertStyle
*/
CPInformationalAlertStyle = 1;
/*
@global
@group CPAlertStyle
*/
CPCriticalAlertStyle = 2;
var CPAlertWarningImage,
CPAlertInformationImage,
CPAlertErrorImage;
/*!
@ingroup appkit
CPAlert is an alert panel that can be displayed modally to present the
user with a message and one or more options.
It can be used to display an information message (<pre>CPInformationalAlertStyle</pre>),
a warning message (<pre>CPWarningAlertStyle</pre> - which is the default), or a critical
alert (<pre>CPCriticalAlertStyle</pre>). In each case the user can be presented with one
or more options by adding buttons using the <pre>addButtonWithTitle:</pre> method.
The panel is displayed modally by calling <pre>runModal</pre> and once the user has
dismissed the panel, a message will be sent to the panel's delegate (if set), informing
it which button was clicked (see delegate methods).
@delegate -(void)alertDidEnd:(CPAlert)theAlert returnCode:(int)returnCode;
Called when the user dismisses the alert by clicking one of the buttons.
@param theAlert the alert panel that the user dismissed
@param returnCode the index of the button that the user clicked (starting from 0,
representing the first button added to the alert which appears on the
right, 1 representing the next button to the left and so on)
*/
@implementation CPAlert : CPObject
{
CPPanel _alertPanel;
CPTextField _messageLabel;
CPImageView _alertImageView;
CPAlertStyle _alertStyle;
CPString _windowTitle;
int _windowStyle;
int _buttonCount;
CPArray _buttons;
id _delegate;
}
+ (void)initialize
{
if (self != CPAlert)
return;
var bundle = [CPBundle bundleForClass:[self class]];
CPAlertWarningImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPAlert/dialog-warning.png"]
size:CGSizeMake(32.0, 32.0)];
CPAlertInformationImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPAlert/dialog-information.png"]
size:CGSizeMake(32.0, 32.0)];
CPAlertErrorImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPAlert/dialog-error.png"]
size:CGSizeMake(32.0, 32.0)];
}
/*!
Initializes a <pre>CPAlert</pre> panel with the default alert style (<pre>CPWarningAlertStyle</pre>).
*/
- (id)init
{
self = [super init];
if (self)
{
_buttonCount = 0;
_buttons = [CPArray array];
_alertStyle = CPWarningAlertStyle;
_messageLabel = [[CPTextField alloc] initWithFrame:CGRectMake(57.0, 10.0, 220.0, 80.0)];
[_messageLabel setFont:[CPFont systemFontOfSize:12.0]];
[_messageLabel setLineBreakMode:CPLineBreakByWordWrapping];
[_messageLabel setAlignment:CPJustifiedTextAlignment];
_alertImageView = [[CPImageView alloc] initWithFrame:CGRectMake(15.0, 12.0, 32.0, 32.0)];
[self setWindowStyle:nil];
}
return self;
}
/*!
Sets the window appearance.
@param styleMask - Either CPHUDBackgroundWindowMask or nil for standard.
*/
- (void)setWindowStyle:(int)styleMask
{
_windowStyle = styleMask;
_alertPanel = [[CPPanel alloc] initWithContentRect:CGRectMake(0.0, 0.0, 300.0, 130.0) styleMask:styleMask ? styleMask | CPTitledWindowMask : CPTitledWindowMask];
[_alertPanel setFloatingPanel:YES];
[_alertPanel center];
[_messageLabel setTextColor:(styleMask == CPHUDBackgroundWindowMask) ? [CPColor whiteColor] : [CPColor blackColor]];
var count = [_buttons count];
for(var i=0; i < count; i++)
{
var button = _buttons[i];
[button setFrameSize:CGSizeMake([button frame].size.width, (styleMask == CPHUDBackgroundWindowMask) ? 20.0 : 24.0)];
[button setBezelStyle:(styleMask == CPHUDBackgroundWindowMask) ? CPHUDBezelStyle : CPRoundedBezelStyle];
[[_alertPanel contentView] addSubview:button];
}
[[_alertPanel contentView] addSubview:_messageLabel];
[[_alertPanel contentView] addSubview:_alertImageView];
}
/*!
Sets the window's title. If this is not defined, a default title based on your warning level will be used.
@param aTitle the title to use in place of the default. Set to nil to use default.
*/
- (void)setTitle:(CPString)aTitle
{
_windowTitle = aTitle;
}
/*!
Gets the window's title.
*/
- (CPString)title
{
return _windowTitle;
}
/*!
Gets the window's style.
*/
- (int)windowStyle
{
return _windowStyle;
}
/*!
Sets the receivers delegate.
@param delegate - Delegate for the alert. nil removes the delegate.
*/
- (void)setDelegate:(id)delegate
{
_delegate = delegate;
}
/*!
Gets the receiver's delegate.
*/
- (void)delegate
{
return _delegate;
}
/*!
Sets the alert style of the receiver.
@param style - Alert style for the alert.
*/
- (void)setAlertStyle:(CPAlertStyle)style
{
_alertStyle = style;
}
/*!
Gets the alert style.
*/
- (CPAlertStyle)alertStyle
{
return _alertStyle;
}
/*!
Sets the receivers message text, or title, to a given text.
@param messageText - Message text for the alert.
*/
- (void)setMessageText:(CPString)messageText
{
[_messageLabel setStringValue:messageText];
}
/*!
Return's the receiver's message text body.
*/
- (CPString)messageText
{
return [_messageLabel stringValue];
}
/*!
Adds a button with a given title to the receiver.
Buttons will be added starting from the right hand side of the <pre>CPAlert</pre> panel.
The first button will have the index 0, the second button 1 and so on.
You really shouldn't need more than 3 buttons.
*/
- (void)addButtonWithTitle:(CPString)title
{
var button = [[CPButton alloc] initWithFrame:CGRectMake(200.0 - (_buttonCount * 90.0), 98.0, 80.0, (_windowStyle == CPHUDBackgroundWindowMask) ? 20.0 : 24.0)];
[button setTitle:title];
[button setTarget:self];
[button setTag:_buttonCount];
[button setAction:@selector(_notifyDelegate:)];
[button setBezelStyle:(_windowStyle == CPHUDBackgroundWindowMask) ? CPHUDBezelStyle : CPRoundRectBezelStyle];
[[_alertPanel contentView] addSubview:button];
if (_buttonCount == 0)
[_alertPanel setDefaultButton:button];
_buttonCount++;
[_buttons addObject:button];
}
/*!
Displays the <pre>CPAlert</pre> panel as a modal dialog. The user will not be
able to interact with any other controls until s/he has dismissed the alert
by clicking on one of the buttons.
*/
- (void)runModal
{
var theTitle;
switch (_alertStyle)
{
case CPWarningAlertStyle: [_alertImageView setImage:CPAlertWarningImage];
theTitle = @"Warning";
break;
case CPInformationalAlertStyle: [_alertImageView setImage:CPAlertInformationImage];
theTitle = @"Information";
break;
case CPCriticalAlertStyle: [_alertImageView setImage:CPAlertErrorImage];
theTitle = @"Error";
break;
}
[_alertPanel setTitle:_windowTitle ? _windowTitle : theTitle];
[CPApp runModalForWindow:_alertPanel];
}
/* @ignore */
- (void)_notifyDelegate:(id)button
{
if (_delegate && [_delegate respondsToSelector:@selector(alertDidEnd:returnCode:)])
[_delegate alertDidEnd:self returnCode:[button tag]];
[CPApp abortModal];
[_alertPanel close];
}
@end
+44 -37
View File
@@ -20,9 +20,10 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
import <Foundation/CPObject.j>
@import <Foundation/CPObject.j>
@import "CAMediaTimingFunction.j"
import "CAMediaTimingFunction.j"
/*
@global
@@ -47,9 +48,14 @@ CPAnimationLinear = 3;
ACTUAL_FRAME_RATE = 0;
/*
/*!
@ingroup appkit
@class CPAnimation
Manages an animation. Contains timing and progress information.
@par Delegate Methods
@delegate -(BOOL)animationShouldStart:(CPAnimation)animation;
Called at the beginning of <code>startAnimation</code>.
@param animation the animation that will start
@@ -65,7 +71,7 @@ ACTUAL_FRAME_RATE = 0;
@param animation the animation that was stopped
@delegate - (float)animation:(CPAnimation)animation valueForProgress:(float)progress;
The value from this method will be returned when <objj>CPAnimation</objj>'s
The value from this method will be returned when CPAnimation's
<code>currentValue</code> method is called.
@param animation the animation to obtain the curve value for
@param progress the current animation progress
@@ -73,7 +79,7 @@ ACTUAL_FRAME_RATE = 0;
*/
@implementation CPAnimation : CPObject
{
CPTimeInterval _startTime;
CPTimeInterval _lastTime;
CPTimeInterval _duration;
CPAnimationCurve _animationCurve;
@@ -86,7 +92,7 @@ ACTUAL_FRAME_RATE = 0;
CPTimer _timer;
}
/*
/*!
Initializes the animation with a duration and animation curve.
@param aDuration the length of the animation
@param anAnimationCurve defines the animation's pace
@@ -98,6 +104,7 @@ ACTUAL_FRAME_RATE = 0;
if (self)
{
_progress = 0.0;
_duration = MAX(0.0, aDuration);
_animationCurve = anAnimationCurve;
_frameRate = 60.0;
@@ -106,17 +113,13 @@ ACTUAL_FRAME_RATE = 0;
return self;
}
/*
/*!
Sets the animation's pace.
@param anAnimationCurve the animation's pace
@throws CPInvalidArgumentException if an invalid animation curve is specified
*/
- (void)setAnimationCurve:(CPAnimationCurve)anAnimationCurve
{
_animationCurve = anAnimationCurve;
var timingFunctionName = kCAMediaTimingFunctionLinear;
switch (_animationCurve)
{
case CPAnimationEaseInOut: timingFunctionName = kCAMediaTimingFunctionEaseInEaseOut;
@@ -127,16 +130,20 @@ ACTUAL_FRAME_RATE = 0;
case CPAnimationEaseOut: timingFunctionName = kCAMediaTimingFunctionEaseOut;
break;
case CPAnimationLinear: timingFunctionName = kCAMediaTimingFunctionLinear;
break;
default: [CPException raise:CPInvalidArgumentException
reason:"Invalid value provided for animation curve"];
break;
}
_animationCurve = anAnimationCurve;
_timingFunction = [CAMediaTimingFunction functionWithName:timingFunctionName];
}
/*
/*!
Returns the animation's pace
*/
- (CPAnimationCurve)animationCurve
@@ -144,7 +151,7 @@ ACTUAL_FRAME_RATE = 0;
return _animationCurve;
}
/*
/*!
Sets the animation's length.
@param aDuration the new animation length
@throws CPInvalidArgumentException if <code>aDuration</code> is negative
@@ -157,7 +164,7 @@ ACTUAL_FRAME_RATE = 0;
_duration = aDuration;
}
/*
/*!
Returns the length of the animation.
*/
- (CPTimeInterval)duration
@@ -165,7 +172,7 @@ ACTUAL_FRAME_RATE = 0;
return _duration;
}
/*
/*!
Sets the animation frame rate. This is not a guaranteed frame rate. 0 means to go as fast as possible.
@param frameRate the new desired frame rate
@throws CPInvalidArgumentException if <code>frameRate</code> is negative
@@ -178,7 +185,7 @@ ACTUAL_FRAME_RATE = 0;
_frameRate = frameRate;
}
/*
/*!
Returns the desired frame rate.
*/
- (float)frameRate
@@ -186,7 +193,7 @@ ACTUAL_FRAME_RATE = 0;
return _frameRate;
}
/*
/*!
Returns the animation's delegate
*/
- (id)delegate
@@ -194,7 +201,7 @@ ACTUAL_FRAME_RATE = 0;
return _delegate;
}
/*
/*!
Sets the animation's delegate.
@param aDelegate the new delegate
*/
@@ -203,7 +210,7 @@ ACTUAL_FRAME_RATE = 0;
_delegate = aDelegate;
}
/*
/*!
Starts the animation. The method calls <code>animationShouldStart:</code>
on the delegate (if it implements it) to see if the animation
should begin.
@@ -214,14 +221,13 @@ ACTUAL_FRAME_RATE = 0;
if (_timer || _delegate && [_delegate respondsToSelector:@selector(animationShouldStart)] && ![_delegate animationShouldStart:self])
return;
_progress = 0.0;
if (_progress === 1.0)
_progress = 0.0;
ACTUAL_FRAME_RATE = 0;
_startTime = new Date();
// FIXME: THIS SHOULD BE A CPTIMER!!!
_timer = window.setInterval(function() {
[self animationTimerDidFire:_timer];
[[CPRunLoop currentRunLoop] performSelectors];
}, 1); // must be 1ms not 0 for IE. //_duration * 1000 / _frameRate);
_lastTime = new Date();
_timer = [CPTimer scheduledTimerWithTimeInterval:0.0 target:self selector:@selector(animationTimerDidFire:) userInfo:nil repeats:YES];
}
/*
@@ -229,25 +235,26 @@ ACTUAL_FRAME_RATE = 0;
*/
- (void)animationTimerDidFire:(CPTimer)aTimer
{
var elapsed = new Date() - _startTime,
progress = MIN(1.0, 1.0 - (_duration - elapsed / 1000.0) / _duration);
var currentTime = new Date(),
progress = MIN(1.0, [self currentProgress] + (currentTime - _lastTime) / (_duration * 1000.0));
_lastTime = currentTime;
++ACTUAL_FRAME_RATE;
[self setCurrentProgress:progress];
if (progress == 1.0)
if (progress === 1.0)
{
window.clearTimeout(_timer);
[_timer invalidate];
_timer = nil;
if ([_delegate respondsToSelector:@selector(animationDidEnd:)])
[_delegate animationDidEnd:self];
}
}
/*
/*!
Stops the animation before it has completed.
*/
- (void)stopAnimation
@@ -255,14 +262,14 @@ ACTUAL_FRAME_RATE = 0;
if (!_timer)
return;
window.clearTimeout(_timer);
[_timer invalidate];
_timer = nil;
if ([_delegate respondsToSelector:@selector(animationDidStop:)])
[_delegate animationDidStop:self];
}
/*
/*!
Returns <code>YES</code> if the animation
is running.
*/
@@ -271,7 +278,7 @@ ACTUAL_FRAME_RATE = 0;
return _timer;
}
/*
/*!
Sets the animation's progress.
@param aProgress the animation's progress
*/
@@ -280,7 +287,7 @@ ACTUAL_FRAME_RATE = 0;
_progress = aProgress;
}
/*
/*!
Returns the animation's progress
*/
- (float)currentProgress
@@ -288,7 +295,7 @@ ACTUAL_FRAME_RATE = 0;
return _progress;
}
/*
/*!
Returns the animation's timing progress.
*/
- (float)currentValue
+184 -66
View File
@@ -20,13 +20,17 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
import <Foundation/CPBundle.j>
@import <Foundation/CPBundle.j>
import "CPCompatibility.j"
import "CPEvent.j"
import "CPMenu.j"
import "CPResponder.j"
import "CPDocumentController.j"
@import "CPCompatibility.j"
@import "CPEvent.j"
@import "CPMenu.j"
@import "CPResponder.j"
@import "CPDocumentController.j"
@import "CPThemeBlend.j"
var CPMainCibFile = @"CPMainCibFile",
CPMainCibFileHumanFriendly = @"Main cib file base name";
CPApp = nil;
@@ -37,7 +41,10 @@ CPRunStoppedResponse = -1000;
CPRunAbortedResponse = -1001;
CPRunContinuesResponse = -1002;
/*
/*!
@ingroup appkit
@class CPApplication
CPApplication is THE way to start up the Cappucino framework for your application to use.
Every GUI application has exactly one instance of CPApplication (or of a custom subclass of
CPApplication). Your program's main() function can create that instance by calling the
@@ -79,9 +86,10 @@ CPRunContinuesResponse = -1002;
CPDictionary _namedArgs;
CPArray _args;
CPString _fullArgsString;
}
/*
/*!
Returns the singleton instance of the running application. If it
doesn't exist, it will be created, and then returned.
@return the application singleton
@@ -94,7 +102,7 @@ CPRunContinuesResponse = -1002;
return CPApp;
}
/*
/*!
Initializes the Document based application with basic menu functions.
Functions are <code>New, Open, Undo, Redo, Save, Cut, Copy, Paste</code>.
@return the initialized application
@@ -133,19 +141,19 @@ CPRunContinuesResponse = -1002;
[_mainMenu addItem:openMenuItem];
var saveMenu = [[CPMenu alloc] initWithTitle:@"Save"],
saveMenuItem = [[CPMenuItem alloc] initWithTitle:@"Save" action:@selector(saveDocument:) keyEquivalent:@""];
saveMenuItem = [[CPMenuItem alloc] initWithTitle:@"Save" action:@selector(saveDocument:) keyEquivalent:nil];
[saveMenuItem setImage:[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPApplication/Save.png"] size:CGSizeMake(16.0, 16.0)]];
[saveMenuItem setAlternateImage:[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPApplication/SaveHighlighted.png"] size:CGSizeMake(16.0, 16.0)]];
[saveMenu addItem:[[CPMenuItem alloc] initWithTitle:@"Save" action:@selector(saveDocument:) keyEquivalent:@"S"]];
[saveMenu addItem:[[CPMenuItem alloc] initWithTitle:@"Save As" action:@selector(saveDocumentAs:) keyEquivalent:@""]];
[saveMenu addItem:[[CPMenuItem alloc] initWithTitle:@"Save As" action:@selector(saveDocumentAs:) keyEquivalent:nil]];
[saveMenuItem setSubmenu:saveMenu];
[_mainMenu addItem:saveMenuItem];
var editMenuItem = [[CPMenuItem alloc] initWithTitle:@"Edit" action:nil keyEquivalent:@""],
var editMenuItem = [[CPMenuItem alloc] initWithTitle:@"Edit" action:nil keyEquivalent:nil],
editMenu = [[CPMenu alloc] initWithTitle:@"Edit"],
undoMenuItem = [[CPMenuItem alloc] initWithTitle:@"Undo" action:@selector(undo:) keyEquivalent:CPUndoKeyEquivalent],
@@ -174,7 +182,7 @@ CPRunContinuesResponse = -1002;
// Configuring Applications
/*
/*!
Sets the delegate for this application. The delegate will receive various notifications
caused by user interactions during the application's run. The delegate can choose to
react to these events.
@@ -217,7 +225,7 @@ CPRunContinuesResponse = -1002;
object:self];
}
/*
/*!
Returns the application's delegate. The app can only have one delegate at a time.
*/
- (id)delegate
@@ -225,10 +233,10 @@ CPRunContinuesResponse = -1002;
return _delegate;
}
/*
/*!
This method is called by <code>run</code> before the event loop begins.
When it successfully completes, it posts the notification
<objj>CPApplicationDidFinishLaunchingNotification</objj>. If you override
CPApplicationDidFinishLaunchingNotification. If you override
<code>finishLaunching</code>, the subclass method should invoke the superclass method.
*/
- (void)finishLaunching
@@ -265,10 +273,10 @@ CPRunContinuesResponse = -1002;
postNotificationName:CPApplicationDidFinishLaunchingNotification
object:self];
[[CPRunLoop currentRunLoop] performSelectors];
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
}
/*
/*!
Calls <code>finishLaunching</code> method which results in starting
the main event loop.
*/
@@ -278,7 +286,7 @@ CPRunContinuesResponse = -1002;
}
// Managing the Event Loop
/*
/*!
Starts a modal event loop for <code>aWindow</code>
@param aWindow the window to start the event loop for
*/
@@ -287,7 +295,7 @@ CPRunContinuesResponse = -1002;
[self runModalSession:[self beginModalSessionForWindow:aWindow]];
}
/*
/*!
Stops the event loop started by <code>runModalForWindow:</code> and
sets the code that <code>runModalForWindow:</code> will return.
@param aCode the return code for the modal event
@@ -303,7 +311,7 @@ CPRunContinuesResponse = -1002;
_currentSession._state = aCode;
_currentSession = _currentSession._previous;
if (aCode == CPRunAbortedResponse)
// if (aCode == CPRunAbortedResponse)
[self _removeRunModalLoop];
}
@@ -313,7 +321,7 @@ CPRunContinuesResponse = -1002;
var count = _eventListeners.length;
while (count--)
if (_eventListeners[count]._callback == _CPRunModalLoop)
if (_eventListeners[count]._callback === _CPRunModalLoop)
{
_eventListeners.splice(count, 1);
@@ -321,7 +329,7 @@ CPRunContinuesResponse = -1002;
}
}
/*
/*!
Stops the modal event loop
*/
- (void)stopModal
@@ -329,7 +337,7 @@ CPRunContinuesResponse = -1002;
[self stopModalWithCode:CPRunStoppedResponse]
}
/*
/*!
Aborts the event loop started by <code>runModalForWindow:</code>
*/
- (void)abortModal
@@ -337,7 +345,7 @@ CPRunContinuesResponse = -1002;
[self stopModalWithCode:CPRunAbortedResponse];
}
/*
/*!
Sets up a modal session with <code>theWindow</code>.
@param aWindow the window to set up the modal session for
*/
@@ -346,7 +354,7 @@ CPRunContinuesResponse = -1002;
return _CPModalSessionMake(aWindow, 0);
}
/*
/*!
Runs a modal session
@param CPModalSession the session to run
*/
@@ -365,7 +373,7 @@ CPRunContinuesResponse = -1002;
[CPApp setCallback:_CPRunModalLoop forNextEventMatchingMask:CPAnyEventMask untilDate:nil inMode:0 dequeue:NO];
}
/*
/*!
Returns the window for the current modal session. If there is no
modal session, it returns <code>nil</code>.
*/
@@ -386,7 +394,7 @@ CPRunContinuesResponse = -1002;
return NO;
}
/*
/*!
Dispatches events to other objects.
@param anEvent the event to dispatch
*/
@@ -418,7 +426,7 @@ CPRunContinuesResponse = -1002;
[super doCommandBySelector:aSelector];
}
/*
/*!
Returns the key window.
*/
- (CPWindow)keyWindow
@@ -426,7 +434,7 @@ CPRunContinuesResponse = -1002;
return _keyWindow;
}
/*
/*!
Returns the main window.
*/
- (CPWindow)mainWindow
@@ -434,16 +442,16 @@ CPRunContinuesResponse = -1002;
return _mainWindow;
}
/*
Returns the <objj>CPWindow</objj> object corresponding to <code>aWindowNumber</code>.
/*!
Returns the CPWindow object corresponding to <code>aWindowNumber</code>.
*/
- (CPWindow)windowWithWindowNumber:(int)aWindowNumber
{
return _windows[aWindowNumber];
}
/*
Returns an array of the application's <objj>CPWindow</objj>s
/*!
Returns an array of the application's CPWindows
*/
- (CPArray)windows
{
@@ -451,7 +459,7 @@ CPRunContinuesResponse = -1002;
}
// Accessing the Main Menu
/*
/*!
Returns the application's main menu
*/
- (CPMenu)mainMenu
@@ -459,7 +467,7 @@ CPRunContinuesResponse = -1002;
return _mainMenu;
}
/*
/*!
Sets the main menu for the application
@param aMenu the menu to set for the application
*/
@@ -468,8 +476,23 @@ CPRunContinuesResponse = -1002;
_mainMenu = aMenu;
}
- (void)orderFrontColorPanel:(id)aSender
{
[[CPColorPanel sharedColorPanel] orderFront:self];
}
- (void)orderFrontStandardAboutPanel:(id)aSender
{
[self orderFrontStandardAboutPanelWithOptions:nil];
}
- (void)orderFrontStandardAboutPanelWithOptions:(CPDictionary)aDictionary
{
// FIXME: Implement.
}
// Posting Actions
/*
/*!
Tries to perform the action with an argument. Performs
the action on itself (if it responds to it), then
tries to perform the action on the delegate.
@@ -483,12 +506,12 @@ CPRunContinuesResponse = -1002;
if (!anAction)
return NO;
if ([self tryToPerform:anAction with:anObject])
if ([super tryToPerform:anAction with:anObject])
return YES;
if([_delegate respondsToSelector:aSelector])
if([_delegate respondsToSelector:anAction])
{
[_delegate performSelector:aSelector withObject:anObject];
[_delegate performSelector:anAction withObject:anObject];
return YES;
}
@@ -496,7 +519,7 @@ CPRunContinuesResponse = -1002;
return NO;
}
/*
/*!
Sends an action to a target.
@param anAction the action to send
@param aTarget the target for the action
@@ -515,7 +538,7 @@ CPRunContinuesResponse = -1002;
return YES;
}
/*
/*!
Finds a target for the specified action. If the
action is <code>nil</code>, returns <code>nil</code>.
If the target is not <code>nil</code>, <code>aTarget</code> is
@@ -537,7 +560,7 @@ CPRunContinuesResponse = -1002;
return [self targetForAction:anAction];
}
/*
/*!
Finds an action-target for a specified window.
It finds a matching target in the following order:
<ol>
@@ -591,13 +614,13 @@ CPRunContinuesResponse = -1002;
return nil;
}
/*
/*!
Looks for a target that can handle the specified action.
Checks for a target in the following order:
<ol>
<li>a responder from the key window</li>
<li>a responder frmo the main window</li>
<li>the <objj>CPApplication</objj> instance</li>
<li>the CPApplication instance</li>
<li>the application delegate</li>
<li>the document controller</li>
</ol>
@@ -646,7 +669,7 @@ CPRunContinuesResponse = -1002;
// Managing Sheets
/*
/*!
Displays a window as a sheet.
@param aSheet the window to display as a sheet
@param aWindow the window that will hold the sheet as a child
@@ -661,9 +684,47 @@ CPRunContinuesResponse = -1002;
- (CPArray)arguments
{
if(_fullArgsString != window.location.hash)
[self _reloadArguments];
return _args;
}
- (void)setArguments:(CPArray)args
{
if(!args || args.length == 0)
{
_args = [];
window.location.hash = @"#";
return;
}
if([args class] != CPArray)
args = [CPArray arrayWithObject:args];
_args = args;
var toEncode = [_args copy];
for(var i=0, count = toEncode.length; i<count; i++)
toEncode[i] = encodeURIComponent(toEncode[i]);
var hash = [toEncode componentsJoinedByString:@"/"];
window.location.hash = @"#" + hash;
}
- (void)_reloadArguments
{
_fullArgsString = window.location.hash;
var args = _fullArgsString.replace("#", "").split("/").slice(0);
for(var i=0, count = args.length; i<count; i++)
args[i] = decodeURIComponent(args[i]);
_args = args;
}
- (CPDictionary)namedArguments
{
return _namedArgs;
@@ -684,51 +745,41 @@ var _CPEventListenerMake = function(anEventMask, aCallback)
var _CPRunModalLoop = function(anEvent)
{
[CPApp setCallback:_CPRunModalLoop forNextEventMatchingMask:CPAnyEventMask untilDate:nil inMode:0 dequeue:NO];
// FIXME: abortModal from event loop?
var theWindow = [anEvent window],
modalSession = CPApp._currentSession;
if (theWindow == modalSession._window || [theWindow worksWhenModal])
[theWindow sendEvent:anEvent];
/*else
[[session modalWindow] makeKeyAndOrderFront:]*/
if (modalSession._state != CPRunContinuesResponse)
[CPApp _removeRunModalLoop];
}
/*
/*!
Starts the GUI and Cappuccino frameworks. This function should be
called from the <code>main()</code> function of your program.
@class CPApplication
@return void
*/
function CPApplicationMain(args, namedArgs)
{
var mainBundle = [CPBundle mainBundle],
principalClass = [mainBundle principalClass];
if (!principalClass)
principalClass = [CPApplication class];
[principalClass sharedApplication];
//[NSBundle loadNibNamed:@"myMain" owner:NSApp];
//FIXME?
if (!args && !namedArgs)
{
var args = window.location.hash.replace("#", "").split("/").slice(0),
var args = [CPApp arguments],
searchParams = window.location.search.substring(1).split("&");
namedArgs = [CPDictionary dictionary];
for(var i=0, count = args.length; i<count; i++)
args[i] = decodeURIComponent(args[i]);
if([args containsObject:"debug"])
CPLogRegister(CPLogPopup);
for(var i=0; i<searchParams.length; i++)
{
var index = searchParams[i].indexOf('=');
@@ -738,9 +789,76 @@ function CPApplicationMain(args, namedArgs)
[namedArgs setObject: searchParams[i].substring(index+1) forKey: searchParams[i].substring(0, index)];
}
}
CPApp._args = args;
CPApp._namedArgs = namedArgs;
[_CPAppBootstrapper performActions];
}
var _CPAppBootstrapperActions = nil;
@implementation _CPAppBootstrapper : CPObject
{
}
+ (void)actions
{
return [@selector(loadDefaultTheme), @selector(loadMainCibFile)];
}
+ (void)performActions
{
if (!_CPAppBootstrapperActions)
_CPAppBootstrapperActions = [self actions];
while (_CPAppBootstrapperActions.length)
{
var action = _CPAppBootstrapperActions.shift();
if (objj_msgSend(self, action))
return;
}
[CPApp run];
}
+ (BOOL)loadDefaultTheme
{
var blend = [[CPThemeBlend alloc] initWithContentsOfURL:[[CPBundle bundleForClass:[CPApplication class]] pathForResource:@"Aristo.blend"]];
[blend loadWithDelegate:self];
return YES;
}
+ (void)blendDidFinishLoading:(CPBundle)aBundle
{
[CPTheme setDefaultTheme:[CPTheme themeNamed:@"Aristo"]];
[self performActions];
}
+ (BOOL)loadMainCibFile
{
var mainBundle = [CPBundle mainBundle],
mainCibFile = [mainBundle objectForInfoDictionaryKey:CPMainCibFile] || [mainBundle objectForInfoDictionaryKey:CPMainCibFileHumanFriendly];
if (mainCibFile)
{
[mainBundle loadCibFile:mainCibFile
externalNameTable:[CPDictionary dictionaryWithObject:CPApp forKey:CPCibOwner]
loadDelegate:self];
return YES;
}
return NO;
}
+ (void)cibDidFinishLoading:(CPCib)aCib
{
[self performActions];
}
@end
+214
View File
@@ -0,0 +1,214 @@
/*
* CPBezierPath.j
*
* Created by Ross Boucher.
* Copyright 2009, 280 North, Inc.
*
* Adapted from Kevin Wojniak, portions Copyright 2009 Kevin Wojniak.
*
* 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
* Copyright 2009 280 North, Inc.
*/
@import <AppKit/CPGraphicsContext.j>
@import <Foundation/CPObject.j>
// Class defaults
var DefaultLineWidth = 1.0;
/*!
@ingroup appkit
@class CPBezierPath
A CPBezierPath allows you to create paths for drawing to the screen using a simpler API than CoreGraphics.
Paths can form any shape, including regular polgyons like squares and triangles; circles, arcs; or complex
line segments.
A path can be stroked and filled using the relevant method. The currently active fill and stroke color will
be used, which can be set by calling setFill: and setStroke: on any CPColor object (or set: for both).
*/
@implementation CPBezierPath : CPObject
{
CGPath _path;
float _lineWidth;
}
+ (CPBezierPath)bezierPath
{
return [[[self class] alloc] init];
}
+ (CPBezierPath)bezierPathWithOvalInRect:(CGRect)rect
{
var path = [[self class] bezierPath];
[path appendBezierPathWithOvalInRect:rect];
return path;
}
+ (CPBezierPath)bezierPathWithRect:(CGRect)rect
{
var path = [[self class] bezierPath];
[path appendBezierPathWithRect:rect];
return path;
}
+ (float)defaultLineWidth
{
return DefaultLineWidth;
}
+ (void)setDefaultLineWidth:(float)width
{
DefaultLineWidth = width;
}
+ (void)fillRect:(CGRect)rect
{
[[[self class] bezierPathWithRect:rect] fill];
}
+ (void)strokeRect:(CGRect)rect
{
[[[self class] bezierPathWithRect:rect] stroke];
}
+ (void)strokeLineFromPoint:(CGPoint)point1 toPoint:(CGPoint)point2
{
var path = [[self class] bezierPath];
[path moveToPoint:point1];
[path lineToPoint:point2];
[path stroke];
}
- (id)init
{
if (self = [super init])
{
_path = CGPathCreateMutable();
_lineWidth = [[self class] defaultLineWidth];
}
return self;
}
- (void)moveToPoint:(CGPoint)point
{
CGPathMoveToPoint(_path, nil, point.x, point.y);
}
- (void)lineToPoint:(CGPoint)point
{
CGPathAddLineToPoint(_path, nil, point.x, point.y);
}
- (void)curveToPoint:(CGPoint)endPoint controlPoint1:(CGPoint)controlPoint1 controlPoint2:(CGPoint)controlPoint2
{
CGPathAddCurveToPoint(_path, nil, controlPoint1.x, controlPoint1.y, controlPoint2.x, controlPoint2.y, endPoint.x, endPoint.y);
}
- (void)closePath
{
CGPathCloseSubpath(_path);
}
- (void)stroke
{
var ctx = [[CPGraphicsContext currentContext] graphicsPort];
CGContextBeginPath(ctx);
CGContextAddPath(ctx, _path);
CGContextSetLineWidth(ctx, [self lineWidth]);
CGContextClosePath(ctx);
CGContextStrokePath(ctx);
}
- (void)fill
{
var ctx = [[CPGraphicsContext currentContext] graphicsPort];
CGContextBeginPath(ctx);
CGContextAddPath(ctx, _path);
CGContextSetLineWidth(ctx, [self lineWidth]);
CGContextClosePath(ctx);
CGContextFillPath(ctx);
}
- (float)lineWidth
{
return _lineWidth;
}
- (void)setLineWidth:(float)lineWidth
{
_lineWidth = lineWidth;
}
- (unsigned)elementCount
{
return _path.count;
}
- (BOOL)isEmpty
{
return CGPathIsEmpty(_path);
}
- (CGPoint)currentPoint
{
return CGPathGetCurrentPoint(_path);
}
- (void)appendBezierPathWithPoints:(CPArray)points count:(unsigned)count
{
CGPathAddLines(_path, nil, points, count);
}
- (void)appendBezierPathWithRect:(CGRect)rect
{
CGPathAddRect(_path, nil, rect);
}
- (void)appendBezierPathWithOvalInRect:(CGRect)rect
{
CGPathAddPath(_path, nil, CGPathWithEllipseInRect(rect));
}
- (void)appendBezierPathWithRoundedRect:(CGRect)rect xRadius:(float)xRadius yRadius:(float)yRadius
{
CGPathAddPath(_path, nil, CGPathWithRoundedRectangleInRect(rect, xRadius, yRadius, YES, YES, YES, YES));
}
- (void)appendBezierPath:(NSBezierPath *)other
{
CGPathAddPath(_path, nil, other._path);
}
- (void)removeAllPoints
{
_path = CGPathCreateMutable();
}
@end
+415 -653
View File
File diff suppressed because it is too large Load Diff
+61
View File
@@ -0,0 +1,61 @@
@import <AppKit/CPView.j>
#include "CoreGraphics/CGGeometry.h"
@implementation CPButtonBar : CPControl
{
}
+ (CPString)themeClass
{
return @"button-bar";
}
+ (id)themeAttributes
{
return [CPDictionary dictionaryWithObjects:[nil]
forKeys:[@"bezel-color"]];
}
- (CGRect)rectForEphemeralSubviewNamed:(CPString)aName
{
if (aName === "bezel-view")
return [self bounds];
return [super rectForEphemeralSubviewNamed:aName];
}
- (CPView)createEphemeralSubviewNamed:(CPString)aName
{
if (aName === "bezel-view")
{
var view = [[CPView alloc] initWithFrame:_CGRectMakeZero()];
[view setHitTests:NO];
return view;
}
return [super createEphemeralSubviewNamed:aName];
}
- (void)layoutSubviews
{
var bezelView = [self layoutEphemeralSubviewNamed:@"bezel-view"
positioned:CPWindowBelow
relativeToEphemeralSubviewNamed:@""];
if (bezelView)
[bezelView setBackgroundColor:[self currentValueForThemeAttribute:@"bezel-color"]];
}
- (void)addSubview:(CPView)aSubview
{
[super addSubview:aSubview];
[aSubview setAutoresizingMask:CPViewMinXMargin];
}
@end
+64
View File
@@ -0,0 +1,64 @@
/*
* CPCheckBox.j
* AppKit
*
* Created by Francisco Tolmasky.
* Copyright 2009, 280 North, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "CPButton.j"
@implementation CPCheckBox : CPButton
{
}
+ (id)checkBoxWithTitle:(CPString)aTitle theme:(CPTheme)aTheme
{
return [self buttonWithTitle:aTitle theme:aTheme];
}
+ (id)checkBoxWithTitle:(CPString)aTitle
{
return [self buttonWithTitle:aTitle];
}
+ (CPString)themeClass
{
return @"check-box";
}
- (id)initWithFrame:(CGRect)aFrame
{
self = [super initWithFrame:aFrame];
if (self)
{
[self setHighlightsBy:CPContentsCellMask];
[self setShowsStateBy:CPContentsCellMask];
// Defaults?
[self setImagePosition:CPImageLeft];
[self setAlignment:CPLeftTextAlignment];
[self setBordered:YES];
}
return self;
}
@end
+69 -16
View File
@@ -20,20 +20,24 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
import "CPView.j"
@import "CPView.j"
#include "CoreGraphics/CGGeometry.h"
/*
<objj>CPClipView</objj> allows you to define a clip rect and display only that portion of its containing view.
It is used to hold the document view in a <objj>CPScrollView</objj>.
/*!
@ingroup appkit
@class CPClipView
CPClipView allows you to define a clip rect and display only that portion of its containing view.
It is used to hold the document view in a CPScrollView.
*/
@implementation CPClipView : CPView
{
CPView _documentView;
}
/*
/*!
Sets the document view to be <code>aView</code>.
@param aView the new document view. It's frame origin will be changed to <code>(0,0)</code> after calling this method.
*/
@@ -63,9 +67,6 @@ import "CPView.j"
if (_documentView)
{
// FIXME: remove when bounds.
[_documentView setFrameOrigin:CGPointMake(0.0, 0.0)];
[self addSubview:_documentView];
[_documentView setPostsFrameChangedNotifications:YES];
@@ -85,7 +86,7 @@ import "CPView.j"
}
}
/*
/*!
Returns the document view.
*/
- (id)documentView
@@ -93,7 +94,7 @@ import "CPView.j"
return _documentView;
}
/*
/*!
Returns a new point that may be adjusted from <code>aPoint</code>
to make sure it lies within the document view.
@param aPoint
@@ -101,6 +102,9 @@ import "CPView.j"
*/
- (CGPoint)constrainScrollPoint:(CGPoint)aPoint
{
if (!_documentView)
return _CGPointMakeZero();
var documentFrame = [_documentView frame];
aPoint.x = MAX(0.0, MIN(aPoint.x, MAX(_CGRectGetWidth(documentFrame) - _CGRectGetWidth(_bounds), 0.0)));
@@ -122,7 +126,7 @@ import "CPView.j"
[superview reflectScrolledClipView:self];
}
/*
/*!
Scrolls the clip view to the specified point. The method
sets its bounds origin to <code>aPoint</code>.
*/
@@ -131,20 +135,31 @@ import "CPView.j"
[self setBoundsOrigin:[self constrainScrollPoint:aPoint]];
}
/*
Handles a <objj>CPViewBoundsDidChangeNotification</objj>.
/*!
Handles a CPViewBoundsDidChangeNotification.
@param aNotification the notification event
*/
- (void)viewBoundsChanged:(CPNotification)aNotification
{
[self viewFrameChanged:aNotification];
[self _constrainScrollPoint];
}
/*
Handles a <objj>CPViewFrameDidChangeNotification</objj>.
/*!
Handles a CPViewFrameDidChangeNotification.
@param aNotification the notification event
*/
- (void)viewFrameChanged:(CPNotification)aNotification
{
[self _constrainScrollPoint];
}
- (void)resizeSubviewsWithOldSize:(CGSize)aSize
{
[super resizeSubviewsWithOldSize:aSize];
[self _constrainScrollPoint];
}
- (void)_constrainScrollPoint
{
var oldScrollPoint = [self bounds].origin;
@@ -164,4 +179,42 @@ import "CPView.j"
[superview reflectScrolledClipView:self];
}
- (BOOL)autoscroll:(CPEvent)anEvent
{
var bounds = [self bounds],
eventLocation = [self convertPoint:[anEvent locationInWindow] fromView:nil];
if (CPRectContainsPoint(bounds, eventLocation))
return NO;
var newRect = CGRectMakeZero();
newRect.origin = eventLocation;
newRect.size = CPSizeMake(10, 10);
return [_documentView scrollRectToVisible:newRect];
}
@end
var CPClipViewDocumentViewKey = @"CPScrollViewDocumentView";
@implementation CPClipView (CPCoding)
- (id)initWithCoder:(CPCoder)aCoder
{
if (self = [super initWithCoder:aCoder])
[self setDocumentView:[aCoder decodeObjectForKey:CPClipViewDocumentViewKey]];
return self;
}
- (void)encodeWithCoder:(CPCoder)aCoder
{
[super encodeWithCoder:aCoder];
[aCoder encodeObject:_documentView forKey:CPClipViewDocumentViewKey];
}
@end
+161 -51
View File
@@ -20,16 +20,24 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
import <Foundation/CPArray.j>
import <Foundation/CPData.j>
import <Foundation/CPIndexSet.j>
import <Foundation/CPKeyedArchiver.j>
import <Foundation/CPKeyedUnarchiver.j>
@import <Foundation/CPArray.j>
@import <Foundation/CPData.j>
@import <Foundation/CPIndexSet.j>
@import <Foundation/CPKeyedArchiver.j>
@import <Foundation/CPKeyedUnarchiver.j>
import <AppKit/CPView.j>
@import <AppKit/CPView.j>
/*
This class presents an array of content as a grid of views.
/*!
@ingroup appkit
@class CPCollectionView
This class displays an array as a grid of objects, where each object is represented by a view.
The view is controlled by creating a CPCollectionViewItem and specifying its view, then
setting that item as the collection view prototype.
@par Delegate Methods
@delegate -(void)collectionViewDidChangeSelection:(CPCollectionView)collectionView;
Called when the selection in the collection view has changed.
@@ -51,7 +59,7 @@ import <AppKit/CPView.j>
Invoked to obtain the data types supported by the specified indices for placement on the pasteboard.
@param collectionView the collection view the items reside in
@param indices the indices to obtain drag types
@return an array of drag types (<objj>CPString</objj>)
@return an array of drag types (CPString)
*/
@implementation CPCollectionView : CPView
{
@@ -73,6 +81,7 @@ import <AppKit/CPView.j>
BOOL _isSelectable;
BOOL _allowsMultipleSelection;
BOOL _allowsEmptySelection;
CPIndexSet _selectionIndexes;
CGSize _itemSize;
@@ -105,12 +114,14 @@ import <AppKit/CPView.j>
_tileWidth = -1.0;
_selectionIndexes = [CPIndexSet indexSet];
_allowsEmptySelection = YES;
_isSelectable = YES;
}
return self;
}
/*
/*!
Sets the item prototype to <code>anItem</code>
@param anItem the new item prototype
*/
@@ -118,11 +129,12 @@ import <AppKit/CPView.j>
{
_itemData = [CPKeyedArchiver archivedDataWithRootObject:anItem];
_itemForDragging = anItem//[CPKeyedUnarchiver unarchiveObjectWithData:_itemData];
_itemPrototype = anItem;
[self reloadContent];
}
/*
/*!
Returns the current item prototype
*/
- (CPCollectionViewItem)itemPrototype
@@ -130,7 +142,7 @@ import <AppKit/CPView.j>
return _itemPrototype;
}
/*
/*!
Returns a collection view item for <code>anObject</code>.
@param anObject the object to be represented.
*/
@@ -150,7 +162,7 @@ import <AppKit/CPView.j>
}
// Working with the Responder Chain
/*
/*!
Returns <code>YES</code> by default.
*/
- (BOOL)acceptsFirstResponder
@@ -158,7 +170,7 @@ import <AppKit/CPView.j>
return YES;
}
/*
/*!
Returns whether the receiver is currently the first responder.
*/
- (BOOL)isFirstResponder
@@ -167,7 +179,7 @@ import <AppKit/CPView.j>
}
// Setting the Content
/*
/*!
Sets the content of the collection view to the content in <code>anArray</code>.
This array can be of any type, and each element will be passed to the <code>setRepresentedObject:</code> method.
It's the responsibility of your custom collection view item to interpret the object.
@@ -183,7 +195,7 @@ import <AppKit/CPView.j>
[self reloadContent];
}
/*
/*!
Returns the collection view content array
*/
- (CPArray)content
@@ -191,7 +203,7 @@ import <AppKit/CPView.j>
return _content;
}
/*
/*!
Returns the collection view items.
*/
- (CPArray)items
@@ -200,7 +212,7 @@ import <AppKit/CPView.j>
}
// Setting the Selection Mode
/*
/*!
Sets whether the user is allowed to select items
@param isSelectable <code>YES</code> allows the user to select items.
*/
@@ -220,7 +232,7 @@ import <AppKit/CPView.j>
}
}
/*
/*!
Returns <code>YES</code> if the collection view is
selected, and <code>NO</code> otherwise.
*/
@@ -229,7 +241,24 @@ import <AppKit/CPView.j>
return _isSelected;
}
/*
/*!
Sets whether the user may have no items selected. If YES, mouse clicks not on any item will empty the current selection. The first item will also start off as selected.
@param shouldAllowMultipleSelection <code>YES</code> allows the user to select multiple items
*/
- (void)setAllowsEmptySelection:(BOOL)shouldAllowEmptySelection
{
_allowsEmptySelection = shouldAllowEmptySelection;
}
/*!
Returns <code>YES</code> if the user can select no items, <code>NO</code> otherwise.
*/
- (BOOL)allowsEmptySelection
{
return _allowsEmptySelection;
}
/*!
Sets whether the user can select multiple items.
@param shouldAllowMultipleSelection <code>YES</code> allows the user to select multiple items
*/
@@ -238,7 +267,7 @@ import <AppKit/CPView.j>
_allowsMultipleSelection = shouldAllowMultipleSelection;
}
/*
/*!
Returns <code>YES</code> if the user can select multiple items, <code>NO</code> otherwise.
*/
- (BOOL)allowsMultipleSelection
@@ -246,32 +275,32 @@ import <AppKit/CPView.j>
return _allowsMultipleSelection;
}
/*
/*!
Sets the selected items based on the provided indices.
@param anIndexSet the set of items to be selected
*/
- (void)setSelectionIndexes:(CPIndexSet)anIndexSet
{
if (_selectionIndexes == anIndexSet)
if (_selectionIndexes == anIndexSet || !_isSelectable)
return;
var index = CPNotFound;
while ((index = [_selectionIndexes indexGreaterThanIndex:index]) != CPNotFound)
[_items[index] setSelected:NO];
_selectionIndexes = anIndexSet;
var index = CPNotFound;
while ((index = [_selectionIndexes indexGreaterThanIndex:index]) != CPNotFound)
[_items[index] setSelected:YES];
if ([_delegate respondsToSelector:@selector(collectionViewDidChangeSelection:)])
[_delegate collectionViewDidChangeSelection:self]
}
/*
/*!
Returns a set of the selected indices.
*/
- (CPIndexSet)selectionIndexes
@@ -322,7 +351,7 @@ import <AppKit/CPView.j>
// either proportioned out to the views (if their minSize != maxSize) or used as
// margin
var itemSize = CGSizeMakeCopy(_minItemSize);
_numberOfColumns = MAX(1.0, FLOOR(width / itemSize.width));
if (_maxNumberOfColumns > 0)
@@ -334,6 +363,10 @@ import <AppKit/CPView.j>
if (remaining > 0 && itemSize.width < _maxItemSize.width)
itemSize.width = MIN(_maxItemSize.width, itemSize.width + FLOOR(remaining / _numberOfColumns));
// When we ONE column and a non-integral width, the FLOORing above can cause the item width to be smaller than the total width.
if (_maxNumberOfColumns == 1 && itemSize.width < _maxItemSize.width && itemSize.width < width)
itemSize.width = MIN(_maxItemSize.width, width);
if (!CGSizeEqualToSize(_itemSize, itemSize))
{
_itemSize = itemSize;
@@ -382,7 +415,7 @@ import <AppKit/CPView.j>
}
// Laying Out the Collection View
/*
/*!
Sets the maximum number of rows.
@param aMaxNumberOfRows the new maximum number of rows
*/
@@ -396,7 +429,7 @@ import <AppKit/CPView.j>
[self tile];
}
/*
/*!
Returns the maximum number of rows.
*/
- (unsigned)maxNumberOfRows
@@ -404,7 +437,7 @@ import <AppKit/CPView.j>
return _maxNumberOfRows;
}
/*
/*!
Sets the maximum number of columns.
@param aMaxNumberOfColumns the new maximum number of columns
*/
@@ -418,7 +451,7 @@ import <AppKit/CPView.j>
[self tile];
}
/*
/*!
Returns the maximum number of columns
*/
- (unsigned)maxNumberOfColumns
@@ -426,7 +459,24 @@ import <AppKit/CPView.j>
return _maxNumberOfColumns;
}
/*
/*!
Returns the current number of rows
*/
- (unsigned)numberOfRows
{
return _numberOfRows;
}
/*!
Returns the current number of columns
*/
- (unsigned)numberOfColumns
{
return _numberOfColumns;
}
/*!
Sets the minimum size for an item
@param aSize the new minimum item size
*/
@@ -440,7 +490,7 @@ import <AppKit/CPView.j>
[self tile];
}
/*
/*!
Returns the current minimum item size
*/
- (CGSize)minItemSize
@@ -448,7 +498,7 @@ import <AppKit/CPView.j>
return _minItemSize;
}
/*
/*!
Sets the maximum item size.
@param aSize the new maximum item size
*/
@@ -462,7 +512,7 @@ import <AppKit/CPView.j>
[self tile];
}
/*
/*!
Returns the current maximum item size.
*/
- (CGSize)maxItemSize
@@ -485,6 +535,8 @@ import <AppKit/CPView.j>
if (index >= 0 && index < _items.length)
[self setSelectionIndexes:[CPIndexSet indexSetWithIndex:index]];
else if (_allowsEmptySelection)
[self setSelectionIndexes:[CPIndexSet indexSet]];
}
- (void)mouseDragged:(CPEvent)anEvent
@@ -509,6 +561,7 @@ import <AppKit/CPView.j>
frame = [view frame];
[view setFrameSize:_itemSize];
[view setAlphaValue:0.7];
[self dragView:view
at:[[_items[[_selectionIndexes firstIndex]] view] frame].origin
@@ -519,7 +572,7 @@ import <AppKit/CPView.j>
slideBack:YES];
}
/*
/*!
Places the selected items on the specified pasteboard. The items are requested from the collection's delegate.
@param aPasteboard the pasteboard to put the items on
@param aType the format the pasteboard data
@@ -531,6 +584,11 @@ import <AppKit/CPView.j>
// Cappuccino Additions
/*!
Sets the collection view's vertical spacing between elements.
@param aVerticalMargin the number of pixels to place between elements
*/
- (void)setVerticalMargin:(float)aVerticalMargin
{
if (_verticalMargin == aVerticalMargin)
@@ -541,7 +599,16 @@ import <AppKit/CPView.j>
[self tile];
}
/*
/*!
Gets the collection view's current vertical spacing between elements.
*/
- (float)verticalMargin
{
return _verticalMargin;
}
/*!
Sets the collection view's delegate
@param aDelegate the new delegate
*/
@@ -550,7 +617,7 @@ import <AppKit/CPView.j>
_delegate = aDelegate;
}
/*
/*!
Returns the collection view's delegate
*/
- (id)delegate
@@ -560,8 +627,8 @@ import <AppKit/CPView.j>
@end
/*
Represents an object inside a <objj>CPCollectionView</objj>.
/*!
Represents an object inside a CPCollectionView.
*/
@implementation CPCollectionViewItem : CPObject
{
@@ -573,7 +640,7 @@ import <AppKit/CPView.j>
}
// Setting the Represented Object
/*
/*!
Sets the object to be represented by this item.
@param anObject the object to be represented
*/
@@ -588,7 +655,7 @@ import <AppKit/CPView.j>
[_view setRepresentedObject:anObject];
}
/*
/*!
Returns the object represented by this view item
*/
- (id)representedObject
@@ -597,7 +664,7 @@ import <AppKit/CPView.j>
}
// Modifying the View
/*
/*!
Sets the view that is used represent this object.
@param aView the view used to represent this object
*/
@@ -606,7 +673,7 @@ import <AppKit/CPView.j>
_view = aView;
}
/*
/*!
Returns the view that represents this object.
*/
- (CPView)view
@@ -615,7 +682,7 @@ import <AppKit/CPView.j>
}
// Modifying the Selection
/*
/*!
Sets whether this view item should be selected.
@param shouldBeSelected <code>YES</code> makes the item selected. <code>NO</code> deselects it.
*/
@@ -630,7 +697,7 @@ import <AppKit/CPView.j>
[_view setSelected:_isSelected];
}
/*
/*!
Returns <code>YES</code> if the item is currently selected. <code>NO</code> if the item is not selected.
*/
- (BOOL)isSelected
@@ -639,7 +706,7 @@ import <AppKit/CPView.j>
}
// Parent Collection View
/*
/*!
Returns the collection view of which this item is a part.
*/
- (CPCollectionView)collectionView
@@ -649,6 +716,49 @@ import <AppKit/CPView.j>
@end
var CPCollectionViewMinItemSizeKey = @"CPCollectionViewMinItemSizeKey",
CPCollectionViewMaxItemSizeKey = @"CPCollectionViewMaxItemSizeKey",
CPCollectionViewVerticalMarginKey = @"CPCollectionViewVerticalMarginKey";
@implementation CPCollectionView (CPCoding)
- (id)initWithCoder:(CPCoder)aCoder
{
self = [super initWithCoder:aCoder];
if (self)
{
_items = [];
_content = [];
_cachedItems = [];
_itemSize = CGSizeMakeZero();
_minItemSize = [aCoder decodeSizeForKey:CPCollectionViewMinItemSizeKey];
_maxItemSize = [aCoder decodeSizeForKey:CPCollectionViewMaxItemSizeKey];
_verticalMargin = [aCoder decodeSizeForKey:CPCollectionViewVerticalMarginKey];
_tileWidth = -1.0;
_selectionIndexes = [CPIndexSet indexSet];
}
return self;
}
- (void)encodeWithCoder:(CPCoder)aCoder
{
[super encodeWithCoder:aCoder];
[aCoder encodeSize:_minItemSize forKey:CPCollectionViewMinItemSizeKey];
[aCoder encodeSize:_maxItemSize forKey:CPCollectionViewMaxItemSizeKey];
[aCoder encodeSize:_verticalMargin forKey:CPCollectionViewVerticalMarginKey];
}
@end
var CPCollectionViewItemViewKey = @"CPCollectionViewItemViewKey";
@implementation CPCollectionViewItem (CPCoding)
@@ -667,7 +777,7 @@ var CPCollectionViewItemViewKey = @"CPCollectionViewItemViewKey";
@implementation CPCollectionViewItem (CPCoding)
/*
/*!
Initializes the view item by unarchiving data from a coder.
@param aCoder the coder from which the data will be unarchived
@return the initialized collection view item
@@ -682,7 +792,7 @@ var CPCollectionViewItemViewKey = @"CPCollectionViewItemViewKey";
return self;
}
/*
/*!
Archives the colletion view item to the provided coder.
@param aCoder the coder to which the view item should be archived
*/
+208 -58
View File
@@ -20,12 +20,13 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
import <Foundation/CPObject.j>
@import <Foundation/CPObject.j>
import "CGColor.j"
@import "CGColor.j"
@import "CPCompatibility.j"
@import "CPImage.j"
import "CPCompatibility.j"
import "CPImage.j"
var _redComponent = 0,
_greenComponent = 1,
@@ -36,7 +37,22 @@ var _hueComponent = 0,
_saturationComponent = 1,
_brightnessComponent = 2;
/*
var cachedBlackColor,
cachedRedColor,
cachedGreenColor,
cachedBlueColor,
cachedYellowColor,
cachedGrayColor,
cachedLightGrayColor,
cachedDarkGrayColor,
cachedWhiteColor,
cachedShadowColor,
cachedClearColor;
/*!
@ingroup appkit
@code CPColor
<code>CPColor</code> can be used to represent color
in an RGB or HSB model with an optional transparency value.</p>
@@ -46,7 +62,7 @@ var _hueComponent = 0,
<p>The class does not have a <code>set:</code> method
like NextStep based frameworks to change the color of
the current context. To change the color of the current
context, use <objj>CGContextSetFillColor()</objj>.
context, use CGContextSetFillColor().
*/
@implementation CPColor : CPObject
{
@@ -56,7 +72,27 @@ var _hueComponent = 0,
CPString _cssString;
}
/*
/*!
Creates a color in the RGB color space, with an alpha value.
Each component should be between the range of 0.0 to 1.0. For
the alpha component, a value of 1.0 is opaque, and 0.0 means
completely transparent.
@param red the red component of the color
@param green the green component of the color
@param blue the blue component of the color
@param alpha the alpha component
@return a color initialized to the values specified
*/
+ (CPColor)colorWithRed:(float)red green:(float)green blue:(float)blue alpha:(float)alpha
{
return [[CPColor alloc] _initWithRGBA:[red, green, blue, alpha]];
}
/*!
@deprecated in favor of colorWithRed:green:blue:alpha:
Creates a color in the RGB color space, with an alpha value.
Each component should be between the range of 0.0 to 1.0. For
the alpha component, a value of 1.0 is opaque, and 0.0 means
@@ -71,10 +107,27 @@ var _hueComponent = 0,
*/
+ (CPColor)colorWithCalibratedRed:(float)red green:(float)green blue:(float)blue alpha:(float)alpha
{
return [[CPColor alloc] _initWithRGBA:[red, green, blue, alpha]];
return [self colorWithRed:red green:green blue:blue alpha:alpha];
}
/*
/*!
Creates a new color object with <code>white</code> for the RGB components.
For the alpha component, a value of 1.0 is opaque, and 0.0 means completely transparent.
@param white a float between 0.0 and 1.0
@param alpha the alpha component between 0.0 and 1.0
@return a color initialized to the values specified
*/
+ (CPColor)colorWithWhite:(float)white alpha:(float)alpha
{
return [[CPColor alloc] _initWithRGBA:[white, white, white, alpha]];
}
/*!
@deprecated in favor of colorWithWhite:apha:
Creates a new color object with <code>white</code> for the RGB components.
For the alpha component, a value of 1.0 is opaque, and 0.0 means completely transparent.
@@ -85,10 +138,10 @@ var _hueComponent = 0,
*/
+ (CPColor)colorWithCalibratedWhite:(float)white alpha:(float)alpha
{
return [[CPColor alloc] _initWithRGBA:[white, white, white, alpha]];
return [self colorWithWhite:white alpha:alpha];
}
/*
/*!
Creates a new color in HSB space.
@param hue the hue value
@@ -99,8 +152,13 @@ var _hueComponent = 0,
*/
+ (CPColor)colorWithHue:(float)hue saturation:(float)saturation brightness:(float)brightness
{
if(saturation == 0.0)
return [CPColor colorWithCalibratedWhite: brightness/100.0 alpha: 1.0];
return [self colorWithHue:hue saturation:saturation brightness:brightness alpha:1.0];
}
+ (CPColor)colorWithHue:(float)hue saturation:(float)saturation brightness:(float)brightness alpha:(float)alpha
{
if(saturation === 0.0)
return [CPColor colorWithCalibratedWhite:brightness / 100.0 alpha:alpha];
var f = hue % 60,
p = (brightness * (100 - saturation)) / 10000,
@@ -110,16 +168,16 @@ var _hueComponent = 0,
switch(FLOOR(hue / 60))
{
case 0: return [CPColor colorWithCalibratedRed: b green: t blue: p alpha: 1.0];
case 1: return [CPColor colorWithCalibratedRed: q green: b blue: p alpha: 1.0];
case 2: return [CPColor colorWithCalibratedRed: p green: b blue: t alpha: 1.0];
case 3: return [CPColor colorWithCalibratedRed: p green: q blue: b alpha: 1.0];
case 4: return [CPColor colorWithCalibratedRed: t green: p blue: b alpha: 1.0];
case 5: return [CPColor colorWithCalibratedRed: b green: p blue: q alpha: 1.0];
case 0: return [CPColor colorWithCalibratedRed: b green: t blue: p alpha: alpha];
case 1: return [CPColor colorWithCalibratedRed: q green: b blue: p alpha: alpha];
case 2: return [CPColor colorWithCalibratedRed: p green: b blue: t alpha: alpha];
case 3: return [CPColor colorWithCalibratedRed: p green: q blue: b alpha: alpha];
case 4: return [CPColor colorWithCalibratedRed: t green: p blue: b alpha: alpha];
case 5: return [CPColor colorWithCalibratedRed: b green: p blue: q alpha: alpha];
}
}
/*
/*!
Creates an RGB color from a hexadecimal string. For example,
the a string of "FFFFFF" would return a white CPColor.
"FF0000" would return a pure red, "00FF00" would return a
@@ -134,87 +192,130 @@ var _hueComponent = 0,
return [[CPColor alloc] _initWithRGBA: hexToRGB(hex)];
}
/*
/*!
Returns a black color object. (RGBA=[0.0, 0.0, 0.0, 1.0])
*/
+ (CPColor)blackColor
{
return [[CPColor alloc] _initWithRGBA:[0.0, 0.0, 0.0, 1.0]];
if (!cachedBlackColor)
cachedBlackColor = [[CPColor alloc] _initWithRGBA:[0.0, 0.0, 0.0, 1.0]];
return cachedBlackColor;
}
/*
/*!
Returns a blue color object. (RGBA=[0.0, 0.0, 1.0, 1.0])
*/
+ (CPColor)blueColor
{
return [[CPColor alloc] _initWithRGBA:[0.0, 0.0, 1.0, 1.0]];
if (!cachedBlueColor)
cachedBlueColor = [[CPColor alloc] _initWithRGBA:[0.0, 0.0, 1.0, 1.0]];
return cachedBlueColor;
}
/*
/*!
Returns a dark gray color object. (RGBA=[0.33 ,0.33, 0.33, 1.0])
*/
+ (CPColor)darkGrayColor
{
return [CPColor colorWithCalibratedWhite:1.0 / 3.0 alpha:1.0];
if (!cachedDarkGrayColor)
cachedDarkGrayColor = [CPColor colorWithCalibratedWhite:1.0 / 3.0 alpha:1.0];
return cachedDarkGrayColor;
}
/*
/*!
Returns a gray color object. (RGBA=[0.5, 0.5, 0.5, 1.0])
*/
+ (CPColor)grayColor
{
return [CPColor colorWithCalibratedWhite:0.5 alpha: 1.0];
if (!cachedGrayColor)
cachedGrayColor = [CPColor colorWithCalibratedWhite:0.5 alpha: 1.0];
return cachedGrayColor;
}
/*
/*!
Returns a green color object. (RGBA=[0.0, 1.0, 0.0, 1.0])
*/
+ (CPColor)greenColor
{
return [[CPColor alloc] _initWithRGBA:[0.0, 1.0, 0.0, 1.0]];
if (!cachedGreenColor)
cachedGreenColor = [[CPColor alloc] _initWithRGBA:[0.0, 1.0, 0.0, 1.0]];
return cachedGreenColor;
}
/*
/*!
Returns a light gray color object (RGBA=[0.66, 0.66, 0.66, 1.0])
*/
+ (CPColor)lightGrayColor
{
return [CPColor colorWithCalibratedWhite:2.0 / 3.0 alpha:1.0];
if (!cachedLightGrayColor)
cachedLightGrayColor = [CPColor colorWithCalibratedWhite:2.0 / 3.0 alpha:1.0];
return cachedLightGrayColor;
}
/*
/*!
Returns a red color object (RGBA=[1.0, 0.0, 0.0, 1.0])
*/
+ (CPColor)redColor
{
return [[CPColor alloc] _initWithRGBA:[1.0, 0.0, 0.0, 1.0]];
if (!cachedRedColor)
cachedRedColor = [[CPColor alloc] _initWithRGBA:[1.0, 0.0, 0.0, 1.0]];
return cachedRedColor;
}
/*
/*!
Returns a white color object (RGBA=[1.0, 1.0, 1.0, 1.0])
*/
+ (CPColor)whiteColor
{
return [[CPColor alloc] _initWithRGBA:[1.0, 1.0, 1.0, 1.0]];
if (!cachedWhiteColor)
cachedWhiteColor = [[CPColor alloc] _initWithRGBA:[1.0, 1.0, 1.0, 1.0]];
return cachedWhiteColor;
}
/*
/*!
Returns a yellow color object (RGBA=[1.0, 1.0, 0.0, 1.0])
*/
+ (CPColor)yellowColor
{
return [[CPColor alloc] _initWithRGBA:[1.0, 1.0, 0.0, 1.0]];
if (!cachedYellowColor)
cachedYellowColor = [[CPColor alloc] _initWithRGBA:[1.0, 1.0, 0.0, 1.0]];
return cachedYellowColor;
}
/*
/*!
Returns a shadow looking color (RGBA=[0.0, 0.0, 0.0, 0.33])
*/
+ (CPColor)shadowColor
{
return [[CPColor alloc] _initWithRGBA:[0.0, 0.0, 0.0, 1.0 / 3.0]];
if (!cachedShadowColor)
cachedShadowColor = [[CPColor alloc] _initWithRGBA:[0.0, 0.0, 0.0, 1.0 / 3.0]];
return cachedShadowColor;
}
/*
/*!
Returns a clear color (RGBA=[0.0, 0.0, 0.0, 0.0])
*/
+ (CPColor)clearColor
{
if (!cachedClearColor)
cachedClearColor = [self colorWithCalibratedWhite:0.0 alpha:0.0];
return cachedClearColor;
}
/*!
Creates a color using a tile pattern with <code>anImage</code>
@param the image to tile
@return a tiled image color object
@@ -224,8 +325,8 @@ var _hueComponent = 0,
return [[CPColor alloc] _initWithPatternImage:anImage];
}
/*
Creates a <objj>CPColor</objj> from a valid CSS RGB string. Example, "rgb(32,64,129)".
/*!
Creates a CPColor from a valid CSS RGB string. Example, "rgb(32,64,129)".
@param aString a CSS color string
@return a color initialized to the value in the css string
@@ -322,13 +423,13 @@ var _hueComponent = 0,
if (self)
{
_patternImage = anImage;
_cssString = "url(\"" + _patternImage._filename + "\")";
_cssString = "url(\"" + [_patternImage filename] + "\")";
}
return self;
}
/*
/*!
Returns the image being used as the pattern for the tile in this color.
*/
- (CPImage)patternImage
@@ -336,7 +437,7 @@ var _hueComponent = 0,
return _patternImage;
}
/*
/*!
Returns the alpha component of this color.
*/
- (float)alphaComponent
@@ -344,7 +445,7 @@ var _hueComponent = 0,
return _components[3];
}
/*
/*!
Returns the blue component of this color.
*/
- (float)blueComponent
@@ -352,7 +453,7 @@ var _hueComponent = 0,
return _components[2];
}
/*
/*!
Returns the green component of this color.
*/
- (float)greenComponent
@@ -360,7 +461,7 @@ var _hueComponent = 0,
return _components[1];
}
/*
/*!
Return the red component of this color.
*/
- (float)redComponent
@@ -368,7 +469,7 @@ var _hueComponent = 0,
return _components[0];
}
/*
/*!
Returns the RGBA components of this color in an array.
The index values are ordered as:
<pre>
@@ -384,7 +485,7 @@ var _hueComponent = 0,
return _components;
}
/*
/*!
Returns a new color with the same RGB as the receiver but a new alpha component.
@param anAlphaComponent the alpha component for the new color
@@ -400,7 +501,7 @@ var _hueComponent = 0,
return [[[self class] alloc] _initWithRGBA:components];
}
/*
/*!
Returns an array with the HSB values for this color.
The index values are ordered as:
<pre>
@@ -451,7 +552,7 @@ var _hueComponent = 0,
];
}
/*
/*!
Returns the CSS representation of this color. The color will
be in one of the following forms:
<pre>
@@ -465,7 +566,7 @@ url("data:image/png;base64,BASE64ENCODEDDATA") // if there is a pattern image
return _cssString;
}
/*
/*!
Returns a 6 character long hex string of this color.
*/
- (CPString)hexString
@@ -473,6 +574,53 @@ url("data:image/png;base64,BASE64ENCODEDDATA") // if there is a pattern image
return rgbToHex([self redComponent], [self greenComponent], [self blueComponent])
}
- (BOOL)isEqual:(CPColor)aColor
{
if (!aColor)
return NO;
if (aColor === self)
return YES;
return [aColor isKindOfClass:CPColor] && [aColor cssString] === [self cssString];
}
- (CPString)description
{
return [super description]+" "+[self cssString];
}
@end
@implementation CPColor (CoreGraphicsExtensions)
/*!
Set's the receiver to be the fill and stroke color in the current graphics context
*/
- (void)set
{
[self setFill];
[self setStroke];
}
/*!
Set's the receiver to be the fill color in the current graphics context
*/
- (void)setFill
{
var ctx = [[CPGraphicsContext currentContext] graphicsPort];
CGContextSetFillColor(ctx, self);
}
/*!
Set's the receiver to be the stroke color in the current graphics context
*/
- (void)setStroke
{
var ctx = [[CPGraphicsContext currentContext] graphicsPort];
CGContextSetStrokeColor(ctx, self);
}
@end
var CPColorComponentsKey = @"CPColorComponentsKey",
@@ -480,7 +628,7 @@ var CPColorComponentsKey = @"CPColorComponentsKey",
@implementation CPColor (CPCoding)
/*
/*!
Initializes this color from the data archived in a coder.
@param aCoder the coder from which the color will be loaded
*/
@@ -492,7 +640,7 @@ var CPColorComponentsKey = @"CPColorComponentsKey",
return [self _initWithRGBA:[aCoder decodeObjectForKey:CPColorComponentsKey]];
}
/*
/*!
Archives this color into a coder.
@param aCoder the coder into which the color will be archived.
*/
@@ -508,14 +656,16 @@ var CPColorComponentsKey = @"CPColorComponentsKey",
var hexCharacters = "0123456789ABCDEF";
/*
Used for the <objj>CPColor</objj> <code>colorWithHexString:</code> implementation
/*!
Used for the CPColor <code>colorWithHexString:</code> implementation
@ignore
@class CPColor
@return an array of rgb components
*/
function hexToRGB(hex)
{
if ( hex.length == 3 )
hex = hex.charAt(0) + hex.charAt(0) + hex.charAt(1) + hex.charAt(1) + hex.charAt(2) + hex.charAt(2);
if(hex.length != 6)
return null;
+197 -219
View File
@@ -20,47 +20,43 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
import "CPButton.j"
import "CPColorPicker.j"
import "CPCookie.j"
import "CPKulerColorPicker.j"
import "CPPanel.j"
import "CPSliderColorPicker.j"
import "CPView.j"
@import "CPButton.j"
@import "CPCookie.j"
@import "CPPanel.j"
@import "CPView.j"
CPColorPanelColorDidChangeNotification = @"CPColorPanelColorDidChangeNotification";
var PREVIEW_HEIGHT = 20.0,
TOOLBAR_HEIGHT = 32.0,
SWATCH_HEIGHT = 14.0;
var SharedColorPanel = nil;
SWATCH_HEIGHT = 14.0,
ICON_WIDTH = 32.0,
ICON_PADDING = 12.0;
var SharedColorPanel = nil,
ColorPickerClasses = [];
/*
A color wheel
@global
@group CPColorPanelMode
*/
CPWheelColorPickerMode = 1;
/*
Kuler color picker
@global
@group CPColorPanelMode
*/
CPKulerColorPickerMode = 2;
/*
Slider based picker
@global
@group CPColorPanelMode
*/
CPSliderColorPickerMode = 3;
CPSliderColorPickerMode = 2;
CPColorPickerViewWidth = 265,
CPColorPickerViewHeight = 370;
/*
<objj>CPColorPanel</objj> provides a reusable panel that can be used
/*!
@ingroup appkit
@class CPColorPanel
CPColorPanel provides a reusable panel that can be used
displayed on screen to prompt the user for a color selection. To
obtain the panel, call the <code>sharedColorPanel</code> method.
*/
@@ -69,26 +65,31 @@ CPColorPickerViewHeight = 370;
_CPColorPanelToolbar _toolbar;
_CPColorPanelSwatches _swatchView;
_CPColorPanelPreview _previewView;
CPTextField _previewLabel;
CPTextField _swatchLabel;
CPView _activeView;
CPColorPicker _activePicker;
CPColorPicker _wheelPicker;
CPColorPicker _kulerPicker;
CPColorPicker _sliderPicker;
CPSlider _opacitySlider;
CPArray _colorPickers;
CPView _currentView;
id _activePicker;
CPColor _color;
id _target;
SEL _action;
int _mode;
SEL _action;
int _mode;
}
/*
/*!
A list of color pickers is collected here, and any color panel created will contain
any picker in this list up to this point. In other words, call before creating a color panel.
*/
+ (void)provideColorPickerClass:(Class)aColorPickerSubclass
{
ColorPickerClasses.push(aColorPickerSubclass);
}
/*!
Returns (and if necessary, creates) the shared color panel.
*/
+ (CPColorPanel)sharedColorPanel
@@ -99,7 +100,7 @@ CPColorPickerViewHeight = 370;
return SharedColorPanel;
}
/*
/*!
Sets the mode for the shared color panel.
@param mode the mode to which the color panel will be set
*/
@@ -115,57 +116,61 @@ CPColorPickerViewHeight = 370;
*/
- (id)init
{
self = [super initWithContentRect:CGRectMake(500.0, 50.0, 218.0, 360.0)
styleMask:(CPHUDBackgroundWindowMask | CPTitledWindowMask | CPClosableWindowMask | CPResizableWindowMask)];
self = [super initWithContentRect:CGRectMake(500.0, 50.0, 219.0, 370.0)
styleMask:(CPTitledWindowMask | CPClosableWindowMask | CPResizableWindowMask)];
if (self)
{
[[self contentView] setBackgroundColor:[CPColor colorWithWhite:0.95 alpha:1.0]];
[self setTitle:@"Color Panel"];
[self setLevel:CPFloatingWindowLevel];
[self setFloatingPanel:YES];
[self setBecomesKeyOnlyIfNeeded:YES];
[self setMinSize:CGSizeMake(218.0, 360.0)];
[self setMaxSize:CGSizeMake(327.0, 540.0)];
[self setMinSize:CGSizeMake(219.0, 342.0)];
[self setMaxSize:CGSizeMake(323.0, 537.0)];
}
return self;
}
/*
/*!
Sets the color of the panel, and updates the picker. Also posts a <code>CPColorPanelDidChangeNotification</code>.
*/
- (void)setColor:(CPColor)aColor
{
{
_color = aColor;
[_previewView setBackgroundColor: _color];
[CPApp sendAction:@selector(changeColor:) to:nil from:self];
if (_target && _action)
objj_msgSend(_target, _action, self);
[CPApp sendAction:_action to:_target from:self];
[[CPNotificationCenter defaultCenter]
postNotificationName:CPColorPanelColorDidChangeNotification
object:self];
[_activePicker setColor:_color];
[_opacitySlider setFloatValue:[_color alphaComponent]];
}
/*
/*!
Sets the selected color of the panel and optionally updates the picker.
@param bool whether or not to update the picker
@ignore
*/
-(void)setColor:(CPColor)aColor updatePicker:(BOOL)bool
{
[self setColor: aColor];
- (void)setColor:(CPColor)aColor updatePicker:(BOOL)bool
{
[self setColor:aColor];
if (bool)
[_activePicker setColor:_color];
}
if(bool)
[_activePicker setColor: _color];
}
/*
/*!
Returns the panel's currently selected color.
*/
- (CPColor)color
@@ -173,7 +178,12 @@ CPColorPickerViewHeight = 370;
return _color;
}
/*
- (float)opacity
{
return [_opacitySlider floatValue];
}
/*!
Sets the target for the color panel. Messages are sent
to the target when colors are selected in the panel.
*/
@@ -182,7 +192,7 @@ CPColorPickerViewHeight = 370;
_target = aTarget;
}
/*
/*!
Returns the current target. The target receives messages
when colors are selected in the panel.
*/
@@ -191,7 +201,7 @@ CPColorPickerViewHeight = 370;
return _target;
}
/*
/*!
Sets the action that gets sent to the target.
This action is sent whenever a color is selected in the panel.
@param anAction the action that will be sent
@@ -201,7 +211,7 @@ CPColorPickerViewHeight = 370;
_action = anAction;
}
/*
/*!
Returns the current target action.
*/
- (selector)action
@@ -209,36 +219,47 @@ CPColorPickerViewHeight = 370;
return _action;
}
/*
/*!
Sets the mode (look) of the color panel.
@param mode the mode in which to display the color panel
*/
- (void)setMode:(CPColorPanelMode)mode
{
if(mode == _mode)
return;
var frame = CPRectCreateCopy([_currentView frame]);
[_currentView removeFromSuperview];
switch(mode)
{
case CPWheelColorPickerMode: _activePicker = _wheelPicker; break;
case CPKulerColorPickerMode: _activePicker = _kulerPicker; break;
case CPSliderColorPickerMode: _activePicker = _sliderPicker; break;
}
_currentView = [_activePicker provideNewView: NO];
[_activePicker setColor: _color];
_mode = mode;
[_currentView setFrame: frame];
[_currentView setAutoresizingMask: (CPViewWidthSizable | CPViewHeightSizable)];
[[self contentView] addSubview: _currentView];
}
/*
- (void)_setPicker:(id)sender
{
var picker = _colorPickers[[sender tag]],
view = [picker provideNewView:NO];
if (!view)
view = [picker provideNewView:YES];
if (view == _currentView)
return;
if (_currentView)
[view setFrame:[_currentView frame]];
else
{
var height = (TOOLBAR_HEIGHT+10+PREVIEW_HEIGHT+5+SWATCH_HEIGHT+32),
bounds = [[self contentView] bounds];
[view setFrameSize: CPSizeMake(bounds.size.width - 10, bounds.size.height - height)];
[view setFrameOrigin: CPPointMake(5, height)];
}
[_currentView removeFromSuperview];
[[self contentView] addSubview:view];
_currentView = view;
_activePicker = picker;
[picker setColor:[self color]];
}
/*!
Returns the color panel's current display mode.
*/
- (CPColorPanelMode)mode
@@ -249,7 +270,6 @@ CPColorPickerViewHeight = 370;
- (void)orderFront:(id)aSender
{
[self _loadContentsIfNecessary];
[super orderFront:aSender];
}
@@ -258,178 +278,130 @@ CPColorPickerViewHeight = 370;
{
if (_toolbar)
return;
if (!_color)
_color = [CPColor whiteColor];
_colorPickers = [];
var count = [ColorPickerClasses count];
for (var i=0; i<count; i++)
{
var currentPickerClass = ColorPickerClasses[i],
currentPicker = [[currentPickerClass alloc] initWithPickerMask:0 colorPanel:self];
_colorPickers.push(currentPicker);
}
var contentView = [self contentView],
bounds = [contentView bounds];
_toolbar = [[_CPColorPanelToolbar alloc] initWithFrame: CPRectMake(0, 0, CGRectGetWidth(bounds), TOOLBAR_HEIGHT)];
_toolbar = [[CPView alloc] initWithFrame:CGRectMake(0, 6, CGRectGetWidth(bounds), TOOLBAR_HEIGHT)];
[_toolbar setAutoresizingMask: CPViewWidthSizable];
var totalToolbarWidth = count * ICON_WIDTH + (count - 1) * ICON_PADDING,
leftOffset = (CGRectGetWidth(bounds) - totalToolbarWidth) / 2.0,
buttonForLater = nil;
for (var i=0; i<count; i++)
{
var image = [_colorPickers[i] provideNewButtonImage],
highlightImage = [_colorPickers[i] provideNewAlternateButtonImage],
button = [[CPButton alloc] initWithFrame:CGRectMake(leftOffset + i*(ICON_WIDTH+ICON_PADDING), 0, ICON_WIDTH, ICON_WIDTH)];
[button setTag:i];
[button setTarget:self];
[button setAction:@selector(_setPicker:)];
[button setBordered:NO];
[button setAutoresizingMask:CPViewMinXMargin|CPViewMaxXMargin];
[button setImage:image];
[button setAlternateImage:highlightImage];
[_toolbar addSubview:button];
if (!buttonForLater)
buttonForLater = button;
}
// FIXME: http://280north.lighthouseapp.com/projects/13294-cappuccino/tickets/25-implement-cpbox
var previewBox = [[CPView alloc] initWithFrame:CGRectMake(76, TOOLBAR_HEIGHT + 10, CGRectGetWidth(bounds) - 86, PREVIEW_HEIGHT)];
_previewView = [[_CPColorPanelPreview alloc] initWithFrame:CGRectInset([previewBox bounds], 2.0, 2.0)];
[_previewView setColorPanel:self];
[_previewView setAutoresizingMask:CPViewWidthSizable];
[previewBox setBackgroundColor:[CPColor grayColor]];
[previewBox setBackgroundColor:[CPColor colorWithWhite:0.8 alpha:1.0]];
[previewBox setAutoresizingMask:CPViewWidthSizable];
[previewBox addSubview:_previewView];
_previewLabel = [[CPTextField alloc] initWithFrame: CPRectMake(10, TOOLBAR_HEIGHT + 14, 60, 15)];
var _previewLabel = [[CPTextField alloc] initWithFrame: CPRectMake(10, TOOLBAR_HEIGHT + 10, 60, 15)];
[_previewLabel setStringValue: "Preview:"];
[_previewLabel setTextColor:[CPColor whiteColor]];
[_previewLabel setTextColor:[CPColor blackColor]];
[_previewLabel setAlignment:CPRightTextAlignment];
// FIXME: http://280north.lighthouseapp.com/projects/13294-cappuccino/tickets/25-implement-cpbox
var swatchBox = [[CPView alloc] initWithFrame:CGRectMake(76, TOOLBAR_HEIGHT + 10 + PREVIEW_HEIGHT + 5, CGRectGetWidth(bounds) - 86, SWATCH_HEIGHT + 2.0)];
[swatchBox setBackgroundColor:[CPColor grayColor]];
[swatchBox setBackgroundColor:[CPColor colorWithWhite:0.8 alpha:1.0]];
[swatchBox setAutoresizingMask:CPViewWidthSizable];
_swatchView = [[_CPColorPanelSwatches alloc] initWithFrame:CGRectInset([swatchBox bounds], 1.0, 1.0)];
[_swatchView setColorPanel: self];
[_swatchView setAutoresizingMask: CPViewWidthSizable];
[swatchBox addSubview:_swatchView];
_swatchLabel = [[CPTextField alloc] initWithFrame: CPRectMake(10, TOOLBAR_HEIGHT + 8 + PREVIEW_HEIGHT + 5, 60, 15)];
var _swatchLabel = [[CPTextField alloc] initWithFrame: CPRectMake(10, TOOLBAR_HEIGHT + 8 + PREVIEW_HEIGHT + 6, 60, 15)];
[_swatchLabel setStringValue: "Swatches:"];
[_swatchLabel setTextColor:[CPColor whiteColor]];
[_swatchLabel setTextColor:[CPColor blackColor]];
[_swatchLabel setAlignment:CPRightTextAlignment];
_wheelPicker = [[CPColorWheelColorPicker alloc] initWithPickerMask: 1|2|3 colorPanel: self];
_currentView = [_wheelPicker provideNewView: YES];
var height = (TOOLBAR_HEIGHT+10+PREVIEW_HEIGHT+5+SWATCH_HEIGHT+10);
[_currentView setFrameSize: CPSizeMake(bounds.size.width - 10, bounds.size.height - height)];
[_currentView setFrameOrigin: CPPointMake(5, TOOLBAR_HEIGHT+10+PREVIEW_HEIGHT+5+SWATCH_HEIGHT+10)];
[_currentView setAutoresizingMask: (CPViewWidthSizable | CPViewHeightSizable)];
var opacityLabel = [[CPTextField alloc] initWithFrame: CPRectMake(10, TOOLBAR_HEIGHT + PREVIEW_HEIGHT + 35, 60, 20)];
[opacityLabel setStringValue: "Opacity:"];
[opacityLabel setTextColor:[CPColor blackColor]];
[opacityLabel setAlignment:CPRightTextAlignment];
_kulerPicker = [[CPKulerColorPicker alloc] initWithPickerMask: 1|2|3 colorPanel: self];
[_kulerPicker provideNewView: YES];
_sliderPicker = [[CPSliderColorPicker alloc] initWithPickerMask: 1|2|3 colorPanel: self];
[_sliderPicker provideNewView: YES];
[contentView addSubview: _toolbar];
[contentView addSubview: previewBox];
[contentView addSubview: _previewLabel];
[contentView addSubview: swatchBox];
[contentView addSubview: _swatchLabel];
[contentView addSubview: _currentView];
_opacitySlider = [[CPSlider alloc] initWithFrame:CGRectMake(76, TOOLBAR_HEIGHT + PREVIEW_HEIGHT + 34, CGRectGetWidth(bounds) - 86, 20.0)];
[_opacitySlider setMinValue:0.0];
[_opacitySlider setMaxValue:1.0];
[_opacitySlider setTarget:self];
[_opacitySlider setAction:@selector(setOpacity:)];
[contentView addSubview:_toolbar];
[contentView addSubview:previewBox];
[contentView addSubview:_previewLabel];
[contentView addSubview:swatchBox];
[contentView addSubview:_swatchLabel];
[contentView addSubview:opacityLabel];
[contentView addSubview:_opacitySlider];
_target = nil;
_action = nil;
_activePicker = _wheelPicker;
[self setColor:[CPColor whiteColor]];
[_activePicker setColor:[CPColor whiteColor]];
_activePicker = nil;
[_previewView setBackgroundColor: _color];
if (buttonForLater)
[self _setPicker:buttonForLater];
}
- (void)setOpacity:(id)sender
{
var components = [[self color] components],
alpha = [sender floatValue];
[self setColor:[_color colorWithAlphaComponent:alpha] updatePicker:YES];
}
@end
var iconSize = 32,
totalIcons = 3;
/* @ignore */
@implementation _CPColorPanelToolbar : CPView
{
CPImage _wheelImage;
CPImage _wheelAlternateImage;
CPButton _wheelButton;
CPImage _sliderImage;
CPImage _sliderAlternateImage;
CPButton _sliderButton;
CPImage _kulerImage;
CPImage _kulerAlternateImage;
CPButton _kulerButton;
}
- (id)initWithFrame:(CPRect)aFrame
{
self = [super initWithFrame:aFrame];
var width = aFrame.size.width;
var center = width / 2.0;
var start = center - ((totalIcons * iconSize) + (totalIcons - 1) * 8.0) / 2.0;
_wheelButton = [[CPButton alloc] initWithFrame:CPRectMake(start, 0, iconSize, iconSize)];
start += iconSize + 8;
var path = [[CPBundle bundleForClass: _CPColorPanelToolbar] pathForResource:@"wheel_button.png"];
_wheelImage = [[CPImage alloc] initWithContentsOfFile:path size: CPSizeMake(iconSize, iconSize)];
path = [[CPBundle bundleForClass: _CPColorPanelToolbar] pathForResource:@"wheel_button_h.png"];
_wheelAlternateImage = [[CPImage alloc] initWithContentsOfFile:path size: CPSizeMake(iconSize, iconSize)];
[_wheelButton setBordered:NO];
[_wheelButton setImage: _wheelImage];
[_wheelButton setAlternateImage: _wheelAlternateImage];
[_wheelButton setTarget: self];
[_wheelButton setAction: @selector(setMode:)];
[_wheelButton setAutoresizingMask:CPViewMinXMargin | CPViewMaxXMargin];
[self addSubview: _wheelButton];
_sliderButton = [[CPButton alloc] initWithFrame:CPRectMake(start, 0, iconSize, iconSize)];
start += iconSize + 8;
path = [[CPBundle bundleForClass: _CPColorPanelToolbar] pathForResource:@"slider_button.png"];
_sliderImage = [[CPImage alloc] initWithContentsOfFile:path size: CPSizeMake(iconSize, iconSize)];
path = [[CPBundle bundleForClass: _CPColorPanelToolbar] pathForResource:@"slider_button_h.png"];
_sliderAlternateImage = [[CPImage alloc] initWithContentsOfFile:path size: CPSizeMake(iconSize, iconSize)];
[_sliderButton setBordered:NO];
[_sliderButton setImage: _sliderImage];
[_sliderButton setAlternateImage: _sliderAlternateImage];
[_sliderButton setTarget: self];
[_sliderButton setAction: @selector(setMode:)];
[_sliderButton setAutoresizingMask:CPViewMinXMargin | CPViewMaxXMargin];
[self addSubview: _sliderButton];
_kulerButton = [[CPButton alloc] initWithFrame:CPRectMake(start, 0, iconSize, iconSize)];
start += iconSize + 8;
path = [[CPBundle bundleForClass: _CPColorPanelToolbar] pathForResource:@"kuler_button.png"];
_kulerImage = [[CPImage alloc] initWithContentsOfFile:path size: CPSizeMake(iconSize, iconSize)];
path = [[CPBundle bundleForClass: _CPColorPanelToolbar] pathForResource:@"kuler_button_h.png"];
_kulerAlternateImage = [[CPImage alloc] initWithContentsOfFile:path size: CPSizeMake(iconSize, iconSize)];
[_kulerButton setBordered:NO];
[_kulerButton setImage: _kulerImage];
[_kulerButton setAlternateImage: _kulerAlternateImage];
[_kulerButton setTarget: self];
[_kulerButton setAction: @selector(setMode:)];
[_kulerButton setAutoresizingMask:CPViewMinXMargin | CPViewMaxXMargin];
[self addSubview: _kulerButton];
return self;
}
- (void)setMode:(id)sender
{
if(sender == _kulerButton)
[[CPColorPanel sharedColorPanel] setMode: CPKulerColorPickerMode];
else if(sender == _wheelButton)
[[CPColorPanel sharedColorPanel] setMode: CPWheelColorPickerMode];
else
[[CPColorPanel sharedColorPanel] setMode: CPSliderColorPickerMode];
}
@end
CPColorDragType = "CPColorDragType";
var CPColorPanelSwatchesCookie = "CPColorPanelSwatchesCookie";
@@ -519,7 +491,7 @@ var CPColorPanelSwatchesCookie = "CPColorPanelSwatchesCookie";
var future = new Date();
future.setYear(2019);
[_swatchCookie setValue: CPJSObjectCreateJSON(result) expires:future domain: nil];
[_swatchCookie setValue: JSON.stringify(result) expires:future domain: nil];
}
- (void)setColorPanel:(CPColorPanel)panel
@@ -682,3 +654,9 @@ var CPColorPanelSwatchesCookie = "CPColorPanelSwatchesCookie";
}
@end
@import "CPColorPicker.j"
@import "CPSliderColorPicker.j"
[CPColorPanel provideColorPickerClass:CPColorWheelColorPicker];
[CPColorPanel provideColorPickerClass:CPSliderColorPicker];
+109 -98
View File
@@ -20,13 +20,14 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
import <Foundation/Foundation.j>
import <AppKit/CPView.j>
import <AppKit/CPImage.j>
import <AppKit/CPImageView.j>
@import <Foundation/CPObject.j>
@import "CPColorPanel.j"
/*
<objj>CPColorPicker</objj> is an abstract superclass for all color picker subclasses. If you want a particular color picker, use <objj>CPColorPanel</objj>'s <code>setPickerMode:</code> method. The simplest way to implement your own color picker is to create a subclass of CPColorPicker.
/*!
@ingroup appkit
@class CPColorPicker
CPColorPicker is an abstract superclass for all color picker subclasses. If you want a particular color picker, use CPColorPanel's <code>setPickerMode:</code> method. The simplest way to implement your own color picker is to create a subclass of CPColorPicker.
*/
@implementation CPColorPicker : CPObject
{
@@ -34,7 +35,7 @@ import <AppKit/CPImageView.j>
int _mask;
}
/*
/*!
Initializes the color picker.
@param aMask a unique unsigned int identifying your color picker
@param aPanel the color panel that owns this picker
@@ -42,14 +43,14 @@ import <AppKit/CPImageView.j>
- (id)initWithPickerMask:(int)aMask colorPanel:(CPColorPanel)aPanel
{
self = [super init];
_panel = aPanel;
_mask = aMask;
return self;
}
/*
/*!
Returns the color panel that owns this picker
*/
- (CPColorPanel)colorPanel
@@ -67,7 +68,7 @@ import <AppKit/CPImageView.j>
return nil;
}
/*
/*!
Sets the color picker's mode.
@param mode the color panel mode
*/
@@ -76,7 +77,7 @@ import <AppKit/CPImageView.j>
return;
}
/*
/*!
Sets the picker's color.
@param aColor the new color for the picker
*/
@@ -93,52 +94,44 @@ import <AppKit/CPImageView.j>
*/
@implementation CPColorWheelColorPicker : CPColorPicker
{
CPView _pickerView;
CPView _pickerView;
CPView _brightnessSlider;
DOMElement _brightnessBarImage;
__CPColorWheel _hueSaturationView;
CPColor _cachedColor;
}
- (id)initWithPickerMask:(int)mask colorPanel:(CPColorPanel)owningColorPanel
{
return [super initWithPickerMask:mask colorPanel: owningColorPanel];
}
-(id)initView
{
aFrame = CPRectMake(0, 0, CPColorPickerViewWidth, CPColorPickerViewHeight);
_pickerView = [[CPView alloc] initWithFrame:aFrame];
var path = [[CPBundle bundleForClass: CPColorPicker] pathForResource:@"brightness_bar.png"];
_brightnessBarImage = new Image();
_brightnessBarImage.src = path;
_brightnessBarImage.style.width = "100%";
_brightnessBarImage.style.height = "100%";
_brightnessBarImage.style.position = "absolute";
_brightnessBarImage.style.top = "0px";
_brightnessBarImage.style.left = "0px";
[_pickerView setAutoresizingMask:CPViewWidthSizable|CPViewHeightSizable];
var brightnessBarView = [[CPView alloc] initWithFrame: CPRectMake(0, (aFrame.size.height - 34), aFrame.size.width, 15)];
[brightnessBarView setAutoresizingMask: (CPViewWidthSizable | CPViewMinYMargin)];
brightnessBarView._DOMElement.appendChild(_brightnessBarImage);
_brightnessSlider = [[CPSlider alloc] initWithFrame: CPRectMake(0, aFrame.size.height - 22, aFrame.size.width, 12)];
[_brightnessSlider setMaxValue: 100.0];
[_brightnessSlider setMinValue: 0.0];
[_brightnessSlider setValue: 100.0];
_brightnessSlider = [[CPSlider alloc] initWithFrame:CGRectMake(0, (aFrame.size.height - 34), aFrame.size.width, 15)];
[_brightnessSlider setTarget: self];
[_brightnessSlider setAction: @selector(brightnessSliderDidChange:)];
[_brightnessSlider setAutoresizingMask: (CPViewWidthSizable | CPViewMinYMargin)];
[_brightnessSlider setValue:15.0 forThemeAttribute:@"track-width"];
[_brightnessSlider setValue:[CPColor colorWithPatternImage:[[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:[CPColorPicker class]] pathForResource:@"brightness_bar.png"]]] forThemeAttribute:@"track-color"];
[_brightnessSlider setMinValue:0.0];
[_brightnessSlider setMaxValue:100.0];
[_brightnessSlider setFloatValue:100.0];
[_brightnessSlider setTarget:self];
[_brightnessSlider setAction:@selector(brightnessSliderDidChange:)];
[_brightnessSlider setAutoresizingMask:CPViewWidthSizable | CPViewMinYMargin];
_hueSaturationView = [[__CPColorWheel alloc] initWithFrame: CPRectMake(0, 0, aFrame.size.width, aFrame.size.height - 38)];
[_hueSaturationView setDelegate: self];
[_hueSaturationView setAutoresizingMask: (CPViewWidthSizable | CPViewHeightSizable)];
[_pickerView addSubview: brightnessBarView];
[_pickerView addSubview: _hueSaturationView];
[_pickerView addSubview: _brightnessSlider];
[_pickerView addSubview:_hueSaturationView];
[_pickerView addSubview:_brightnessSlider];
}
-(void)brightnessSliderDidChange:(id)sender
@@ -155,41 +148,59 @@ import <AppKit/CPImageView.j>
{
var hue = [_hueSaturationView angle],
saturation = [_hueSaturationView distance],
brightness = [_brightnessSlider value];
brightness = [_brightnessSlider floatValue];
[_hueSaturationView setWheelBrightness: brightness / 100.0];
_brightnessBarImage.style.backgroundColor = "#"+[[CPColor colorWithHue: hue saturation: saturation brightness: 100] hexString];
[_hueSaturationView setWheelBrightness:brightness / 100.0];
[_brightnessSlider setBackgroundColor:[CPColor colorWithHue:hue saturation:saturation brightness:100]];
[[self colorPanel] setColor:[CPColor colorWithHue: hue saturation: saturation brightness: brightness]];
var colorPanel = [self colorPanel],
opacity = [colorPanel opacity];
_cachedColor = [CPColor colorWithHue:hue saturation:saturation brightness:brightness alpha:opacity];
[[self colorPanel] setColor:_cachedColor];
}
- (BOOL)supportsMode:(int)mode
- (BOOL)supportsMode:(int)mode
{
return (mode == CPWheelColorPickerMode) ? YES : NO;
}
- (int)currentMode
- (int)currentMode
{
return CPWheelColorPickerMode;
}
- (CPView)provideNewView:(BOOL)initialRequest
- (CPView)provideNewView:(BOOL)initialRequest
{
if (initialRequest)
if (initialRequest)
[self initView];
return _pickerView;
}
- (void)setColor:(CPColor)newColor
{
var hsb = [newColor hsbComponents];
[_hueSaturationView setPositionToColor: newColor];
[_brightnessSlider setValue: hsb[2]];
[_hueSaturationView setWheelBrightness: hsb[2] / 100.0];
_brightnessBarImage.style.backgroundColor = "#"+[[CPColor colorWithHue: hsb[0] saturation: hsb[1] brightness: 100] hexString];
- (void)setColor:(CPColor)newColor
{
if ([newColor isEqual:_cachedColor])
return;
var hsb = [newColor hsbComponents];
[_hueSaturationView setPositionToColor:newColor];
[_brightnessSlider setFloatValue:hsb[2]];
[_hueSaturationView setWheelBrightness:hsb[2] / 100.0];
[_brightnessSlider setBackgroundColor:[CPColor colorWithHue:hsb[0] saturation:hsb[1] brightness:100]];
}
- (CPImage)provideNewButtonImage
{
return [[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:CPColorPicker] pathForResource:"wheel_button.png"] size:CGSizeMake(32, 32)];
}
- (CPImage)provideNewAlternateButtonImage
{
return [[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:CPColorPicker] pathForResource:"wheel_button_h.png"] size:CGSizeMake(32, 32)];
}
@end
@@ -199,28 +210,28 @@ import <AppKit/CPImageView.j>
{
DOMElement _wheelImage;
DOMElement _blackWheelImage;
CPView _crosshair;
id _delegate;
float _angle;
float _distance;
float _radius;
}
-(id)initWithFrame:(CPRect)aFrame
{
self = [super initWithFrame: aFrame];
var path = [[CPBundle bundleForClass: CPColorPicker] pathForResource:@"wheel.png"];
{
self = [super initWithFrame:aFrame];
var path = [[CPBundle bundleForClass:CPColorPicker] pathForResource:@"wheel.png"];
_wheelImage = new Image();
_wheelImage.src = path;
_wheelImage.style.position = "absolute";
path = [[CPBundle bundleForClass: CPColorPicker] pathForResource:@"wheel_black.png"];
path = [[CPBundle bundleForClass:CPColorPicker] pathForResource:@"wheel_black.png"];
_blackWheelImage = new Image();
_blackWheelImage.src = path;
@@ -230,19 +241,19 @@ import <AppKit/CPImageView.j>
_DOMElement.appendChild(_wheelImage);
_DOMElement.appendChild(_blackWheelImage);
[self setWheelSize: aFrame.size];
[self setWheelSize:aFrame.size];
_crosshair = [[CPView alloc] initWithFrame:CPRectMake(_radius - 2, _radius - 2, 4, 4)];
[_crosshair setBackgroundColor:[CPColor blackColor]];
var view = [[CPView alloc] initWithFrame:CGRectInset([_crosshair bounds], 1.0, 1.0)];
[view setBackgroundColor:[CPColor whiteColor]];
[_crosshair addSubview:view];
[self addSubview: _crosshair];
[self addSubview:_crosshair];
return self;
}
@@ -254,8 +265,8 @@ import <AppKit/CPImageView.j>
-(void)setFrameSize:(CPSize)aSize
{
[super setFrameSize: aSize];
[self setWheelSize: aSize];
[super setFrameSize:aSize];
[self setWheelSize:aSize];
}
-(void)setWheelSize:(CPSize)aSize
@@ -277,8 +288,8 @@ import <AppKit/CPImageView.j>
_wheelImage.style.left = (aSize.width - min) / 2.0 + "px";
_radius = min / 2.0;
[self setAngle: [self degreesToRadians: _angle] distance: (_distance / 100.0) * _radius];
[self setAngle:[self degreesToRadians:_angle] distance:(_distance / 100.0) * _radius];
}
-(void)setDelegate:(id)aDelegate
@@ -303,29 +314,28 @@ import <AppKit/CPImageView.j>
-(void)mouseDown:(CPEvent)anEvent
{
[self reposition: anEvent];
[self reposition:anEvent];
}
-(void)mouseDragged:(CPEvent)anEvent
{
[self reposition: anEvent];
[self reposition:anEvent];
}
-(void)reposition:(CPEvent)anEvent
{
var bounds = [self bounds],
location = [self convertPoint: [anEvent locationInWindow] fromView: nil];
location = [self convertPoint:[anEvent locationInWindow] fromView:nil];
var midX = CGRectGetMidX(bounds);
var midY = CGRectGetMidY(bounds);
var distance = MIN(SQRT((location.x - midX)*(location.x - midX) + (location.y - midY)*(location.y - midY)), _radius);
var angle = ATAN2(location.y - midY, location.x - midX);
[self setAngle: angle distance: distance];
if(_delegate)
[_delegate colorWheelDidChange: self];
[self setAngle:angle distance:distance];
[_delegate colorWheelDidChange:self];
}
-(void)setAngle:(int)angle distance:(float)distance
@@ -333,10 +343,10 @@ import <AppKit/CPImageView.j>
var bounds = [self bounds];
var midX = CGRectGetMidX(bounds);
var midY = CGRectGetMidY(bounds);
_angle = [self radiansToDegrees: angle];
_distance = (distance / _radius) * 100.0;
_angle = [self radiansToDegrees:angle];
_distance = (distance / _radius) * 100.0;
[_crosshair setFrameOrigin:CPPointMake(COS(angle) * distance + midX - 2.0, SIN(angle) * distance + midY - 2.0)];
}
@@ -344,11 +354,11 @@ import <AppKit/CPImageView.j>
{
var hsb = [aColor hsbComponents],
bounds = [self bounds];
var angle = [self degreesToRadians: hsb[0]],
var angle = [self degreesToRadians:hsb[0]],
distance = (hsb[1] / 100.0) * _radius;
[self setAngle: angle distance: distance];
[self setAngle:angle distance:distance];
}
-(int)radiansToDegrees:(float)radians
@@ -361,4 +371,5 @@ import <AppKit/CPImageView.j>
return -(((degrees - 360) / 180) * PI);
}
@end
@end
+111 -30
View File
@@ -20,23 +20,27 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
import <Foundation/CPString.j>
@import <Foundation/CPString.j>
import "CPView.j"
import "CPColor.j"
import "CPColorPanel.j"
@import "CPView.j"
@import "CPColor.j"
@import "CPColorPanel.j"
var _CPColorWellDidBecomeExclusiveNotification = @"_CPColorWellDidBecomeExclusiveNotification";
/*
<objj>CPColorWell</objj> is a <objj>CPControl</objj> for selecting and displaying a single color value. An example of a <objj>CPColorWell</objj> object (or simply color well) is found in <objj>CPColorPanel</objj>, which uses a color well to display the current color selection.</p>
/*!
@ingroup appkit
@class CPColorWell
<p>An application can have one or more active <objj>CPColorWell</objj>s. You can activate multiple <objj>CPColorWell</objj>s by invoking the <code>activate:</code> method with <code>NO</code> as its argument. When a mouse-down event occurs on an <objj>CPColorWell</objj>'s border, it becomes the only active color well. When a color well becomes active, it brings up the color panel also.
CPColorWell is a CPControl for selecting and displaying a single color value. An example of a CPColorWell object (or simply color well) is found in CPColorPanel, which uses a color well to display the current color selection.</p>
<p>An application can have one or more active CPColorWells. You can activate multiple CPColorWells by invoking the <code>activate:</code> method with <code>NO</code> as its argument. When a mouse-down event occurs on an CPColorWell's border, it becomes the only active color well. When a color well becomes active, it brings up the color panel also.
*/
@implementation CPColorWell : CPControl
{
BOOL _active;
BOOL _bordered;
CPColor _color;
CPView _wellView;
@@ -49,33 +53,59 @@ var _CPColorWellDidBecomeExclusiveNotification = @"_CPColorWellDidBecomeExclusiv
if (self)
{
_active = NO;
_bordered = YES;
_color = [CPColor whiteColor];
[self drawBezelWithHighlight:NO];
[self drawWellInside:CGRectInset([self bounds], 3.0, 3.0)];
var defaultCenter = [CPNotificationCenter defaultCenter];
[defaultCenter
addObserver:self
selector:@selector(colorWellDidBecomeExclusive:)
name:_CPColorWellDidBecomeExclusiveNotification
object:nil];
[defaultCenter
addObserver:self
selector:@selector(colorPanelWillClose:)
name:CPWindowWillCloseNotification
object:[CPColorPanel sharedColorPanel]];
[self _registerForNotifications];
}
return self;
}
- (void)_registerForNotifications
{
var defaultCenter = [CPNotificationCenter defaultCenter];
[defaultCenter
addObserver:self
selector:@selector(colorWellDidBecomeExclusive:)
name:_CPColorWellDidBecomeExclusiveNotification
object:nil];
[defaultCenter
addObserver:self
selector:@selector(colorPanelWillClose:)
name:CPWindowWillCloseNotification
object:[CPColorPanel sharedColorPanel]];
}
/*!
Returns whether the color well is bordered
*/
- (BOOL)isBordered
{
return _bordered;
}
/*!
Sets the color well's current color.
*/
- (void)setBordered:(BOOL)bordered
{
if (_bordered == bordered)
return;
_bordered = bordered;
[self drawWellInside:CGRectInset([self bounds], 3.0, 3.0)];
}
// Managing Color From Color Wells
/*
/*!
Returns the color well's current color.
*/
- (CPColor)color
@@ -83,7 +113,7 @@ var _CPColorWellDidBecomeExclusiveNotification = @"_CPColorWellDidBecomeExclusiv
return _color;
}
/*
/*!
Sets the color well's current color.
*/
- (void)setColor:(CPColor)aColor
@@ -96,7 +126,7 @@ var _CPColorWellDidBecomeExclusiveNotification = @"_CPColorWellDidBecomeExclusiv
[self drawWellInside:CGRectInset([self bounds], 3.0, 3.0)];
}
/*
/*!
Changes the color of the well to that of <code>aSender</code>.
@param aSender the object from which to retrieve the color
*/
@@ -106,9 +136,9 @@ var _CPColorWellDidBecomeExclusiveNotification = @"_CPColorWellDidBecomeExclusiv
}
// Activating and Deactivating Color Wells
/*
/*!
Activates the color well, displays the color panel, and makes the panel's current color the same as its own.
If exclusive is <code>YES</code>, deactivates any other <objj>CPColorWell</objj>s. <code>NO</code>, keeps them active.
If exclusive is <code>YES</code>, deactivates any other CPColorWells. <code>NO</code>, keeps them active.
@param shouldBeExclusive whether other color wells should be deactivated.
*/
- (void)activate:(BOOL)shouldBeExclusive
@@ -132,7 +162,7 @@ var _CPColorWellDidBecomeExclusiveNotification = @"_CPColorWellDidBecomeExclusiv
object:[CPColorPanel sharedColorPanel]];
}
/*
/*!
Deactivates the color well.
*/
- (void)deactivate
@@ -148,7 +178,7 @@ var _CPColorWellDidBecomeExclusiveNotification = @"_CPColorWellDidBecomeExclusiv
object:[CPColorPanel sharedColorPanel]];
}
/*
/*!
Returns <code>YES</code> if the color well is active.
*/
- (BOOL)isActive
@@ -162,7 +192,7 @@ var _CPColorWellDidBecomeExclusiveNotification = @"_CPColorWellDidBecomeExclusiv
{
}
/*
/*!
Draws the colored area inside the color well without borders.
@param aRect the location at which to draw
*/
@@ -171,6 +201,7 @@ var _CPColorWellDidBecomeExclusiveNotification = @"_CPColorWellDidBecomeExclusiv
if (!_wellView)
{
_wellView = [[CPView alloc] initWithFrame:aRect];
[_wellView setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
[self addSubview:_wellView];
}
@@ -220,8 +251,58 @@ var _CPColorWellDidBecomeExclusiveNotification = @"_CPColorWellDidBecomeExclusiv
var colorPanel = [CPColorPanel sharedColorPanel];
[colorPanel setColor:_color];
[colorPanel orderFront:self];
}
@end
var CPColorWellColorKey = "CPColorWellColorKey",
CPColorWellBorderedKey = "CPColorWellBorderedKey";
@implementation CPColorWell (CPCoding)
/*!
Initializes the color well by unarchiving data from <code>aCoder</code>.
@param aCoder the coder containing the archived CPColorWell.
*/
- (id)initWithCoder:(CPCoder)aCoder
{
self = [super initWithCoder:aCoder];
if (self)
{
_active = NO;
_bordered = [aCoder decodeObjectForKey:CPColorWellBorderedKey];
_color = [aCoder decodeObjectForKey:CPColorWellColorKey];
[self drawBezelWithHighlight:NO];
[self drawWellInside:CGRectInset([self bounds], 3.0, 3.0)];
[self _registerForNotifications];
}
return self;
}
/*!
Archives this button into the provided coder.
@param aCoder the coder to which the color well's instance data will be written.
*/
- (void)encodeWithCoder:(CPCoder)aCoder
{
// We do this in order to avoid encoding the _wellView, which
// should just automatically be created programmatically as needed.
var actualSubviews = _subviews;
_subviews = [_subviews copy];
[_subviews removeObjectIdenticalTo:_wellView];
[super encodeWithCoder:aCoder];
_subviews = actualSubviews;
[aCoder encodeObject:_color forKey:CPColorWellColorKey];
[aCoder encodeObject:_bordered forKey:CPColorWellBorderedKey];
}
@end
+35 -7
View File
@@ -20,7 +20,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
import "CPEvent.j"
@import "CPEvent.j"
// Browser Engines
CPUnknownBrowserEngine = 0;
@@ -41,6 +41,7 @@ CPJavascriptTextContentFeature = 1 << 9;
CPJavascriptClipboardEventsFeature = 1 << 10;
CPJavascriptClipboardAccessFeature = 1 << 11;
CPJavaScriptCanvasDrawFeature = 1 << 12;
CPJavaScriptCanvasTransformFeature = 1 << 13;
CPVMLFeature = 1 << 14;
@@ -48,12 +49,23 @@ CPJavascriptRemedialKeySupport = 1 << 15;
CPJavaScriptShadowFeature = 1 << 20;
CPJavaScriptNegativeMouseWheelValues = 1 << 22;
CPJavaScriptMouseWheelValues_8_15 = 1 << 23
var USER_AGENT = "";
CPOpacityRequiresFilterFeature = 1 << 24;
//Internet explorer does not allow dynamically changing the type of an input element
CPInputTypeCanBeChangedFeature = 1 << 25;
var USER_AGENT = "",
PLATFORM_ENGINE = CPUnknownBrowserEngine,
PLATFORM_FEATURES = 0;
// default these features to true
PLATFORM_FEATURES |= CPInputTypeCanBeChangedFeature;
if (typeof window != "undfined" && typeof window.navigator != "undefined")
USER_AGENT = window.navigator.userAgent;
@@ -74,6 +86,10 @@ else if (window.attachEvent) // Must follow Opera check.
PLATFORM_FEATURES |= CPVMLFeature;
PLATFORM_FEATURES |= CPJavascriptRemedialKeySupport;
PLATFORM_FEATURES |= CPJavaScriptShadowFeature;
PLATFORM_FEATURES |= CPOpacityRequiresFilterFeature;
PLATFORM_FEATURES &= ~CPInputTypeCanBeChangedFeature;
}
// WebKit
@@ -97,32 +113,44 @@ else if (USER_AGENT.indexOf("AppleWebKit/") != -1)
}
// KHTML
else if (USER_AGENT.indexOf('KHTML') != -1) // Must follow WebKit check.
else if (USER_AGENT.indexOf("KHTML") != -1) // Must follow WebKit check.
{
PLATFORM_ENGINE = CPKHTMLBrowserEngine;
}
// Gecko
else if (USER_AGENT.indexOf('Gecko') != -1) // Must follow KHTML check.
else if (USER_AGENT.indexOf("Gecko") !== -1) // Must follow KHTML check.
{
PLATFORM_ENGINE = CPGeckoBrowserEngine;
PLATFORM_FEATURES |= CPJavaScriptCanvasDrawFeature;
var index = USER_AGENT.indexOf("Firefox"),
version = (index == -1) ? 2.0 : parseFloat(USER_AGENT.substring(index+"Firefox".length+1));
version = (index === -1) ? 2.0 : parseFloat(USER_AGENT.substring(index + "Firefox".length + 1));
if (version >= 3.0)
PLATFORM_FEATURES |= CPCSSRGBAFeature;
if (version < 3.0)
PLATFORM_FEATURES |= CPJavaScriptMouseWheelValues_8_15;
}
// Feature Specific Checks
if (typeof document != "undefined")
{
var canvasElement = document.createElement("canvas");
// Detect Canvas Support
if (document.createElement("canvas").getContext)
if (canvasElement && canvasElement.getContext)
{
PLATFORM_FEATURES |= CPHTMLCanvasFeature;
// Detect Canvas setTransform/transform support
var context = document.createElement("canvas").getContext("2d");
if (context && context.setTransform && context.transform)
PLATFORM_FEATURES |= CPJavaScriptCanvasTransformFeature;
}
var DOMElement = document.createElement("div");
// Detect whether we have innerText or textContent (or neither)
+468 -281
View File
@@ -20,10 +20,11 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
import "CPFont.j"
import "CPShadow.j"
import "CPView.j"
@import "CPFont.j"
@import "CPShadow.j"
@import "CPView.j"
#include "CoreGraphics/CGGeometry.h"
#include "Platform/Platform.h"
/*
@@ -68,36 +69,68 @@ CPSmallControlSize = 1;
*/
CPMiniControlSize = 2;
CPControlNormalBackgroundColor = @"CPControlNormalBackgroundColor";
CPControlSelectedBackgroundColor = @"CPControlSelectedBackgroundColor";
CPControlHighlightedBackgroundColor = @"CPControlHighlightedBackgroundColor";
CPControlDisabledBackgroundColor = @"CPControlDisabledBackgroundColor";
CPControlNormalBackgroundColor = "CPControlNormalBackgroundColor";
CPControlSelectedBackgroundColor = "CPControlSelectedBackgroundColor";
CPControlHighlightedBackgroundColor = "CPControlHighlightedBackgroundColor";
CPControlDisabledBackgroundColor = "CPControlDisabledBackgroundColor";
CPControlTextDidBeginEditingNotification = "CPControlTextDidBeginEditingNotification";
CPControlTextDidChangeNotification = "CPControlTextDidChangeNotification";
CPControlTextDidEndEditingNotification = "CPControlTextDidEndEditingNotification";
var CPControlBlackColor = [CPColor blackColor];
/*
<objj>CPControl</objj> is an abstract superclass used to implement user interface elements. As a subclass of <objj>CPView</objj> and <objj>CPResponder</objj> it has the ability to handle screen drawing and handling user input.
/*!
@ingroup appkit
@class CPControl
CPControl is an abstract superclass used to implement user interface elements. As a subclass of CPView and CPResponder it has the ability to handle screen drawing and handling user input.
*/
@implementation CPControl : CPView
{
id _value;
id _value;
// Target-Action Support
id _target;
SEL _action;
int _sendActionOn;
// Mouse Tracking Support
BOOL _continuousTracking;
BOOL _trackingWasWithinFrame;
unsigned _trackingMouseDownFlags;
CGPoint _previousTrackingLocation;
JSObject _ephemeralSubviewsForNames;
CPSet _ephereralSubviews;
BOOL _isEnabled;
int _alignment;
CPFont _font;
CPColor _textColor;
CPShadow _textShadow;
id _target;
SEL _action;
int _sendActionOn;
CPColor _backgroundColor;
CPColor _highlightedBackgroundColor;
CPDictionary _backgroundColors;
CPString _currentBackgroundColorName;
CPString _toolTip;
}
+ (CPDictionary)themeAttributes
{
return [CPDictionary dictionaryWithObjects:[CPLeftTextAlignment,
CPTopVerticalTextAlignment,
CPLineBreakByClipping,
[CPColor blackColor],
[CPFont systemFontOfSize:12.0],
nil,
_CGSizeMakeZero(),
CPImageLeft,
CPScaleToFit,
_CGSizeMakeZero(),
_CGSizeMake(-1.0, -1.0)]
forKeys:[@"alignment",
@"vertical-alignment",
@"line-break-mode",
@"text-color",
@"font",
@"text-shadow-color",
@"text-shadow-offset",
@"image-position",
@"image-scaling",
@"min-size",
@"max-size"]];
}
- (id)initWithFrame:(CGRect)aFrame
@@ -107,125 +140,13 @@ var CPControlBlackColor = [CPColor blackColor];
if (self)
{
_sendActionOn = CPLeftMouseUpMask;
_isEnabled = YES;
[self setFont:[CPFont systemFontOfSize:12.0]];
[self setTextColor:CPControlBlackColor];
_backgroundColors = [CPDictionary dictionary];
_trackingMouseDownFlags = 0;
}
return self;
}
/*
Sets whether the receiver responds to mouse events.
@param isEnabled whether the receiver will respond to mouse events
*/
- (void)setEnabled:(BOOL)isEnabled
{
[self setAlphaValue:(_isEnabled = isEnabled) ? 1.0 : 0.3];
}
/*
Returns <code>YES</code> if the receiver responds to mouse events.
*/
- (BOOL)isEnabled
{
return _isEnabled;
}
/*
Sets the color of the receiver's text.
*/
- (void)setTextColor:(CPColor)aColor
{
if (_textColor == aColor)
return;
_textColor = aColor;
#if PLATFORM(DOM)
_DOMElement.style.color = [aColor cssString];
#endif
}
/*
Returns the color of the receiver's text
*/
- (CPColor)textColor
{
return _textColor;
}
/*
Returns the receiver's alignment
*/
- (CPTextAlignment)alignment
{
return _alignment;
}
/*
Sets the receiver's alignment
@param anAlignment the receiver's alignment
*/
- (void)setAlignment:(CPTextAlignment)anAlignment
{
_alignment = anAlignment;
}
/*
Sets the receiver's font
@param aFont the font for the receiver
*/
- (void)setFont:(CPFont)aFont
{
if (_font == aFont)
return;
_font = aFont;
#if PLATFORM(DOM)
_DOMElement.style.font = [_font ? _font : [CPFont systemFontOfSize:12.0] cssString];
#endif
}
/*
Returns the receiver's font
*/
- (CPFont)font
{
return _font;
}
/*
Sets the shadow for the receiver's text.
@param aTextShadow the text shadow
*/
- (void)setTextShadow:(CPShadow)aTextShadow
{
_DOMElement.style.textShadow = [_textShadow = aTextShadow cssString];
}
/*
Returns the receiver's text shadow
*/
- (CPShadow)textShadow
{
return _textShadow;
}
/*
Returns the receiver's target action
*/
- (SEL)action
{
return _action;
}
/*
/*!
Sets the receiver's target action
@param anAction Sets the action message that gets sent to the target.
*/
@@ -234,15 +155,15 @@ var CPControlBlackColor = [CPColor blackColor];
_action = anAction;
}
/*
Returns the receiver's target. The target receives action messages from the receiver.
/*!
Returns the receiver's target action
*/
- (id)target
- (SEL)action
{
return _target;
return _action;
}
/*
/*!
Sets the receiver's target. The target receives action messages from the receiver.
@param aTarget the object that will receive the message specified by action
*/
@@ -251,15 +172,15 @@ var CPControlBlackColor = [CPColor blackColor];
_target = aTarget;
}
- (void)mouseUp:(CPEvent)anEvent
/*!
Returns the receiver's target. The target receives action messages from the receiver.
*/
- (id)target
{
if (_sendActionOn & CPLeftMouseUpMask && CPRectContainsPoint([self bounds], [self convertPoint:[anEvent locationInWindow] fromView:nil]))
[self sendAction:_action to:_target];
[super mouseUp:anEvent];
return _target;
}
/*
/*!
Causes <code>anAction</code> to be sent to <code>anObject</code>.
@param anAction the action to send
@param anObject the object to which the action will be sent
@@ -269,23 +190,151 @@ var CPControlBlackColor = [CPColor blackColor];
[CPApp sendAction:anAction to:anObject from:self];
}
/*
Returns the receiver's float value
*/
- (float)floatValue
- (int)sendActionOn:(int)mask
{
return _value ? parseFloat(_value, 10) : 0.0;
var previousMask = _sendActionOn;
_sendActionOn = mask;
return previousMask;
}
/*
Sets the receiver's float value
/*!
Sets the tooltip for the receiver.
@param aToolTip the tooltip
*/
- (void)setFloatValue:(float)aValue
/*
-(void)setToolTip:(CPString)aToolTip
{
[self setObjectValue:aValue];
if (_toolTip == aToolTip)
return;
_toolTip = aToolTip;
#if PLATFORM(DOM)
_DOMElement.title = aToolTip;
#endif
}
*/
/*!
Returns the receiver's tooltip
*/
/*
-(CPString)toolTip
{
return _toolTip;
}
*/
/*!
Returns whether the control can continuously send its action messages.
*/
- (BOOL)isContinuous
{
// Some subclasses should redefine this with CPLeftMouseDraggedMask
return (_sendActionOn & CPPeriodicMask) !== 0;
}
/*
/*!
Sets whether the cell can continuously send its action messages.
*/
- (void)setContinuous:(BOOL)flag
{
// Some subclasses should redefine this with CPLeftMouseDraggedMask
if (flag)
_sendActionOn |= CPPeriodicMask;
else
_sendActionOn &= ~CPPeriodicMask;
}
- (BOOL)tracksMouseOutsideOfFrame
{
return NO;
}
- (void)trackMouse:(CPEvent)anEvent
{
var type = [anEvent type],
currentLocation = [self convertPoint:[anEvent locationInWindow] fromView:nil];
isWithinFrame = [self tracksMouseOutsideOfFrame] || CGRectContainsPoint([self bounds], currentLocation);
if (type === CPLeftMouseUp)
{
[self stopTracking:_previousTrackingLocation at:currentLocation mouseIsUp:YES];
_trackingMouseDownFlags = 0;
}
else
{
if (type === CPLeftMouseDown)
{
_trackingMouseDownFlags = [anEvent modifierFlags];
_continuousTracking = [self startTrackingAt:currentLocation];
}
else if (type === CPLeftMouseDragged)
{
if (isWithinFrame)
{
if (!_trackingWasWithinFrame)
_continuousTracking = [self startTrackingAt:currentLocation];
else if (_continuousTracking)
_continuousTracking = [self continueTracking:_previousTrackingLocation at:currentLocation];
}
else
[self stopTracking:_previousTrackingLocation at:currentLocation mouseIsUp:NO];
}
[CPApp setTarget:self selector:@selector(trackMouse:) forNextEventMatchingMask:CPLeftMouseDraggedMask | CPLeftMouseUpMask untilDate:nil inMode:nil dequeue:YES];
}
if ((_sendActionOn & (1 << type)) && isWithinFrame)
[self sendAction:_action to:_target];
_trackingWasWithinFrame = isWithinFrame;
_previousTrackingLocation = currentLocation;
}
- (void)performClick:(id)sender
{
[self highlight:YES];
[self setState:[self nextState]];
[self sendAction:[self action] to:[self target]];
[self highlight:NO];
}
- (unsigned)mouseDownFlags
{
return _trackingMouseDownFlags;
}
- (BOOL)startTrackingAt:(CGPoint)aPoint
{
[self highlight:YES];
return (_sendActionOn & CPPeriodicMask) || (_sendActionOn & CPLeftMouseDraggedMask);
}
- (BOOL)continueTracking:(CGPoint)lastPoint at:(CGPoint)aPoint
{
return (_sendActionOn & CPPeriodicMask) || (_sendActionOn & CPLeftMouseDraggedMask);
}
- (void)stopTracking:(CGPoint)lastPoint at:(CGPoint)aPoint mouseIsUp:(BOOL)mouseIsUp
{
[self highlight:NO];
}
- (void)mouseDown:(CPEvent)anEvent
{
if (![self isEnabled])
return;
[self trackMouse:anEvent];
}
/*!
Returns the receiver's object value
*/
- (id)objectValue
@@ -293,122 +342,280 @@ var CPControlBlackColor = [CPColor blackColor];
return _value;
}
/*
/*!
Set's the receiver's object value
*/
- (void)setObjectValue:(id)anObject
{
_value = anObject;
[self setNeedsLayout];
[self setNeedsDisplay:YES];
}
/*
/*!
Returns the receiver's float value
*/
- (float)floatValue
{
var floatValue = parseFloat(_value, 10);
return isNaN(floatValue) ? 0.0 : floatValue;
}
/*!
Sets the receiver's float value
*/
- (void)setFloatValue:(float)aValue
{
[self setObjectValue:aValue];
}
/*!
Returns the receiver's double value
*/
- (id)doubleValue
- (double)doubleValue
{
return [self floatValue];
var doubleValue = parseFloat(_value, 10);
return isNaN(doubleValue) ? 0.0 : doubleValue;
}
/*
/*!
Set's the receiver's double value
*/
- (void)setDoubleValue:(id)anObject
- (void)setDoubleValue:(double)anObject
{
[self setObjectValue:anObject];
}
/*
/*!
Returns the receiver's int value
*/
- (id)intValue
- (int)intValue
{
return _value ? parseInt(_value, 10) : 0;
var intValue = parseInt(_value, 10);
return isNaN(intValue) ? 0.0 : intValue;
}
/*
/*!
Set's the receiver's int value
*/
- (void)setIntValue:(id)anObject
- (void)setIntValue:(int)anObject
{
[self setObjectValue:anObject];
}
/*
/*!
Returns the receiver's int value
*/
- (id)stringValue
- (int)integerValue
{
return _value ? ""+_value : "";
var intValue = parseInt(_value, 10);
return isNaN(intValue) ? 0.0 : intValue;
}
/*
/*!
Set's the receiver's int value
*/
- (void)setStringValue:(id)anObject
- (void)setIntegerValue:(int)anObject
{
[self setObjectValue:anObject];
}
- (void)setBackgroundColor:(CPColor)aColor
/*!
Returns the receiver's int value
*/
- (CPString)stringValue
{
_backgroundColors = [CPDictionary dictionary];
[self setBackgroundColor:aColor forName:CPControlNormalBackgroundColor];
[super setBackgroundColor:aColor];
return (_value === undefined || _value === nil) ? "" : String(_value);
}
- (void)setBackgroundColor:(CPColor)aColor forName:(CPString)aName
/*!
Set's the receiver's int value
*/
- (void)setStringValue:(CPString)anObject
{
if (!aColor)
[_backgroundColors removeObjectForKey:aName];
[self setObjectValue:anObject];
}
- (void)takeDoubleValueFrom:(id)sender
{
if ([sender respondsToSelector:@selector(doubleValue)])
[self setDoubleValue:[sender doubleValue]];
}
- (void)takeFloatValueFrom:(id)sender
{
if ([sender respondsToSelector:@selector(floatValue)])
[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)])
[self setObjectValue:[sender objectValue]];
}
- (void)takeStringValueFrom:(id)sender
{
if ([sender respondsToSelector:@selector(stringValue)])
[self setStringValue:[sender stringValue]];
}
- (void)textDidBeginEditing:(CPNotification)note
{
//this looks to prevent false propagation of notifications for other objects
if([note object] != self)
return;
[[CPNotificationCenter defaultCenter] postNotificationName:CPControlTextDidBeginEditingNotification object:self userInfo:[CPDictionary dictionaryWithObject:[note object] forKey:"CPFieldEditor"]];
}
- (void)textDidChange:(CPNotification)note
{
//this looks to prevent false propagation of notifications for other objects
if([note object] != self)
return;
[[CPNotificationCenter defaultCenter] postNotificationName:CPControlTextDidChangeNotification object:self userInfo:[CPDictionary dictionaryWithObject:[note object] forKey:"CPFieldEditor"]];
}
- (void)textDidEndEditing:(CPNotification)note
{
//this looks to prevent false propagation of notifications for other objects
if([note object] != self)
return;
[[CPNotificationCenter defaultCenter] postNotificationName:CPControlTextDidEndEditingNotification object:self userInfo:[CPDictionary dictionaryWithObject:[note object] forKey:"CPFieldEditor"]];
}
#define BRIDGE(UPPERCASE, LOWERCASE, ATTRIBUTENAME) \
/*! Sets the value for ATTRIBUTENAME */\
- (void)set##UPPERCASE:(id)aValue\
{\
[self setValue:aValue forThemeAttribute:ATTRIBUTENAME];\
}\
/*! Returns the current value for ATTRIBUTENAME */\
- (id)LOWERCASE\
{\
return [self valueForThemeAttribute:ATTRIBUTENAME];\
}
BRIDGE(Alignment, alignment, "alignment")
BRIDGE(VerticalAlignment, verticalAlignment, "vertical-alignment")
BRIDGE(LineBreakMode, lineBreakMode, "line-break-mode")
BRIDGE(TextColor, textColor, "text-color")
BRIDGE(Font, font, "font")
BRIDGE(TextShadowColor, textShadowColor, "text-shadow-color")
BRIDGE(TextShadowOffset, textShadowOffset, "text-shadow-offset")
BRIDGE(ImagePosition, imagePosition, "image-position")
BRIDGE(ImageScaling, imageScaling, "image-scaling")
- (void)setEnabled:(BOOL)isEnabled
{
if (isEnabled)
[self unsetThemeState:CPThemeStateDisabled];
else
[_backgroundColors setObject:aColor forKey:aName];
if (_currentBackgroundColorName == aName)
[self setBackgroundColorWithName:_currentBackgroundColorName];
[self setThemeState:CPThemeStateDisabled];
}
- (CPColor)backgroundColorForName:(CPString)aName
- (BOOL)isEnabled
{
var backgroundColor = [_backgroundColors objectForKey:aName];
if (!backgroundColor && aName != CPControlNormalBackgroundColor)
return [_backgroundColors objectForKey:CPControlNormalBackgroundColor];
return backgroundColor;
return ![self hasThemeState:CPThemeStateDisabled];
}
- (void)setBackgroundColorWithName:(CPString)aName
- (void)highlight:(BOOL)shouldHighlight
{
_currentBackgroundColorName = aName;
[super setBackgroundColor:[self backgroundColorForName:aName]];
[self setHighlighted:shouldHighlight];
}
/*
Ð doubleValue
Ð setDoubleValue:
Ð intValue
Ð setIntValue:
Ð objectValue
Ð setObjectValue:
Ð stringValue
Ð setStringValue:
Ð setNeedsDisplay
Ð attributedStringValue
Ð setAttributedStringValue:
*/
- (void)setHighlighted:(BOOL)isHighlighted
{
if (isHighlighted)
[self setThemeState:CPThemeStateHighlighted];
else
[self unsetThemeState:CPThemeStateHighlighted];
}
- (BOOL)isHighlighted
{
return [self hasThemeState:CPThemeStateHighlighted];
}
- (CPView)createEphemeralSubviewNamed:(CPString)aViewName
{
return nil;
}
- (CGRect)rectForEphemeralSubviewNamed:(CPString)aViewName
{
return _CGRectMakeZero();
}
- (CPView)layoutEphemeralSubviewNamed:(CPString)aViewName
positioned:(CPWindowOrderingMode)anOrderingMode
relativeToEphemeralSubviewNamed:(CPString)relativeToViewName
{
if (!_ephemeralSubviewsForNames)
{
_ephemeralSubviewsForNames = {};
_ephemeralSubviews = [CPSet set];
}
var frame = [self rectForEphemeralSubviewNamed:aViewName];
if (frame && !_CGRectIsEmpty(frame))
{
if (!_ephemeralSubviewsForNames[aViewName])
{
_ephemeralSubviewsForNames[aViewName] = [self createEphemeralSubviewNamed:aViewName];
[_ephemeralSubviews addObject:_ephemeralSubviewsForNames[aViewName]];
if (_ephemeralSubviewsForNames[aViewName])
[self addSubview:_ephemeralSubviewsForNames[aViewName] positioned:anOrderingMode relativeTo:_ephemeralSubviewsForNames[relativeToViewName]];
}
if (_ephemeralSubviewsForNames[aViewName])
[_ephemeralSubviewsForNames[aViewName] setFrame:frame];
}
else if (_ephemeralSubviewsForNames[aViewName])
{
[_ephemeralSubviewsForNames[aViewName] removeFromSuperview];
[_ephemeralSubviews removeObject:_ephemeralSubviewsForNames[aViewName]];
delete _ephemeralSubviewsForNames[aViewName];
}
return _ephemeralSubviewsForNames[aViewName];
}
@end
var CPControlIsEnabledKey = @"CPControlIsEnabledKey",
CPControlAlignmentKey = @"CPControlAlignmentKey",
CPControlFontKey = @"CPControlFontKey",
CPControlTextColorKey = @"CPControlTextColorKey",
CPControlTargetKey = @"CPControlTargetKey",
CPControlActionKey = @"CPControlActionKey",
CPControlSendActionOnKey = @"CPControlSendActionOnKey";
var CPControlValueKey = "CPControlValueKey",
CPControlControlStateKey = @"CPControlControlStateKey",
CPControlIsEnabledKey = "CPControlIsEnabledKey",
CPControlTargetKey = "CPControlTargetKey",
CPControlActionKey = "CPControlActionKey",
CPControlSendActionOnKey = "CPControlSendActionOnKey";
var __Deprecated__CPImageViewImageKey = @"CPImageViewImageKey";
@implementation CPControl (CPCoding)
@@ -420,19 +627,15 @@ var CPControlIsEnabledKey = @"CPControlIsEnabledKey",
- (id)initWithCoder:(CPCoder)aCoder
{
self = [super initWithCoder:aCoder];
if (self)
{
[self setEnabled:[aCoder decodeIntForKey:CPControlIsEnabledKey]];
[self setAlignment:[aCoder decodeIntForKey:CPControlAlignmentKey]];
[self setFont:[aCoder decodeObjectForKey:CPControlFontKey]];
[self setTextColor:[aCoder decodeObjectForKey:CPControlTextColorKey]];
[self setObjectValue:[aCoder decodeObjectForKey:CPControlValueKey]];
[self setTarget:[aCoder decodeObjectForKey:CPControlTargetKey]];
[self setAction:[aCoder decodeObjectForKey:CPControlActionKey]];
_sendActionOn = [aCoder decodeIntForKey:CPControlSendActionOnKey];
[self sendActionOn:[aCoder decodeIntForKey:CPControlSendActionOnKey]];
}
return self;
@@ -444,30 +647,45 @@ var CPControlIsEnabledKey = @"CPControlIsEnabledKey",
*/
- (void)encodeWithCoder:(CPCoder)aCoder
{
var count = [_subviews count],
ephemeral
subviews = nil;
if (count > 0 && [_ephemeralSubviews count] > 0)
{
subviews = [_subviews.slice(0) copy];
while (count--)
if ([_ephemeralSubviews containsObject:_subviews[count]])
_subviews.splice(count, 1);
}
[super encodeWithCoder:aCoder];
[aCoder encodeInt:_isEnabled forKey:CPControlIsEnabledKey];
[aCoder encodeInt:_alignment forKey:CPControlAlignmentKey];
[aCoder encodeObject:_font forKey:CPControlFontKey];
[aCoder encodeObject:_textColor forKey:CPControlTextColorKey];
[aCoder encodeConditionalObject:_target forKey:CPControlTargetKey];
[aCoder encodeObject:_action forKey:CPControlActionKey];
if (subviews)
_subviews = subviews;
if (_value !== nil)
[aCoder encodeObject:_value forKey:CPControlValueKey];
if (_target !== nil)
[aCoder encodeConditionalObject:_target forKey:CPControlTargetKey];
if (_action !== NULL)
[aCoder encodeObject:_action forKey:CPControlActionKey];
[aCoder encodeInt:_sendActionOn forKey:CPControlSendActionOnKey];
}
@end
var _CPControlSizeIdentifiers = [],
_CPControlCachedThreePartImages = {},
_CPControlCachedColorWithPatternImages = {},
_CPControlCachedThreePartImagePattern = {};
_CPControlSizeIdentifiers[CPRegularControlSize] = @"Regular";
_CPControlSizeIdentifiers[CPSmallControlSize] = @"Small";
_CPControlSizeIdentifiers[CPMiniControlSize] = @"Mini";
_CPControlSizeIdentifiers[CPRegularControlSize] = "Regular";
_CPControlSizeIdentifiers[CPSmallControlSize] = "Small";
_CPControlSizeIdentifiers[CPMiniControlSize] = "Mini";
function _CPControlIdentifierForControlSize(aControlSize)
{
@@ -478,7 +696,7 @@ function _CPControlColorWithPatternImage(sizes, aClassName)
{
var index = 1,
count = arguments.length,
identifier = @"";
identifier = "";
for (; index < count; ++index)
identifier += arguments[index];
@@ -489,7 +707,7 @@ function _CPControlColorWithPatternImage(sizes, aClassName)
{
var bundle = [CPBundle bundleForClass:[CPControl class]];
color = [CPColor colorWithPatternImage:[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:aClassName + "/" + identifier + @".png"] size:sizes[identifier]]];
color = [CPColor colorWithPatternImage:[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:aClassName + "/" + identifier + ".png"] size:sizes[identifier]]];
_CPControlCachedColorWithPatternImages[identifier] = color;
}
@@ -497,41 +715,11 @@ function _CPControlColorWithPatternImage(sizes, aClassName)
return color;
}
function _CPControlThreePartImages(sizes, aClassName)
{
var index = 1,
count = arguments.length,
identifier = @"";
for (; index < count; ++index)
identifier += arguments[index];
var images = _CPControlCachedThreePartImages[identifier];
if (!images)
{
var bundle = [CPBundle bundleForClass:[CPControl class]],
path = aClassName + "/" + identifier;
sizes = sizes[identifier];
images = [
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:path + @"0.png"] size:sizes[0]],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:path + @"1.png"] size:sizes[1]],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:path + @"2.png"] size:sizes[2]]
];
_CPControlCachedThreePartImages[identifier] = images;
}
return images;
}
function _CPControlThreePartImagePattern(isVertical, sizes, aClassName)
{
var index = 2,
count = arguments.length,
identifier = @"";
identifier = "";
for (; index < count; ++index)
identifier += arguments[index];
@@ -546,9 +734,9 @@ function _CPControlThreePartImagePattern(isVertical, sizes, aClassName)
sizes = sizes[identifier];
color = [CPColor colorWithPatternImage:[[CPThreePartImage alloc] initWithImageSlices:[
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:path + @"0.png"] size:sizes[0]],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:path + @"1.png"] size:sizes[1]],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:path + @"2.png"] size:sizes[2]]
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:path + "0.png"] size:sizes[0]],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:path + "1.png"] size:sizes[1]],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:path + "2.png"] size:sizes[2]]
] isVertical:isVertical]];
_CPControlCachedThreePartImagePattern[identifier] = color;
@@ -556,4 +744,3 @@ function _CPControlThreePartImagePattern(isVertical, sizes, aClassName)
return color;
}
+11 -9
View File
@@ -20,12 +20,14 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
import <Foundation/CPObject.j>
import <Foundation/CPString.j>
@import <Foundation/CPObject.j>
@import <Foundation/CPString.j>
/*
<objj>CPCookie</objj> is the Cappuccino interface to a web browser cookie. You can set the name
/*!
@ingroup appkit
@class CPCookie
CPCookie is the Cappuccino interface to a web browser cookie. You can set the name
*/
@implementation CPCookie : CPObject
{
@@ -35,7 +37,7 @@ import <Foundation/CPString.j>
CPString _expires;
}
/*
/*!
Initializes a cookie with a given name <code>aName</code>.
@param the name for the cookie
*/
@@ -49,7 +51,7 @@ import <Foundation/CPString.j>
return self;
}
/*
/*!
Returns the cookie's data value
*/
- (CPString)value
@@ -57,7 +59,7 @@ import <Foundation/CPString.j>
return _cookieValue;
}
/*
/*!
Returns the cookie's name
*/
- (CPString)name
@@ -65,7 +67,7 @@ import <Foundation/CPString.j>
return _cookieName;
}
/*
/*!
Returns the cookie's expiration date
*/
- (CPString)expires
@@ -73,7 +75,7 @@ import <Foundation/CPString.j>
return _expires;
}
/*
/*!
Sets a value, expiration date, and domain for the cookie
@param value the cookie's value
@param date the cookie's expiration date
+46 -38
View File
@@ -20,11 +20,12 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
import <Foundation/CPString.j>
import <Foundation/CPArray.j>
@import <Foundation/CPString.j>
@import <Foundation/CPArray.j>
@import "CPResponder.j"
@import "CPWindowController.j"
import "CPResponder.j"
import "CPWindowController.j"
/*
@global
@@ -79,11 +80,14 @@ CPDocumentDidFailToSaveNotification = @"CPDocumentDidFailToSaveNotification";
var CPDocumentUntitledCount = 0;
/*
<objj>CPDocument</objj> is used to represent a document/file in a Cappuccino application.
/*!
@ingroup appkit
@class CPDocument
CPDocument is used to represent a document/file in a Cappuccino application.
In a document-based application, generally multiple documents are open simutaneously
(multiple text documents, slide presentations, spreadsheets, etc.), and multiple
<objj>CPDocument</objj>s should be used to represent this.
CPDocuments should be used to represent this.
*/
@implementation CPDocument : CPResponder
{
@@ -101,7 +105,7 @@ var CPDocumentUntitledCount = 0;
CPURLRequest _writeRequest;
}
/*
/*!
Initializes an empty document.
@return the initialized document
*/
@@ -122,7 +126,7 @@ var CPDocumentUntitledCount = 0;
return self;
}
/*
/*!
Initializes the document with a specific data type.
@param aType the type of document to initialize
@param anError not used
@@ -138,7 +142,7 @@ var CPDocumentUntitledCount = 0;
return self;
}
/*
/*!
Initializes a document of a specific type located at a URL. Notifies
the provided delegate after initialization.
@param anAbsoluteURL the url of the document content
@@ -164,7 +168,7 @@ var CPDocumentUntitledCount = 0;
return self;
}
/*
/*!
Initializes the document from a URL.
@param anAbsoluteURL the document location
@param absoluteContentsURL the location of the document's contents
@@ -189,7 +193,7 @@ var CPDocumentUntitledCount = 0;
return self;
}
/*
/*!
Returns the receiver's data in a specified type. The default implementation just
throws an exception.
@param aType the format of the data
@@ -203,7 +207,7 @@ var CPDocumentUntitledCount = 0;
reason:"dataOfType:error: must be overridden by the document subclass."];
}
/*
/*!
Sets the content of the document by reading the provided
data. The default implementation just throws an exception.
@param aData the document's data
@@ -219,7 +223,7 @@ var CPDocumentUntitledCount = 0;
}
// Creating and managing window controllers
/*
/*!
Creates the window controller for this document.
*/
- (void)makeWindowControllers
@@ -229,7 +233,7 @@ var CPDocumentUntitledCount = 0;
[self addWindowController:controller];
}
/*
/*!
Returns the document's window controllers
*/
- (CPArray)windowControllers
@@ -237,7 +241,7 @@ var CPDocumentUntitledCount = 0;
return _windowControllers;
}
/*
/*!
Add a controller to the document's list of controllers. This should
be called after making a new window controller.
@param aWindowController the controller to add
@@ -254,7 +258,7 @@ var CPDocumentUntitledCount = 0;
}
// Managing Document Windows
/*
/*!
Shows all the document's windows.
*/
- (void)showWindows
@@ -262,7 +266,7 @@ var CPDocumentUntitledCount = 0;
[_windowControllers makeObjectsPerformSelector:@selector(showWindow:) withObject:self];
}
/*
/*!
Returns the name of the document as displayed in the title bar.
*/
- (CPString)displayName
@@ -279,7 +283,7 @@ var CPDocumentUntitledCount = 0;
return @"Untitled " + _untitledDocumentIndex;
}
/*
/*!
Returns the document's Cib name
*/
- (CPString)windowCibName
@@ -287,7 +291,7 @@ var CPDocumentUntitledCount = 0;
return nil;
}
/*
/*!
Called after <code>aWindowController<code> loads the document's Nib file.
@param aWindowController the controller that loaded the Nib file
*/
@@ -295,7 +299,7 @@ var CPDocumentUntitledCount = 0;
{
}
/*
/*!
Called before <code>aWindowController</code> will load the document's Nib file.
@param aWindowController the controller that will load the Nib file
*/
@@ -304,7 +308,7 @@ var CPDocumentUntitledCount = 0;
}
// Reading from and Writing to URLs
/*
/*!
Set the document's data from a URL. Notifies the provided delegate afterwards.
@param anAbsoluteURL the URL to the document's content
@param aType the document type
@@ -322,7 +326,7 @@ var CPDocumentUntitledCount = 0;
_readConnection.session = _CPReadSessionMake(aType, aDelegate, aDidReadSelector, aContextInfo);
}
/*
/*!
Returns the path to the document's file.
*/
- (CPURL)fileURL
@@ -330,7 +334,7 @@ var CPDocumentUntitledCount = 0;
return _fileURL;
}
/*
/*!
Sets the path to the document's file.
@param aFileURL the path to the document's file
*/
@@ -344,7 +348,7 @@ var CPDocumentUntitledCount = 0;
[_windowControllers makeObjectsPerformSelector:@selector(synchronizeWindowTitleWithDocumentName)];
}
/*
/*!
Saves the document to the specified URL. Notifies the provided delegate
with the provided selector and context info afterwards.
@param anAbsoluteURL the url to write the document data to
@@ -384,10 +388,14 @@ var CPDocumentUntitledCount = 0;
*/
- (void)connection:(CPURLConnection)aConnection didReceiveResponse:(CPURLResponse)aResponse
{
// If we got this far and it wasn't an HTTP request, then everything is fine.
if (![aResponse isKindOfClass:[CPHTTPURLResponse class]])
return;
var statusCode = [aResponse statusCode];
// Nothing to do if everything is hunky dory.
if (statusCode == 200)
if (statusCode === 200)
return;
var session = aConnection.session;
@@ -493,7 +501,7 @@ var CPDocumentUntitledCount = 0;
}
// Managing Document Status
/*
/*!
Returns <code>YES</code> if there are any unsaved changes.
*/
- (BOOL)isDocumentEdited
@@ -501,7 +509,7 @@ var CPDocumentUntitledCount = 0;
return _changeCount != 0;
}
/*
/*!
Updates the number of unsaved changes to the document.
@param aChangeType a new document change to apply
*/
@@ -521,7 +529,7 @@ var CPDocumentUntitledCount = 0;
}
// Managing File Types
/*
/*!
Sets the document's file type
@param aType the document's type
*/
@@ -530,7 +538,7 @@ var CPDocumentUntitledCount = 0;
_fileType = aType;
}
/*
/*!
Returns the document's file type
*/
- (CPString)fileType
@@ -539,17 +547,17 @@ var CPDocumentUntitledCount = 0;
}
// Working with Undo Manager
/*
/*!
Returns <code>YES</code> if the document has a
<objj>CPUndoManager</objj>.
CPUndoManager.
*/
- (BOOL)hasUndoManager
{
return _hasUndoManager;
}
/*
Sets whether the document should have a <objj>CPUndoManager</objj>.
/*!
Sets whether the document should have a CPUndoManager.
@param aFlag <code>YES</code> makes the document have an undo manager
*/
- (void)setHasUndoManager:(BOOL)aFlag
@@ -632,7 +640,7 @@ var CPDocumentUntitledCount = 0;
}
}
/*
/*!
Returns the document's undo manager. If the document
should have one, but the manager is <code>nil</code>, it
will be created and then returned.
@@ -647,7 +655,7 @@ var CPDocumentUntitledCount = 0;
}
/*
Implemented as a delegate of a <objj>CPWindow</objj>
Implemented as a delegate of a CPWindow
@ignore
*/
- (CPUndoManager)windowWillReturnUndoManager:(CPWindow)aWindow
@@ -656,7 +664,7 @@ var CPDocumentUntitledCount = 0;
}
// Handling User Actions
/*
/*!
Saves the document. If the document does not
have a file path to save to (<code>fileURL</code>)
then <code>saveDocumentAs:</code> will be called.
@@ -676,7 +684,7 @@ var CPDocumentUntitledCount = 0;
[self saveDocumentAs:self];
}
/*
/*!
Saves the document to a user specified path.
@param aSender the object requesting the operation
*/
+22 -19
View File
@@ -20,14 +20,17 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
import <Foundation/CPObject.j>
import <Foundation/CPBundle.j>
@import <Foundation/CPObject.j>
@import <Foundation/CPBundle.j>
@import "CPDocument.j"
import "CPDocument.j"
var CPSharedDocumentController = nil;
/*
/*!
@ingroup appkit
@class CPDocumentController
This class is responsible for managing an application's open documents.
*/
@implementation CPDocumentController : CPObject
@@ -36,10 +39,10 @@ var CPSharedDocumentController = nil;
CPArray _documentTypes;
}
/*
/*!
Returns the singleton instance of the application's document controller. If it has not
been created yet, it will be created then returned.
@return a <objj>CPDocumentController</objj>
@return a CPDocumentController
*/
+ (id)sharedDocumentController
{
@@ -70,7 +73,7 @@ var CPSharedDocumentController = nil;
// Creating and Opening Documents
/*
/*!
Returns the document matching the specified URL. This
method searches documents already open. It does not
open the document at the URL if it is not already open.
@@ -93,7 +96,7 @@ var CPSharedDocumentController = nil;
return nil;
}
/*
/*!
Creates a new document of the specified type.
@param aType the type of the new document
@param shouldDisplay whether to display the document on screen
@@ -114,7 +117,7 @@ var CPSharedDocumentController = nil;
return theDocument;
}
/*
/*!
Creates a document of the specified type.
@param aType the document type
@param anError not used
@@ -125,7 +128,7 @@ var CPSharedDocumentController = nil;
return [[[self documentClassForType:aType] alloc] initWithType:aType error:anError];
}
/*
/*!
Opens the document at the specified URL.
@param anAbsoluteURL the path to the document's file
@param shouldDisplay whether to display the document on screen
@@ -148,7 +151,7 @@ var CPSharedDocumentController = nil;
return result;
}
/*
/*!
Loads a document for a specified URL with it's content
retrieved from another URL.
@param anAbsoluteURL the document URL
@@ -161,7 +164,7 @@ var CPSharedDocumentController = nil;
return [self makeDocumentForURL:anAbsoluteURL withContentsOfURL:absoluteContentsURL ofType:[[_documentTypes objectAtIndex:0] objectForKey:@"CPBundleTypeName"] delegate:self didReadSelector:@selector(document:didRead:contextInfo:) contextInfo:nil];
}
/*
/*!
Creates a document from the contents at the specified URL.
Notifies the provided delegate with the provided selector afterwards.
@param anAbsoluteURL the location of the document data
@@ -175,7 +178,7 @@ var CPSharedDocumentController = nil;
return [[[self documentClassForType:aType] alloc] initWithContentsOfURL:anAbsoluteURL ofType:aType delegate:aDelegate didReadSelector:aSelector contextInfo:aContextInfo];
}
/*
/*!
Creates a document from the contents of a URL, and sets
the document's URL location as another URL.
@param anAbsoluteURL the document's location
@@ -207,7 +210,7 @@ var CPSharedDocumentController = nil;
[aDocument showWindows];
}
/*
/*!
Opens a new document in the application.
@param aSender the requesting object
*/
@@ -218,7 +221,7 @@ var CPSharedDocumentController = nil;
// Managing Documents
/*
/*!
Returns the array of all documents being managed. This is
the same as all open documents in the application.
*/
@@ -227,7 +230,7 @@ var CPSharedDocumentController = nil;
return _documents;
}
/*
/*!
Adds <code>aDocument</code> under the control of the receiver.
@param aDocument the document to add
*/
@@ -236,7 +239,7 @@ var CPSharedDocumentController = nil;
[_documents addObject:aDocument];
}
/*
/*!
Removes <code>aDocument</code> from the control of the receiver.
@param aDocument the document to remove
*/
@@ -292,8 +295,8 @@ var CPSharedDocumentController = nil;
return nil;
}
/*
Returns the <objj>CPDocument</objj> subclass associated with <code>aType</code>.
/*!
Returns the CPDocument subclass associated with <code>aType</code>.
@param aType the type of document
@return a Cappuccino Class object, or <code>nil</code> if no match was found
*/
+83 -44
View File
@@ -20,21 +20,28 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
import <AppKit/CPView.j>
import <AppKit/CPEvent.j>
import <AppKit/CPPasteboard.j>
import <AppKit/CPImageView.j>
@import <AppKit/CPView.j>
@import <AppKit/CPEvent.j>
@import <AppKit/CPPasteboard.j>
@import <AppKit/CPImageView.j>
#import "CoreGraphics/CGGeometry.h"
#define DRAGGING_WINDOW(anObject) ([anObject isKindOfClass:[CPWindow class]] ? anObject : [anObject window])
var CPSharedDragServer = nil;
var CPDragServerView = nil,
CPDragServerSource = nil,
CPDragServerWindow = nil,
CPDragServerOffset = nil,
CPDragServerLocation = nil,
CPDragServerPasteboard = nil,
CPDragServerDestination = nil,
CPDragServerDraggingInfo = nil;
var CPDragServerView = nil,
CPDragServerSource = nil,
CPDragServerWindow = nil,
CPDragServerOffset = nil,
CPDragServerLocation = nil,
CPDragServerPasteboard = nil,
CPDragServerDestination = nil,
CPDragServerDraggingInfo = nil,
CPDragServerPreviousEvent = nil,
CPDragServerAutoscrollInterval = nil;
var CPDragServerIsDraggingImage = NO,
@@ -44,6 +51,11 @@ var CPDragServerIsDraggingImage = NO,
CPDragServerShouldSendDraggedViewEndedAtOperation = NO,
CPDragServerShouldSendDraggedImageEndedAtOperation = NO;
var CPDragServerAutoscroll = function()
{
[CPDragServerSource autoscroll:CPDragServerPreviousEvent];
}
var CPDragServerStartDragging = function(anEvent)
{
CPDragServerUpdateDragging(anEvent);
@@ -54,7 +66,12 @@ var CPDragServerUpdateDragging = function(anEvent)
// If this is a mouse up, then complete the drag.
if([anEvent type] == CPLeftMouseUp)
{
CPDragServerLocation = [[CPDragServerDestination window] convertBridgeToBase:[[anEvent window] convertBaseToBridge:[anEvent locationInWindow]]];
if (CPDragServerAutoscrollInterval !== nil)
clearInterval(CPDragServerAutoscrollInterval);
CPDragServerAutoscrollInterval = nil;
CPDragServerLocation = [DRAGGING_WINDOW(CPDragServerDestination) convertBridgeToBase:[[anEvent window] convertBaseToBridge:[anEvent locationInWindow]]];
[CPDragServerView removeFromSuperview];
[CPSharedDragServer._dragWindow orderOut:nil];
@@ -72,10 +89,18 @@ var CPDragServerUpdateDragging = function(anEvent)
CPDragServerIsDraggingImage = NO;
CPDragServerDestination = nil;
return;
}
if (CPDragServerAutoscrollInterval === nil)
{
if ([CPDragServerSource respondsToSelector:@selector(autoscroll:)])
CPDragServerAutoscrollInterval = setInterval(CPDragServerAutoscroll, 100);
}
CPDragServerPreviousEvent = anEvent;
// If we're not a mouse up, then we're going to want to grab the next event.
[CPApp setCallback:CPDragServerUpdateDragging
forNextEventMatchingMask:CPMouseMovedMask | CPLeftMouseDraggedMask | CPLeftMouseUpMask
@@ -88,7 +113,7 @@ var CPDragServerUpdateDragging = function(anEvent)
// We have to convert base to bridge since the drag event comes from the source window, not the drag window.
var draggingDestination = [[CPDOMWindowBridge sharedDOMWindowBridge] _dragHitTest:bridgeLocation pasteboard:CPDragServerPasteboard];
CPDragServerLocation = [[CPDragServerDestination window] convertBridgeToBase:bridgeLocation];
CPDragServerLocation = [DRAGGING_WINDOW(draggingDestination) convertBridgeToBase:bridgeLocation];
if(draggingDestination != CPDragServerDestination)
{
@@ -115,25 +140,11 @@ var CPDragServerUpdateDragging = function(anEvent)
}
/*
<objj>CPDraggingInfo</objj> is a container of information about a specific dragging session.
CPDraggingInfo is a container of information about a specific dragging session.
@ignore
*/
@implementation CPDraggingInfo : CPObject
{
CPWindow _window;
}
/*
Initializes the receiver with the window
*/
- (id)initWithWindow:(CPWindow)aWindow
{
self = [super init];
if (self)
_window = aWindow;
return this;
}
- (id)draggingSource
@@ -151,6 +162,26 @@ var CPDragServerUpdateDragging = function(anEvent)
return CPDragServerPasteboard;
}
- (CPImage)draggedImage
{
return [CPDragServerView image];
}
- (CGPoint)draggedImageLocation
{
return [self draggedViewLocation];
}
- (CGPoint)draggedViewLocation
{
return [DRAGGING_WINDOW(CPDragServerDestination) convertBridgeToBase:[CPDragServerView frame].origin];
}
- (CPView)draggedView
{
return CPDragServerView;
}
@end
@implementation CPDragServer : CPObject
@@ -195,7 +226,7 @@ var CPDragServerUpdateDragging = function(anEvent)
return self;
}
/*
/*!
Initiates a drag session.
@param aView the view being dragged
@param aWindow the window where the drag source is
@@ -250,7 +281,7 @@ var CPDragServerUpdateDragging = function(anEvent)
CPDragServerStartDragging(anEvent);
}
/*
/*!
Initiates a drag session.
@param anImage the image to be dragged
@param aWindow the source window of the drag session
@@ -277,23 +308,31 @@ var CPDragServerUpdateDragging = function(anEvent)
@end
@implementation CPView (CPDraggingAdditions)
@implementation CPWindow (CPDraggingAdditions)
/* @ignore */
- (CPView)_dragHitTest:(CPPoint)aPoint pasteboard:(CPPasteboard)aPasteboard
- (id)_dragHitTest:(CGPoint)aPoint pasteboard:(CPPasteboard)aPasteboard
{
if(!CPRectContainsPoint(_frame, aPoint) || self == CPDragServerView)
// If none of our views or ourselves has registered for drag events...
if (!_inclusiveRegisteredDraggedTypes)
return nil;
// We don't need to do this because the only place this gets called
// -_dragHitTest: in CPDOMWindowBridge does this already. Perhaps to
// be safe?
// if (![self containsPoint:aPoint])
// return nil;
var adjustedPoint = _CGPointMake(aPoint.x - _CGRectGetMinX(_frame), aPoint.y - _CGRectGetMinY(_frame)),
hitView = [_windowView hitTest:adjustedPoint];
while (hitView && ![aPasteboard availableTypeFromArray:[hitView registeredDraggedTypes]])
hitView = [hitView superview];
var view = nil,
i = [_subviews count],
adjustedPoint = CPPointMake(aPoint.x - CPRectGetMinX(_frame), aPoint.y - CPRectGetMinY(_frame));
while (i--)
if (view = [_subviews[i] _dragHitTest:adjustedPoint pasteboard:aPasteboard])
return view;
if ([aPasteboard availableTypeFromArray:_registeredDraggedTypes])
if (hitView)
return hitView;
if ([aPasteboard availableTypeFromArray:[self registeredDraggedTypes]])
return self;
return nil;
+72 -36
View File
@@ -20,10 +20,11 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
import <Foundation/CPObject.j>
@import <Foundation/CPObject.j>
#include "CoreGraphics/CGGeometry.h"
/*
@global
@group CPEventType
@@ -129,6 +130,13 @@ CPOtherMouseUp = 26;
@group CPEventType
*/
CPOtherMouseDragged = 27;
// iPhone Event Types
CPTouchStart = 28;
CPTouchMove = 29;
CPTouchEnd = 30;
CPTouchCancel = 31;
CPAlphaShiftKeyMask = 1 << 16;
CPShiftKeyMask = 1 << 17;
@@ -174,12 +182,18 @@ CPDOMEventKeyPress = "keypress";
CPDOMEventCopy = "copy";
CPDOMEventPaste = "paste";
CPDOMEventScrollWheel = "mousewheel";
CPDOMEventTouchStart = "touchstart";
CPDOMEventTouchMove = "touchmove";
CPDOMEventTouchEnd = "touchend";
CPDOMEventTouchCancel = "touchcancel";
var _CPEventPeriodicEventPeriod = 0,
_CPEventPeriodicEventTimer = nil;
/*
<objj>CPEvent</objj> encapsulates the details of a Cappuccino keyboard or mouse event.
/*!
@ingroup appkit
@class CPEvent
CPEvent encapsulates the details of a Cappuccino keyboard or mouse event.
*/
@implementation CPEvent : CPObject
{
@@ -192,6 +206,7 @@ var _CPEventPeriodicEventPeriod = 0,
unsigned _clickCount;
float _pressure;
CPWindow _window;
Number _windowNumber;
CPString _characters;
CPString _charactersIgnoringModifiers
BOOL _isARepeat;
@@ -203,20 +218,20 @@ var _CPEventPeriodicEventPeriod = 0,
float _deltaZ;
}
/*
/*!
Creates a new keyboard event.
@param anEventType the event type. Must be one of <objj>CPKeyDown</objj>, <objj>CPKeyUp</objj> or <objj>CPFlagsChanged</objj>
@param anEventType the event type. Must be one of CPKeyDown, CPKeyUp or CPFlagsChanged
@param aPoint the location of the cursor in the window specified by <code>aWindowNumber</code>
@param modifierFlags a bitwise combination of the modifiers specified in the <objj>CPEvent</objj> globals
@param modifierFlags a bitwise combination of the modifiers specified in the CPEvent globals
@param aTimestamp the time the event occurred
@param aWindowNumber the number of the <objj>CPWindow</objj> where the event occurred
@param aWindowNumber the number of the CPWindow where the event occurred
@param aGraphicsContext the graphics context where the event occurred
@param characters the characters associated with the event
@param unmodCharacters the string of keys pressed without the presence of any modifiers other than Shift
@param repeatKey <code>YES</code> if this is caused by the system repeat as opposed to the user pressing the key again
@param code a number associated with the keyboard key of this event
@throws CPInternalInconsistencyException if <code>anEventType</code> is not a <objj>CPKeyDown</objj>,
<objj>CPKeyUp</objj> or <objj>CPFlagsChanged</objj>
@throws CPInternalInconsistencyException if <code>anEventType</code> is not a CPKeyDown,
CPKeyUp or CPFlagsChanged
@return the keyboard event
*/
+ (CPEvent)keyEventWithType:(CPEventType)anEventType location:(CGPoint)aPoint modifierFlags:(unsigned int)modifierFlags
@@ -228,13 +243,13 @@ var _CPEventPeriodicEventPeriod = 0,
characters:characters charactersIgnoringModifiers:unmodCharacters isARepeat:repeatKey keyCode:code];
}
/*
/*!
Creates a new mouse event
@param anEventType the event type
@param aPoint the location of the cursor in the window specified by <code>aWindowNumber</code>
@param modifierFlags a bitwise combination of the modifiers specified in the <objj>CPEvent</objj> globals
@param modifierFlags a bitwise combination of the modifiers specified in the CPEvent globals
@param aTimestamp the time the event occurred
@param aWindowNumber the number of the <objj>CPWindow</objj> where the event occurred
@param aWindowNumber the number of the CPWindow where the event occurred
@param aGraphicsContext the graphics context where the event occurred
@param anEventNumber a number for this event
@param aClickCount the number of clicks that caused this event
@@ -250,13 +265,13 @@ var _CPEventPeriodicEventPeriod = 0,
timestamp:aTimestamp windowNumber:aWindowNumber context:aGraphicsContext eventNumber:anEventNumber clickCount:aClickCount pressure:aPressure];
}
/*
/*!
Creates a new custom event
@param anEventType the event type. Must be one of <objj>CPAppKitDefined</objj>, <objj>CPSystemDefined</objj>, <objj>CPApplicationDefined</objj> or <objj>CPPeriodic</objj>
@param anEventType the event type. Must be one of CPAppKitDefined, CPSystemDefined, CPApplicationDefined or CPPeriodic
@param aLocation the location of the cursor in the window specified by <code>aWindowNumber</code>
@param modifierFlags a bitwise combination of the modifiers specified in the <objj>CPEvent</objj> globals
@param modifierFlags a bitwise combination of the modifiers specified in the CPEvent globals
@param aTimestamp the time the event occurred
@param aWindowNumber the number of the <objj>CPWindow</objj> where the event occurred
@param aWindowNumber the number of the CPWindow where the event occurred
@param aGraphicsContext the graphics context where the event occurred
@param aSubtype a numeric identifier to differentiate this event from other custom events
@param aData1 more data that describes the event
@@ -313,7 +328,7 @@ var _CPEventPeriodicEventPeriod = 0,
_charactersIgnoringModifiers = unmodCharacters;
_isARepeat = isARepeat;
_keyCode = code;
_window = [CPApp windowWithWindowNumber:aWindowNumber];
_windowNumber = aWindowNumber;
}
return self;
@@ -341,7 +356,7 @@ var _CPEventPeriodicEventPeriod = 0,
return self;
}
/*
/*!
Returns the location of the mouse (for mouse events).
If this is not a mouse event, it returns <code>nil</code>.
If <code>window</code> returns <code>nil</code>, then
@@ -354,7 +369,7 @@ var _CPEventPeriodicEventPeriod = 0,
return _location;
}
/*
/*!
Returns event information as a bit mask
*/
- (unsigned)modifierFlags
@@ -362,7 +377,7 @@ var _CPEventPeriodicEventPeriod = 0,
return _modifierFlags;
}
/*
/*!
Returns the time the event occurred
*/
- (CPTimeInterval)timestamp
@@ -370,7 +385,7 @@ var _CPEventPeriodicEventPeriod = 0,
return _timestamp;
}
/*
/*!
Returns the type of event.
*/
- (CPEventType)type
@@ -378,15 +393,18 @@ var _CPEventPeriodicEventPeriod = 0,
return _type;
}
/*
/*!
Returns the event's associated window
*/
- (CPWindow)window
{
if (!_window)
_window = [CPApp windowWithWindowNumber:_windowNumber];
return _window;
}
/*
/*!
The number of the window associated with the event.
*/
- (int)windowNumber
@@ -395,7 +413,7 @@ var _CPEventPeriodicEventPeriod = 0,
}
// Mouse Event Information
/*
/*!
Returns the button number for the mouse that generated the event.
*/
- (int)buttonNumber
@@ -403,7 +421,7 @@ var _CPEventPeriodicEventPeriod = 0,
return _buttonNumber;
}
/*
/*!
Returns the number of clicks that caused this event. (mouse only)
*/
- (int)clickCount
@@ -411,7 +429,7 @@ var _CPEventPeriodicEventPeriod = 0,
return _clickCount;
}
/*
/*!
Returns the characters associated with this event (keyboard only)
@throws CPInternalInconsistencyException if this method is called on a non-key event
*/
@@ -420,7 +438,7 @@ var _CPEventPeriodicEventPeriod = 0,
return _characters;
}
/*
/*!
Returns the character ignoring any modifiers (except shift).
@throws CPInternalInconsistencyException if this method is called on a non-key event
*/
@@ -429,7 +447,7 @@ var _CPEventPeriodicEventPeriod = 0,
return _charactersIgnoringModifiers;
}
/*
/*!
Returns <code>YES</code> if the keyboard event was caused by the key being held down.
@throws CPInternalInconsistencyException if this method is called on a non-key event
*/
@@ -438,7 +456,7 @@ var _CPEventPeriodicEventPeriod = 0,
return _isARepeat;
}
/*
/*!
Returns the key's key code.
@throws CPInternalInconsistencyException if this method is called on a non-key event
*/
@@ -461,7 +479,7 @@ var _CPEventPeriodicEventPeriod = 0,
}
// Getting Scroll Wheel Event Infomration
/*
/*!
Returns the change in the x-axis for a mouse event.
*/
- (float)deltaX
@@ -469,7 +487,7 @@ var _CPEventPeriodicEventPeriod = 0,
return _deltaX;
}
/*
/*!
Returns the change in the y-axis for a mouse event.
*/
- (float)deltaY
@@ -477,7 +495,7 @@ var _CPEventPeriodicEventPeriod = 0,
return _deltaY;
}
/*
/*!
Returns the change in the x-axis for a mouse event.
*/
- (float)deltaZ
@@ -485,7 +503,7 @@ var _CPEventPeriodicEventPeriod = 0,
return _deltaZ;
}
/*
/*!
Generates periodic events every <code>aPeriod</code> seconds.
@param aDelay the number of seconds before the first event
@param aPeriod the length of time in seconds between successive events
@@ -498,7 +516,7 @@ var _CPEventPeriodicEventPeriod = 0,
_CPEventPeriodicEventTimer = window.setTimeout(function() { _CPEventPeriodicEventTimer = window.setInterval(_CPEventFirePeriodEvent, aPeriod * 1000.0); }, aDelay * 1000.0);
}
/*
/*!
Stops the periodic events from being generated
*/
+ (void)stopPeriodicEvents
@@ -516,7 +534,25 @@ var _CPEventPeriodicEventPeriod = 0,
function _CPEventFirePeriodEvent()
{
[CPApp sendEvent:[CPEvent otherEventWithType:CPPeriodic location:_CGPointMakeZero() modifierFlags:0 timestamp:0 windowNumber:0 context:nil subtype:0 data1:0 data2:0]];
[[CPRunLoop currentRunLoop] performSelectors];
}
var CPEventClass = [CPEvent class];
function _CPEventFromNativeMouseEvent(aNativeEvent, anEventType, aPoint, modifierFlags, aTimestamp, aWindowNumber, aGraphicsContext, anEventNumber, aClickCount, aPressure)
{
aNativeEvent.isa = CPEventClass;
aNativeEvent._type = anEventType;
aNativeEvent._location = aPoint;
aNativeEvent._modifierFlags = modifierFlags;
aNativeEvent._timestamp = aTimestamp;
aNativeEvent._windowNumber = aWindowNumber;
aNativeEvent._window = nil;
aNativeEvent._context = aGraphicsContext;
aNativeEvent._eventNumber = anEventNumber;
aNativeEvent._clickCount = aClickCount;
aNativeEvent._pressure = aPressure;
return aNativeEvent;
}
+16 -1
View File
@@ -20,19 +20,34 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
import <Foundation/CPObject.j>
@import <Foundation/CPObject.j>
/*!
@ingroup appkit
@class CPFlashMovie
CPFlashMovie is used to represent a Flash movie in the Cappuccino framework.
*/
@implementation CPFlashMovie : CPObject
{
CPString _fileName;
}
/*!
Creates a new Flash movie with the swf at <code>aFileName</code>.
@param aFilename the swf to load
@return the initialized CPFlashMovie
*/
+ (id)flashMovieWithFile:(CPString)aFileName
{
return [[self alloc] initWithFile:aFileName];
}
/*!
Initializes the Flash movie.
@param aFilename the swf to load
@return the initialized CPFlashMovie
*/
- (id)initWithFile:(CPString)aFileName
{
self = [super init];
+7 -5
View File
@@ -20,11 +20,13 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
import "CPDOMWindowBridge.j"
import "CPFlashMovie.j"
import "CPView.j"
@import "CPDOMWindowBridge.j"
@import "CPFlashMovie.j"
@import "CPView.j"
/*!
@ingroup appkit
*/
@implementation CPFlashView : CPView
{
CPFlashMovie _flashMovie;
@@ -61,7 +63,7 @@ import "CPView.j"
_DOMEmbedElement = document.createElement("embed");
_DOMEmbedElement.type = "application/x-shockwave-flash";
_DOMEmbedElement.wmode = "transparent";
_DOMEmbedElement.setAttribute("wmode", "transparent");
_DOMEmbedElement.width = "100%";
_DOMEmbedElement.height = "100%";
+15 -12
View File
@@ -25,8 +25,11 @@ var _CPFonts = {};
#define _CPCachedFont(aName, aSize, isBold) _CPFonts[(isBold ? @"bold " : @"") + ROUND(aSize) + @"px '" + aName + @"'"]
/*
The <objj>CPFont</objj> class allows control of the fonts used for displaying text anywhere on the screen. The primary method for getting a particular font is through one of the class methods that take a name and/or size as arguments, and return the appropriate <objj>CPFont</objj>.
/*!
@ingroup appkit
@class CPFont
The CPFont class allows control of the fonts used for displaying text anywhere on the screen. The primary method for getting a particular font is through one of the class methods that take a name and/or size as arguments, and return the appropriate CPFont.
*/
@implementation CPFont : CPObject
{
@@ -37,7 +40,7 @@ var _CPFonts = {};
CPString _cssString;
}
/*
/*!
Returns a font with the specified name and size.
@param aName the name of the font
@param aSize the size of the font (in points)
@@ -48,7 +51,7 @@ var _CPFonts = {};
return _CPCachedFont(aName, aSize, NO) || [[CPFont alloc] _initWithName:aName size:aSize bold:NO];
}
/*
/*!
Returns a bold font with the specified name and size.
@param aName the name of the font
@param aSize the size of the font (in points)
@@ -59,7 +62,7 @@ var _CPFonts = {};
return _CPCachedFont(aName, aSize, YES) || [[CPFont alloc] _initWithName:aName size:aSize bold:YES];
}
/*
/*!
Returns the system font scaled to the specified size
@param aSize the size of the font (in points)
@return the requested system font
@@ -69,7 +72,7 @@ var _CPFonts = {};
return _CPCachedFont(_CPFontSystemFontFace, aSize, NO) || [[CPFont alloc] _initWithName:_CPFontSystemFontFace size:aSize bold:NO];
}
/*
/*!
Returns the bold system font scaled to the specified size
@param aSize the size of the font (in points)
@return the requested bold system font
@@ -79,7 +82,7 @@ var _CPFonts = {};
return _CPCachedFont(_CPFontSystemFontFace, aSize, YES) || [[CPFont alloc] _initWithName:_CPFontSystemFontFace size:aSize bold:YES];
}
/** FIXME Font Descriptor
/* FIXME Font Descriptor
@ignore
*/
- (id)_initWithName:(CPString)aName size:(float)aSize bold:(BOOL)isBold
@@ -100,7 +103,7 @@ var _CPFonts = {};
return self;
}
/*
/*!
Returns the font size (in points)
*/
- (float)size
@@ -108,7 +111,7 @@ var _CPFonts = {};
return _size;
}
/*
/*!
Returns the font as a CSS string
*/
- (CPString)cssString
@@ -116,7 +119,7 @@ var _CPFonts = {};
return _cssString;
}
/*
/*!
Returns the font's family name
*/
- (CPString)familyName
@@ -132,7 +135,7 @@ var CPFontNameKey = @"CPFontNameKey",
@implementation CPFont (CPCoding)
/*
/*!
Initializes the font from a coder.
@param aCoder the coder from which to read the font data
@return the initialized font
@@ -144,7 +147,7 @@ var CPFontNameKey = @"CPFontNameKey",
bold:[aCoder decodeBoolForKey:CPFontIsBoldKey]];
}
/*
/*!
Writes the font information out to a coder.
@param aCoder the coder to which the data will be written
*/
+9 -6
View File
@@ -20,21 +20,24 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
import <Foundation/CPObject.j>
@import <Foundation/CPObject.j>
import <AppKit/CPFont.j>
@import <AppKit/CPFont.j>
var CPSharedFontManager = nil,
CPFontManagerFactory = Nil;
/*!
@ingroup appkit
*/
@implementation CPFontManager : CPObject
{
CPArray _availableFonts;
}
// Getting the Shared Font Manager
/*
/*!
Returns the application's font manager. If the font
manager does not exist yet, it will be created.
*/
@@ -47,7 +50,7 @@ var CPSharedFontManager = nil,
}
// Changing the Default Font Conversion Classes
/*
/*!
Sets the class that will be used to create the applcation's
font manager.
*/
@@ -56,7 +59,7 @@ var CPSharedFontManager = nil,
CPFontManagerFactory = aClass;
}
/*
/*!
Returns an array of the available fonts
*/
- (CPArray)availableFonts
@@ -84,7 +87,7 @@ var CPSharedFontManager = nil,
return _availableFonts;
}
/*
/*!
Returns the available fonts matching the provided name.
@param aFontName the name of the font
*/
+90 -80
View File
@@ -20,7 +20,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
import "CGGeometry.j"
@import "CGGeometry.j"
CPMinXEdge = 0;
CPMinYEdge = 1;
@@ -32,7 +33,12 @@ CPMakePoint = CGPointMake;
CPMakeSize = CGSizeMake;
CPMakeRect = CGRectMake;
/**
/*!
@addtogroup appkit
@{
*/
/*!
Creates a copy of a specified point and returns the copy
@group CGPoint
@param the point to be copied
@@ -43,7 +49,7 @@ function CPPointCreateCopy(aPoint)
return { x: aPoint.x, y: aPoint.y };
}
/**
/*!
Makes a CGPoint object out of two numbers provided as arguments
@group CGPoint
@param x the x-coordinate of the CGPoint
@@ -55,7 +61,7 @@ function CPPointMake(x, y)
return { x: x, y: y };
}
/*
/*!
Makes a CGRect with an origin and size equal to <code>aRect</code> less the <code>dX/dY</code> insets specified.
@param dX the size of the inset in the x-axis
@param dY the size of the inset in the y-axis
@@ -68,7 +74,7 @@ function CPRectInset(aRect, dX, dY)
aRect.size.width - 2 * dX, aRect.size.height - 2*dY);
}
/*
/*!
@group CGRect
@ignore
@return void
@@ -80,7 +86,7 @@ function CPRectIntegral(aRect)
alert("CPRectIntegral unimplemented");
}
/*
/*!
Returns the intersection of the two provided rectangles as a new rectangle
@group CGRect
@param lhsRect the first rectangle used for calculation
@@ -100,7 +106,7 @@ function CPRectIntersection(lhsRect, rhsRect)
return CPRectIsEmpty(intersection) ? CPRectMakeZero() : intersection;
}
/*
/*!
Creates a copy of the provided rectangle
@group CGRect
@param aRect the CGRect that will be copied
@@ -111,7 +117,7 @@ function CPRectCreateCopy(aRect)
return { origin: CPPointCreateCopy(aRect.origin), size: CPSizeCreateCopy(aRect.size) };
}
/*
/*!
Returns a CGRect made of the specified arguments
@group CGRect
@param x the x-coordinate of the rectangle's origin
@@ -125,7 +131,7 @@ function CPRectMake(x, y, width, height)
return { origin: CPPointMake(x, y), size: CPSizeMake(width, height) };
}
/*
/*!
Creates a new rectangle with its origin offset by <code>dX</code> and <code>dY</code>.
@group CGRect
@param aRect the rectangle to copy the origin and size from
@@ -138,7 +144,7 @@ function CPRectOffset(aRect, dX, dY)
return CPRectMake(aRect.origin.x + dX, aRect.origin.y + dY, aRect.size.width, aRect.size.height);
}
/*
/*!
@group CGRect
@param aRect a CGRect
@return CGRect
@@ -164,7 +170,7 @@ function CPRectStandardize(aRect)
return standardized;
}
/*
/*!
Returns the smallest rectangle that can contain the two argument <code>CGRect</code>s.
@group CGRect
@param lhsRect the first CGRect to use for the union calculation
@@ -181,7 +187,7 @@ function CPRectUnion(lhsRect, rhsRect)
return CPRectMake(minX, minY, maxX - minX, maxY - minY);
}
/*
/*!
Creates and returns a copy of the provided CGSize
@group CGSize
@param aSize the CGSize to copy
@@ -192,7 +198,7 @@ function CPSizeCreateCopy(aSize)
return { width: aSize.width, height: aSize.height };
}
/*
/*!
Creates and returns a new CGSize object from the provided dimensions.
@group CGSize
@param width the width for the new CGSize
@@ -204,9 +210,9 @@ function CPSizeMake(width, height)
return { width: width, height: height };
}
/*
Returns <code>YES</code> if the <objj>CGRect</objj>, <code>aRect</code>, contains
the <objj>CGPoint</objj>, <code>aPoint</code>.
/*!
Returns <code>YES</code> if the CGRect, <code>aRect</code>, contains
the CGPoint, <code>aPoint</code>.
@param aRect the rectangle to test with
@param aPoint the point to test with
@group CGRect
@@ -220,12 +226,12 @@ function CPRectContainsPoint(aRect, aPoint)
aPoint.y < CPRectGetMaxY(aRect);
}
/*
Returns a <code>BOOL</code> indicating whether <objj>CGRect</objj> <code>possibleOuter</code>
contains <objj>CGRect</objj> <code>possibleInner</code>.
/*!
Returns a <code>BOOL</code> indicating whether CGRect <code>possibleOuter</code>
contains CGRect <code>possibleInner</code>.
@group CGRect
@param possibleOuter the <objj>CGRect</objj> to test if <code>possibleInner</code> is inside of
@param possibleInner the <objj>CGRect</objj> to test if it fits inside <code>possibleOuter</code>.
@param possibleOuter the CGRect to test if <code>possibleInner</code> is inside of
@param possibleInner the CGRect to test if it fits inside <code>possibleOuter</code>.
@return BOOL <code>YES</code> if <code>possibleInner</code> fits inside <code>possibleOuter</code>.
*/
function CPRectContainsRect(lhsRect, rhsRect)
@@ -233,12 +239,12 @@ function CPRectContainsRect(lhsRect, rhsRect)
return CPRectEqualToRect(CPUnionRect(lhsRect, rhsRect), rhsRect);
}
/*
Tests whether the two <objj>CGPoint</objj>s are equal to each other by comparing their
/*!
Tests whether the two CGPoints are equal to each other by comparing their
<code>x</code> and <code>y</code> members.
@group @CGPoint
@param lhsPoint the first <objj>CGPoint</objj> to check
@param rhsPoint the second <objj>CGPoint</objj> to check
@param lhsPoint the first CGPoint to check
@param rhsPoint the second CGPoint to check
@return BOOL <code>YES</code> if the two points have the same x's, and the same y's.
*/
function CPPointEqualToPoint(lhsPoint, rhsPoint)
@@ -246,11 +252,11 @@ function CPPointEqualToPoint(lhsPoint, rhsPoint)
return lhsPoint.x == rhsPoint.x && lhsPoint.y == rhsPoint.y;
}
/*
Test whether the two <objj>CGRect</objj>s have the same origin and size
/*!
Test whether the two CGRects have the same origin and size
@group CGRect
@param lhsRect the first <objj>CGRect</objj> to compare
@param rhsRect the second <objj>CGRect</objj> to compare
@param lhsRect the first CGRect to compare
@param rhsRect the second CGRect to compare
@return BOOL <code>YES</code> if the two rectangles have the same origin and size. <code>NO</code>, otherwise.
*/
function CPRectEqualToRect(lhsRect, rhsRect)
@@ -259,9 +265,9 @@ function CPRectEqualToRect(lhsRect, rhsRect)
CPSizeEqualToSize(lhsRect.size, rhsRect.size);
}
/*
/*!
@group CGRect
@param aRect a <objj>CGRect</objj>
@param aRect a CGRect
@return int
*/
function CPRectGetHeight(aRect)
@@ -269,9 +275,9 @@ function CPRectGetHeight(aRect)
return aRect.size.height;
}
/*
/*!
@group CGRect
@param aRect a <objj>CGRect</objj>
@param aRect a CGRect
@return int
*/
function CPRectGetMaxX(aRect)
@@ -279,9 +285,9 @@ function CPRectGetMaxX(aRect)
return aRect.origin.x + aRect.size.width;
}
/*
/*!
@group CGRect
@param aRect a <objj>CGRect</objj>
@param aRect a CGRect
@return int
*/
function CPRectGetMaxY(aRect)
@@ -289,9 +295,9 @@ function CPRectGetMaxY(aRect)
return aRect.origin.y + aRect.size.height;
}
/*
/*!
@group CGRect
@param aRect a <objj>CGRect</objj>
@param aRect a CGRect
@return float
*/
function CPRectGetMidX(aRect)
@@ -299,9 +305,9 @@ function CPRectGetMidX(aRect)
return aRect.origin.x + (aRect.size.width) / 2.0;
}
/*
/*!
@group CGRect
@param aRect a <objj>CGRect</objj>
@param aRect a CGRect
@return float
*/
function CPRectGetMidY(aRect)
@@ -309,9 +315,9 @@ function CPRectGetMidY(aRect)
return aRect.origin.y + (aRect.size.height) / 2.0;
}
/*
/*!
@group CGRect
@param aRect a <objj>CGRect</objj>
@param aRect a CGRect
@return int
*/
function CPRectGetMinX(aRect)
@@ -319,9 +325,9 @@ function CPRectGetMinX(aRect)
return aRect.origin.x;
}
/*
/*!
@group CGRect
@param aRect a <objj>CGRect</objj>
@param aRect a CGRect
@return int
*/
function CPRectGetMinY(aRect)
@@ -329,9 +335,9 @@ function CPRectGetMinY(aRect)
return aRect.origin.y;
}
/*
/*!
@group CGRect
@param aRect a <objj>CGRect</objj>
@param aRect a CGRect
@return int
*/
function CPRectGetWidth(aRect)
@@ -339,11 +345,11 @@ function CPRectGetWidth(aRect)
return aRect.size.width;
}
/*
/*!
Returns <code>YES</code> if the two rectangles intersect
@group CGRect
@param lhsRect the first <objj>CGRect</objj>
@param rhsRect the second <objj>CGRect</objj>
@param lhsRect the first CGRect
@param rhsRect the second CGRect
@return BOOL <code>YES</code> if the two rectangles have any common spaces, and <code>NO</code>, otherwise.
*/
function CPRectIntersectsRect(lhsRect, rhsRect)
@@ -351,34 +357,34 @@ function CPRectIntersectsRect(lhsRect, rhsRect)
return !CPRectIsEmpty(CPRectIntersection(lhsRect, rhsRect));
}
/*
Returns <code>YES</code> if the <objj>CGRect</objj> has no area.
/*!
Returns <code>YES</code> if the CGRect has no area.
The test is performed by checking if the width and height are both zero.
@group CGRect
@param aRect the <objj>CGRect</objj> to test
@return BOOL <code>YES</code> if the <objj>CGRect</objj> has no area, and <code>NO</code>, otherwise.
@param aRect the CGRect to test
@return BOOL <code>YES</code> if the CGRect has no area, and <code>NO</code>, otherwise.
*/
function CPRectIsEmpty(aRect)
{
return aRect.size.width <= 0.0 || aRect.size.height <= 0.0;
}
/*
Returns <code>YES</code> if the <objj>CGRect</objj> has no area.
/*!
Returns <code>YES</code> if the CGRect has no area.
The test is performed by checking if the width and height are both zero.
@group CGRect
@return BOOL <code>YES</code> if the <objj>CGRect</objj> has no area, and <code>NO</code>, otherwise.
@return BOOL <code>YES</code> if the CGRect has no area, and <code>NO</code>, otherwise.
*/
function CPRectIsNull(aRect)
{
return aRect.size.width <= 0.0 || aRect.size.height <= 0.0;
}
/*
Returns <code>YES</code> if the two <objj>CGSize</objj>s are identical.
/*!
Returns <code>YES</code> if the two CGSizes are identical.
@group CGSize
@param lhsSize the first <objj>CGSize</objj> to compare
@param rhsSize the second <objj>CGSize</objj> to compare
@param lhsSize the first CGSize to compare
@param rhsSize the second CGSize to compare
@return BOOL <code>YES</code> if the two sizes are identical. <code>NO</code>, otherwise.
*/
function CPSizeEqualToSize(lhsSize, rhsSize)
@@ -386,30 +392,30 @@ function CPSizeEqualToSize(lhsSize, rhsSize)
return lhsSize.width == rhsSize.width && lhsSize.height == rhsSize.height;
}
/*
Returns a human readable string of the provided <objj>CGPoint</objj>.
/*!
Returns a human readable string of the provided CGPoint.
@group CGPoint
@param aPoint the point to represent
@return CGPoint a string representation of the <objj>CGPoint</objj>
@return CGPoint a string representation of the CGPoint
*/
function CPStringFromPoint(aPoint)
{
return "{" + aPoint.x + ", " + aPoint.y + "}";
}
/*
Returns a human readable string of the provided <objj>CGSize</objj>.
/*!
Returns a human readable string of the provided CGSize.
@group CGSize
@param aSize the size to represent
@return CGSize a string representation of the <objj>CGSize</objj>
@return CGSize a string representation of the CGSize
*/
function CPStringFromSize(aSize)
{
return "{" + aSize.width + ", " + aSize.height + "}";
}
/*
Returns a human readable string of the provided <objj>CGRect</objj>.
/*!
Returns a human readable string of the provided CGRect.
@group CGRect
@param aRect the rectangle to represent
@return CGString the string representation of the rectangle
@@ -419,8 +425,8 @@ function CPStringFromRect(aRect)
return "{" + CPStringFromPoint(aRect.origin) + ", " + CPStringFromSize(aRect.size) + "}";
}
/*
Returns a <objj>CGPoint</objj> from a string with a comma separated pair of integers.
/*!
Returns a CGPoint from a string with a comma separated pair of integers.
@group CGPoint
@param aString a string containing two comma separated integers
@return CGPoint the point object created from the string
@@ -429,11 +435,11 @@ function CPPointFromString(aString)
{
var comma = aString.indexOf(',');
return { x:parseInt(aString.substr(1, comma - 1)), y:parseInt(aString.substring(comma + 1, aString.length)) };
return { x:parseFloat(aString.substr(1, comma - 1), 10), y:parseFloat(aString.substring(comma + 1, aString.length), 10) };
}
/*
Returns a <objj>CGSize</objj> from a string containing a pair of comma separated integers.
/*!
Returns a CGSize from a string containing a pair of comma separated integers.
@group CGSize
@param aString a string containing two comma separated integers
@return CGSize the size object created from the string
@@ -442,11 +448,11 @@ function CPSizeFromString(aString)
{
var comma = aString.indexOf(',');
return { width:parseInt(aString.substr(1, comma - 1)), height:parseInt(aString.substring(comma + 1, aString.length)) };
return { width:parseFloat(aString.substr(1, comma - 1), 10), height:parseFloat(aString.substring(comma + 1, aString.length), 10) };
}
/*
Returns a <objj>CGRect</objj> created from a string.
/*!
Returns a CGRect created from a string.
@group CGRect
@param aString a string in the form generated by <code>CPStringFromRect</code>
@return CGRect the rectangle created from the string
@@ -458,7 +464,7 @@ function CPRectFromString(aString)
return { origin:CPPointFromString(aString.substr(1, comma - 1)), size:CPSizeFromString(aString.substring(comma + 2, aString.length)) };
}
/*
/*!
@group CGPoint
@param anEvent
@return CGPoint
@@ -468,8 +474,8 @@ function CPPointFromEvent(anEvent)
return CPPointMake(anEvent.clientX, anEvent.clientY, 0);
}
/*
Returns a zero sized <objj>CGSize</objj>.
/*!
Returns a zero sized CGSize.
@group CGSize
@return CGSize a size object with zeros for <code>width</code> and <code>height</code>
*/
@@ -478,7 +484,7 @@ function CPSizeMakeZero()
return CPSizeMake(0, 0);
}
/*
/*!
Returns a rectangle at origin <code>(0,0)</code> and size of <code>(0,0)</code>.
@group CGRect
@return CGRect a zeroed out CGRect
@@ -488,7 +494,7 @@ function CPRectMakeZero()
return CPRectMake(0, 0, 0, 0);
}
/*
/*!
Returns a point located at <code>(0, 0)</code>.
@group CGPoint
@return CGPoint a point located at <code>(0, 0)</code>
@@ -497,3 +503,7 @@ function CPPointMakeZero()
{
return CPPointMake(0, 0, 0);
}
/*!
@}
*/
+7 -6
View File
@@ -22,7 +22,8 @@
var CPGraphicsContextCurrent = nil;
/*
/*!
@ingroup appkit
Provides an interface for drawing to the screen.
*/
@implementation CPGraphicsContext : CPObject
@@ -30,7 +31,7 @@ var CPGraphicsContextCurrent = nil;
CPContext _graphicsPort;
}
/*
/*!
Returns the current graphics context.
*/
+ (CPGraphicsContext)currentContext
@@ -38,7 +39,7 @@ var CPGraphicsContextCurrent = nil;
return CPGraphicsContextCurrent;
}
/*
/*!
Sets the current graphics context
*/
+ (void)setCurrentContext:(CPGraphicsContext)aGraphicsContext
@@ -46,7 +47,7 @@ var CPGraphicsContextCurrent = nil;
CPGraphicsContextCurrent = aGraphicsContext;
}
/*
/*!
Creates a graphics context with a provided port.
@param aContext the context to initialize with
@param aFlag whether the context should be flipped
@@ -57,7 +58,7 @@ var CPGraphicsContextCurrent = nil;
return [[self alloc] initWithGraphicsPort:aContext];
}
/*
/*!
Initializes the context with a graphics port.
@param aGraphicsPort the graphics port to initialize with
@return the initialized context
@@ -72,7 +73,7 @@ var CPGraphicsContextCurrent = nil;
return self;
}
/*
/*!
Returns the graphics context's port.
*/
- (CGContext)graphicsPort
+91 -30
View File
@@ -20,13 +20,13 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
import <Foundation/CPBundle.j>
import <Foundation/CPNotificationCenter.j>
import <Foundation/CPObject.j>
import <Foundation/CPRunLoop.j>
import <Foundation/CPString.j>
@import <Foundation/CPBundle.j>
@import <Foundation/CPNotificationCenter.j>
@import <Foundation/CPObject.j>
@import <Foundation/CPRunLoop.j>
@import <Foundation/CPString.j>
import "CPGeometry.j"
@import "CPGeometry.j"
CPImageLoadStatusInitialized = 0;
CPImageLoadStatusLoading = 1;
@@ -38,19 +38,35 @@ CPImageLoadStatusReadError = 6;
CPImageDidLoadNotification = @"CPImageDidLoadNotification";
function CPImageInBundle(aFilename, aSize, aBundle)
{
if (!aBundle)
aBundle = [CPBundle mainBundle];
if (aSize)
return [[CPImage alloc] initWithContentsOfFile:[aBundle pathForResource:aFilename] size:aSize];
return [[CPImage alloc] initWithContentsOfFile:[aBundle pathForResource:aFilename]];
}
@implementation CPBundle (CPImageAdditions)
- (CPString)pathForResource:(CPString)aFilename
{
return [self bundlePath] + "Resources/" + aFilename;
return [self resourcePath] + '/' + aFilename;
}
@end
/*
<objj>CPImage</objj> is used to represent images in the Cappuccino framework. It supports loading
/*!
@ingroup appkit
@class CPImage
CPImage is used to represent images in the Cappuccino framework. It supports loading
all image types supported by the browser.
@par Delegate Methods
@delegate -(void)imageDidLoad:(CPImage)image;
Called when the specified image has finished loading.
@param image the image that loaded
@@ -74,7 +90,7 @@ CPImageDidLoadNotification = @"CPImageDidLoadNotification";
Image _image;
}
/*
/*!
Initializes the image, by associating it with a filename. The image
denoted in <code>aFilename</code> is not actually loaded. It will
be loaded once needed.
@@ -96,7 +112,7 @@ CPImageDidLoadNotification = @"CPImageDidLoadNotification";
return self;
}
/*
/*!
Initializes the image. Loads the specified image into memory.
@param aFilename the image to load
@param aSize the size of the image
@@ -112,7 +128,7 @@ CPImageDidLoadNotification = @"CPImageDidLoadNotification";
return self;
}
/*
/*!
Initializes the receiver with the contents of the specified
image file. The method loads the data into memory.
@param aFilename the file name of the image
@@ -128,7 +144,7 @@ CPImageDidLoadNotification = @"CPImageDidLoadNotification";
return self;
}
/*
/*!
Returns the path of the file associated with this image.
*/
- (CPString)filename
@@ -136,7 +152,7 @@ CPImageDidLoadNotification = @"CPImageDidLoadNotification";
return _filename;
}
/*
/*!
Sets the size of the image.
@param the size of the image
*/
@@ -145,7 +161,7 @@ CPImageDidLoadNotification = @"CPImageDidLoadNotification";
_size = CGSizeMakeCopy(aSize);
}
/*
/*!
Returns the size of the image
*/
- (CGSize)size
@@ -153,7 +169,7 @@ CPImageDidLoadNotification = @"CPImageDidLoadNotification";
return _size;
}
/*
/*!
Sets the receiver's delegate.
@param the delegate
*/
@@ -162,7 +178,7 @@ CPImageDidLoadNotification = @"CPImageDidLoadNotification";
_delegate = aDelegate;
}
/*
/*!
Returns the receiver's delegate
*/
- (id)delegate
@@ -170,7 +186,7 @@ CPImageDidLoadNotification = @"CPImageDidLoadNotification";
return _delegate;
}
/*
/*!
Returns <code>YES</code> if the image data has already been loaded.
*/
- (BOOL)loadStatus
@@ -178,11 +194,12 @@ CPImageDidLoadNotification = @"CPImageDidLoadNotification";
return _loadStatus;
}
/*
/*!
Loads the image data from the file into memory. You
should not call this method directly. Instead use
one of the initializers.
*/
- (void)load
{
if (_loadStatus == CPImageLoadStatusLoading || _loadStatus == CPImageLoadStatusCompleted)
@@ -195,9 +212,41 @@ CPImageDidLoadNotification = @"CPImageDidLoadNotification";
var isSynchronous = YES;
// FIXME: We need a better/performance way of doing this.
_image.onload = function () { if (isSynchronous) window.setTimeout(function() { [self _imageDidLoad] }, 0); else [self _imageDidLoad]; }
_image.onerror = function () { if (isSynchronous) window.setTimeout(function() { [self _imageDidError] }, 0); else [self _imageDidError]; }
_image.onabort = function () { if (isSynchronous) window.setTimeout(function() { [self _imageDidAbort] }, 0); else [self _imageDidAbort]; }
_image.onload = function ()
{
if (isSynchronous)
window.setTimeout(function() { [self _imageDidLoad]; }, 0);
else
{
[self _imageDidLoad];
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
}
[self _derefFromImage];
}
_image.onerror = function ()
{
if (isSynchronous)
window.setTimeout(function() { [self _imageDidError]; }, 0);
else
{
[self _imageDidError];
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
}
[self _derefFromImage];
}
_image.onabort = function ()
{
if (isSynchronous)
window.setTimeout(function() { [self _imageDidAbort]; }, 0);
else
{
[self _imageDidAbort];
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
}
[self _derefFromImage];
}
_image.src = _filename;
@@ -214,6 +263,14 @@ CPImageDidLoadNotification = @"CPImageDidLoadNotification";
return NO;
}
/* @ignore */
- (void)_derefFromImage
{
_image.onload = null;
_image.onerror = null;
_image.onabort = null;
}
/* @ignore */
- (void)_imageDidLoad
{
@@ -229,8 +286,6 @@ CPImageDidLoadNotification = @"CPImageDidLoadNotification";
if ([_delegate respondsToSelector:@selector(imageDidLoad:)])
[_delegate imageDidLoad:self];
[[CPRunLoop currentRunLoop] performSelectors];
}
/* @ignore */
@@ -240,8 +295,6 @@ CPImageDidLoadNotification = @"CPImageDidLoadNotification";
if ([_delegate respondsToSelector:@selector(imageDidError:)])
[_delegate imageDidError:self];
[[CPRunLoop currentRunLoop] performSelectors];
}
/* @ignore */
@@ -251,15 +304,13 @@ CPImageDidLoadNotification = @"CPImageDidLoadNotification";
if ([_delegate respondsToSelector:@selector(imageDidAbort:)])
[_delegate imageDidAbort:self];
[[CPRunLoop currentRunLoop] performSelectors];
}
@end
@implementation CPImage (CPCoding)
/*
/*!
Initializes the image with data from a coder.
@param aCoder the coder from which to read the image data
@return the initialized image
@@ -269,7 +320,7 @@ CPImageDidLoadNotification = @"CPImageDidLoadNotification";
return [self initWithContentsOfFile:[aCoder decodeObjectForKey:@"CPFilename"] size:[aCoder decodeSizeForKey:@"CPSize"]];
}
/*
/*!
Writes the image data from memory into the coder.
@param aCoder the coder to which the data will be written
*/
@@ -300,6 +351,11 @@ CPImageDidLoadNotification = @"CPImageDidLoadNotification";
return self;
}
- (CPString)filename
{
return @"";
}
- (CPArray)imageSlices
{
return _imageSlices;
@@ -364,6 +420,11 @@ var CPThreePartImageImageSlicesKey = @"CPThreePartImageImageSlicesKey",
return self;
}
- (CPString)filename
{
return @"";
}
- (CPArray)imageSlices
{
return _imageSlices;
+147 -85
View File
@@ -20,11 +20,11 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
import <Foundation/CPNotificationCenter.j>
@import <Foundation/CPNotificationCenter.j>
import "CPControl.j"
import "CPImage.j"
import "CPShadowView.j"
@import "CPControl.j"
@import "CPImage.j"
@import "CPShadowView.j"
#include "Platform/Platform.h"
#include "Platform/DOM/CPDOMDisplayServer.h"
@@ -58,19 +58,21 @@ var LEFT_SHADOW_INSET = 3.0,
VERTICAL_SHADOW_INSET = TOP_SHADOW_INSET + BOTTOM_SHADOW_INSET,
HORIZONTAL_SHADOW_INSET = LEFT_SHADOW_INSET + RIGHT_SHADOW_INSET;
/*
/*!
@ingroup appkit
@class CPImageView
This class is a control that displays an image.
*/
@implementation CPImageView : CPControl
{
CPImage _image;
DOMElement _DOMImageElement;
CPImageScaling _imageScaling;
BOOL _hasShadow;
CPView _shadowView;
BOOL _isEditable;
CGRect _imageRect;
}
@@ -95,56 +97,70 @@ var LEFT_SHADOW_INSET = 3.0,
return self;
}
/*
/*!
Returns the view's image.
*/
- (CPImage)image
{
return _image;
return [self objectValue];
}
/*
Sets the image for the view.
@param anImage the view's image
*/
- (void)setImage:(CPImage)anImage
{
if (_image == anImage)
[self setObjectValue:anImage];
}
/*! @ignore */
- (void)setObjectValue:(CPImage)anImage
{
var oldImage = [self objectValue];
if (oldImage === anImage)
return;
[super setObjectValue:anImage];
var center = [CPNotificationCenter defaultCenter];
var defaultCenter = [CPNotificationCenter defaultCenter];
if (_image)
[center removeObserver:self name:CPImageDidLoadNotification object:_image];
if (oldImage)
[defaultCenter removeObserver:self name:CPImageDidLoadNotification object:oldImage];
_image = anImage;
_DOMImageElement.src = [anImage filename];
var size = [_image size];
var newImage = [self objectValue];
if (size && size.width == -1 && size.height == -1)
#if PLATFORM(DOM)
_DOMImageElement.src = newImage ? [newImage filename] : "";
#endif
var size = [newImage size];
if (size && size.width === -1 && size.height === -1)
{
[center addObserver:self selector:@selector(imageDidLoad:) name:CPImageDidLoadNotification object:_image];
[defaultCenter addObserver:self selector:@selector(imageDidLoad:) name:CPImageDidLoadNotification object:newImage];
#if PLATFORM(DOM)
_DOMImageElement.width = 0;
_DOMImageElement.height = 0;
#endif
[_shadowView setHidden:YES];
}
else
{
[self hideOrDisplayContents];
[self tile];
[self setNeedsLayout];
[self setNeedsDisplay:YES];
}
}
- (void)imageDidLoad:(CPNotification)aNotification
{
[self hideOrDisplayContents];
[self tile];
[self setNeedsLayout];
[self setNeedsDisplay:YES];
}
/*
/*!
Returns <code>YES</code> if the image view draws with
a drop shadow. The default is <code>NO</code>.
*/
@@ -153,7 +169,7 @@ var LEFT_SHADOW_INSET = 3.0,
return _hasShadow;
}
/*
/*!
Sets whether the image view should draw with a drop shadow.
@param shouldHaveShadow whether the image view should have a shadow
*/
@@ -170,7 +186,8 @@ var LEFT_SHADOW_INSET = 3.0,
[self addSubview:_shadowView];
[self tile];
[self setNeedsLayout];
[self setNeedsDisplay:YES];
}
else
{
@@ -182,60 +199,48 @@ var LEFT_SHADOW_INSET = 3.0,
[self hideOrDisplayContents];
}
/*
/*!
Sets the type of image scaling that should be used to
render the image.
@param anImageScaling the type of scaling to use
*/
- (void)setImageScaling:(CPImageScaling)anImageScaling
{
if (_imageScaling == anImageScaling)
return;
[super setImageScaling:anImageScaling];
_imageScaling = anImageScaling;
if (_imageScaling == CPScaleToFit)
#if PLATFORM(DOM)
if ([self currentValueForThemeAttribute:@"image-scaling"] === CPScaleToFit)
{
CPDOMDisplayServerSetStyleLeftTop(_DOMImageElement, NULL, 0.0, 0.0);
}
#endif
[self tile];
[self setNeedsLayout];
[self setNeedsDisplay:YES];
}
/*
Returns the image scaling method used to
render this image.
*/
- (CPImageScaling)imageScaling
{
return _imageScaling;
}
- (void)setFrameSize:(CGSize)aSize
{
[super setFrameSize:aSize];
[self tile];
}
/*
/*!
Toggles the display of the image view.
*/
- (void)hideOrDisplayContents
{
if (!_image)
if (![self image])
{
#if PLATFORM(DOM)
_DOMImageElement.style.visibility = "hidden";
#endif
[_shadowView setHidden:YES];
}
else
{
#if PLATFORM(DOM)
_DOMImageElement.style.visibility = "visible";
#endif
[_shadowView setHidden:NO];
}
}
/*
/*!
Returns the view's image rectangle
*/
- (CGRect)imageRect
@@ -243,15 +248,17 @@ var LEFT_SHADOW_INSET = 3.0,
return _imageRect;
}
/*
/*!
Add a description
*/
- (void)tile
- (void)layoutSubviews
{
if (!_image)
if (![self image])
return;
var bounds = [self bounds],
image = [self image],
imageScaling = [self currentValueForThemeAttribute:@"image-scaling"],
x = 0.0,
y = 0.0,
insetWidth = (_hasShadow ? HORIZONTAL_SHADOW_INSET : 0.0),
@@ -260,20 +267,22 @@ var LEFT_SHADOW_INSET = 3.0,
boundsHeight = _CGRectGetHeight(bounds),
width = boundsWidth - insetWidth,
height = boundsHeight - insetHeight;
if (_imageScaling == CPScaleToFit)
if (imageScaling === CPScaleToFit)
{
#if PLATFORM(DOM)
_DOMImageElement.width = ROUND(width);
_DOMImageElement.height = ROUND(height);
#endif
}
else
{
var size = [_image size];
var size = [image size];
if (size.width == -1 && size.height == -1)
return;
if (_imageScaling == CPScaleProportionally)
if (imageScaling === CPScaleProportionally)
{
// The max size it can be is size.width x size.height, so only
// only proportion otherwise.
@@ -292,9 +301,11 @@ var LEFT_SHADOW_INSET = 3.0,
else
height = width / imageRatio;
}
#if PLATFORM(DOM)
_DOMImageElement.width = ROUND(width);
_DOMImageElement.height = ROUND(height);
#endif
}
else
{
@@ -302,16 +313,20 @@ var LEFT_SHADOW_INSET = 3.0,
height = size.height;
}
if (_imageScaling == CPScaleNone)
if (imageScaling == CPScaleNone)
{
#if PLATFORM(DOM)
_DOMImageElement.width = ROUND(size.width);
_DOMImageElement.height = ROUND(size.height);
#endif
}
var x = (boundsWidth - width) / 2.0,
y = (boundsHeight - height) / 2.0;
#if PLATFORM(DOM)
CPDOMDisplayServerSetStyleLeftTop(_DOMImageElement, NULL, x, y);
#endif
}
_imageRect = _CGRectMake(x, y, width, height);
@@ -320,45 +335,92 @@ var LEFT_SHADOW_INSET = 3.0,
[_shadowView setFrame:_CGRectMake(x - LEFT_SHADOW_INSET, y - TOP_SHADOW_INSET, width + insetWidth, height + insetHeight)];
}
- (void)mouseDown:(CPEvent)anEvent
{
// Should we do something with this event?
[[self nextResponder] mouseDown:anEvent];
}
- (void)setEditable:(BOOL)shouldBeEditable
{
if (_isEditable === shouldBeEditable)
return;
_isEditable = shouldBeEditable;
if (_isEditable)
[self registerForDraggedTypes:[CPImagesPboardType]];
else
{
var draggedTypes = [self registeredDraggedTypes];
[self unregisterDraggedTypes];
[draggedTypes removeObjectIdenticalTo:CPImagesPboardType];
[self registerForDraggedTypes:draggedTypes];
}
}
- (BOOL)isEditable
{
return _isEditable;
}
- (void)performDragOperation:(CPDraggingInfo)aSender
{
var images = [CPKeyedUnarchiver unarchiveObjectWithData:[[aSender draggingPasteboard] dataForType:CPImagesPboardType]];
if ([images count])
[self setImage:images[0]];
}
@end
var CPImageViewImageKey = @"CPImageViewImageKey",
CPImageViewImageScalingKey = @"CPImageViewImageScalingKey",
CPImageViewHasShadowKey = @"CPImageViewHasShadowKey";
CPImageViewHasShadowKey = @"CPImageViewHasShadowKey",
CPImageViewIsEditableKey = @"CPImageViewIsEditableKey";
@implementation CPImageView (CPCoding)
/*
/*!
Initializes the image view with the provided coder.
@param aCoder the coder from which data will be read.
@return the initialized image view
*/
- (id)initWithCoder:(CPCoder)aCoder
{
#if PLATFORM(DOM)
_DOMImageElement = document.createElement("img");
_DOMImageElement.style.position = "absolute";
_DOMImageElement.style.left = "0px";
_DOMImageElement.style.top = "0px";
_DOMImageElement.style.visibility = "hidden";
#endif
self = [super initWithCoder:aCoder];
if (self)
{
_DOMImageElement = document.createElement("img");
_DOMImageElement.style.position = "absolute";
_DOMImageElement.style.left = "0px";
_DOMImageElement.style.top = "0px";
#if PLATFORM(DOM)
_DOMElement.appendChild(_DOMImageElement);
_DOMImageElement.style.visibility = "hidden";
[self setImage:[aCoder decodeObjectForKey:CPImageViewImageKey]];
[self setImageScaling:[aCoder decodeIntForKey:CPImageViewImageScalingKey]];
#endif
[self setHasShadow:[aCoder decodeBoolForKey:CPImageViewHasShadowKey]];
[self tile];
if ([aCoder decodeBoolForKey:CPImageViewIsEditableKey] || NO)
[self setEditable:YES];
[self setNeedsLayout];
[self setNeedsDisplay:YES];
}
return self;
}
/*
/*!
Writes the image view out to the coder.
@param aCoder the coder to which the image
view will be written
@@ -380,10 +442,10 @@ var CPImageViewImageKey = @"CPImageViewImageKey",
if (_shadowView)
_subviews = actualSubviews;
[aCoder encodeObject:_image forKey:CPImageViewImageKey];
[aCoder encodeInt:_imageScaling forKey:CPImageViewImageScalingKey];
[aCoder encodeBool:_hasShadow forKey:CPImageViewHasShadowKey];
if (_isEditable)
[aCoder encodeBool:_isEditable forKey:CPImageViewIsEditableKey];
}
@end
-372
View File
@@ -1,372 +0,0 @@
/*
* CPApplication.j
* AppKit
*
* Created by Ross Boucher.
* Copyright 2008, 280 North, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
import <Foundation/Foundation.j>
import "CPView.j"
import "CPButton.j"
import "CPImage.j"
import "CPImageView.j"
import "CPColorPicker.j"
import "CPColorPanel.j"
import "CPTabView.j"
import "CPTabViewItem.j"
/*
@ignore
*/
@implementation CPKulerColorPicker : CPColorPicker
{
CPView _contentView;
CPTabView _tabView;
CPScrollView _searchView;
CPScrollView _popularView;
CPView _searchView;
DOMElement _FIXME_searchField;
CPURLConnection _searchConnection;
CPURLConnection _popularConnection
}
- (id)initWithPickerMask:(int)mask colorPanel:(CPColorPanel)owningColorPanel
{
return [super initWithPickerMask:mask colorPanel: owningColorPanel];
}
-(id)initView
{
aFrame = CPRectMake(0, 0, CPColorPickerViewWidth, CPColorPickerViewHeight);
_contentView = [[CPView alloc] initWithFrame:aFrame];
_tabView = [[CPTabView alloc] initWithFrame:CGRectMake(0.0, 0.0, CGRectGetWidth(aFrame), CGRectGetHeight(aFrame) - 20)];
[_tabView setAutoresizingMask: CPViewWidthSizable | CPViewHeightSizable];
[_tabView setDelegate: self];
[_contentView addSubview: _tabView];
var label = [[CPButton alloc] initWithFrame:CPRectMake((CPColorPickerViewWidth-150)/2, CPColorPickerViewHeight-20, 150, 20)];
[label setAutoresizingMask: CPViewMinXMargin | CPViewMaxXMargin | CPViewMinYMargin];
[label setFont:[CPFont boldSystemFontOfSize:10.0]];
[label setTextColor: [CPColor whiteColor]];
[label setTitle: @"Powered by Adobe Kuler"];
[label setTarget: self];
[label setAction: @selector(openKulerLink:)];
[label setBordered: NO];
[_contentView addSubview: label];
var searchThemeView = [[_CPKulerThemeView alloc] initWithFrame: CPRectMake(0, 0, aFrame.size.width, 0)];
[searchThemeView setDelegate: self];
[searchThemeView setAutoresizingMask: CPViewWidthSizable];
_searchView = [[CPScrollView alloc] initWithFrame: CPRectMake(0, 0, aFrame.size.width, CPColorPickerViewHeight - 10)];
[_searchView setDocumentView: searchThemeView];
[_searchView setHasHorizontalScroller: NO];
[_searchView setAutoresizingMask: (CPViewWidthSizable | CPViewHeightSizable)];
[[_searchView verticalScroller] setControlSize:CPSmallControlSize];
[_searchView setAutohidesScrollers:YES];
var auxiliarySearchView = [[CPView alloc] initWithFrame:CGRectMake(0.0, 0.0, CPColorPickerViewWidth, 26.0)];
[auxiliarySearchView setAutoresizingMask: (CPViewMinYMargin | CPViewWidthSizable)];
_FIXME_searchField = document.createElement("input");
if(!window.addEventListener)
_FIXME_searchField.type = "text";
else
_FIXME_searchField.type = "search";
_FIXME_searchField.style.position = "absolute";
_FIXME_searchField.style.width = "96%";
_FIXME_searchField.style.left = "2%";
_FIXME_searchField.style.top = "2px";
_FIXME_searchField.onkeypress = function(aDOMEvent)
{
aDOMEvent = aDOMEvent || window.event;
if (aDOMEvent.keyCode == 13)
{
[self search];
if(aDOMEvent.preventDefault)
aDOMEvent.preventDefault();
else if(aDOMEvent.stopPropagation)
aDOMEvent.stopPropagation();
_FIXME_searchField.blur();
}
};
auxiliarySearchView._DOMElement.appendChild(_FIXME_searchField);
var popularThemeView = [[_CPKulerThemeView alloc] initWithFrame: CPRectMake(0, 0, aFrame.size.width, 0)];
[popularThemeView setDelegate: self];
[popularThemeView setAutoresizingMask: CPViewWidthSizable];
_popularView = [[CPScrollView alloc] initWithFrame: CPRectMake(0, 0, aFrame.size.width, CPColorPickerViewHeight)];
[_popularView setDocumentView: popularThemeView];
[_popularView setHasHorizontalScroller: NO];
[_popularView setAutoresizingMask: (CPViewWidthSizable | CPViewHeightSizable)];
[[_popularView verticalScroller] setControlSize:CPSmallControlSize];
[_popularView setAutohidesScrollers:YES];
var mostPopularItem = [[CPTabViewItem alloc] initWithIdentifier:@"Popular"];
var searchItem = [[CPTabViewItem alloc] initWithIdentifier:@"Search"];
[searchItem setLabel:@"Search"];
[searchItem setView:_searchView];
[searchItem setAuxiliaryView: auxiliarySearchView];
[mostPopularItem setLabel:@"Popular"];
[mostPopularItem setView: _popularView];
[_tabView addTabViewItem: mostPopularItem];
[_tabView addTabViewItem: searchItem];
[self popularThemes];
}
- (void)openKulerLink:(id)sender
{
window.open("http://kuler.adobe.com");
}
- (CPView)provideNewView:(BOOL)initialRequest
{
if (initialRequest)
[self initView];
return _contentView;
}
- (int)currentMode
{
return CPKulerColorPickerMode;
}
- (BOOL)supportsMode:(int)mode
{
return (mode == CPKulerColorPickerMode) ? YES : NO;
}
-(void)search
{
var query = escape(_FIXME_searchField.value);
if(query.replace("%20", "") == "")
return;
[_searchConnection cancel];
_searchConnection = nil;
_searchConnection = [CPURLConnection connectionWithRequest:
[CPURLRequest requestWithURL: BASE_URL + "kuler.php?mode=search&query="+query]
delegate: self];
}
-(void)popularThemes
{
[_popularConnection cancel];
_popularConnection = nil;
_popularConnection = [CPURLConnection connectionWithRequest:
[CPURLRequest requestWithURL: BASE_URL + "kuler.php?mode=popular"] delegate: self];
}
/*
-(void)topRatedThemes
{
_connection = [CPURLConnection connectionWithRequest:
[CPURLRequest requestWithURL: BASE_URL + "kuler.php?mode=rating"] delegate:self];
}
*/
- (void)connection:(CPURLConnection)aConnection didReceiveData:(CPString)data
{
var data = CPJSObjectCreateWithJSON(data);
if(!data)
var themes = [];
else
var themes = data.result;
if(aConnection == _popularConnection)
[[_popularView documentView] setThemes: themes];
if(aConnection == _searchConnection)
[[_searchView documentView] setThemes: themes];
}
- (void)connection:(CPURLConnection)aConnection didFailWithError:(CPError)anError
{
[self connectionDidFinishLoading:aConnection];
}
-(void)connectionDidFinishLoading:(CPURLConnection)aConnection
{
}
-(void)chooseColor:(CPColor)aColor
{
[[self colorPanel] setColor: aColor];
}
@end
/* @ignore */
@implementation _CPKulerThemeView : CPView
{
CPArray _themes;
id _delegate;
CPColor _alternateBGColor;
}
-(id)initWithFrame:(CPRect)aFrame
{
self = [super initWithFrame:aFrame];
_alternateBGColor = [CPColor colorWithCalibratedRed: 241.0/255.0 green: 245.0/255.0 blue: 250.0/255.0 alpha: 1.0];
return self;
}
-(id)delegate
{
return _delegate;
}
-(void)setDelegate:(id)delegate
{
_delegate = delegate;
}
-(CPArray)themes
{
return _themes;
}
-(void)setThemes:(CPArray)themes
{
_themes = themes;
[self updateDisplay];
}
-(void)updateDisplay
{
var width = [self frame].size.width;
var subviews = [self subviews];
for(var i = [subviews count]-1; i >= 0; --i)
[subviews[i] removeFromSuperview];
for(var i=0, count = [_themes count]; i<count; i++)
{
var swatches = _themes[i].swatches;
var containerView = [[CPView alloc] initWithFrame: CPRectMake(0, 1+ 20*i, width, 20)];
[containerView setAutoresizingMask: CPViewWidthSizable];
for(var j=0; j<swatches.length; j++)
{
var outerView = [[CPView alloc] initWithFrame: CGRectMake(2+20*j, 1, 18, 18)],
innerView = [[_CPColorView alloc] initWithFrame: CGRectInset([outerView bounds], 1.0, 1.0)];
[innerView setTarget: self];
[innerView setAction: @selector(selectedColor:)];
[innerView setBackgroundColor: [CPColor colorWithHexString: swatches[j].hexColor]];
[outerView setBackgroundColor: [CPColor blackColor]];
[outerView addSubview: innerView];
[containerView addSubview: outerView];
}
var label = [[CPTextField alloc] initWithFrame: CPRectMake(102, 0, width - 102, 20)];
[label setStringValue: _themes[i].title];
[label setFont: [CPFont systemFontOfSize: 11.0]];
[label setLineBreakMode: CPLineBreakByTruncatingTail];
[label setAutoresizingMask: CPViewWidthSizable];
[containerView addSubview: label];
if(i%2 == 1)
[containerView setBackgroundColor: _alternateBGColor];
[self addSubview: containerView];
}
[self setFrameSize: CPSizeMake(width, (count)*20 + 2)];
}
-(void)selectedColor:(id)sender
{
[_delegate chooseColor:[sender backgroundColor]];
}
@end
/* @ignore */
@implementation _CPColorView : CPControl
{
}
-(id)initWithFrame:(CPRect)aFrame
{
self = [super initWithFrame: aFrame];
[self registerForDraggedTypes:[CPArray arrayWithObjects:CPColorDragType]];
return self;
}
- (void)mouseDragged:(CPEvent)anEvent
{
[[CPPasteboard pasteboardWithName:CPDragPboard] declareTypes:[CPArray arrayWithObject:CPColorDragType] owner:self];
var bounds = CPRectMake(0, 0, 15, 15),
point = [self convertPoint:[anEvent locationInWindow] fromView:nil];
var outerView = [[CPView alloc] initWithFrame: bounds],
innerView = [[CPView alloc] initWithFrame: CGRectInset([outerView bounds], 1.0, 1.0)];
[innerView setBackgroundColor: [self backgroundColor]];
[outerView setBackgroundColor: [CPColor blackColor]];
[outerView addSubview: innerView];
[self dragView: outerView
at: CPPointMake(point.x - bounds.size.width / 2.0, point.y - bounds.size.height / 2.0)
offset: CPPointMake(0.0, 0.0)
event: anEvent
pasteboard: nil
source: self
slideBack: YES];
}
- (void)pasteboard:(CPPasteboard)aPasteboard provideDataForType:(CPString)aType
{
if(aType == CPColorDragType)
[aPasteboard setData:[self backgroundColor] forType:aType];
}
@end
+315 -106
View File
@@ -20,16 +20,15 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
import <Foundation/CPArray.j>
import <Foundation/CPDictionary.j>
import <Foundation/CPNotificationCenter.j>
import <Foundation/CPString.j>
@import <Foundation/CPArray.j>
@import <Foundation/CPDictionary.j>
@import <Foundation/CPNotificationCenter.j>
@import <Foundation/CPString.j>
import "_CPImageAndTitleView.j"
import "CPApplication.j"
import "CPClipView.j"
import "CPMenuItem.j"
import "CPPanel.j"
@import "CPApplication.j"
@import "CPClipView.j"
@import "CPMenuItem.j"
@import "CPPanel.j"
#include "Platform/Platform.h"
@@ -46,13 +45,20 @@ var _CPMenuBarVisible = NO,
_CPMenuBarTitle = @"",
_CPMenuBarIconImage = nil,
_CPMenuBarIconImageAlphaValue = 1.0,
_CPMenuBarAttributes = nil,
_CPMenuBarSharedWindow = nil;
/*
Menus provide the user with a list of actions and/or submenus. Submenus themselves are full fledged menus and so a heirarchical structure appears.
/*!
@ingroup appkit
@class CPMenu
Menus provide the user with a list of actions and/or submenus. Submenus themselves are full fledged menus
and so a heirarchical structure appears.
*/
@implementation CPMenu : CPObject
{
CPMenu _supermenu;
CPString _title;
CPMutableArray _items;
@@ -60,7 +66,7 @@ var _CPMenuBarVisible = NO,
BOOL _autoenablesItems;
BOOL _showsStateColumn;
id _delegate;
CPMenuItem _highlightedIndex;
@@ -69,6 +75,11 @@ var _CPMenuBarVisible = NO,
// Managing the Menu Bar
+ (void)initialize
{
[[self class] setMenuBarAttributes:[CPDictionary dictionary]];
}
+ (BOOL)menuBarVisible
{
return _CPMenuBarVisible;
@@ -92,10 +103,19 @@ var _CPMenuBarVisible = NO,
[_CPMenuBarSharedWindow setIconImage:_CPMenuBarIconImage];
[_CPMenuBarSharedWindow setIconImageAlphaValue:_CPMenuBarIconImageAlphaValue];
[_CPMenuBarSharedWindow setColor:[_CPMenuBarAttributes objectForKey:@"CPMenuBarBackgroundColor"]];
[_CPMenuBarSharedWindow setTextColor:[_CPMenuBarAttributes objectForKey:@"CPMenuBarTextColor"]];
[_CPMenuBarSharedWindow setTitleColor:[_CPMenuBarAttributes objectForKey:@"CPMenuBarTitleColor"]];
[_CPMenuBarSharedWindow setTextShadowColor:[_CPMenuBarAttributes objectForKey:@"CPMenuBarTextShadowColor"]];
[_CPMenuBarSharedWindow setTitleShadowColor:[_CPMenuBarAttributes objectForKey:@"CPMenuBarTitleShadowColor"]];
[_CPMenuBarSharedWindow setHighlightColor:[_CPMenuBarAttributes objectForKey:@"CPMenuBarHighlightColor"]];
[_CPMenuBarSharedWindow setHighlightTextColor:[_CPMenuBarAttributes objectForKey:@"CPMenuBarHighlightTextColor"]];
[_CPMenuBarSharedWindow setHighlightTextShadowColor:[_CPMenuBarAttributes objectForKey:@"CPMenuBarHighlightTextShadowColor"]];
[_CPMenuBarSharedWindow orderFront:self];
}
else
[_CPMenuBarWindow orderOut:self];
[_CPMenuBarSharedWindow orderOut:self];
// FIXME: There must be a better way to do this.
#if PLATFORM(DOM)
@@ -125,6 +145,73 @@ var _CPMenuBarVisible = NO,
return _CPMenuBarImage;
}
+ (void)setMenuBarAttributes:(CPDictionary)attributes
{
if (_CPMenuBarAttributes == attributes)
return;
_CPMenuBarAttributes = [attributes copy];
var textColor = [attributes objectForKey:@"CPMenuBarTextColor"],
titleColor = [attributes objectForKey:@"CPMenuBarTitleColor"],
textShadowColor = [attributes objectForKey:@"CPMenuBarTextShadowColor"],
titleShadowColor = [attributes objectForKey:@"CPMenuBarTitleShadowColor"],
highlightColor = [attributes objectForKey:@"CPMenuBarHighlightColor"],
highlightTextColor = [attributes objectForKey:@"CPMenuBarHighlightTextColor"],
highlightTextShadowColor = [attributes objectForKey:@"CPMenuBarHighlightTextShadowColor"];
if (!textColor && titleColor)
[_CPMenuBarAttributes setObject:titleColor forKey:@"CPMenuBarTextColor"];
else if (textColor && !titleColor)
[_CPMenuBarAttributes setObject:textColor forKey:@"CPMenuBarTitleColor"];
else if (!textColor && !titleColor)
{
[_CPMenuBarAttributes setObject:[CPColor colorWithRed:0.051 green:0.2 blue:0.275 alpha:1.0] forKey:@"CPMenuBarTextColor"];
[_CPMenuBarAttributes setObject:[CPColor colorWithRed:0.051 green:0.2 blue:0.275 alpha:1.0] forKey:@"CPMenuBarTitleColor"];
}
if (!textShadowColor && titleShadowColor)
[_CPMenuBarAttributes setObject:titleShadowColor forKey:@"CPMenuBarTextShadowColor"];
else if (textShadowColor && !titleShadowColor)
[_CPMenuBarAttributes setObject:textShadowColor forKey:@"CPMenuBarTitleShadowColor"];
else if (!textShadowColor && !titleShadowColor)
{
[_CPMenuBarAttributes setObject:[CPColor whiteColor] forKey:@"CPMenuBarTextShadowColor"];
[_CPMenuBarAttributes setObject:[CPColor whiteColor] forKey:@"CPMenuBarTitleShadowColor"];
}
if (!highlightColor)
[_CPMenuBarAttributes setObject:[CPColor colorWithCalibratedRed:94.0/255.0 green:130.0/255.0 blue:186.0/255.0 alpha:1.0] forKey:@"CPMenuBarHighlightColor"];
if (!highlightTextColor)
[_CPMenuBarAttributes setObject:[CPColor whiteColor] forKey:@"CPMenuBarHighlightTextColor"];
if (!highlightTextShadowColor)
[_CPMenuBarAttributes setObject:[CPColor blackColor] forKey:@"CPMenuBarHighlightTextShadowColor"];
if (_CPMenuBarSharedWindow)
{
[_CPMenuBarSharedWindow setColor:[_CPMenuBarAttributes objectForKey:@"CPMenuBarBackgroundColor"]];
[_CPMenuBarSharedWindow setTextColor:[_CPMenuBarAttributes objectForKey:@"CPMenuBarTextColor"]];
[_CPMenuBarSharedWindow setTitleColor:[_CPMenuBarAttributes objectForKey:@"CPMenuBarTitleColor"]];
[_CPMenuBarSharedWindow setTextShadowColor:[_CPMenuBarAttributes objectForKey:@"CPMenuBarTextShadowColor"]];
[_CPMenuBarSharedWindow setTitleShadowColor:[_CPMenuBarAttributes objectForKey:@"CPMenuBarTitleShadowColor"]];
[_CPMenuBarSharedWindow setHighlightColor:[_CPMenuBarAttributes objectForKey:@"CPMenuBarHighlightColor"]];
[_CPMenuBarSharedWindow setHighlightTextColor:[_CPMenuBarAttributes objectForKey:@"CPMenuBarHighlightTextColor"]];
[_CPMenuBarSharedWindow setHighlightTextShadowColor:[_CPMenuBarAttributes objectForKey:@"CPMenuBarHighlightTextShadowColor"]];
}
}
+ (CPDictionary)menuBarAttributes
{
return _CPMenuBarAttributes;
}
+ (void)_setMenuBarIconImageAlphaValue:(float)anAlphaValue
{
_CPMenuBarIconImageAlphaValue = anAlphaValue;
@@ -139,8 +226,13 @@ var _CPMenuBarVisible = NO,
return 0.0;
}
+ (float)menuBarHeight
{
return MENUBAR_HEIGHT;
}
// Creating a CPMenu Object
/*
/*!
Initializes the menu with a specified title.
@param aTile the menu title
@return the initialized menu
@@ -161,8 +253,13 @@ var _CPMenuBarVisible = NO,
return self;
}
- (id)init
{
return [self initWithTitle:@""];
}
// Setting Up Menu Commands
/*
/*!
Inserts a menu item at the specified index.
@param aMenuItem the item to insert
@param anIndex the index in the menu to insert the item.
@@ -187,7 +284,7 @@ var _CPMenuBarVisible = NO,
}
/*
/*!
Creates and inserts a new menu item with the specified attributes.
@param aTitle the title of the menu item
@param anAction the action initiated when the user selects the item
@@ -204,7 +301,7 @@ var _CPMenuBarVisible = NO,
return item;
}
/*
/*!
Adds a menu item at the end of the menu.
@param aMenuItem the menu item to add
*/
@@ -213,7 +310,7 @@ var _CPMenuBarVisible = NO,
[self insertItem:aMenuItem atIndex:[_items count]];
}
/*
/*!
Creates and adds a menu item with the specified attributes
at the end of the menu.
@param aTitle the title of the new menu item
@@ -226,7 +323,7 @@ var _CPMenuBarVisible = NO,
return [self insertItemWithTitle:aTitle action:anAction keyEquivalent:aKeyEquivalent atIndex:[_items count]];
}
/*
/*!
Removes the specified item from the menu
@param aMenuItem the item to remove
*/
@@ -235,7 +332,7 @@ var _CPMenuBarVisible = NO,
[self removeItemAtIndex:[_items indexOfObjectIdenticalTo:aMenuItem]];
}
/*
/*!
Removes the item at the specified index from the menu
@param anIndex the index of the item to remove
*/
@@ -253,7 +350,7 @@ var _CPMenuBarVisible = NO,
userInfo:[CPDictionary dictionaryWithObject:anIndex forKey:@"CPMenuItemIndex"]];
}
/*
/*!
Called when a menu item has visually changed.
@param aMenuItem the item that changed
*/
@@ -269,7 +366,7 @@ var _CPMenuBarVisible = NO,
}
// Finding Menu Items
/*
/*!
Returns the menu item with the specified tag
@param the tag of the desired menu item
@return the menu item or <code>nil</code> if a match was not found
@@ -284,7 +381,7 @@ var _CPMenuBarVisible = NO,
return _items[index];
}
/*
/*!
Returns the menu item with the specified title.
@param aTitle the title of the menu item
@return the menu item or <code>nil</code> if a match was not found
@@ -299,7 +396,7 @@ var _CPMenuBarVisible = NO,
return _items[index];
}
/*
/*!
Returns the menu item at the specified index
@param anIndex the index of the requested item
*/
@@ -308,7 +405,7 @@ var _CPMenuBarVisible = NO,
return [_items objectAtIndex:anIndex];
}
/*
/*!
Returns the number of menu items in the menu
*/
- (unsigned)numberOfItems
@@ -316,7 +413,7 @@ var _CPMenuBarVisible = NO,
return [_items count];
}
/*
/*!
Returns the array of menu items backing this menu
*/
- (CPArray)itemArray
@@ -325,10 +422,10 @@ var _CPMenuBarVisible = NO,
}
// Finding Indices of Menu Items
/*
/*!
Returns the index of the specified menu item
@param aMenuItem the item to find the index for
@return the item index or <objj>CPNotFound</objj>
@return the item index or CPNotFound
*/
- (int)indexOfItem:(CPMenuItem)aMenuItem
{
@@ -338,10 +435,10 @@ var _CPMenuBarVisible = NO,
return [_items indexOfObjectIdenticalTo:aMenuItem];
}
/*
/*!
Returns the index of the item with the specified title.
@param aTitle the desired title to match
@return the index of the item or <objj>CPNotFound</objj>
@return the index of the item or CPNotFound
*/
- (int)indexOfItemWithTitle:(CPString)aTitle
{
@@ -355,10 +452,10 @@ var _CPMenuBarVisible = NO,
return CPNotFound;
}
/*
/*!
Returns the index of the item with the specified tag
@param aTag the desired tag to match
@return the index of the item or <objj>CPNotFound</objj>
@return the index of the item or CPNotFound
*/
- (int)indexOfItemWithTag:(int)aTag
{
@@ -372,11 +469,11 @@ var _CPMenuBarVisible = NO,
return CPNotFound;
}
/*
/*!
Returns the index of the item with the specified target and action.
@param aTarget the target of the desired menu item
@param anAction the action of the desired menu item
@return the index of the item or <objj>CPNotFound</objj>
@return the index of the item or CPNotFound
*/
- (int)indexOfItemWithTarget:(id)aTarget andAction:(SEL)anAction
{
@@ -394,10 +491,10 @@ var _CPMenuBarVisible = NO,
return CPNotFound;
}
/*
/*!
Returns the index of the menu item with the specified represented object.
@param anObject the represented object of the desired item
@return the index of the item or <objj>CPNotFound</objj>
@return the index of the item or CPNotFound
*/
- (int)indexOfItemWithRepresentedObject:(id)anObject
{
@@ -411,10 +508,10 @@ var _CPMenuBarVisible = NO,
return CPNotFound;
}
/*
/*!
Returns the index of the item with the specified submenu.
@param the submenu of the desired menu item
@return the index of the item or <objj>CPNotFound</objj>
@return the index of the item or CPNotFound
*/
- (int)indexOfItemWithSubmenu:(CPMenu)aMenu
{
@@ -429,7 +526,7 @@ var _CPMenuBarVisible = NO,
}
// Managing Submenus
/*
/*!
Sets a submenu for a menu item
@param aMenu the submenu
@param aMenuItem the menu item to set the submenu on
@@ -442,7 +539,7 @@ var _CPMenuBarVisible = NO,
[aMenuItem setSubmenu:aMenu];
}
/*
/*!
The action method of menu items that open submenus.
The default implementation does nothing, but it may
be subclassed to provide different behavior.
@@ -453,7 +550,7 @@ var _CPMenuBarVisible = NO,
}
/*
/*!
Returns the attaced menu, or <code>nil</code> if there isn't one.
*/
- (CPMenu)attachedMenu
@@ -461,7 +558,7 @@ var _CPMenuBarVisible = NO,
return _attachedMenu;
}
/*
/*!
Returns <code>YES</code> if the menu is attached to another menu.
*/
- (BOOL)isAttached
@@ -469,7 +566,7 @@ var _CPMenuBarVisible = NO,
return _isAttached;
}
/*
/*!
Not yet implemented
*/
- (CGPoint)locationOfSubmenu:(CPMenu)aMenu
@@ -477,7 +574,7 @@ var _CPMenuBarVisible = NO,
// FIXME: IMPLEMENT.
}
/*
/*!
Returns the super menu or <code>nil</code> if there is none.
*/
- (CPMenu)supermenu
@@ -485,7 +582,7 @@ var _CPMenuBarVisible = NO,
return _supermenu;
}
/*
/*!
Sets the super menu.
@param aMenu the new super menu
*/
@@ -494,7 +591,7 @@ var _CPMenuBarVisible = NO,
_supermenu = aMenu;
}
/*
/*!
If there are two instances of this menu visible, return <code>NO</code>.
Otherwise, return <code>YES</code> if we are a detached menu and visible.
*/
@@ -504,7 +601,7 @@ var _CPMenuBarVisible = NO,
}
// Enabling and Disabling Menu Items
/*
/*!
Sets whether the menu automatically enables menu items.
@param aFlag <code>YES</code> sets the menu to automatically enable items.
*/
@@ -513,7 +610,7 @@ var _CPMenuBarVisible = NO,
_autoenablesItems = aFlag;
}
/*
/*!
Returns <code>YES</code> if the menu auto enables items.
*/
- (BOOL)autoenablesItems
@@ -521,7 +618,7 @@ var _CPMenuBarVisible = NO,
return _autoenablesItems;
}
/*
/*!
Not implemented.
*/
- (void)update
@@ -530,7 +627,7 @@ var _CPMenuBarVisible = NO,
}
// Managing the Title
/*
/*!
Sets the menu title.
@param the new title
*/
@@ -539,7 +636,7 @@ var _CPMenuBarVisible = NO,
_title = aTitle;
}
/*
/*!
Returns the menu title
*/
- (CPString)title
@@ -568,10 +665,10 @@ var _CPMenuBarVisible = NO,
if (!aFont)
aFont = [CPFont systemFontOfSize:12.0];
var theWindow = [aView window],
menuWindow = [_CPMenuWindow menuWindowWithMenu:aMenu font:aFont];
[menuWindow setDelegate:self];
[menuWindow setBackgroundStyle:isForMenuBar ? _CPMenuWindowMenuBarBackgroundStyle : _CPMenuWindowPopUpBackgroundStyle];
@@ -583,31 +680,21 @@ var _CPMenuBarVisible = NO,
+ (void)_menuWindowDidFinishTracking:(_CPMenuWindow)aMenuWindow highlightedItem:(CPMenuItem)aMenuItem
{
[_CPMenuWindow poolMenuWindow:aMenuWindow];
// var index = [self indexOfItem:aMenuItem];
// if (index == CPNotFound)
// return;
var target = nil,
action = [aMenuItem action];
if (!action)
{
// target = [self target];
// action = [self action];
}
// FIXME: If [selectedItem target] == nil do we use our own target?
else
target = [aMenuItem target];
var menu = [aMenuWindow menu];
[CPApp sendAction:action to:target from:nil];
[_CPMenuWindow poolMenuWindow:aMenuWindow];
var delegate = [menu delegate];
if ([delegate respondsToSelector:@selector(menuDidClose:)])
[delegate menuDidClose:menu];
if([aMenuItem isEnabled])
[CPApp sendAction:[aMenuItem action] to:[aMenuItem target] from:aMenuItem];
}
// Managing Display of State Column
/*
/*!
Sets whether to show the state column
@param shouldShowStateColumn <code>YES</code> shows the state column
*/
@@ -616,7 +703,7 @@ var _CPMenuBarVisible = NO,
_showsStateColumn = shouldShowStateColumn;
}
/*
/*!
Returns <code>YES</code> if the menu shows the state column
*/
- (BOOL)showsStateColumn
@@ -625,7 +712,7 @@ var _CPMenuBarVisible = NO,
}
// Handling Highlighting
/*
/*!
Returns the currently highlighted menu item.
@return the highlighted menu item or <code>nil</code> if no item is currently highlighted
*/
@@ -647,7 +734,7 @@ var _CPMenuBarVisible = NO,
}
// Handling Tracking
/*
/*!
Cancels tracking.
*/
- (void)cancelTracking
@@ -661,7 +748,7 @@ var _CPMenuBarVisible = NO,
_menuWindow = aMenuWindow;
}
/*
/*!
Initiates the action of the menu item that
has a keyboard shortcut equivalent to <code>anEvent</code>
@param anEvent the keyboard event
@@ -703,7 +790,7 @@ var _CPMenuBarVisible = NO,
}
// Simulating Mouse Clicks
/*
/*!
Sends the action of the menu item at the specified index.
@param anIndex the index of the item
*/
@@ -742,12 +829,13 @@ var _CPMenuBarVisible = NO,
@end
var CPMenuTitleKey = @"CPMenuTitleKey",
CPMenuItemsKey = @"CPMenuItemsKey";
var CPMenuTitleKey = @"CPMenuTitleKey",
CPMenuItemsKey = @"CPMenuItemsKey",
CPMenuShowsStateColumnKey = @"CPMenuShowsStateColumnKey";
@implementation CPMenu (CPCoding)
/*
/*!
Initializes the menu with data from the specified coder.
@param aCoder the coder from which to read the data
@return the initialized menu
@@ -760,12 +848,14 @@ var CPMenuTitleKey = @"CPMenuTitleKey",
{
_title = [aCoder decodeObjectForKey:CPMenuTitleKey];
_items = [aCoder decodeObjectForKey:CPMenuItemsKey];
_showsStateColumn = ![aCoder containsValueForKey:CPMenuShowsStateColumnKey] || [aCoder decodeBoolForKey:CPMenuShowsStateColumnKey];
}
return self;
}
/*
/*!
Encodes the data of the menu into a coder
@param aCoder the coder to which the data will be written
*/
@@ -773,6 +863,9 @@ var CPMenuTitleKey = @"CPMenuTitleKey",
{
[aCoder encodeObject:_title forKey:CPMenuTitleKey];
[aCoder encodeObject:_items forKey:CPMenuItemsKey];
if (!_showsStateColumn)
[aCoder encodeBool:_showsStateColumn forKey:CPMenuShowsStateColumnKey];
}
@end
@@ -865,7 +958,7 @@ var STICKY_TIME_INTERVAL = 500,
if (self)
{
[self setLevel:CPTornOffMenuWindowLevel];
[self setLevel:CPPopUpMenuWindowLevel];
[self setHasShadow:YES];
[self setAcceptsMouseMovedEvents:YES];
@@ -898,6 +991,11 @@ var STICKY_TIME_INTERVAL = 500,
return self;
}
- (CGFloat)overlapOffsetWidth
{
return LEFT_MARGIN;
}
- (void)setFont:(CPFont)aFont
{
[_menuView setFont:aFont];
@@ -1154,6 +1252,9 @@ var STICKY_TIME_INTERVAL = 500,
if (_trackingCanceled)
{
// Stop all periodic events at this point.
[CPEvent stopPeriodicEvents];
var highlightedItem = [[_menuView menu] highlightedItem];
[menu _highlightItemAtIndex:CPNotFound];
@@ -1189,6 +1290,7 @@ var STICKY_TIME_INTERVAL = 500,
@implementation _CPMenuView : CPView
{
CPArray _menuItemViews;
CPArray _visibleMenuItemInfos;
CPFont _font;
}
@@ -1215,21 +1317,33 @@ var STICKY_TIME_INTERVAL = 500,
- (int)itemIndexAtPoint:(CGPoint)aPoint
{
var index = 0,
count = _menuItemViews.length;
var x = aPoint.x,
bounds = [self bounds];
for (; index < count; ++index)
if (x < CGRectGetMinX(bounds) || x > CGRectGetMaxX(bounds))
return CPNotFound;
var y = aPoint.y,
low = 0,
high = _visibleMenuItemInfos.length - 1;
while (low <= high)
{
var view = _menuItemViews[index];
var middle = FLOOR(low + (high - low) / 2),
info = _visibleMenuItemInfos[middle]
frame = [info.view frame];
if ([view isHidden])
continue;
if (y < CGRectGetMinY(frame))
high = middle - 1;
if (CGRectContainsPoint([view frame], aPoint))
return index;
}
return CPNotFound;
else if (y > CGRectGetMaxY(frame))
low = middle + 1;
else
return info.index;
}
return CPNotFound;
}
- (void)setMenu:(CPMenu)aMenu
@@ -1239,6 +1353,7 @@ var STICKY_TIME_INTERVAL = 500,
[_menuItemViews makeObjectsPerformSelector:@selector(removeFromSuperview)];
_menuItemViews = [];
_visibleMenuItemInfos = [];
var menu = [self menu];
@@ -1262,6 +1377,8 @@ var STICKY_TIME_INTERVAL = 500,
if ([item isHidden])
continue;
_visibleMenuItemInfos.push({ view:view, index:index });
[view setFont:_font];
[view setShowsStateColumn:showsStateColumn];
[view synchronizeWithMenuItem];
@@ -1311,6 +1428,16 @@ var _CPMenuBarWindowBackgroundColor = nil,
CPImageView _iconImageView;
CPTextField _titleField;
CPColor _textColor;
CPColor _titleColor;
CPColor _textShadowColor;
CPColor _titleShadowColor;
CPColor _highlightColor;
CPColor _highlightTextColor;
CPColor _highlightTextShadowColor;
}
+ (void)initialize
@@ -1320,8 +1447,6 @@ var _CPMenuBarWindowBackgroundColor = nil,
var bundle = [CPBundle bundleForClass:self];
_CPMenuBarWindowBackgroundColor = [CPColor colorWithPatternImage:[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuBarWindow/_CPMenuBarWindowBackground.png"] size:CGSizeMake(1.0, 18.0)]];
_CPMenuBarWindowFont = [CPFont systemFontOfSize:11.0];
}
@@ -1339,7 +1464,6 @@ var _CPMenuBarWindowBackgroundColor = nil,
var contentView = [self contentView];
[contentView setBackgroundColor:_CPMenuBarWindowBackgroundColor];
[contentView setAutoresizesSubviews:NO];
[self setBecomesKeyOnlyIfNeeded:YES];
@@ -1349,12 +1473,11 @@ var _CPMenuBarWindowBackgroundColor = nil,
[contentView addSubview:_iconImageView];
_titleField = [[_CPImageAndTitleView alloc] initWithFrame:CGRectMakeZero()];
_titleField = [[CPTextField alloc] initWithFrame:CGRectMakeZero()];
[_titleField setFont:[CPFont boldSystemFontOfSize:12.0]];
[_titleField setImagePosition:CPImageLeft];
[_titleField setAlignment:CPCenterTextAlignment];
[_titleField setTextShadowOffset:CGSizeMake(0, 1)];
[contentView addSubview:_titleField];
}
@@ -1375,7 +1498,7 @@ var _CPMenuBarWindowBackgroundColor = nil,
document.title = bundleName;
#endif
[_titleField setTitle:aTitle];
[_titleField setStringValue:aTitle];
[_titleField sizeToFit];
[self tile];
@@ -1394,6 +1517,87 @@ var _CPMenuBarWindowBackgroundColor = nil,
[_iconImageView setAlphaValue:anAlphaValue];
}
- (void)setColor:(CPColor)aColor
{
if (!aColor)
{
if (!_CPMenuBarWindowBackgroundColor)
_CPMenuBarWindowBackgroundColor = [CPColor colorWithPatternImage:[[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:[_CPMenuBarWindow class]] pathForResource:@"_CPMenuBarWindow/_CPMenuBarWindowBackground.png"] size:CGSizeMake(1.0, 18.0)]];
[[self contentView] setBackgroundColor:_CPMenuBarWindowBackgroundColor];
}
else
[[self contentView] setBackgroundColor:aColor];
}
- (void)setTextColor:(CPColor)aColor
{
if (_textColor == aColor)
return;
_textColor = aColor;
[_menuItemViews makeObjectsPerformSelector:@selector(setTextColor:) withObject:_textColor];
}
- (void)setTitleColor:(CPColor)aColor
{
if (_titleColor == aColor)
return;
_titleColor = aColor;
[_titleField setTextColor:aColor ? aColor : [CPColor blackColor]];
}
- (void)setTextShadowColor:(CPColor)aColor
{
if (_textShadowColor == aColor)
return;
_textShadowColor = aColor;
[_menuItemViews makeObjectsPerformSelector:@selector(setTextShadowColor:) withObject:_textShadowColor];
}
- (void)setTitleShadowColor:(CPColor)aColor
{
if (_titleShadowColor == aColor)
return;
_titleShadowColor = aColor;
[_titleField setTextShadowColor:aColor ? aColor : [CPColor whiteColor]];
}
- (void)setHighlightColor:(CPColor)aColor
{
if (_highlightColor == aColor)
return;
_highlightColor = aColor;
}
- (void)setHighlightTextColor:(CPColor)aColor
{
if (_highlightTextColor == aColor)
return;
_highlightTextColor = aColor;
[_menuItemViews makeObjectsPerformSelector:@selector(setActivateColor:) withObject:_highlightTextColor];
}
- (void)setHighlightTextShadowColor:(CPColor)aColor
{
if (_highlightTextShadowColor == aColor)
return;
_highlightTextShadowColor = aColor;
[_menuItemViews makeObjectsPerformSelector:@selector(setActivateShadowColor:) withObject:_highlightTextShadowColor];
}
- (void)setMenu:(CPMenu)aMenu
{
if (_menu == aMenu)
@@ -1464,6 +1668,7 @@ var _CPMenuBarWindowBackgroundColor = nil,
[menuItemView setShowsStateColumn:NO];
[menuItemView setBelongsToMenuBar:YES];
[menuItemView setFont:_CPMenuBarWindowFont];
[menuItemView setTextColor:_textColor];
[menuItemView setHidden:[item isHidden]];
[menuItemView synchronizeWithMenuItem];
@@ -1496,6 +1701,7 @@ var _CPMenuBarWindowBackgroundColor = nil,
[menuItemView setShowsStateColumn:NO];
[menuItemView setBelongsToMenuBar:YES];
[menuItemView setFont:_CPMenuBarWindowFont];
[menuItemView setTextColor:_textColor];
[menuItemView setHidden:[menuItem isHidden]];
[menuItemView synchronizeWithMenuItem];
@@ -1566,7 +1772,7 @@ var _CPMenuBarWindowBackgroundColor = nil,
{
var type = [anEvent type];
if (type == CPPeriodic)
if (type === CPPeriodic)
return [self showMenu:anEvent];
var frame = [self frameForMenuItem:_trackingMenuItem],
@@ -1577,8 +1783,11 @@ var _CPMenuBarWindowBackgroundColor = nil,
{
if ([_trackingMenuItem submenu] != nil)
{
var action = [_trackingMenuItem action];
// If the item has a submenu, but not direct action, a.k.a. a "pure" menu, simply show the menu.
if (![_trackingMenuItem action])
// FIXME: (?) should we use submenuAction: or not?
if (!action || action === @selector(submenuAction:))
return [self showMenu:anEvent];
// If this is a hybrid button/menu, show it in a bit...
@@ -1603,7 +1812,7 @@ var _CPMenuBarWindowBackgroundColor = nil,
[menuItemView highlight:NO];
if (onMenuItemView)
[CPApp sendAction:[_trackingMenuItem action] to:[_trackingMenuItem target] from:nil];
[CPApp sendAction:[_trackingMenuItem action] to:[_trackingMenuItem target] from:_trackingMenuItem];
return;
}
@@ -1622,7 +1831,7 @@ var _CPMenuBarWindowBackgroundColor = nil,
{
_highlightView = [[CPView alloc] initWithFrame:frame];
[_highlightView setBackgroundColor:[CPColor colorWithCalibratedRed:81.0 / 255.0 green:83.0 / 255.0 blue:109.0 / 255.0 alpha:1.0]];
[_highlightView setBackgroundColor:_highlightColor ? _highlightColor : [CPColor colorWithRed:95.0/255.0 green:131.0/255.0 blue:185.0/255.0 alpha:1.0]];
}
else
[_highlightView setFrame:frame];
+330 -189
View File
File diff suppressed because it is too large Load Diff
+8 -8
View File
@@ -20,11 +20,11 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
import "CPTableView.j"
@import "CPTableView.j"
/*
/*!
@ignore
This class is a subclass of <objj>CPTableView</objj> which provides the user with a way to display
This class is a subclass of CPTableView which provides the user with a way to display
tree structured data in an outline format. It is particularly useful for displaying hierarchical data
such as a class inheritance tree or any other set of relationships.
*/
@@ -48,14 +48,14 @@ import "CPTableView.j"
return self;
}
/*
/*!
@ignore
Sets the outline's data source. The data source must implement the following methods:
<pre>
- (id)outlineView:(<objj>CPOutlineView</objj>)outlineView child:(int)index ofItem:(id)item
- (BOOL)outlineView:(<objj>CPOutlineView</objj>)outlineView isItemExpandable:(id)item
- (int)outlineView:(<objj>CPOutlineView</objj>)outlineView numberOfChildrenOfItem:(id)item
- (id)outlineView:(<objj>CPOutlineView</objj>)outlineView objectValueForTableColumn:(<objj>CPTableColumn</objj>)tableColumn byItem:(id)item
- (id)outlineView:(CPOutlineView)outlineView child:(int)index ofItem:(id)item
- (BOOL)outlineView:(CPOutlineView)outlineView isItemExpandable:(id)item
- (int)outlineView:(CPOutlineView)outlineView numberOfChildrenOfItem:(id)item
- (id)outlineView:(CPOutlineView)outlineView objectValueForTableColumn:(CPTableColumn)tableColumn byItem:(id)item
</pre>
@param aDataSource the outline's data source
@throws CPInternalInconsistencyException if the data source does not implement all the required methods
+11 -8
View File
@@ -20,14 +20,17 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
import "CPWindow.j"
@import "CPWindow.j"
CPOKButton = 1;
CPCancelButton = 0;
/*
The <objj>CPPanel</objj> class defines objects that manage the panels of the Cappuccino user interface. A panel is a window that serves an auxiliary function within an application. It generally displays controls that the user can act on to give instructions to the application or to modify the contents of a standard window.</p>
/*!
@ingroup appkit
@class CPPanel
The CPPanel class defines objects that manage the panels of the Cappuccino user interface. A panel is a window that serves an auxiliary function within an application. It generally displays controls that the user can act on to give instructions to the application or to modify the contents of a standard window.</p>
<p>Panels behave differently from standard windows in only a small number of ways, but the ways are important to the user interface:</p>
@@ -49,7 +52,7 @@ CPCancelButton = 0;
BOOL _worksWhenModal;
}
/*
/*!
Returns <code>YES</code> if the receiver is a floating panel (like a palette).
*/
- (BOOL)isFloatingPanel
@@ -57,7 +60,7 @@ CPCancelButton = 0;
return [self level] == CPFloatingWindowLevel;
}
/*
/*!
Sets the receiver to be a floating panel. <code>YES</code>
makes the window a floating panel. <code>NO</code> makes it a normal window.
@param isFloatingPanel specifies whether to make it floating
@@ -67,7 +70,7 @@ CPCancelButton = 0;
[self setLevel:isFloatingPanel ? CPFloatingWindowLevel : CPNormalWindowLevel];
}
/*
/*!
Returns <code>YES</code> if the window only becomes key
if needed. <code>NO</code> means it behaves just like other windows.
*/
@@ -76,7 +79,7 @@ CPCancelButton = 0;
return _becomesKeyOnlyIfNeeded;
}
/*
/*!
Sets whether the the window becomes key only if needed.
@param shouldBecomeKeyOnlyIfNeeded <code>YES</code> makes the window become key only if needed
*/
@@ -90,7 +93,7 @@ CPCancelButton = 0;
return _worksWhenModal;
}
/*
/*!
Sets whether this window can receive input while another window is running modally.
@param shouldWorkWhenModal whether to receive input while another window is modal
*/
+26 -19
View File
@@ -20,10 +20,10 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
import <Foundation/CPObject.j>
import <Foundation/CPArray.j>
import <Foundation/CPDictionary.j>
import <Foundation/CPPropertyListSerialization.j>
@import <Foundation/CPObject.j>
@import <Foundation/CPArray.j>
@import <Foundation/CPDictionary.j>
@import <Foundation/CPPropertyListSerialization.j>
CPGeneralPboard = @"CPGeneralPboard";
@@ -38,12 +38,19 @@ CPFontPboardType = @"CPFontPboardType";
CPHTMLPboardType = @"CPHTMLPboardType";
CPStringPboardType = @"CPStringPboardType";
CPURLPboardType = @"CPURLPboardType";
CPImagesPboardType = @"CPImagesPboardType";
CPVideosPboardType = @"CPVideosPboardType";
// Deprecated
CPImagePboardType = @"CPImagePboardType";
var CPPasteboards = nil;
/*
<objj>CPPasteBoard</objj> is the object responsible for cut/copy/paste and drag&drop operations.
/*!
@ingroup appkit
@class CPPasteboard
CPPasteBoard is the object responsible for cut/copy/paste and drag&drop operations.
*/
@implementation CPPasteboard : CPObject
{
@@ -68,7 +75,7 @@ var CPPasteboards = nil;
CPPasteboards = [CPDictionary dictionary];
}
/*
/*!
Returns a new instance of a pasteboard
*/
+ (id)generalPasteboard
@@ -76,7 +83,7 @@ var CPPasteboards = nil;
return [CPPasteboard pasteboardWithName:CPGeneralPboard];
}
/*
/*!
Returns a pasteboard with the specified name. If the pasteboard doesn't exist, it will be created.
@param aName the name of the pasteboard
@return the requested pasteboard
@@ -113,7 +120,7 @@ var CPPasteboards = nil;
return self;
}
/*
/*!
Adds supported data types to the pasteboard
@param types the data types
@param anOwner the object that contains the data types
@@ -140,7 +147,7 @@ var CPPasteboards = nil;
return ++_changeCount;
}
/*
/*!
Sets the data types that this pasteboard will contain.
@param type the data types it will support
@param anOwner the object that contains the the data
@@ -161,7 +168,7 @@ var CPPasteboards = nil;
return ++_changeCount;
}
/*
/*!
Sets the pasteboard data for the specified type
@param aData the data
@param aType the data type being set
@@ -174,7 +181,7 @@ var CPPasteboards = nil;
return YES;
}
/*
/*!
Writes the specified property list as data for the specified type
@param aPropertyList the property list to write
@param aType the data type
@@ -185,7 +192,7 @@ var CPPasteboards = nil;
return [self setData:[CPPropertyListSerialization dataFromPropertyList:aPropertyList format:CPPropertyListXMLFormat_v1_0 errorDescription:nil] forType:aType];
}
/*
/*!
Sets the specified string as data for the specified type
@param aString the string to write
@param aType the data type
@@ -197,7 +204,7 @@ var CPPasteboards = nil;
}
// Determining Types
/*
/*!
Checks the pasteboard's types for a match with the types listen in the specified array. The array should
be ordered by the requestor's most preferred data type first.
@param anArray an array of requested types ordered by preference
@@ -208,7 +215,7 @@ var CPPasteboards = nil;
return [_types firstObjectCommonWithArray:anArray];
}
/*
/*!
Returns the pasteboards supported types
*/
- (CPArray)types
@@ -217,7 +224,7 @@ var CPPasteboards = nil;
}
// Reading data
/*
/*!
Returns the number of changes that have occurred to this pasteboard
*/
- (unsigned)changeCount
@@ -225,7 +232,7 @@ var CPPasteboards = nil;
return _changeCount;
}
/*
/*!
Returns the pasteboard data for the specified data type
@param aType the requested data type
@return the requested data or <code>nil</code> if the data doesn't exist
@@ -251,7 +258,7 @@ var CPPasteboards = nil;
return nil;
}
/*
/*!
Returns the property list for the specified data type
@param aType the requested data type
@return the property list or <code>nil</code> if the list was not found
@@ -266,7 +273,7 @@ var CPPasteboards = nil;
return nil;
}
/*
/*!
Returns the string for the specified data type
@param aType the requested data type
@return the string or <code>nil</code> if the string was not found
+151 -147
View File
@@ -20,31 +20,38 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
import "CPButton.j"
import "CPGeometry.j"
import "CPMenu.j"
import "CPMenuItem.j"
@import "CPButton.j"
@import "CPGeometry.j"
@import "CPMenu.j"
@import "CPMenuItem.j"
#include "CoreGraphics/CGGeometry.h"
var VISIBLE_MARGIN = 7.0;
var CPPopUpButtonArrowsImage = nil;
CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
/*
A <objj>CPPopUpButton</objj> contains a pop-up menu of items that a user can select from.
/*!
@ingroup appkit
@class CPPopUpButton
A CPPopUpButton contains a pop-up menu of items that a user can select from.
*/
@implementation CPPopUpButton : CPButton
{
BOOL _pullsDown;
int _selectedIndex;
CPRectEdge _preferredEdge;
CPImageView _arrowsView;
CPMenu _menu;
}
/*
+ (CPString)themeClass
{
return "popup-button";
}
/*!
Initializes the pop-up button to the specified size.
@param aFrame the size for the button
@param shouldPullDown <code>YES</code> makes this a pull-down menu, <code>NO</code> makes it a pop-up menu.
@@ -56,16 +63,16 @@ var CPPopUpButtonArrowsImage = nil;
if (self)
{
_pullsDown = shouldPullDown;
_selectedIndex = CPNotFound;
_preferredEdge = CPMaxYEdge;
[self setBezelStyle:CPTexturedRoundedBezelStyle];
[self setImagePosition:CPImageLeft];
[self setAlignment:CPLeftTextAlignment];
[self setValue:CPImageLeft forThemeAttribute:@"image-position"];
[self setValue:CPLeftTextAlignment forThemeAttribute:@"alignment"];
[self setValue:CPLineBreakByTruncatingTail forThemeAttribute:@"line-break-mode"];
[self setMenu:[[CPMenu alloc] initWithTitle:@""]];
[self setPullsDown:shouldPullDown];
}
return self;
@@ -76,76 +83,61 @@ var CPPopUpButtonArrowsImage = nil;
return [self initWithFrame:aFrame pullsDown:NO];
}
- (void)setBordered:(BOOL)shouldBeBordered
{
if (shouldBeBordered)
{
var bounds = [self bounds];
_arrowsView = [[CPImageView alloc] initWithFrame:CGRectMake(CGRectGetWidth(bounds) - 10.0, (CGRectGetHeight(bounds) - 8.0) / 2.0, 5.0, 8.0)];
if (!CPPopUpButtonArrowsImage)
CPPopUpButtonArrowsImage = [[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:[CPPopUpButton class]] pathForResource:@"CPPopUpButton/CPPopUpButtonArrows.png"] size:CGSizeMake(5.0, 8.0)];
[_arrowsView setImage:CPPopUpButtonArrowsImage];
[_arrowsView setAutoresizingMask:CPViewMaxXMargin | CPViewMinYMargin | CPViewMaxYMargin];
[self addSubview:_arrowsView];
}
else
{
[_arrowsView removeFromSuperview];
_arrowsView = nil;
}
[super setBordered:shouldBeBordered];
}
// Setting the Type of Menu
/*
/*!
Specifies whether the object is a pull-down or a pop-up menu.
@param shouldPullDown <code>YES</code> makes the pop-up button
a pull-down menu. <code>NO</code> makes it a pop-up menu.
*/
- (void)setPullsDown:(BOOL)shouldPullDown
{
if (_pullsDown == shouldPullDown)
if (shouldPullDown)
var changed = [self setThemeState:CPPopUpButtonStatePullsDown];
else
var changed = [self unsetThemeState:CPPopUpButtonStatePullsDown];
if (!changed)
return;
_pullsDown = shouldPullDown;
var items = [_menu itemArray];
if (items.length <= 0)
if ([items count] <= 0)
return;
[items[0] setHidden:_pullsDown];
[items[0] setHidden:[self pullsDown]];
[self synchronizeTitleAndSelectedItem];
}
/*
/*!
Returns <code>YES</code> if the button is a pull-down menu. <code>NO</code> if the button is a pop-up menu.
*/
- (BOOL)pullsDown
{
return _pullsDown;
return [self hasThemeState:CPPopUpButtonStatePullsDown];
}
// Inserting and Deleting Items
/*
/*!
Adds a new menu item using a CPMenuItem object.
*/
- (void)addItem:(CPMenuItem)anItem
{
[_menu addItem:anItem];
}
/*!
Adds a new menu item with the specified title.
@param the new menu item's tite
*/
- (void)addItemWithTitle:(CPString)aTitle
{
[_menu addItemWithTitle:aTitle action:NULL keyEquivalent:NULL];
[_menu addItemWithTitle:aTitle action:NULL keyEquivalent:nil];
}
/*
/*!
Adds multiple new menu items with the titles specified in the provided array.
@param titles an arry of names for the new items
*/
@@ -158,7 +150,7 @@ var CPPopUpButtonArrowsImage = nil;
[self addItemWithTitle:titles[index]];
}
/*
/*!
Inserts a new item with the specified title and index location.
@param aTitle the new itme's title
@param anIndex the item's index in the menu
@@ -172,10 +164,10 @@ var CPPopUpButtonArrowsImage = nil;
if ([items[count] title] == aTitle)
[self removeItemAtIndex:count];
[_menu insertItemWithTitle:aTitle action:NULL keyEquivalent:NULL atIndex:anIndex];
[_menu insertItemWithTitle:aTitle action:NULL keyEquivalent:nil atIndex:anIndex];
}
/*
/*!
Removes all menu items from the pop-up button's menu
*/
- (void)removeAllItems
@@ -186,7 +178,7 @@ var CPPopUpButtonArrowsImage = nil;
[_menu removeItemAtIndex:0];
}
/*
/*!
Removes a menu item with the specified title from the button.
@param aTitle the title of the item to remove
*/
@@ -196,7 +188,7 @@ var CPPopUpButtonArrowsImage = nil;
[self synchronizeTitleAndSelectedItem];
}
/*
/*!
Removes the menu item at the specified index
@param anIndex the index of the item to remove
*/
@@ -207,7 +199,7 @@ var CPPopUpButtonArrowsImage = nil;
}
// Getting the User's Selection
/*
/*!
Returns the selected item or <code>nil</code> if no item is selected.
*/
- (CPMenuItem)selectedItem
@@ -218,7 +210,7 @@ var CPPopUpButtonArrowsImage = nil;
return [_menu itemAtIndex:_selectedIndex];
}
/*
/*!
Returns the title of the selected item or <code>nil</code> if no item is selected.
*/
- (CPString)titleOfSelectedItem
@@ -226,8 +218,8 @@ var CPPopUpButtonArrowsImage = nil;
return [[self selectedItem] title];
}
/*
Returns the index of the selected item. If no item is selected, it returns <objj>CPNotFound</objj>.
/*!
Returns the index of the selected item. If no item is selected, it returns CPNotFound.
*/
- (int)indexOfSelectedItem
{
@@ -235,8 +227,8 @@ var CPPopUpButtonArrowsImage = nil;
}
// For us, CPNumber is toll-free bridged to Number, so just return the selected index.
/*
Returns the selected item's index. If no item is selected, it returns <objj>CPNotFound</objj>.
/*!
Returns the selected item's index. If no item is selected, it returns CPNotFound.
*/
- (id)objectValue
{
@@ -244,7 +236,7 @@ var CPPopUpButtonArrowsImage = nil;
}
// Setting the Current Selection
/*
/*!
Selects the specified menu item.
@param aMenuItem the item to select
*/
@@ -253,7 +245,7 @@ var CPPopUpButtonArrowsImage = nil;
[self selectItemAtIndex:[self indexOfItem:aMenuItem]];
}
/*
/*!
Selects the item at the specified index
@param anIndex the index of the item to select
*/
@@ -262,18 +254,18 @@ var CPPopUpButtonArrowsImage = nil;
if (_selectedIndex == anIndex)
return;
if (_selectedIndex >= 0 && !_pullsDown)
if (_selectedIndex >= 0 && ![self pullsDown])
[[self selectedItem] setState:CPOffState];
_selectedIndex = anIndex;
if (_selectedIndex >= 0 && !_pullsDown)
if (_selectedIndex >= 0 && ![self pullsDown])
[[self selectedItem] setState:CPOnState];
[self synchronizeTitleAndSelectedItem];
}
/*
/*!
Selects the menu item with the specified tag
@param the tag of the item to select
*/
@@ -282,7 +274,7 @@ var CPPopUpButtonArrowsImage = nil;
[self selectItemAtIndex:[self indexOfItemWithTag:aTag]];
}
/*
/*!
Selects the item with the specified title
@param the title of the item to select
*/
@@ -291,7 +283,7 @@ var CPPopUpButtonArrowsImage = nil;
[self selectItemAtIndex:[self indexOfItemWithTitle:aTitle]];
}
/*
/*!
Sets the object for the selected item. If no item is selected, then this method has no effect.
@param the object set for the selected item
*/
@@ -301,7 +293,7 @@ var CPPopUpButtonArrowsImage = nil;
}
// Getting Menu Items
/*
/*!
Returns the button's menu of items.
*/
- (CPMenu)menu
@@ -309,12 +301,12 @@ var CPPopUpButtonArrowsImage = nil;
return _menu;
}
/*
/*!
Sets the menu for the button
*/
- (void)setMenu:(CPMenu)aMenu
{
if (_menu == aMenu)
if (_menu === aMenu)
return;
var defaultCenter = [CPNotificationCenter defaultCenter];
@@ -323,19 +315,16 @@ var CPPopUpButtonArrowsImage = nil;
{
[defaultCenter
removeObserver:self
selector:@selector(menuDidAddItem:)
name:CPMenuDidAddItemNotification
object:_menu];
[defaultCenter
removeObserver:self
selector:@selector(menuDidChangeItem:)
name:CPMenuDidChangeItemNotification
object:_menu];
[defaultCenter
removeObserver:self
selector:@selector(menuDidRemoveItem:)
name:CPMenuDidRemoveItemNotification
object:_menu];
}
@@ -366,7 +355,7 @@ var CPPopUpButtonArrowsImage = nil;
[self synchronizeTitleAndSelectedItem];
}
/*
/*!
Returns a count of the number of items in the button's menu.
*/
- (int)numberOfItems
@@ -374,7 +363,7 @@ var CPPopUpButtonArrowsImage = nil;
return [_menu numberOfItems];
}
/*
/*!
Returns an array of the items in the menu
*/
- (CPArray)itemArray
@@ -382,7 +371,7 @@ var CPPopUpButtonArrowsImage = nil;
return [_menu itemArray];
}
/*
/*!
Returns the item at the specified index or <code>nil</code> if the item does not exist.
@param anIndex the index of the item to obtain
*/
@@ -391,7 +380,7 @@ var CPPopUpButtonArrowsImage = nil;
return [_menu itemAtIndex:anIndex];
}
/*
/*!
Returns the title of the item at the specified index or <code>nil</code> if no item exists.
@param anIndex the index of the item
*/
@@ -400,7 +389,7 @@ var CPPopUpButtonArrowsImage = nil;
return [[_menu itemAtIndex:anIndex] title];
}
/*
/*!
Returns an array of all the menu item titles.
*/
- (CPArray)itemTitles
@@ -415,7 +404,7 @@ var CPPopUpButtonArrowsImage = nil;
items.push([items[index] title]);
}
/*
/*!
Returns the menu item with the specified title.
@param aTitle the title of the desired menu item
*/
@@ -424,7 +413,7 @@ var CPPopUpButtonArrowsImage = nil;
return [_menu itemAtIndex:[_menu indexOfItemWithTitle:aTitle]];
}
/*
/*!
Returns the last menu item
*/
- (CPMenuItem)lastItem
@@ -433,8 +422,8 @@ var CPPopUpButtonArrowsImage = nil;
}
// Getting the Indices of Menu Items
/*
Returns the index of the specified item or <objj>CPNotFound</objj> if the item is not in the list.
/*!
Returns the index of the specified item or CPNotFound if the item is not in the list.
@param aMenuItem the item to obtain the index for
*/
- (int)indexOfItem:(CPMenuItem)aMenuItem
@@ -442,17 +431,17 @@ var CPPopUpButtonArrowsImage = nil;
return [_menu indexOfItem:aMenuItem];
}
/*
Returns the index of the item with the specified tag or <objj>CPNotFound</objj> if the item is not in the list.
/*!
Returns the index of the item with the specified tag or CPNotFound if the item is not in the list.
@param aTag the item's tag
*/
- (int)indexOfItemWithTag:(int)aTag
{
return [_menu indexOfItemWithTag:aMenuItem];
return [_menu indexOfItemWithTag:aTag];
}
/*
Returns the index of the item with the specified title or <objj>CPNotFound</objj>.
/*!
Returns the index of the item with the specified title or CPNotFound.
@param aTitle the item's titel
*/
- (int)indexOfItemWithTitle:(CPString)aTitle
@@ -460,20 +449,20 @@ var CPPopUpButtonArrowsImage = nil;
return [_menu indexOfItemWithTitle:aTitle];
}
/*
/*!
Returns the index of the item with the specified
represented object or <objj>CPNotFound</objj>
represented object or CPNotFound
if a match does not exist.
@param anObject the item's represented object
*/
- (int)indexOfItemWithRepresentedObject:(id)anObject
{
return [_menu indexOfItemWithRepresentedObejct:anObject];
return [_menu indexOfItemWithRepresentedObject:anObject];
}
/*
/*!
Returns the index of the item with the specified target
and action. Returns <objj>CPNotFound</objj> if the no
and action. Returns CPNotFound if the no
such item is in the list.
@param aTarget the item's target
@param anAction the item's action
@@ -484,7 +473,7 @@ var CPPopUpButtonArrowsImage = nil;
}
// Setting the Cell Edge to Pop out in Restricted Situations
/*
/*!
Returns the button's edge where the pop-up menu will be
displayed when there is not enough room to display directly
above the button.
@@ -494,7 +483,7 @@ var CPPopUpButtonArrowsImage = nil;
return _preferredEdge;
}
/*
/*!
Sets the preffered edge of the button to display the
pop-up when there is a limited amount of screen space.
By default, the pop-up should draw on top of the button.
@@ -505,19 +494,27 @@ var CPPopUpButtonArrowsImage = nil;
}
// Setting the Title
/*
/*!
Sets the pop-up button's title.
@param aTitle the new title
*/
- (void)setTitle:(CPString)aTitle
{
if ([self title] == aTitle)
if ([self title] === aTitle)
return;
if (_pullsDown)
if ([self pullsDown])
{
[_items[0] setTitle:aTitle];
[self synchronizeTitleAndSelectedItem];
var items = [_menu itemArray];
if ([items count] <= 0)
[self addItemWithTitle:aTitle];
else
{
[items[0] setTitle:aTitle];
[self synchronizeTitleAndSelectedItem];
}
}
else
{
@@ -535,7 +532,7 @@ var CPPopUpButtonArrowsImage = nil;
}
// Setting the Image
/*
/*!
This method has no effect. Because the image is taken
from the currently selected item, this method serves
no purpose.
@@ -546,7 +543,7 @@ var CPPopUpButtonArrowsImage = nil;
}
// Setting the State
/*
/*!
Makes sure the selected item and the item
being displayed are one and the same.
*/
@@ -554,11 +551,11 @@ var CPPopUpButtonArrowsImage = nil;
{
var item = nil;
if (_pullsDown)
if ([self pullsDown])
{
var items = [_menu itemArray];
if (items.length > 0)
if ([items count] > 0)
item = items[0];
}
else
@@ -569,7 +566,7 @@ var CPPopUpButtonArrowsImage = nil;
}
//
/*
/*!
Called when the menu has a new item added to it.
@param aNotification information about the event
*/
@@ -586,7 +583,7 @@ var CPPopUpButtonArrowsImage = nil;
else if (index < _selectedIndex)
++_selectedIndex;
if (index == 0 && _pullsDown)
if (index == 0 && [self pullsDown])
{
var items = [_menu itemArray];
@@ -595,9 +592,18 @@ var CPPopUpButtonArrowsImage = nil;
if (items.length > 0)
[items[1] setHidden:NO];
}
var item = [_menu itemArray][index],
action = [item action];
if (!action || (action === @selector(_popUpItemAction:)))
{
[item setTarget:self];
[item setAction:@selector(_popUpItemAction:)];
}
}
/*
/*!
Called when a menu item has changed.
@param aNotification information about the event
*/
@@ -605,16 +611,16 @@ var CPPopUpButtonArrowsImage = nil;
{
var index = [[aNotification userInfo] objectForKey:@"CPMenuItemIndex"];
if (_pullsDown && index != 0)
if ([self pullsDown] && index != 0)
return;
if (!_pullsDown && index != _selectedIndex)
if (![self pullsDown] && index != _selectedIndex)
return;
[self synchronizeTitleAndSelectedItem];
}
/*
/*!
Called when an item was removed from the menu.
@param aNotification information about the event
*/
@@ -633,34 +639,40 @@ var CPPopUpButtonArrowsImage = nil;
[self highlight:YES];
var theWindow = [self window],
menuWindow = [_CPMenuWindow menuWindowWithMenu:[self menu] font:[self font]];
var menu = [self menu],
theWindow = [self window],
menuWindow = [_CPMenuWindow menuWindowWithMenu:menu font:[self font]];
[menuWindow setDelegate:self];
[menuWindow setBackgroundStyle:_CPMenuWindowPopUpBackgroundStyle];
var menuOrigin = [theWindow convertBaseToBridge:[self convertPoint:CGPointMakeZero() toView:nil]];
// Pull Down Menus show up directly below their buttons.
if (_pullsDown)
menuOrigin.y += CGRectGetHeight([self frame]);
if ([self pullsDown])
var menuOrigin = [theWindow convertBaseToBridge:[self convertPoint:CGPointMake(0.0, CGRectGetMaxY([self bounds])) toView:nil]];
// Pop Up Menus attempt to show up "on top" of the selected item.
else
{
var contentRect = [menuWindow rectForItemAtIndex:_selectedIndex];
// This is confusing, I KNOW, so let me explain it to you.
// We want the *content* of the selected menu item to overlap the *content* of our pop up.
// 1. So calculate where our content is, then calculate where the menu item is.
// 2. Move LEFT by whatever indentation we have (offsetWidths, aka, window margin, item margin, etc).
// 3. MOVE UP by the difference in sizes of the content and menu item, this will only work if the content is vertically centered.
var contentRect = [self convertRect:[self contentRectForBounds:[self bounds]] toView:nil],
menuOrigin = [theWindow convertBaseToBridge:contentRect.origin],
menuItemRect = [menuWindow rectForItemAtIndex:_selectedIndex];
menuOrigin.x -= CGRectGetMinX(contentRect) + [_CPMenuItemView leftMargin];
menuOrigin.y -= CGRectGetMinY(contentRect);
menuOrigin.x -= CGRectGetMinX(menuItemRect) + [menuWindow overlapOffsetWidth] + [[[menu itemAtIndex:_selectedIndex] _menuItemView] overlapOffsetWidth];
menuOrigin.y -= CGRectGetMinY(menuItemRect) + (CGRectGetHeight(menuItemRect) - CGRectGetHeight(contentRect)) / 2.0;
}
[menuWindow setFrameOrigin:menuOrigin];
var menuMaxX = CGRectGetMaxX([menuWindow frame]),
buttonMaxX = CGRectGetMaxX([self convertRect:[self bounds] toView:nil]);
buttonMaxX = [theWindow convertBaseToBridge:CGPointMake(CGRectGetMaxX([self convertRect:[self bounds] toView:nil]), 0.0)].x;
if (menuMaxX < buttonMaxX)
[menuWindow setMinWidth:CGRectGetWidth([menuWindow frame]) + buttonMaxX - menuMaxX - VISIBLE_MARGIN];
[menuWindow setMinWidth:CGRectGetWidth([menuWindow frame]) + buttonMaxX - menuMaxX - ([self pullsDown] ? 0.0 : VISIBLE_MARGIN)];
[menuWindow orderFront:self];
[menuWindow beginTrackingWithEvent:anEvent sessionDelegate:self didEndSelector:@selector(menuWindowDidFinishTracking:highlightedItem:)];
@@ -682,21 +694,12 @@ var CPPopUpButtonArrowsImage = nil;
[self selectItemAtIndex:index];
var selectedItem = [self selectedItem],
target = nil,
action = [selectedItem action];
if (!action)
{
target = [self target];
action = [self action];
}
// FIXME: If [selectedItem target] == nil do we use our own target?
else
target = [selectedItem target];
[CPApp sendAction:[aMenuItem action] to:[aMenuItem target] from:aMenuItem];
}
[self sendAction:action to:target];
- (void)_popUpItemAction:(id)aSender
{
[self sendAction:[self action] to:[self target]];
}
@end
@@ -706,7 +709,7 @@ var CPPopUpButtonMenuKey = @"CPPopUpButtonMenuKey",
CPPopUpButtonPullsDownKey = @"CPPopUpButtonPullsDownKey";
@implementation CPPopUpButton (CPCoding)
/*
/*!
Initializes the pop-up button with data from the
specified coder.
@param aCoder the coder from which to read
@@ -719,15 +722,17 @@ var CPPopUpButtonMenuKey = @"CPPopUpButtonMenuKey",
if (self)
{
// Nothing is currently selected
_selectedIndex = -1;
[self setMenu:[aCoder decodeObjectForKey:CPPopUpButtonMenuKey]];
[self selectItemAtIndex:[aCoder decodeObjectForKey:CPPopUpButtonSelectedIndexKey]];
[self setPullsDown:[aCoder decodeBoolForKey:CPPopUpButtonPullsDownKey]];
}
return self;
}
/*
/*!
Encodes the data of the pop-up button into a coder
@param aCoder the coder to which the data
will be written
@@ -738,7 +743,6 @@ var CPPopUpButtonMenuKey = @"CPPopUpButtonMenuKey",
[aCoder encodeObject:_menu forKey:CPPopUpButtonMenuKey];
[aCoder encodeInt:_selectedIndex forKey:CPPopUpButtonSelectedIndexKey];
[aCoder encodeBool:_pullsDown forKey:CPPopUpButtonPullsDownKey];
}
@end
+28 -24
View File
@@ -20,12 +20,13 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
import <AppKit/CGGeometry.j>
import <AppKit/CPImageView.j>
import <AppKit/CPView.j>
@import <AppKit/CGGeometry.j>
@import <AppKit/CPImageView.j>
@import <AppKit/CPView.j>
#include "CoreGraphics/CGGeometry.h"
/*
@global
@group CPProgressIndicatorStyle
@@ -48,7 +49,10 @@ var CPProgressIndicatorSpinningStyleColors = nil,
CPProgressIndicatorStyleIdentifiers = nil,
CPProgressIndicatorStyleSizes = nil;
/*
/*!
@ingroup appkit
@class CPProgressIndicator
This class is used in a Cappuccino GUI to display the progress of a
function or task. If the duration of the task is unknown, there is
also an indeterminate mode for the indicator.
@@ -178,7 +182,7 @@ var CPProgressIndicatorSpinningStyleColors = nil,
{
}
/*
/*!
Starts the animation of the progress indicator in indeterminate mode.
@param the requesting object
*/
@@ -189,7 +193,7 @@ var CPProgressIndicatorSpinningStyleColors = nil,
[self _hideOrDisplay];
}
/*
/*!
Stops the animation of the progress indicator in indeterminate mode.
@param the requesting object
*/
@@ -200,7 +204,7 @@ var CPProgressIndicatorSpinningStyleColors = nil,
[self _hideOrDisplay];
}
/*
/*!
Always returns <code>NO</code>. Cappuccino does not have multiple threads.
*/
- (BOOL)usesThreadedAnimation
@@ -209,7 +213,7 @@ var CPProgressIndicatorSpinningStyleColors = nil,
}
// Advancing the Progress Bar
/*
/*!
Increases the progress of the bar by the specified value.
@param aValue the amount to increase the progress value
*/
@@ -218,7 +222,7 @@ var CPProgressIndicatorSpinningStyleColors = nil,
[self setDoubleValue:_doubleValue + aValue];
}
/*
/*!
Sets the progress value of the indicator.
*/
- (void)setDoubleValue:(double)aValue
@@ -228,7 +232,7 @@ var CPProgressIndicatorSpinningStyleColors = nil,
[self drawBar];
}
/*
/*!
Returns the value of the progress indicator.
*/
- (double)doubleValue
@@ -236,7 +240,7 @@ var CPProgressIndicatorSpinningStyleColors = nil,
return _doubleValue;
}
/*
/*!
Sets the minimum value of the progress indicator. The default is 0.0.
@param aValue the new minimum value
*/
@@ -245,7 +249,7 @@ var CPProgressIndicatorSpinningStyleColors = nil,
_minValue = aValue;
}
/*
/*!
Returns the minimum value of the progress indicator.
*/
- (double)minValue
@@ -253,7 +257,7 @@ var CPProgressIndicatorSpinningStyleColors = nil,
return _minValue;
}
/*
/*!
Sets the maximum value of the progress indicator. The default is 100.0.
@param aValue the new maximum value.
*/
@@ -262,7 +266,7 @@ var CPProgressIndicatorSpinningStyleColors = nil,
_maxValue = aValue;
}
/*
/*!
Returns the maximum value of the progress indicator.
*/
- (double)maxValue
@@ -271,7 +275,7 @@ var CPProgressIndicatorSpinningStyleColors = nil,
}
// Setting the Appearance
/*
/*!
Sets the progress indicator's size.
@param aControlSize the new size
*/
@@ -285,7 +289,7 @@ var CPProgressIndicatorSpinningStyleColors = nil,
[self updateBackgroundColor];
}
/*
/*!
Returns the progress indicator's size
*/
- (CPControlSize)controlSize
@@ -323,13 +327,13 @@ var CPProgressIndicatorSpinningStyleColors = nil,
return YES;
}
/*
/*!
Specifies whether this progress indicator should be indeterminate or display progress based on it's max and min.
@param isDeterminate <code>YES</code> makes the indicator indeterminate
*/
- (void)setIndeterminate:(BOOL)isIndeterminate
{
if (_indeterminate == isIndeterminate)
if (_isIndeterminate == isIndeterminate)
return;
_isIndeterminate = isIndeterminate;
@@ -337,7 +341,7 @@ var CPProgressIndicatorSpinningStyleColors = nil,
[self updateBackgroundColor];
}
/*
/*!
Returns <code>YES</code> if the progress bar is indeterminate.
*/
- (BOOL)isIndeterminate
@@ -345,7 +349,7 @@ var CPProgressIndicatorSpinningStyleColors = nil,
return _isIndeterminate;
}
/*
/*!
Sets the progress indicator's style
@param aStyle the style to set it to
*/
@@ -359,7 +363,7 @@ var CPProgressIndicatorSpinningStyleColors = nil,
[self updateBackgroundColor];
}
/*
/*!
Resizes the indicator based on it's style.
*/
- (void)sizeToFit
@@ -372,9 +376,9 @@ var CPProgressIndicatorSpinningStyleColors = nil,
_CPControlIdentifierForControlSize(_controlSize)][0].height)];
}
/*
/*!
Sets whether the indicator should be displayed when it isn't animating. By default this is <code>YES</code> if the style
is <objj>CPProgressIndicatorBarStyle</objj>, and <code>NO</code> if it's <objj>CPProgressIndicatorSpinningStyle</objj>.
is CPProgressIndicatorBarStyle, and <code>NO</code> if it's CPProgressIndicatorSpinningStyle.
@param isDisplayedWhenStopped <code>YES</code> means the indicator will be displayed when it's not animating.
*/
- (void)setDisplayedWhenStopped:(BOOL)isDisplayedWhenStopped
@@ -389,7 +393,7 @@ var CPProgressIndicatorSpinningStyleColors = nil,
[self _hideOrDisplay];
}
/*
/*!
Returns <code>YES</code> if the progress bar is displayed when not animating.
*/
- (BOOL)isDisplayedWhenStopped
+254
View File
@@ -0,0 +1,254 @@
/*
* CPRadio.j
* AppKit
*
* Created by Francisco Tolmasky.
* Copyright 2009, 280 North, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import <Foundation/CPObject.j>
@import <Foundation/CPSet.j>
@import "CPButton.j"
/*!
@ingroup appkit
from this mailing list thread:
http://groups.google.com/group/objectivej/browse_thread/thread/7c41cbd9cbee9ea3
-----------------------------------
Creating a checkbox is easy enough:
checkbox = [[CPCheckBox alloc] initWithFrame:aFrame];
That's basically all there is to it. Radio buttons are very similar,
the key difference is the introduction of a new class CPRadioGroup,
which defines which radio buttons are part of the same group:
[myRadioButton setRadioGroup:aRadioGroup];
Every radio button receives a unique radio group by default (so if you
do nothing further, they will all behave independently), but you can
use an existing radio button's group with other buttons as so:
button1 = [[CPRadio alloc] initWithFrame:aFrame];
...
button2 = [[CPRadio alloc] initWithFrame:aFrame radioGroup:[button1
radioGroup]];
...
button3 = [[CPRadio alloc] initWithFrame:aFrame radioGroup:[button1
radioGroup]];
...etc...
Here, all the radio buttons will act "together". [[button1 radioGroup]
allRadios] returns every button that's part of this group, and
[[button1 radioGroup] selectedRadio] returns the currently selected
option.
*/
@implementation CPRadio : CPButton
{
CPRadioGroup _radioGroup;
}
+ (id)radioWithTitle:(CPString)aTitle theme:(CPTheme)aTheme
{
return [self buttonWithTitle:aTitle theme:aTheme];
}
+ (id)radioWithTitle:(CPString)aTitle
{
return [self buttonWithTitle:aTitle];
}
+ (CPButton)standardButtonWithTitle:(CPString)aTitle
{
var button = [[CPRadio alloc] init];
[button setTitle:aTitle];
return button;
}
+ (CPString)themeClass
{
return @"radio";
}
// Designated Initializer
- (id)initWithFrame:(CGRect)aFrame radioGroup:(CPRadioGroup)aRadioGroup
{
self = [super initWithFrame:aFrame];
if (self)
{
[self setRadioGroup:aRadioGroup || [CPRadioGroup new]];
[self setHighlightsBy:CPContentsCellMask];
[self setShowsStateBy:CPContentsCellMask];
// Defaults?
[self setImagePosition:CPImageLeft];
[self setAlignment:CPLeftTextAlignment];
[self setBordered:YES];
}
return self;
}
- (id)initWithFrame:(CGRect)aFrame
{
return [self initWithFrame:aFrame radioGroup:nil];
}
- (CPInteger)nextState
{
return CPOnState;
}
- (void)setRadioGroup:(CPRadioGroup)aRadioGroup
{
if (_radioGroup === aRadioGroup)
return;
[_radioGroup _removeRadio:self];
_radioGroup = aRadioGroup;
[_radioGroup _addRadio:self];
}
- (CPRadioGroup)radioGroup
{
return _radioGroup;
}
- (void)setObjectValue:(id)aValue
{
[super setObjectValue:aValue];
if ([self state] === CPOnState)
[_radioGroup _setSelectedRadio:self];
}
@end
var CPRadioRadioGroupKey = @"CPRadioRadioGroupKey";
@implementation CPRadio (CPCoding)
- (id)initWithCoder:(CPCoder)aCoder
{
self = [super initWithCoder:aCoder];
if (self)
_radioGroup = [aCoder decodeObjectForKey:CPRadioRadioGroupKey];
return self;
}
- (void)encodeWithCoder:(CPCoder)aCoder
{
[super encodeWithCoder:aCoder];
[aCoder encodeObject:_radioGroup forKey:CPRadioRadioGroupKey];
}
@end
@implementation CPRadioGroup : CPObject
{
CPSet _radios;
CPRadio _selectedRadio;
}
- (id)init
{
self = [super init];
if (self)
{
_radios = [CPSet set];
_selectedRadio = nil;
}
return self;
}
- (void)_addRadio:(CPRadio)aRadio
{
[_radios addObject:aRadio];
if ([aRadio state] === CPOnState)
[self _setSelectedRadio:aRadio];
}
- (void)_removeRadio:(CPRadio)aRadio
{
if (_selectedRadio === aRadio)
_selectedRadio = nil;
[_radios removeObject:aRadio];
}
- (void)_setSelectedRadio:(CPRadio)aRadio
{
if (_selectedRadio === aRadio)
return;
[_selectedRadio setState:CPOffState];
_selectedRadio = aRadio;
}
- (CPRadio)selectedRadio
{
return _selectedRadio;
}
- (CPArray)radios
{
return [_radios allObjects];
}
@end
var CPRadioGroupRadiosKey = @"CPRadioGroupRadiosKey",
CPRadioGroupSelectedRadioKey = @"CPRadioGroupSelectedRadioKey";
@implementation CPRadioGroup (CPCoding)
- (id)initWithCoder:(CPCoder)aCoder
{
self = [super init];
if (self)
{
_radios = [aCoder decodeObjectForKey:CPRadioGroupRadiosKey];
_selectedRadio = [aCoder decodeObjectForKey:CPRadioGroupSelectedRadioKey];
}
return self;
}
- (void)encodeWithCoder:(CPCoder)aCoder
{
[aCoder encodeObject:_radios forKey:CPRadioGroupRadiosKey];
[aCoder encodeObject:_selectedRadio forKey:CPRadioGroupSelectedRadioKey];
}
@end
+79 -32
View File
@@ -20,14 +20,24 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
import <Foundation/CPObject.j>
@import <Foundation/CPObject.j>
CPDeleteKeyCode = 8;
CPUpArrowKeyCode = 63232;
CPDownArrowKeyCode = 63233;
CPLeftArrowKeyCode = 63234;
CPRightArrowKeyCode = 63235;
CPTabKeyCode = 9;
CPReturnKeyCode = 13;
CPEscapeKeyCode = 27;
CPLeftArrowKeyCode = 37;
CPUpArrowKeyCode = 38;
CPRightArrowKeyCode = 39;
CPDownArrowKeyCode = 40;
/*!
@ingroup appkit
@class CPResponder
Subclasses of CPResonder can be part of the responder chain.
*/
@implementation CPResponder : CPObject
{
CPMenu _menu;
@@ -35,7 +45,7 @@ CPRightArrowKeyCode = 63235;
}
// Changing the first responder
/*
/*!
Returns <code>YES</code> if the receiver is able to become the first responder. <code>NO</code> otherwise.
*/
- (BOOL)acceptsFirstResponder
@@ -43,7 +53,7 @@ CPRightArrowKeyCode = 63235;
return NO;
}
/*
/*!
Notifies the receiver that it will become the first responder. The receiver can reject first
responder if it returns <code>NO</code>. The default implementation always returns <code>YES</code>.
@return <code>YES</code> if the receiver accepts first responder status.
@@ -53,7 +63,7 @@ CPRightArrowKeyCode = 63235;
return YES;
}
/*
/*!
Notifies the receiver that it has been asked to give up first responder status.
@return <code>YES</code> if the receiver is willing to give up first responder status.
*/
@@ -63,7 +73,7 @@ CPRightArrowKeyCode = 63235;
}
// Setting the next responder
/*
/*!
Sets the receiver's next responder.
@param aResponder the responder after the receiver
*/
@@ -72,7 +82,7 @@ CPRightArrowKeyCode = 63235;
_nextResponder = aResponder;
}
/*
/*!
Returns the responder after the receiver.
*/
- (CPResponder)nextResponder
@@ -80,9 +90,9 @@ CPRightArrowKeyCode = 63235;
return _nextResponder;
}
/*
/*!
Called to interpret a series of key events.
@param events an array of key <objj>CPEvent</objj>s
@param events an array of key CPEvents
*/
- (void)interpretKeyEvents:(CPArray)events
{
@@ -103,15 +113,28 @@ CPRightArrowKeyCode = 63235;
break;
case CPDeleteKeyCode: [self deleteBackward:self];
break;
case 3:
case 13: [self insertLineBreak:self];
case CPReturnKeyCode:
case 3: [self insertLineBreak:self];
break;
case CPEscapeKeyCode: [self cancel:self];
break;
case CPTabKeyCode: var shift = [event modifierFlags] & CPShiftKeyMask;
if (!shift)
[self insertTab:self];
else
[self insertBackTab:self];
break;
default: [self insertText:[event characters]];
}
}
}
/*
/*!
Notifies the receiver that the user has clicked the mouse down in its area.
@param anEvent contains information about the click
*/
@@ -120,7 +143,7 @@ CPRightArrowKeyCode = 63235;
[_nextResponder performSelector:_cmd withObject:anEvent];
}
/*
/*!
Notifies the receiver that the user has initiated a drag
over it. A drag is a mouse movement while the left button is down.
@param anEvent contains information about the drag
@@ -130,7 +153,7 @@ CPRightArrowKeyCode = 63235;
[_nextResponder performSelector:_cmd withObject:anEvent];
}
/*
/*!
Notifies the receiver that the user has released the left mouse button.
@param anEvent contains information about the release
*/
@@ -139,7 +162,7 @@ CPRightArrowKeyCode = 63235;
[_nextResponder performSelector:_cmd withObject:anEvent];
}
/*
/*!
Notifies the receiver that the user has moved the mouse (with no buttons down).
@param anEvent contains information about the movement
*/
@@ -153,7 +176,7 @@ CPRightArrowKeyCode = 63235;
[_nextResponder performSelector:_cmd withObject:anEvent];
}
/*
/*!
Notifies the receiver that the mouse exited the receiver's area.
@param anEvent contains information about the exit
*/
@@ -162,7 +185,7 @@ CPRightArrowKeyCode = 63235;
[_nextResponder performSelector:_cmd withObject:anEvent];
}
/*
/*!
Notifies the receiver that the mouse scroll wheel has moved.
@param anEvent information about the scroll
*/
@@ -171,7 +194,7 @@ CPRightArrowKeyCode = 63235;
[_nextResponder performSelector:_cmd withObject:anEvent];
}
/*
/*!
Notifies the receiver that the user has pressed a key.
@param anEvent information about the key press
*/
@@ -180,7 +203,7 @@ CPRightArrowKeyCode = 63235;
[_nextResponder performSelector:_cmd withObject:anEvent];
}
/*
/*!
Notifies the receiver that the user has released a key.
@param anEvent information about the key press
*/
@@ -201,7 +224,7 @@ CPRightArrowKeyCode = 63235;
}
// Action Methods
/*
/*!
Deletes one character backward, or the selection if anything is selected.
@param aSender the object requesting this
*/
@@ -209,15 +232,37 @@ CPRightArrowKeyCode = 63235;
{
}
/*
/*!
Insert a line break at the caret position or selection.
@param aSender the object requesting this
*/
- (void)insertLineBreak:(id)aSender
{
[self insertNewline:aSender];
}
/*
/*!
Insert a line break at the caret position or selection.
@param aSender the object requesting this
*/
- (void)insertNewline:(id)aSender
{
[self insertNewline:aSender];
}
- (void)cancel:(id)sender
{
}
- (void)insertTab:(id)sender
{
}
- (void)insertBackTab:(id)sender
{
}
/*!
Inserts some text at the caret position or selection.
@param aString the string to insert
*/
@@ -226,7 +271,7 @@ CPRightArrowKeyCode = 63235;
}
// Dispatch methods
/*
/*!
The receiver will attempt to perform the command,
if it responds to it. If not, the <code>nextResponder</code> will be called to do it.
@param aSelector the command to attempt
@@ -239,7 +284,7 @@ CPRightArrowKeyCode = 63235;
[_nextResponder doCommandBySelector:aSelector];
}
/*
/*!
The receiver will attempt to perform the command, or pass it on to the next responder if it doesn't respond to it.
@param aSelector the command to perform
@param anObject the argument to the method
@@ -271,7 +316,7 @@ CPRightArrowKeyCode = 63235;
}
// Getting the Undo Manager
/*
/*!
Returns the undo manager for the receiver.
*/
- (CPUndoManager)undoManager
@@ -280,7 +325,7 @@ CPRightArrowKeyCode = 63235;
}
// Terminating the responder chain
/*
/*!
Called when an event finds no suitable responder.
@param anEventSelector the command that failed
*/
@@ -294,7 +339,7 @@ var CPResponderNextResponderKey = @"CPResponderNextResponderKey";
@implementation CPResponder (CPCoding)
/*
/*!
Initializes the responder with data from a coder.
@param aCoder the coder from which data will be read
@return the initialized responder
@@ -309,13 +354,15 @@ var CPResponderNextResponderKey = @"CPResponderNextResponderKey";
return self;
}
/*
/*!
Archives the responder to a coder.
@param aCoder the coder to which the responder will be archived
*/
- (void)encodeWithCoder:(CPCoder)aCoder
{
[aCoder encodeConditionalObject:_nextResponder forKey:CPResponderNextResponderKey];
// This will come out nil on the other side with decodeObjectForKey:
if (_nextResponder !== nil)
[aCoder encodeConditionalObject:_nextResponder forKey:CPResponderNextResponderKey];
}
@end
+136 -80
View File
@@ -20,14 +20,18 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
import "CPView.j"
import "CPClipView.j"
import "CPScroller.j"
@import "CPView.j"
@import "CPClipView.j"
@import "CPScroller.j"
#include "CoreGraphics/CGGeometry.h"
/*
Used to display views that are too large for the viewing area. the <objj>CPScrollView</objj>
/*!
@ingroup appkit
@class CPScrollView
Used to display views that are too large for the viewing area. the CPScrollView
places scroll bars on the side of the view to allow the user to scroll and see the entire
contents of the view.
*/
@@ -74,7 +78,7 @@ import "CPScroller.j"
}
// Determining component sizes
/*
/*!
Returns the size of the scroll view's content view.
*/
- (CGRect)contentSize
@@ -82,7 +86,7 @@ import "CPScroller.j"
return [_contentView frame].size;
}
/*
/*!
Returns the view that is scrolled for the user.
*/
- (id)documentView
@@ -90,7 +94,7 @@ import "CPScroller.j"
return [_contentView documentView];
}
/*
/*!
Sets the content view that clips the document
@param aContentView the content view
*/
@@ -116,7 +120,7 @@ import "CPScroller.j"
[self addSubview:_contentView];
}
/*
/*!
Returns the content view that clips the document.
*/
- (CPClipView)contentView
@@ -124,7 +128,7 @@ import "CPScroller.j"
return _contentView;
}
/*
/*!
Sets the view that is scrolled for the user.
@param aView the view that will be scrolled
*/
@@ -134,14 +138,13 @@ import "CPScroller.j"
[self reflectScrolledClipView:_contentView];
}
/*
Resizes the scroll view to contain the specified
clip view.
/*!
Resizes the scroll view to contain the specified clip view.
@param aClipView the clip view to resize to
*/
- (void)reflectScrolledClipView:(CPClipView)aClipView
{
if(_contentView != aClipView)
if(_contentView !== aClipView)
return;
if (_recursionCount > 5)
@@ -160,8 +163,8 @@ import "CPScroller.j"
}
else
{
[_verticalScroller setEnabled:NO];
[_horizontalScroller setEnabled:NO];
// [_verticalScroller setEnabled:NO];
// [_horizontalScroller setEnabled:NO];
}
[_contentView setFrame:[self bounds]];
@@ -179,22 +182,24 @@ import "CPScroller.j"
shouldShowHorizontalScroller = (!_autohidesScrollers || difference.width > 0.0) && _hasHorizontalScroller,
wasShowingVerticalScroller = ![_verticalScroller isHidden],
wasShowingHorizontalScroller = ![_horizontalScroller isHidden],
verticalScrollerWidth = [CPScroller scrollerWidthForControlSize:[_verticalScroller controlSize]],
horizontalScrollerHeight = [CPScroller scrollerWidthForControlSize:[_horizontalScroller controlSize]];
verticalScrollerWidth = _CGRectGetWidth([_verticalScroller frame]);
horizontalScrollerHeight = _CGRectGetHeight([_horizontalScroller frame]);
if (_autohidesScrollers)
{
// Check to see if either affected the other!
if (shouldShowVerticalScroller)
shouldShowHorizontalScroller = (!_autohidesScrollers || difference.width > -verticalScrollerWidth) && _hasHorizontalScroller;
if (shouldShowHorizontalScroller)
shouldShowVerticalScroller = (!_autohidesScrollers || difference.height > -horizontalScrollerHeight) && _hasVerticalScroller;
}
[_verticalScroller setHidden:!shouldShowVerticalScroller];
[_verticalScroller setEnabled:!_autohidesScrollers && difference.height < 0];
[_verticalScroller setEnabled:difference.height > 0.0];
[_horizontalScroller setHidden:!shouldShowHorizontalScroller];
[_horizontalScroller setEnabled:!_autohidesScrollers && difference.width < 0];
[_horizontalScroller setEnabled:difference.width > 0.0];
if (shouldShowVerticalScroller)
{
@@ -231,13 +236,13 @@ import "CPScroller.j"
}
// Managing Scrollers
/*
/*!
Sets the scroll view's horizontal scroller.
@param aScroller the horizontal scroller for the scroll view
*/
- (void)setHorizontalScroller:(CPScroller)aScroller
{
if (_horizontalScroller == aScroller)
if (_horizontalScroller === aScroller)
return;
[_horizontalScroller removeFromSuperview];
@@ -254,7 +259,7 @@ import "CPScroller.j"
[self reflectScrolledClipView:_contentView];
}
/*
/*!
Returns the scroll view's horizontal scroller
*/
- (CPScroller)horizontalScroller
@@ -262,20 +267,20 @@ import "CPScroller.j"
return _horizontalScroller;
}
/*
/*!
Specifies whether the scroll view can have a horizontal scroller.
@param hasHorizontalScroller <code>YES</code> lets the scroll view
allocate a horizontal scroller if necessary.
*/
- (void)setHasHorizontalScroller:(BOOL)shouldHaveHorizontalScroller
{
if (_hasHorizontalScroller == shouldHaveHorizontalScroller)
if (_hasHorizontalScroller === shouldHaveHorizontalScroller)
return;
_hasHorizontalScroller = shouldHaveHorizontalScroller;
if (_hasHorizontalScroller && !_horizontalScroller)
[self setHorizontalScroller:[[CPScroller alloc] initWithFrame:CPRectMake(0.0, 0.0, CPRectGetWidth([self bounds]), [CPScroller scrollerWidth])]];
[self setHorizontalScroller:[[CPScroller alloc] initWithFrame:CGRectMake(0.0, 0.0, CPRectGetWidth([self bounds]), [CPScroller scrollerWidth])]];
else if (!_hasHorizontalScroller && _horizontalScroller)
{
@@ -285,22 +290,21 @@ import "CPScroller.j"
}
}
/*
Returns <code>YES</code> if the scroll view can have a horizontal
scroller.
/*!
Returns <code>YES</code> if the scroll view can have a horizontal scroller.
*/
- (BOOL)hasHorizontalScroller
{
return _hasHorizontalScroller;
}
/*
/*!
Sets the scroll view's vertical scroller.
@param aScroller the vertical scroller
*/
- (void)setVerticalScroller:(CPScroller)aScroller
{
if (_verticalScroller == aScroller)
if (_verticalScroller === aScroller)
return;
[_verticalScroller removeFromSuperview];
@@ -317,7 +321,7 @@ import "CPScroller.j"
[self reflectScrolledClipView:_contentView];
}
/*
/*!
Return's the scroll view's vertical scroller
*/
- (CPScroller)verticalScroller
@@ -325,7 +329,7 @@ import "CPScroller.j"
return _verticalScroller;
}
/*
/*!
Specifies whether the scroll view has can have
a vertical scroller. It allocates it if necessary.
@param hasVerticalScroller <code>YES</code> allows
@@ -333,7 +337,7 @@ import "CPScroller.j"
*/
- (void)setHasVerticalScroller:(BOOL)shouldHaveVerticalScroller
{
if (_hasVerticalScroller == shouldHaveVerticalScroller)
if (_hasVerticalScroller === shouldHaveVerticalScroller)
return;
_hasVerticalScroller = shouldHaveVerticalScroller;
@@ -349,26 +353,30 @@ import "CPScroller.j"
}
}
/*
Returns <code>YES</code> if the scroll view can have
a vertical scroller.
/*!
Returns <code>YES</code> if the scroll view can have a vertical scroller.
*/
- (BOOL)hasHorizontalScroller
- (BOOL)hasVerticalScroller
{
return _hasHorizontalScroller;
return _hasVerticalScroller;
}
/*
/*!
Sets whether the scroll view hides its scoll bars when not needed.
@param autohidesScrollers <code>YES</code> causes the scroll bars
to be hidden when not needed.
*/
- (void)setAutohidesScrollers:(BOOL)autohidesScrollers
{
if (_autohidesScrollers == autohidesScrollers)
return;
_autohidesScrollers = autohidesScrollers;
[self reflectScrolledClipView:_contentView];
}
/*
/*!
Returns <code>YES</code> if the scroll view hides its scroll
bars when not necessary.
*/
@@ -442,7 +450,7 @@ import "CPScroller.j"
[_contentView scrollToPoint:contentBounds.origin];
}
/*
/*!
Lays out the scroll view's components.
*/
- (void)tile
@@ -462,11 +470,9 @@ import "CPScroller.j"
}
// Setting Scrolling Behavior
/*
Sets how much the document moves when scrolled. Sets
the vertical and horizontal scroll.
@param aLineScroll the amount to move the document
when scrolled
/*!
Sets how much the document moves when scrolled. Sets the vertical and horizontal scroll.
@param aLineScroll the amount to move the document when scrolled
*/
- (void)setLineScroll:(float)aLineScroll
{
@@ -474,59 +480,51 @@ import "CPScroller.j"
[self setVerticalLineScroll:aLineScroll];
}
/*
Returns how much the document moves
when scrolled
/*!
Returns how much the document moves when scrolled
*/
- (float)lineScroll
{
return [self horizontalLineScroll];
}
/*
Sets how much the document moves when scrolled
horizontally.
@param aLineScroll the amount to move horizontally
when scrolled.
/*!
Sets how much the document moves when scrolled horizontally.
@param aLineScroll the amount to move horizontally when scrolled.
*/
- (void)setHorizontalLineScroll:(float)aLineScroll
{
_horizontalLineScroll = aLineScroll;
}
/*
Returns how much the document moves horizontally
when scrolled.
/*!
Returns how much the document moves horizontally when scrolled.
*/
- (float)horizontalLineScroll
{
return _horizontalLineScroll;
}
/*
Sets how much the document moves when scrolled
vertically.
@param aLineScroll the new amount to move vertically
when scrolled.
/*!
Sets how much the document moves when scrolled vertically.
@param aLineScroll the new amount to move vertically when scrolled.
*/
- (void)setVerticalLineScroll:(float)aLineScroll
{
_verticalLineScroll = aLineScroll;
}
/*
Returns how much the document moves vertically
when scrolled.
/*!
Returns how much the document moves vertically when scrolled.
*/
- (float)verticalLineScroll
{
return _verticalLineScroll;
}
/*
/*!
Sets the horizontal and vertical page scroll amount.
@param aPageScroll the new horizontal and vertical page
scroll amount
@param aPageScroll the new horizontal and vertical page scroll amount
*/
- (void)setPageScroll:(float)aPageScroll
{
@@ -534,16 +532,15 @@ import "CPScroller.j"
[self setVerticalPageScroll:aPageScroll];
}
/*
Returns the vertical and horizontal page scroll
amount.
/*!
Returns the vertical and horizontal page scroll amount.
*/
- (float)pageScroll
{
return [self horizontalPageScroll];
}
/*
/*!
Sets the horizontal page scroll amount.
@param aPageScroll the new horizontal page scroll amount
*/
@@ -552,7 +549,7 @@ import "CPScroller.j"
_horizontalPageScroll = aPageScroll;
}
/*
/*!
Returns the horizontal page scroll amount.
*/
- (float)horizontalPageScroll
@@ -560,17 +557,16 @@ import "CPScroller.j"
return _horizontalPageScroll;
}
/*
/*!
Sets the vertical page scroll amount.
@param aPageScroll the new vertcal page scroll
amount
@param aPageScroll the new vertcal page scroll amount
*/
- (void)setVerticalPageScroll:(float)aPageScroll
{
_verticalPageScroll = aPageScroll;
}
/*
/*!
Returns the vertical page scroll amount.
*/
- (float)verticalPageScroll
@@ -578,7 +574,7 @@ import "CPScroller.j"
return _verticalPageScroll;
}
/*
/*!
Handles a scroll wheel event from the user.
@param anEvent the scroll wheel event
*/
@@ -634,3 +630,63 @@ import "CPScroller.j"
}
@end
var CPScrollViewContentViewKey = "CPScrollViewContentView",
CPScrollViewVLineScrollKey = "CPScrollViewVLineScroll",
CPScrollViewHLineScrollKey = "CPScrollViewHLineScroll",
CPScrollViewVPageScrollKey = "CPScrollViewVPageScroll",
CPScrollViewHPageScrollKey = "CPScrollViewHPageScroll",
CPScrollViewHasVScrollerKey = "CPScrollViewHasVScroller",
CPScrollViewHasHScrollerKey = "CPScrollViewHasHScroller",
CPScrollViewVScrollerKey = "CPScrollViewVScroller",
CPScrollViewHScrollerKey = "CPScrollViewHScroller",
CPScrollViewAutohidesScrollerKey = "CPScrollViewAutohidesScroller";
@implementation CPScrollView (CPCoding)
- (id)initWithCoder:(CPCoder)aCoder
{
if (self = [super initWithCoder:aCoder])
{
_verticalLineScroll = [aCoder decodeFloatForKey:CPScrollViewVLineScrollKey];
_verticalPageScroll = [aCoder decodeFloatForKey:CPScrollViewVPageScrollKey];
_horizontalLineScroll = [aCoder decodeFloatForKey:CPScrollViewHLineScrollKey];
_horizontalPageScroll = [aCoder decodeFloatForKey:CPScrollViewHPageScrollKey];
_contentView = [aCoder decodeObjectForKey:CPScrollViewContentViewKey];
_verticalScroller = [aCoder decodeObjectForKey:CPScrollViewVScrollerKey];
_horizontalScroller = [aCoder decodeObjectForKey:CPScrollViewHScrollerKey];
_hasVerticalScroller = [aCoder decodeBoolForKey:CPScrollViewHasVScrollerKey];
_hasHorizontalScroller = [aCoder decodeBoolForKey:CPScrollViewHasHScrollerKey];
_autohidesScrollers = [aCoder decodeBoolForKey:CPScrollViewAutohidesScrollerKey];
// Do to the anything goes nature of decoding, our subviews may not exist yet, so layout at the end of the run loop when we're sure everything is in a correct state.
[[CPRunLoop currentRunLoop] performSelector:@selector(reflectScrolledClipView:) target:self argument:_contentView order:0 modes:[CPDefaultRunLoopMode]];
}
return self;
}
- (void)encodeWithCoder:(CPCoder)aCoder
{
[super encodeWithCoder:aCoder];
[aCoder encodeObject:_contentView forKey:CPScrollViewContentViewKey];
[aCoder encodeObject:_verticalScroller forKey:CPScrollViewVScrollerKey];
[aCoder encodeObject:_horizontalScroller forKey:CPScrollViewHScrollerKey];
[aCoder encodeFloat:_verticalLineScroll forKey:CPScrollViewVLineScrollKey];
[aCoder encodeFloat:_verticalPageScroll forKey:CPScrollViewVPageScrollKey];
[aCoder encodeFloat:_horizontalLineScroll forKey:CPScrollViewHLineScrollKey];
[aCoder encodeFloat:_horizontalPageScroll forKey:CPScrollViewHPageScrollKey];
[aCoder encodeBool:_hasVerticalScroller forKey:CPScrollViewHasVScrollerKey];
[aCoder encodeBool:_hasHorizontalScroller forKey:CPScrollViewHasHScrollerKey];
[aCoder encodeBool:_autohidesScrollers forKey:CPScrollViewAutohidesScrollerKey];
}
@end
+225 -299
View File
@@ -20,7 +20,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
import "CPControl.j"
@import "CPControl.j"
#include "CoreGraphics/CGGeometry.h"
@@ -41,38 +41,20 @@ CPNoScrollerParts = 0;
CPOnlyScrollerArrows = 1;
CPAllScrollerParts = 2;
var _CPScrollerWidths = [],
_CPScrollerKnobMinimumHeights = [],
_CPScrollerArrowHeights = [],
_CPScrollerArrowUsableHeights = [];
/*!
@ingroup appkit
@class CPScroller
*/
_CPScrollerWidths[CPRegularControlSize] = 14.0;
_CPScrollerWidths[CPSmallControlSize] = 11.0;
_CPScrollerWidths[CPMiniControlSize] = 11.0; // FIXME
_CPScrollerKnobMinimumHeights[CPRegularControlSize] = 18.0;
_CPScrollerKnobMinimumHeights[CPSmallControlSize] = 12.0;
_CPScrollerKnobMinimumHeights[CPMiniControlSize] = 12.0; // FIXME
var PARTS_ARRANGEMENT = [CPScrollerKnobSlot, CPScrollerDecrementLine, CPScrollerIncrementLine, CPScrollerKnob],
NAMES_FOR_PARTS = {},
PARTS_FOR_NAMES = {};
_CPScrollerArrowHeights[CPRegularControlSize] = 21.0;
_CPScrollerArrowHeights[CPSmallControlSize] = 16.0;
_CPScrollerArrowHeights[CPMiniControlSize] = 16.0; // FIXME
NAMES_FOR_PARTS[CPScrollerDecrementLine] = @"decrement-line";
NAMES_FOR_PARTS[CPScrollerIncrementLine] = @"increment-line";
NAMES_FOR_PARTS[CPScrollerKnobSlot] = @"knob-slot";
NAMES_FOR_PARTS[CPScrollerKnob] = @"knob";
_CPScrollerArrowUsableHeights[CPRegularControlSize] = 16.0
_CPScrollerArrowUsableHeights[CPSmallControlSize] = 10.0;
_CPScrollerArrowUsableHeights[CPMiniControlSize] = 10.0; // FIXME
var _CPScrollerKnobIdentifier = @"Knob",
_CPScrollerKnobSlotIdentifier = @"KnobSlot",
_CPScrollerDecrementArrowIdentifier = @"DecrementArrow",
_CPScrollerIncrementArrowIdentifier = @"IncrementArrow",
_CPScrollerHorizontalIdentifier = @"Horizontal",
_CPScrollerVerticalIdentifier = @"Vertical",
_CPScrollerHighlightedIdentifier = @"Highlighted",
_CPScrollerDisabledIdentifier = @"Disabled";
var _CPScrollerClassName = nil,
_CPScrollerPartSizes = {};
@implementation CPScroller : CPControl
{
@@ -80,7 +62,7 @@ var _CPScrollerClassName = nil,
CPUsableScrollerParts _usableParts;
CPArray _partRects;
BOOL _isHorizontal;
BOOL _isVertical @accessors(readonly, getter=isVertical);
float _knobProportion;
CPScrollerPart _hitPart;
@@ -88,97 +70,29 @@ var _CPScrollerClassName = nil,
CPScrollerPart _trackingPart;
float _trackingFloatValue;
CGPoint _trackingStartPoint;
CPView _knobView;
CPView _knobSlotView;
CPView _decrementArrowView;
CPView _incrementArrowView;
}
/*
@ignore
*/
+ (void)initialize
+ (CPString)themeClass
{
if (self != [CPScroller class])
return;
_CPScrollerClassName = [self className];
var regularIdentifier = _CPControlIdentifierForControlSize(CPRegularControlSize),
smallIdentifier = _CPControlIdentifierForControlSize(CPSmallControlSize),
miniIdentifier = _CPControlIdentifierForControlSize(CPMiniControlSize);
// Horizontal Knob Sizes
var prefix = _CPScrollerClassName + _CPScrollerKnobIdentifier + _CPScrollerHorizontalIdentifier;
_CPScrollerPartSizes[prefix + regularIdentifier] = [_CGSizeMake(9.0, _CPScrollerWidths[CPRegularControlSize]), _CGSizeMake(1.0, _CPScrollerWidths[CPRegularControlSize]), _CGSizeMake(9.0, _CPScrollerWidths[CPRegularControlSize])];
_CPScrollerPartSizes[prefix + smallIdentifier] = [_CGSizeMake(6.0, _CPScrollerWidths[CPSmallControlSize]), _CGSizeMake(1.0, _CPScrollerWidths[CPSmallControlSize]), _CGSizeMake(6.0, _CPScrollerWidths[CPSmallControlSize])];
_CPScrollerPartSizes[prefix + miniIdentifier] = [_CGSizeMake(6.0, _CPScrollerWidths[CPMiniControlSize]), _CGSizeMake(1.0, _CPScrollerWidths[CPMiniControlSize]), _CGSizeMake(6.0, _CPScrollerWidths[CPMiniControlSize])];
// Vertical Knob Sizes
var prefix = _CPScrollerClassName + _CPScrollerKnobIdentifier + _CPScrollerVerticalIdentifier;
_CPScrollerPartSizes[prefix + regularIdentifier] = [_CGSizeMake(_CPScrollerWidths[CPRegularControlSize], 9.0), _CGSizeMake(_CPScrollerWidths[CPRegularControlSize], 1.0), _CGSizeMake(_CPScrollerWidths[CPRegularControlSize], 9.0)];
_CPScrollerPartSizes[prefix + smallIdentifier] = [_CGSizeMake(_CPScrollerWidths[CPSmallControlSize], 6.0), _CGSizeMake(_CPScrollerWidths[CPSmallControlSize], 1.0), _CGSizeMake(_CPScrollerWidths[CPSmallControlSize], 6.0)];
_CPScrollerPartSizes[prefix + miniIdentifier] = [_CGSizeMake(_CPScrollerWidths[CPMiniControlSize], 6.0), _CGSizeMake(_CPScrollerWidths[CPMiniControlSize], 1.0), _CGSizeMake(_CPScrollerWidths[CPMiniControlSize], 6.0)];
// Horizontal Knob Slot Sizes
var prefix = _CPScrollerClassName + _CPScrollerKnobSlotIdentifier + _CPScrollerHorizontalIdentifier;
_CPScrollerPartSizes[prefix + regularIdentifier] = _CGSizeMake(1.0, _CPScrollerWidths[CPRegularControlSize]);
_CPScrollerPartSizes[prefix + smallIdentifier] = _CGSizeMake(1.0, _CPScrollerWidths[CPSmallControlSize]);
_CPScrollerPartSizes[prefix + miniIdentifier] = _CGSizeMake(1.0, _CPScrollerWidths[CPMiniControlSize]);
// Vertical Knob Slot Sizes
var prefix = _CPScrollerClassName + _CPScrollerKnobSlotIdentifier + _CPScrollerVerticalIdentifier;
_CPScrollerPartSizes[prefix + regularIdentifier] = _CGSizeMake(_CPScrollerWidths[CPRegularControlSize], 1.0);
_CPScrollerPartSizes[prefix + smallIdentifier] = _CGSizeMake(_CPScrollerWidths[CPSmallControlSize], 1.0);
_CPScrollerPartSizes[prefix + miniIdentifier] = _CGSizeMake(_CPScrollerWidths[CPMiniControlSize], 1.0);
// Horizontal Decrement Arrows Sizes
var prefix = _CPScrollerClassName + _CPScrollerDecrementArrowIdentifier + _CPScrollerHorizontalIdentifier;
_CPScrollerPartSizes[prefix + regularIdentifier] = _CGSizeMake(_CPScrollerArrowHeights[CPRegularControlSize], _CPScrollerWidths[CPRegularControlSize]);
_CPScrollerPartSizes[prefix + regularIdentifier + _CPScrollerHighlightedIdentifier] = _CGSizeMake(_CPScrollerArrowHeights[CPRegularControlSize], _CPScrollerWidths[CPRegularControlSize]);
_CPScrollerPartSizes[prefix + smallIdentifier] = _CGSizeMake(_CPScrollerArrowHeights[CPSmallControlSize] , _CPScrollerWidths[CPSmallControlSize]);
_CPScrollerPartSizes[prefix + smallIdentifier + _CPScrollerHighlightedIdentifier] = _CGSizeMake(_CPScrollerArrowHeights[CPSmallControlSize] , _CPScrollerWidths[CPSmallControlSize]);
_CPScrollerPartSizes[prefix + miniIdentifier] = _CGSizeMake(_CPScrollerArrowHeights[CPMiniControlSize], _CPScrollerWidths[CPMiniControlSize]);
_CPScrollerPartSizes[prefix + miniIdentifier + _CPScrollerHighlightedIdentifier] = _CGSizeMake(_CPScrollerArrowHeights[CPMiniControlSize], _CPScrollerWidths[CPMiniControlSize]);
// Vertical Decrement Arrows Sizes
var prefix = _CPScrollerClassName + _CPScrollerDecrementArrowIdentifier + _CPScrollerVerticalIdentifier;
_CPScrollerPartSizes[prefix + regularIdentifier] = _CGSizeMake(_CPScrollerWidths[CPRegularControlSize], _CPScrollerArrowHeights[CPRegularControlSize]);
_CPScrollerPartSizes[prefix + regularIdentifier + _CPScrollerHighlightedIdentifier] = _CGSizeMake(_CPScrollerWidths[CPRegularControlSize], _CPScrollerArrowHeights[CPRegularControlSize]);
_CPScrollerPartSizes[prefix + smallIdentifier] = _CGSizeMake(_CPScrollerWidths[CPSmallControlSize], _CPScrollerArrowHeights[CPSmallControlSize]);
_CPScrollerPartSizes[prefix + smallIdentifier + _CPScrollerHighlightedIdentifier] = _CGSizeMake(_CPScrollerWidths[CPSmallControlSize], _CPScrollerArrowHeights[CPSmallControlSize]);
_CPScrollerPartSizes[prefix + miniIdentifier] = _CGSizeMake(_CPScrollerWidths[CPMiniControlSize], _CPScrollerArrowHeights[CPMiniControlSize]);
_CPScrollerPartSizes[prefix + miniIdentifier + _CPScrollerHighlightedIdentifier] = _CGSizeMake(_CPScrollerWidths[CPMiniControlSize], _CPScrollerArrowHeights[CPMiniControlSize]);
// Horizontal Increment Arrows Sizes
var prefix = _CPScrollerClassName + _CPScrollerIncrementArrowIdentifier + _CPScrollerHorizontalIdentifier;
_CPScrollerPartSizes[prefix + regularIdentifier] = _CGSizeMake(_CPScrollerArrowHeights[CPRegularControlSize], _CPScrollerWidths[CPRegularControlSize]);
_CPScrollerPartSizes[prefix + regularIdentifier + _CPScrollerHighlightedIdentifier] = _CGSizeMake(_CPScrollerArrowHeights[CPRegularControlSize], _CPScrollerWidths[CPRegularControlSize]);
_CPScrollerPartSizes[prefix + smallIdentifier] = _CGSizeMake(_CPScrollerArrowHeights[CPSmallControlSize], _CPScrollerWidths[CPSmallControlSize]);
_CPScrollerPartSizes[prefix + smallIdentifier + _CPScrollerHighlightedIdentifier] = _CGSizeMake(_CPScrollerArrowHeights[CPSmallControlSize], _CPScrollerWidths[CPSmallControlSize]);
_CPScrollerPartSizes[prefix + miniIdentifier] = _CGSizeMake(_CPScrollerArrowHeights[CPMiniControlSize], _CPScrollerWidths[CPMiniControlSize]);
_CPScrollerPartSizes[prefix + miniIdentifier + _CPScrollerHighlightedIdentifier] = _CGSizeMake(_CPScrollerArrowHeights[CPMiniControlSize], _CPScrollerWidths[CPMiniControlSize]);
// Vertical Increment Arrows Sizes
var prefix = _CPScrollerClassName + _CPScrollerIncrementArrowIdentifier + _CPScrollerVerticalIdentifier;
_CPScrollerPartSizes[prefix + regularIdentifier] = _CGSizeMake(_CPScrollerWidths[CPRegularControlSize], _CPScrollerArrowHeights[CPRegularControlSize]);
_CPScrollerPartSizes[prefix + regularIdentifier + _CPScrollerHighlightedIdentifier] = _CGSizeMake(_CPScrollerWidths[CPRegularControlSize], _CPScrollerArrowHeights[CPRegularControlSize]);
_CPScrollerPartSizes[prefix + smallIdentifier] = _CGSizeMake(_CPScrollerWidths[CPSmallControlSize], _CPScrollerArrowHeights[CPSmallControlSize]);
_CPScrollerPartSizes[prefix + smallIdentifier + _CPScrollerHighlightedIdentifier] = _CGSizeMake(_CPScrollerWidths[CPSmallControlSize], _CPScrollerArrowHeights[CPSmallControlSize]);
_CPScrollerPartSizes[prefix + miniIdentifier] = _CGSizeMake(_CPScrollerWidths[CPMiniControlSize], _CPScrollerArrowHeights[CPMiniControlSize]);
_CPScrollerPartSizes[prefix + miniIdentifier + _CPScrollerHighlightedIdentifier] = _CGSizeMake(_CPScrollerWidths[CPMiniControlSize], _CPScrollerArrowHeights[CPMiniControlSize]);
return "scroller";
}
+ (id)themeAttributes
{
return [CPDictionary dictionaryWithObjects:[ nil, nil, nil, nil,
_CGSizeMakeZero(), _CGSizeMakeZero(), _CGInsetMakeZero(), _CGInsetMakeZero(), _CGSizeMakeZero()]
forKeys:[ @"knob-slot-color",
@"decrement-line-color",
@"increment-line-color",
@"knob-color",
@"decrement-line-size",
@"increment-line-size",
@"track-inset",
@"knob-inset",
@"minimum-knob-length"]];
}
// Calculating Layout
- (id)initWithFrame:(CGRect)aFrame
@@ -192,38 +106,33 @@ var _CPScrollerClassName = nil,
[self setFloatValue:0.0 knobProportion:1.0];
_isHorizontal = CPRectGetWidth(aFrame) > CPRectGetHeight(aFrame);
_hitPart = CPScrollerNoPart;
[self checkSpaceForParts];
[self drawParts];
[self layoutSubviews];
[self _recalculateIsVertical];
}
return self;
}
// Determining CPScroller Size
/*
Returns the <objj>CPScroller</objj>'s width for a <objj>CPRegularControlSize</objj>.
/*!
Returns the CPScroller's width for a CPRegularControlSize.
*/
+ (float)scrollerWidth
{
return [self scrollerWidthForControlSize:CPRegularControlSize];
return 17.0;//[self scrollerWidthForControlSize:CPRegularControlSize];
}
/*
Returns the width of a <objj>CPScroller</objj> for the specified <objj>CPControlSize</objj>.
/*!
Returns the width of a CPScroller for the specified CPControlSize.
@param aControlSize the size of a controller to return the width for
*/
+ (float)scrollerWidthForControlSize:(CPControlSize)aControlSize
{
return _CPScrollerWidths[aControlSize];
return 17.0;//_CPScrollerWidths[aControlSize];
}
/*
/*!
Sets the scroller's size.
@param aControlSize the scroller's size
*/
@@ -234,15 +143,11 @@ var _CPScrollerClassName = nil,
_controlSize = aControlSize;
[self drawKnobSlot];
[self drawKnob];
[self drawArrow:CPScrollerDecrementArrow highlight:NO];
[self drawArrow:CPScrollerIncrementArrow highlight:NO];
[self layoutSubviews];
[self setNeedsLayout];
[self setNeedsDisplay:YES];
}
/*
/*!
Returns the scroller's control size
*/
- (CPControlSize)controlSize
@@ -251,7 +156,7 @@ var _CPScrollerClassName = nil,
}
// Setting the Knob Position
/*
/*!
Sets the scroller's knob position (ranges from 0.0 to 1.0).
@param aValue the knob position (ranges from 0.0 to 1.0)
*/
@@ -259,11 +164,10 @@ var _CPScrollerClassName = nil,
{
[super setFloatValue:MIN(1.0, MAX(0.0, aValue))];
[self checkSpaceForParts];
[self layoutSubviews];
[self setNeedsLayout];
}
/*
/*!
Sets the position and proportion of the knob.
@param aValue the knob position (ranges from 0.0 to 1.0)
@param aProportion the knob's proportion (ranges from 0.0 to 1.0)
@@ -275,7 +179,7 @@ var _CPScrollerClassName = nil,
[self setFloatValue:aValue];
}
/*
/*!
Return's the knob's proportion
*/
- (float)knobProportion
@@ -283,6 +187,16 @@ var _CPScrollerClassName = nil,
return _knobProportion;
}
- (id)currentValueForThemeAttribute:(CPString)anAttributeName
{
var themeState = _themeState;
if (NAMES_FOR_PARTS[_hitPart] + "-color" !== anAttributeName)
themeState &= ~CPThemeStateHighlighted;
return [self valueForThemeAttribute:anAttributeName inState:themeState];
}
// Calculating Layout
- (CGRect)rectForPart:(CPScrollerPart)aPart
@@ -293,7 +207,7 @@ var _CPScrollerClassName = nil,
return _partRects[aPart];
}
/*
/*!
Returns the part of the scroller that would be hit by <code>aPoint</code>.
@param aPoint the simulated point hit
@return the part of the scroller that intersects the point
@@ -326,7 +240,7 @@ var _CPScrollerClassName = nil,
return CPScrollerNoPart;
}
/*
/*!
Check if there's enough space in the scroller to display the knob
*/
- (void)checkSpaceForParts
@@ -334,7 +248,7 @@ var _CPScrollerClassName = nil,
var bounds = [self bounds];
// Assume we won't be needing the arrows.
if (_knobProportion == 1.0)
if (_knobProportion === 1.0)
{
_usableParts = CPNoScrollerParts;
@@ -350,43 +264,56 @@ var _CPScrollerClassName = nil,
return;
}
var width = _CGRectGetWidth(bounds),
height = _CGRectGetHeight(bounds),
usableArrowHeight = _CPScrollerArrowUsableHeights[_controlSize],
slotWidth = (_isHorizontal ? width : height) - 2.0 * usableArrowHeight,
knobWidth = MAX(_CPScrollerKnobMinimumHeights[_controlSize], (slotWidth * _knobProportion));
_usableParts = CPAllScrollerParts;
var arrowHeight = _CPScrollerArrowHeights[_controlSize],
knobLocation = usableArrowHeight + (slotWidth - knobWidth) * [self floatValue];
// At this point we know we're going to need arrows.
if (_isHorizontal)
_usableParts = CPAllScrollerParts;
var knobInset = [self currentValueForThemeAttribute:@"knob-inset"],
trackInset = [self currentValueForThemeAttribute:@"track-inset"],
width = _CGRectGetWidth(bounds),
height = _CGRectGetHeight(bounds);
if ([self isVertical])
{
// ASSERT(_CPScrollerWidths[_controlSize] == height)
_partRects[CPScrollerDecrementPage] = _CGRectMake(usableArrowHeight, 0.0, knobLocation - usableArrowHeight, height);
_partRects[CPScrollerKnob] = _CGRectMake(knobLocation, 0.0, knobWidth, _CPScrollerWidths[_controlSize]);
_partRects[CPScrollerIncrementPage] = _CGRectMake(knobLocation + knobWidth, 0.0, width - (knobLocation + knobWidth) - usableArrowHeight, height);
_partRects[CPScrollerKnobSlot] = _CGRectMake(usableArrowHeight, 0.0, slotWidth, height);
_partRects[CPScrollerDecrementLine] = _CGRectMake(0.0, 0.0, arrowHeight, height);
_partRects[CPScrollerIncrementLine] = _CGRectMake(width - _CPScrollerArrowHeights[_controlSize], 0.0, arrowHeight, height);
var decrementLineSize = [self currentValueForThemeAttribute:"decrement-line-size"],
incrementLineSize = [self currentValueForThemeAttribute:"increment-line-size"],
effectiveDecrementLineHeight = decrementLineSize.height + trackInset.top,
effectiveIncrementLineHeight = incrementLineSize.height + trackInset.bottom,
slotHeight = height - effectiveDecrementLineHeight - effectiveIncrementLineHeight,
minimumKnobLength = [self currentValueForThemeAttribute:"minimum-knob-length"],
knobWidth = width - knobInset.left - knobInset.right,
knobHeight = MAX(minimumKnobLength, (slotHeight * _knobProportion)),
knobLocation = effectiveDecrementLineHeight + (slotHeight - knobHeight) * [self floatValue];
_partRects[CPScrollerDecrementPage] = _CGRectMake(0.0, effectiveDecrementLineHeight, width, knobLocation - effectiveDecrementLineHeight);
_partRects[CPScrollerKnob] = _CGRectMake(knobInset.left, knobLocation, knobWidth, knobHeight);
_partRects[CPScrollerIncrementPage] = _CGRectMake(0.0, knobLocation + knobHeight, width, height - (knobLocation + knobHeight) - effectiveIncrementLineHeight);
_partRects[CPScrollerKnobSlot] = _CGRectMake(trackInset.left, effectiveDecrementLineHeight, width - trackInset.left - trackInset.right, slotHeight);
_partRects[CPScrollerDecrementLine] = _CGRectMake(0.0, 0.0, decrementLineSize.width, decrementLineSize.height);
_partRects[CPScrollerIncrementLine] = _CGRectMake(0.0, height - incrementLineSize.height, incrementLineSize.width, incrementLineSize.height);
}
else
{
// ASSERT(_CPScrollerWidths[_controlSize] == width)
_partRects[CPScrollerDecrementPage] = _CGRectMake(0.0, usableArrowHeight, width, knobLocation - usableArrowHeight);
_partRects[CPScrollerKnob] = _CGRectMake(0.0, knobLocation, _CPScrollerWidths[_controlSize], knobWidth);
_partRects[CPScrollerIncrementPage] = _CGRectMake(0.0, knobLocation + knobWidth, width, height - (knobLocation + knobWidth) - usableArrowHeight);
_partRects[CPScrollerKnobSlot] = _CGRectMake(0.0, usableArrowHeight, width, slotWidth);
_partRects[CPScrollerDecrementLine] = _CGRectMake(0.0, 0.0, width, arrowHeight);
_partRects[CPScrollerIncrementLine] = _CGRectMake(0.0, height - _CPScrollerArrowHeights[_controlSize], width, arrowHeight);
var decrementLineSize = [self currentValueForThemeAttribute:"decrement-line-size"],
incrementLineSize = [self currentValueForThemeAttribute:"increment-line-size"],
effectiveDecrementLineWidth = decrementLineSize.width + trackInset.left,
effectiveIncrementLineWidth = incrementLineSize.width + trackInset.right;
slotWidth = width - effectiveDecrementLineWidth - effectiveIncrementLineWidth,
minimumKnobLength = [self currentValueForThemeAttribute:"minimum-knob-length"],
knobWidth = MAX(minimumKnobLength, (slotWidth * _knobProportion)),
knobHeight = height - knobInset.top - knobInset.bottom,
knobLocation = effectiveDecrementLineWidth + (slotWidth - knobWidth) * [self floatValue];
_partRects[CPScrollerDecrementPage] = _CGRectMake(effectiveDecrementLineWidth, 0.0, knobLocation - effectiveDecrementLineWidth, height);
_partRects[CPScrollerKnob] = _CGRectMake(knobLocation, knobInset.top, knobWidth, knobHeight);
_partRects[CPScrollerIncrementPage] = _CGRectMake(knobLocation + knobWidth, 0.0, width - (knobLocation + knobWidth) - effectiveIncrementLineWidth, height);
_partRects[CPScrollerKnobSlot] = _CGRectMake(effectiveDecrementLineWidth, trackInset.top, slotWidth, height - trackInset.top - trackInset.bottom);
_partRects[CPScrollerDecrementLine] = _CGRectMake(0.0, 0.0, decrementLineSize.width, decrementLineSize.height);
_partRects[CPScrollerIncrementLine] = _CGRectMake(width - incrementLineSize.width, 0.0, incrementLineSize.width, incrementLineSize.height);
}
}
/*
/*!
Returns all the parts of the scroller that
are usable for displaying.
*/
@@ -396,107 +323,86 @@ var _CPScrollerClassName = nil,
}
// Drawing the Parts
/*
/*!
Draws the specified arrow and sets the highlight.
@param anArrow the arrow to draw
@param shouldHighlight sets whether the arrow should be highlighted
*/
- (void)drawArrow:(CPScrollerArrow)anArrow highlight:(BOOL)shouldHighlight
{
var identifier = (anArrow == CPScrollerDecrementArrow ? _CPScrollerDecrementArrowIdentifier : _CPScrollerIncrementArrowIdentifier),
arrowView = (anArrow == CPScrollerDecrementArrow ? _decrementArrowView : _incrementArrowView);
[arrowView setBackgroundColor:_CPControlColorWithPatternImage(
_CPScrollerPartSizes,
_CPScrollerClassName,
identifier,
_isHorizontal ? _CPScrollerHorizontalIdentifier : _CPScrollerVerticalIdentifier,
_CPControlIdentifierForControlSize(_controlSize),
shouldHighlight ? _CPScrollerHighlightedIdentifier : @"")];
}
/*
/*!
Draws the knob
*/
- (void)drawKnob
{
[_knobView setBackgroundColor:_CPControlThreePartImagePattern(
!_isHorizontal,
_CPScrollerPartSizes,
_CPScrollerClassName,
_CPScrollerKnobIdentifier,
_isHorizontal ? _CPScrollerHorizontalIdentifier : _CPScrollerVerticalIdentifier,
_CPControlIdentifierForControlSize(_controlSize))];
}
/*
/*!
Draws the knob's slot
*/
- (void)drawKnobSlot
{
[_knobSlotView setBackgroundColor:_CPControlColorWithPatternImage(
_CPScrollerPartSizes,
_CPScrollerClassName,
_CPScrollerKnobSlotIdentifier,
_isHorizontal ? _CPScrollerHorizontalIdentifier : _CPScrollerVerticalIdentifier,
_CPControlIdentifierForControlSize(_controlSize))];
}
/*
- (CPView)createViewForPart:(CPScrollerPart)aPart
{
var view = [[CPView alloc] initWithFrame:_CGRectMakeZero()];
[view setHitTests:NO];
return view;
}
- (CGRect)rectForEphemeralSubviewNamed:(CPString)aName
{
return _partRects[aName];
}
- (CPView)createEphemeralSubviewNamed:(CPString)aName
{
var view = [[CPView alloc] initWithFrame:_CGRectMakeZero()];
[view setHitTests:NO];
return view;
}
- (void)layoutSubviews
{
[self checkSpaceForParts];
var index = 0,
count = PARTS_ARRANGEMENT.length;
for (; index < count; ++index)
{
var part = PARTS_ARRANGEMENT[index];
if (index === 0)
view = [self layoutEphemeralSubviewNamed:part positioned:CPWindowBelow relativeToEphemeralSubviewNamed:PARTS_ARRANGEMENT[index + 1]];
else
view = [self layoutEphemeralSubviewNamed:part positioned:CPWindowAbove relativeToEphemeralSubviewNamed:PARTS_ARRANGEMENT[index - 1]];
if (view)
[view setBackgroundColor:[self currentValueForThemeAttribute:NAMES_FOR_PARTS[part] + "-color"]];
}
}
/*!
Caches images for the scroll arrow and knob.
*/
- (void)drawParts
{
_knobSlotView = [[CPView alloc] initWithFrame:_CGRectMakeZero()];
[_knobSlotView setHitTests:NO];
[self addSubview:_knobSlotView];
{
[self drawKnobSlot];
_knobView = [[CPView alloc] initWithFrame:_CGRectMakeZero()];
[_knobView setHitTests:NO];
[self addSubview:_knobView];
[self drawKnob];
_decrementArrowView = [[CPView alloc] initWithFrame:_CGRectMakeZero()];
[_decrementArrowView setHitTests:NO];
[self addSubview:_decrementArrowView];
[self drawArrow:CPScrollerDecrementArrow highlight:NO];
_incrementArrowView = [[CPView alloc] initWithFrame:_CGRectMakeZero()];
[_incrementArrowView setHitTests:NO];
[self addSubview:_incrementArrowView];
[self drawArrow:CPScrollerIncrementArrow highlight:NO];
}
/*
Draws the scroller's arrow with a possible highlight,
if the user's mouse is over it.
@param shouldHighlight <code>YES</code> will draw the
arrow highlighted if the mouse is hovering over it.
*/
- (void)highlight:(BOOL)shouldHighlight
{
if (_trackingPart == CPScrollerDecrementLine)
[self drawArrow:CPScrollerDecrementArrow highlight:shouldHighlight];
else if (_trackingPart == CPScrollerIncrementLine)
[self drawArrow:CPScrollerIncrementArrow highlight:shouldHighlight];
}
// Event Handling
/*
/*!
Returns the part of the scroller that was hit.
*/
- (CPScrollerPart)hitPart
@@ -504,7 +410,7 @@ var _CPScrollerClassName = nil,
return _hitPart;
}
/*
/*!
Tracks the knob.
@param anEvent the input event
*/
@@ -512,31 +418,31 @@ var _CPScrollerClassName = nil,
{
var type = [anEvent type];
if (type == CPLeftMouseUp)
if (type === CPLeftMouseUp)
{
_hitPart = CPScrollerNoPart;
return;
}
if (type == CPLeftMouseDown)
if (type === CPLeftMouseDown)
{
_trackingFloatValue = [self floatValue];
_trackingStartPoint = [self convertPoint:[anEvent locationInWindow] fromView:nil];
}
else if (type == CPLeftMouseDragged)
else if (type === CPLeftMouseDragged)
{
var knobRect = [self rectForPart:CPScrollerKnob],
knobSlotRect = [self rectForPart:CPScrollerKnobSlot],
remainder = _isHorizontal ? (_CGRectGetWidth(knobSlotRect) - _CGRectGetWidth(knobRect)) : (_CGRectGetHeight(knobSlotRect) - _CGRectGetHeight(knobRect));
remainder = ![self isVertical] ? (_CGRectGetWidth(knobSlotRect) - _CGRectGetWidth(knobRect)) : (_CGRectGetHeight(knobSlotRect) - _CGRectGetHeight(knobRect));
if (remainder <= 0)
[self setFloatValue:0.0];
else
{
var location = [self convertPoint:[anEvent locationInWindow] fromView:nil];
delta = _isHorizontal ? location.x - _trackingStartPoint.x : location.y - _trackingStartPoint.y;
delta = ![self isVertical] ? location.x - _trackingStartPoint.x : location.y - _trackingStartPoint.y;
[self setFloatValue:_trackingFloatValue + delta / remainder];
}
@@ -547,7 +453,7 @@ var _CPScrollerClassName = nil,
[self sendAction:[self action] to:[self target]];
}
/*
/*!
Tracks the scroll button.
@param anEvent the input event
*/
@@ -555,7 +461,7 @@ var _CPScrollerClassName = nil,
{
var type = [anEvent type];
if (type == CPLeftMouseUp)
if (type === CPLeftMouseUp)
{
[self highlight:NO];
[CPEvent stopPeriodicEvents];
@@ -565,7 +471,7 @@ var _CPScrollerClassName = nil,
return;
}
if (type == CPLeftMouseDown)
if (type === CPLeftMouseDown)
{
_trackingPart = [self hitPart];
@@ -575,16 +481,18 @@ var _CPScrollerClassName = nil,
{
if (_trackingPart == CPScrollerDecrementLine)
_hitPart = CPScrollerDecrementPage;
else if (_trackingPart == CPScrollerIncrementLine)
_hitPart = CPScrollerIncrementPage;
else if (_trackingPart == CPScrollerDecrementPage || _trackingPart == CPScrollerIncrementPage)
{
var knobRect = [self rectForPart:CPScrollerKnob],
knobWidth = _isHorizontal ? _CGRectGetWidth(knobRect) : _CGRectGetHeight(knobRect),
knobWidth = ![self isVertical] ? _CGRectGetWidth(knobRect) : _CGRectGetHeight(knobRect),
knobSlotRect = [self rectForPart:CPScrollerKnobSlot],
remainder = (_isHorizontal ? _CGRectGetWidth(knobSlotRect) : _CGRectGetHeight(knobSlotRect)) - knobWidth;
remainder = (![self isVertical] ? _CGRectGetWidth(knobSlotRect) : _CGRectGetHeight(knobSlotRect)) - knobWidth;
[self setFloatValue:((_isHorizontal ? _trackingStartPoint.x - _CGRectGetMinX(knobSlotRect) : _trackingStartPoint.y - _CGRectGetMinY(knobSlotRect)) - knobWidth / 2.0) / remainder];
[self setFloatValue:((![self isVertical] ? _trackingStartPoint.x - _CGRectGetMinX(knobSlotRect) : _trackingStartPoint.y - _CGRectGetMinY(knobSlotRect)) - knobWidth / 2.0) / remainder];
_hitPart = CPScrollerKnob;
@@ -601,7 +509,7 @@ var _CPScrollerClassName = nil,
[CPEvent startPeriodicEventsAfterDelay:0.5 withPeriod:0.04];
}
else if (type == CPLeftMouseDragged)
else if (type === CPLeftMouseDragged)
{
_trackingStartPoint = [self convertPoint:[anEvent locationInWindow] fromView:nil];
@@ -625,52 +533,36 @@ var _CPScrollerClassName = nil,
}
- (void)_recalculateIsVertical
{
// Recalculate isVertical.
var bounds = [self bounds],
width = _CGRectGetWidth(bounds),
height = _CGRectGetHeight(bounds);
_isVertical = width < height ? 1 : (width > height ? 0 : -1);
if (_isVertical === 1)
[self setThemeState:CPThemeStateVertical];
else if (_isVertical === 0)
[self unsetThemeState:CPThemeStateVertical];
}
- (void)setFrameSize:(CGSize)aSize
{
[super setFrameSize:aSize];
[self _recalculateIsVertical];
[self checkSpaceForParts];
var frame = [self frame],
isHorizontal = CPRectGetWidth(frame) > CPRectGetHeight(frame);
if (_isHorizontal != isHorizontal)
{
_isHorizontal = isHorizontal;
[self drawParts];
}
[self layoutSubviews];
}
/*
Lays out the scrollers subviews
*/
- (void)layoutSubviews
{
[_knobSlotView setFrame:[self rectForPart:CPScrollerKnobSlot]];
var usableParts = [self usableParts],
hidden = !(usableParts == CPAllScrollerParts);
if (hidden != [_knobView isHidden])
{
[_knobView setHidden:hidden];
[_decrementArrowView setHidden:hidden];
[_incrementArrowView setHidden:hidden];
}
if (!hidden)
{
[_knobView setFrame:[self rectForPart:CPScrollerKnob]];
[_decrementArrowView setFrame:[self rectForPart:CPScrollerDecrementLine]];
[_incrementArrowView setFrame:[self rectForPart:CPScrollerIncrementLine]];
}
[self setNeedsLayout];
}
- (void)mouseDown:(CPEvent)anEvent
{
if (![self isEnabled])
return;
_hitPart = [self testPart:[anEvent locationInWindow]];
switch (_hitPart)
@@ -684,9 +576,43 @@ var _CPScrollerClassName = nil,
}
}
// FIXME: This is a result of the "dumb" code that just makes things transparent when disabled.
- (void)setEnabled:(BOOL)shouldBeEnabled
@end
var CPScrollerControlSizeKey = "CPScrollerControlSize",
CPScrollerKnobProportionKey = "CPScrollerKnobProportion";
@implementation CPScroller (CPCoding)
- (id)initWithCoder:(CPCoder)aCoder
{
if (self = [super initWithCoder:aCoder])
{
_controlSize = CPRegularControlSize;
if ([aCoder containsValueForKey:CPScrollerControlSizeKey])
_controlSize = [aCoder decodeIntForKey:CPScrollerControlSizeKey];
_knobProportion = 1.0;
if ([aCoder containsValueForKey:CPScrollerKnobProportionKey])
_knobProportion = [aCoder decodeFloatForKey:CPScrollerKnobProportionKey];
_partRects = [];
_hitPart = CPScrollerNoPart;
[self _recalculateIsVertical];
// [self checkSpaceForParts];
// [self setNeedsLayout];
}
return self;
}
- (void)encodeWithCoder:(CPCoder)aCoder
{
[super encodeWithCoder:aCoder];
[aCoder encodeInt:_controlSize forKey:CPScrollerControlSizeKey];
[aCoder encodeFloat:_knobProportion forKey:CPScrollerKnobProportionKey];
}
@end
+7 -94
View File
@@ -1,103 +1,16 @@
import "CPTextField.j"
#include "Platform/Platform.h"
var TOP_PADDING = 4.0,
BOTTOM_PADDING = 3.0;
HORIZONTAL_PADDING = 3.0;
var CPSecureTextFieldDOMInputElement = nil;
@import "CPTextField.j"
/*!
@ingroup appkit
*/
@implementation CPSecureTextField : CPTextField
{
}
#if PLATFORM(DOM)
+ (DOMElement)_inputElement
- (BOOL)isSecure
{
if (!CPSecureTextFieldDOMInputElement)
{
CPSecureTextFieldDOMInputElement = document.createElement("input");
CPSecureTextFieldDOMInputElement.type = "password";
CPSecureTextFieldDOMInputElement.style.position = "absolute";
CPSecureTextFieldDOMInputElement.style.top = "0px";
CPSecureTextFieldDOMInputElement.style.left = "0px";
CPSecureTextFieldDOMInputElement.style.width = "100%"
CPSecureTextFieldDOMInputElement.style.height = "100%";
CPSecureTextFieldDOMInputElement.style.border = "0px";
CPSecureTextFieldDOMInputElement.style.padding = "0px";
CPSecureTextFieldDOMInputElement.style.whiteSpace = "pre";
CPSecureTextFieldDOMInputElement.style.background = "transparent";
CPSecureTextFieldDOMInputElement.style.outline = "none";
CPSecureTextFieldDOMInputElement.style.paddingLeft = HORIZONTAL_PADDING + "px";
CPSecureTextFieldDOMInputElement.style.paddingTop = TOP_PADDING - 2.0 + "px";
CPSecureTextFieldDOMInputElement.style.margin = "0px";
}
return CPSecureTextFieldDOMInputElement;
}
#endif
- (id)initWithFrame:(CGRect)aFrame
{
self = [super initWithFrame:aFrame];
if (self)
{
#if PLATFORM(DOM)
_DOMElement.removeChild(_DOMTextElement);
_DOMTextElement = document.createElement("input");
_DOMTextElement.type = "password";
_DOMTextElement.style.position = "absolute";
_DOMTextElement.style.top = TOP_PADDING + "px";
_DOMTextElement.style.left = HORIZONTAL_PADDING + "px";
_DOMTextElement.style.width = MAX(0.0, CGRectGetWidth(aFrame) - 2.0 * HORIZONTAL_PADDING) + "px";
_DOMTextElement.style.height = MAX(0.0, CGRectGetHeight(aFrame) - TOP_PADDING - BOTTOM_PADDING) + "px";
_DOMTextElement.style.whiteSpace = "pre";
_DOMTextElement.style.cursor = "default";
_DOMTextElement.style.zIndex = 100;
_DOMTextElement.style.border = "0";
_DOMTextElement.style.font = _DOMElement.style.font;
_DOMTextElement.style.padding = "0px";
_DOMTextElement.style.margin = "0px";
_DOMElement.appendChild(_DOMTextElement);
#endif
}
return self;
return YES;
}
- (void)setFont:(CPFont)aFont
{
[super setFont:aFont];
#if PLATFORM(DOM)
if (_DOMTextElement)
_DOMTextElement.style.font = _DOMElement.style.font;
#endif
}
- (CPString)stringValue
{
// All of this needs to be better.
#if PLATFORM(DOM)
if ([[self window] firstResponder] == self)
return [[self class] _inputElement].value;
#endif
return _DOMTextElement.value;
}
- (void)setStringValue:(CPString)aStringValue
{
_value = aStringValue;
#if PLATFORM(DOM)
_DOMTextElement.value = _value;
#endif
}
@end
@end
+431 -182
View File
@@ -20,9 +20,11 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
import <Foundation/CPArray.j>
@import <Foundation/CPArray.j>
import "CPControl.j"
@import "CPControl.j"
#include "CoreGraphics/CGGeometry.h"
/*
@global
@@ -40,40 +42,54 @@ CPSegmentSwitchTrackingSelectAny = 1;
*/
CPSegmentSwitchTrackingMomentary = 2;
/*
This class is a horizontal button with multiple
segments.
/*!
@ingroup appkit
@class CPSegmentedControl
This class is a horizontal button with multiple segments.
*/
@implementation CPSegmentedControl : CPControl
{
unsigned _segmentCount;
CPArray _segments;
CPArray _selectedSegment;
CPArray _themeStates;
int _selectedSegment;
int _segmentStyle;
CPSegmentSwitchTracking _trackingMode;
unsigned _trackingSegment;
BOOL _trackingHighlighted;
}
+ (CPString)themeClass
{
return "segmented-control";
}
+ (id)themeAttributes
{
return [CPDictionary dictionaryWithObjects:[CPCenterTextAlignment, CPCenterVerticalTextAlignment, CPImageLeft, CPScaleNone, _CGInsetMakeZero(), _CGInsetMakeZero(), nil, nil, nil, nil, 1.0, 24.0]
forKeys:[@"alignment", @"vertical-alignment", @"image-position", @"image-scaling", @"bezel-inset", @"content-inset", @"left-segment-bezel-color", @"right-segment-bezel-color", @"center-segment-bezel-color", @"divider-bezel-color", @"divider-thickness", @"default-height"]];
}
- (id)initWithFrame:(CGRect)aRect
{
_segments = [];
_themeStates = [];
self = [super initWithFrame:aRect];
if (self)
{
_segments = [];
_selectedSegment = -1;
_segmentCount = 0;
_trackingMode = CPSegmentSwitchTrackingSelectOne;
}
return self;
}
/*
/*!
Returns the tag of the selected segment.
*/
- (int)selectedTag
@@ -82,59 +98,47 @@ CPSegmentSwitchTrackingMomentary = 2;
}
// Specifying the number of segments
/*
/*!
Sets the number of segments in the button.
@param aCount the number of segments on
the button
@param aCount the number of segments on the button
*/
- (void)setSegmentCount:(unsigned)aCount
{
if (_segmentCount == aCount)
if (_segments.length == aCount)
return;
var height = CGRectGetHeight([self bounds]);
if (_segmentCount < aCount)
{
var index = _segmentCount;
for (; index < aCount; ++index)
if (_segments.length < aCount)
{
for (var index = _segments.length; index < aCount; ++index)
{
_segments[index] = _CPSegmentMake();
_segments[index].frame.size.height = height;
_segments[index] = [[_CPSegmentItem alloc] init];
_themeStates[index] = CPThemeStateNormal;
}
}
else if (aCount < _segmentCount)
else if (aCount < _segments.length)
{
var index = aCount;
for (; index < _segmentCount; ++index)
{
[_segments[index].imageView removeFromSuperview];
[_segments[index].labelView removeFromSuperview];
for (var index = aCount; index < _segments.length; ++index)
_segments[index] = nil;
}
}
_segmentCount = aCount;
if (_selectedSegment < _segmentCount)
if (_selectedSegment < _segments.length)
_selectedSegment = -1;
[self tileWithChangedSegment:0];
}
/*
/*!
Returns the number of segments in the button.
*/
- (unsigned)segmentCount
{
return _segmentCount;
return _segments.length;
}
// Specifying Selected Segment
/*
/*!
Selects a segment.
@param aSegment the segment to select
@throws CPRangeException if <code>aSegment</code> is out of bounds
@@ -145,7 +149,7 @@ CPSegmentSwitchTrackingMomentary = 2;
[self setSelected:YES forSegment:aSegment];
}
/*
/*!
Returns the selected segment.
*/
- (unsigned)selectedSegment
@@ -153,15 +157,14 @@ CPSegmentSwitchTrackingMomentary = 2;
return _selectedSegment;
}
/*
Selects the button segment with the
specified tag.
/*!
Selects the button segment with the specified tag.
*/
- (BOOL)selectSegmentWithTag:(int)aTag
{
var index = 0;
for (; index < _segmentCount; ++index)
for (; index < _segments.length; ++index)
if (_segments[index].tag == aTag)
{
[self setSelectedSegment:index];
@@ -191,7 +194,7 @@ CPSegmentSwitchTrackingMomentary = 2;
var index = 0,
selected = NO;
for (; index < _segmentCount; ++index)
for (; index < _segments.length; ++index)
if (_segments[index].selected)
if (selected)
[self setSelected:NO forSegment:index];
@@ -203,13 +206,13 @@ CPSegmentSwitchTrackingMomentary = 2;
{
var index = 0;
for (; index < _segmentCount; ++index)
for (; index < _segments.length; ++index)
if (_segments[index].selected)
[self setSelected:NO forSegment:index];
}
}
/*
/*!
Returns the control's tracking mode.
*/
- (CPSegmentSwitchTracking)trackingMode
@@ -218,7 +221,7 @@ CPSegmentSwitchTrackingMomentary = 2;
}
// Working with Individual Segments
/*
/*!
Sets the width of the specified segment.
@param aWidth the new width for the segment
@param aSegment the segment to set the width for
@@ -231,7 +234,7 @@ CPSegmentSwitchTrackingMomentary = 2;
[self tileWithChangedSegment:aSegment];
}
/*
/*!
Returns the width for the specified segment.
@param aSegment the segment to get the width for
@throws CPRangeException if <code>aSegment</code> is out of bounds
@@ -241,7 +244,7 @@ CPSegmentSwitchTrackingMomentary = 2;
return _segments[aSegment].width;
}
/*
/*!
Sets the image for the specified segment.
@param anImage the image for the segment
@param aSegment the segment to set the image on
@@ -251,35 +254,12 @@ CPSegmentSwitchTrackingMomentary = 2;
{
var segment = _segments[aSegment];
if (!anImage)
{
[segment.imageView removeFromSuperview];
segment.imageView = nil;
}
else
{
if (!segment.imageView)
{
segment.imageView = [[CPImageView alloc] initWithFrame:CGRectMakeZero()];
[self addSubview:segment.imageView];
}
[segment.imageView setImage:anImage];
[segment.imageView setFrameSize:CGSizeMakeCopy([anImage size])];
}
segment.image = anImage;
if (segment.width)
[self drawSegment:aSegment highlight:NO];
else
[self tileWithChangedSegment:aSegment];
[self tileWithChangedSegment:aSegment];
}
/*
/*!
Returns the image for the specified segment
@param aSegment the segment to obtain the image for
@throws CPRangeException if <code>aSegment</code> is out of bounds
@@ -289,7 +269,7 @@ CPSegmentSwitchTrackingMomentary = 2;
return _segments[aSegment].image;
}
/*
/*!
Sets the label for the specified segment
@param aLabel the label for the segment
@param aSegment the segment to label
@@ -298,38 +278,13 @@ CPSegmentSwitchTrackingMomentary = 2;
- (void)setLabel:(CPString)aLabel forSegment:(unsigned)aSegment
{
var segment = _segments[aSegment];
if (!aLabel || !aLabel.length)
{
[segment.labelView removeFromSuperview];
segment.labelView = nil;
}
else
{
if (!segment.labelView)
{
segment.labelView = [[CPTextField alloc] initWithFrame:CGRectMakeZero()];
[segment.labelView setFont:[self font]];
[self addSubview:segment.labelView];
}
[segment.labelView setStringValue:aLabel];
[segment.labelView sizeToFit];
}
_segments[aSegment].label = aLabel;
if (segment.width)
[self drawSegment:aSegment highlight:NO];
else
[self tileWithChangedSegment:aSegment];
[self tileWithChangedSegment:aSegment];
}
/*
/*!
Returns the label for the specified segment
@param the segment to obtain the label for
@throws CPRangeException if <code>aSegment</code> is out of bounds
@@ -339,7 +294,7 @@ CPSegmentSwitchTrackingMomentary = 2;
return _segments[aSegment].label;
}
/*
/*!
Sets the menu for the specified segment
@param aMenu the menu to set
@param aSegment the segment to set the menu on
@@ -350,7 +305,7 @@ CPSegmentSwitchTrackingMomentary = 2;
_segments[aSegment].menu = aMenu;
}
/*
/*!
Returns the menu for the specified segment.
@param aSegment the segment to obtain the menu for
@throws CPRangeException if <code>aSegment</code> is out of bounds
@@ -360,7 +315,7 @@ CPSegmentSwitchTrackingMomentary = 2;
return _segments[aSegment].menu;
}
/*
/*!
Sets the selection for the specified segment. If only one segment
can be selected at a time, any other segment will be deselected.
@param isSelected <code>YES</code> selects the segment. <code>NO</code> deselects it.
@@ -377,6 +332,8 @@ CPSegmentSwitchTrackingMomentary = 2;
segment.selected = isSelected;
_themeStates[aSegment] = isSelected ? CPThemeStateSelected : CPThemeStateNormal;
// We need to do some cleanup if we only allow one selection.
if (isSelected)
{
@@ -387,6 +344,7 @@ CPSegmentSwitchTrackingMomentary = 2;
if (_trackingMode == CPSegmentSwitchTrackingSelectOne && oldSelectedSegment != aSegment && oldSelectedSegment != -1)
{
_segments[oldSelectedSegment].selected = NO;
_themeStates[oldSelectedSegment] = CPThemeStateNormal;
[self drawSegmentBezel:oldSelectedSegment highlight:NO];
}
@@ -394,9 +352,12 @@ CPSegmentSwitchTrackingMomentary = 2;
if (_trackingMode != CPSegmentSwitchTrackingMomentary)
[self drawSegmentBezel:aSegment highlight:NO];
[self setNeedsLayout];
[self setNeedsDisplay:YES];
}
/*
/*!
Returns <code>YES</code> if the specified segment is selected.
@param aSegment the segment to check for selection
@throws CPRangeException if <code>aSegment</code> is out of bounds
@@ -406,7 +367,7 @@ CPSegmentSwitchTrackingMomentary = 2;
return _segments[aSegment].selected;
}
/*
/*!
Enables/diables the specified segment.
@param isEnabled <code>YES</code> enables the segment
@param aSegment the segment to enable/disble
@@ -415,9 +376,12 @@ CPSegmentSwitchTrackingMomentary = 2;
- (void)setEnabled:(BOOL)isEnabled forSegment:(unsigned)aSegment
{
_segments[aSegment].enabled = isEnabled;
[self setNeedsLayout];
[self setNeedsDisplay:YES];
}
/*
/*!
Returns <code>YES</code> if the specified segment is enabled.
@param aSegment the segment to check
@throws CPRangeException if <code>aSegment</code> is out of bounds
@@ -427,7 +391,7 @@ CPSegmentSwitchTrackingMomentary = 2;
return _segments[aSegment].enabled;
}
/*
/*!
Sets a tag for the specified segment.
@param aTag the tag to set
@param aSegment the segment to set the tag on
@@ -437,7 +401,7 @@ CPSegmentSwitchTrackingMomentary = 2;
_segments[aSegment].tag = aTag;
}
/*
/*!
Returns the tag for the specified segment.
@param aSegment the segment to obtain the tag for
*/
@@ -447,83 +411,208 @@ CPSegmentSwitchTrackingMomentary = 2;
}
// Drawings
/*
/*!
Draws the specified segment bezel
@param aSegment the segment to draw the bezel for
@param shouldHighlight <code>YES</code> highlights the bezel
*/
- (void)drawSegmentBezel:(int)aSegment highlight:(BOOL)shouldHighlight
{
if (shouldHighlight)
_themeStates[aSegment] |= CPThemeStateHighlighted;
else
_themeStates[aSegment] &= ~CPThemeStateHighlighted;
[self setNeedsLayout];
[self setNeedsDisplay:YES];
}
/*
- (float)_leftOffsetForSegment:(unsigned)segment
{
var bezelInset = [self currentValueForThemeAttribute:@"bezel-inset"];
if (segment == 0)
return bezelInset.left;
var thickness = [self currentValueForThemeAttribute:@"divider-thickness"];
return [self _leftOffsetForSegment:segment - 1] + [self widthForSegment:segment - 1] + thickness;
}
- (CGRect)rectForEphemeralSubviewNamed:(CPString)aName
{
var height = [self currentValueForThemeAttribute:@"default-height"],
contentInset = [self currentValueForThemeAttribute:@"content-inset"],
bezelInset = [self currentValueForThemeAttribute:@"bezel-inset"],
bounds = [self bounds];
if (aName === "left-segment-bezel")
{
return CGRectMake(bezelInset.left, bezelInset.top, contentInset.left, height);
}
else if (aName === "right-segment-bezel")
{
return CGRectMake(CGRectGetMaxX(bounds) - contentInset.right - bezelInset.right, bezelInset.top, contentInset.right, height);
}
else if (aName.substring(0, "segment-bezel".length) == "segment-bezel")
{
var segment = parseInt(aName.substring("segment-bezel-".length), 10),
frame = CGRectCreateCopy(_segments[segment].frame);
if (segment == 0)
{
frame.origin.x += contentInset.left;
frame.size.width -= contentInset.left;
}
if (segment == _segments.length - 1)
frame.size.width -= contentInset.right;
return frame;
}
else if (aName.substring(0, "divider-bezel".length) == "divider-bezel")
{
var segment = parseInt(aName.substring("divider-bezel-".length), 10),
width = [self widthForSegment:segment],
left = [self _leftOffsetForSegment:segment],
thickness = [self currentValueForThemeAttribute:@"divider-thickness"];
return CGRectMake(left + width, bezelInset.top, thickness, height);
}
else if (aName.substring(0, "segment-content".length) == "segment-content")
{
var segment = parseInt(aName.substring("segment-content-".length), 10);
return [self contentFrameForSegment:segment];
}
return [super rectForEphemeralSubviewNamed:aName];
}
- (CPView)createEphemeralSubviewNamed:(CPString)aName
{
if (aName.substring(0, "segment-content".length) == "segment-content")
return [[_CPImageAndTextView alloc] initWithFrame:_CGRectMakeZero()];
return [[CPView alloc] initWithFrame:_CGRectMakeZero()];
}
- (void)layoutSubviews
{
var leftCapColor = [self valueForThemeAttribute:@"left-segment-bezel-color"
inState:_themeStates[0]];
var leftBezelView = [self layoutEphemeralSubviewNamed:@"left-segment-bezel"
positioned:CPWindowBelow
relativeToEphemeralSubviewNamed:nil];
[leftBezelView setBackgroundColor:leftCapColor];
var rightCapColor = [self valueForThemeAttribute:@"right-segment-bezel-color"
inState:_themeStates[_themeStates.length - 1]];
var rightBezelView = [self layoutEphemeralSubviewNamed:@"right-segment-bezel"
positioned:CPWindowBelow
relativeToEphemeralSubviewNamed:nil];
[rightBezelView setBackgroundColor:rightCapColor];
for (var i=0, count = _themeStates.length; i<count; i++)
{
var themeState = _themeStates[i];
themeState |= _themeState & CPThemeStateDisabled;
var bezelColor = [self valueForThemeAttribute:@"center-segment-bezel-color"
inState:themeState];
var bezelView = [self layoutEphemeralSubviewNamed:"segment-bezel-"+i
positioned:CPWindowBelow
relativeToEphemeralSubviewNamed:nil];
[bezelView setBackgroundColor:bezelColor];
//layout image/title views
var segment = _segments[i];
var contentView = [self layoutEphemeralSubviewNamed:@"segment-content-"+i
positioned:CPWindowAbove
relativeToEphemeralSubviewNamed:@"segment-bezel-"+i];
[contentView setText:segment.label];
[contentView setImage:segment.image];
[contentView setFont:[self valueForThemeAttribute:@"font" inState:themeState]];
[contentView setTextColor:[self valueForThemeAttribute:@"text-color" inState:themeState]];
[contentView setAlignment:[self valueForThemeAttribute:@"alignment" inState:themeState]];
[contentView setVerticalAlignment:[self valueForThemeAttribute:@"vertical-alignment" inState:themeState]];
[contentView setLineBreakMode:[self valueForThemeAttribute:@"line-break-mode" inState:themeState]];
[contentView setTextShadowColor:[self valueForThemeAttribute:@"text-shadow-color" inState:themeState]];
[contentView setTextShadowOffset:[self valueForThemeAttribute:@"text-shadow-offset" inState:themeState]];
[contentView setImageScaling:[self valueForThemeAttribute:@"image-scaling" inState:themeState]];
if (segment.image && segment.label)
[contentView setImagePosition:[self valueForThemeAttribute:@"image-position" inState:themeState]];
else if (segment.image)
[contentView setImagePosition:CPImageOnly];
if (i == count - 1)
continue;
var borderState = _themeStates[i] | _themeStates[i+1];
borderState = (borderState & CPThemeStateSelected & ~CPThemeStateHighlighted) ? CPThemeStateSelected : CPThemeStateNormal;
borderState |= _themeState & CPThemeStateDisabled;
var borderColor = [self valueForThemeAttribute:@"divider-bezel-color"
inState:borderState];
var borderView = [self layoutEphemeralSubviewNamed:"divider-bezel-"+i
positioned:CPWindowBelow
relativeToEphemeralSubviewNamed:nil];
[borderView setBackgroundColor:borderColor];
}
}
/*!
Draws the specified segment
@param aSegment the segment to draw
@param shouldHighlight <code>YES</code> highlights the bezel
*/
- (void)drawSegment:(int)aSegment highlight:(BOOL)shouldHighlight
{
var segment = _segments[aSegment],
imageView = segment.imageView,
labelView = segment.labelView,
frame = segment.frame,
segmentX = CGRectGetMinX(frame),
segmentWidth = CGRectGetWidth(frame),
segmentHeight = CGRectGetHeight(frame) - 1.0;
if (imageView && labelView)
{
var imageViewSize = [imageView frame].size,
labelViewSize = [labelView frame].size,
totalHeight = imageViewSize.height + labelViewSize.height,
labelWidth = MIN(labelViewSize.width, width),
y = (segmentHeight - totalHeight) / 2.0;
[imageView setFrameOrigin:CGPointMake(segmentX + (segmentWidth - imageViewSize.width) / 2.0, y)];
if (labelWidth < labelViewSize.width)
[labelView setFrameSize:CGSizeMake(labelWidth, labelViewSize.height)];
[labelView setFrameOrigin:CGPointMake(segmentX + (segmentWidth - labelWidth) / 2.0, y + imageViewSize.height)];
}
else if (imageView)
{
var imageViewSize = [imageView frame].size;
[imageView setFrameOrigin:CGPointMake(segmentX + (segmentWidth - imageViewSize.width) / 2.0, (segmentHeight - imageViewSize.height) / 2.0)];
}
else if (labelView)
{
var labelViewSize = [labelView frame].size,
labelWidth = MIN(labelViewSize.width, segmentWidth);
if (labelWidth < labelViewSize.width)
[labelView setFrameSize:CGSizeMake(labelWidth, labelViewSize.height)];
[labelView setFrameOrigin:CGPointMake(segmentX + (segmentWidth - labelWidth) / 2.0, (segmentHeight - labelViewSize.height) / 2.0)];
}
}
- (void)tileWithChangedSegment:(unsigned)aSegment
{
if (aSegment >= _segments.length)
return;
var segment = _segments[aSegment],
segmentWidth = segment.width;
segmentWidth = segment.width,
themeState = _themeStates[aSegment] | (_themeState & CPThemeStateDisabled),
contentInset = [self valueForThemeAttribute:@"content-inset" inState:themeState],
font = [self valueForThemeAttribute:@"font" inState:themeState];
if (!segmentWidth)
{
if (segment.labelView && segment.imageView)
segmentWidth = MAX(CGRectGetWidth([segment.labelView frame]) , CGRectGetWidth([segment.imageView frame]));
else if (segment.labelView)
segmentWidth = CGRectGetWidth([segment.labelView frame]);
else if (segment.imageView)
segmentWidth = CGRectGetWidth([segment.imageView frame]);
if (segment.image && segment.label)
segmentWidth = [segment.label sizeWithFont:font].width + [segment.image size].width + contentInset.left + contentInset.right;
else if (segment.image)
segmentWidth = [segment.image size].width + contentInset.left + contentInset.right;
else if (segment.label)
segmentWidth = [segment.label sizeWithFont:font].width + contentInset.left + contentInset.right;
else
segmentWidth = 0.0;
}
var delta = segmentWidth - CGRectGetWidth(segment.frame);
if (!delta)
return;
@@ -533,12 +622,13 @@ CPSegmentSwitchTrackingMomentary = 2;
[self setFrameSize:CGSizeMake(CGRectGetWidth(frame) + delta, CGRectGetHeight(frame))];
// Update Segment Width
segment.frame.size.width = segmentWidth;
segment.width = segmentWidth;
segment.frame = [self frameForSegment:aSegment];;
// Update Following Segments Widths
var index = aSegment + 1;
for (; index < _segmentCount; ++index)
for (; index < _segments.length; ++index)
{
_segments[index].frame.origin.x += delta;
@@ -548,18 +638,41 @@ CPSegmentSwitchTrackingMomentary = 2;
[self drawSegmentBezel:aSegment highlight:NO];
[self drawSegment:aSegment highlight:NO];
[self setNeedsLayout];
[self setNeedsDisplay:YES];
}
/*
/*!
Returns the bounding rectangle for the specified segment.
@param aSegment the segment to get the rectangle for
*/
- (CGRect)frameForSegment:(unsigned)aSegment
{
return _segments[aSegment].frame;
return [self bezelFrameForSegment:aSegment];
}
/*
- (CGRect)bezelFrameForSegment:(unsigned)aSegment
{
var height = [self currentValueForThemeAttribute:@"default-height"],
bezelInset = [self currentValueForThemeAttribute:@"bezel-inset"],
width = [self widthForSegment:aSegment],
left = [self _leftOffsetForSegment:aSegment];
return CGRectMake(left, bezelInset.top, width, height);
}
- (CGRect)contentFrameForSegment:(unsigned)aSegment
{
var height = [self currentValueForThemeAttribute:@"default-height"],
contentInset = [self currentValueForThemeAttribute:@"content-inset"],
width = [self widthForSegment:aSegment],
left = [self _leftOffsetForSegment:aSegment];
return CGRectMake(left + contentInset.left, contentInset.top, width - contentInset.left - contentInset.right, height - contentInset.top - contentInset.bottom);
}
/*!
Returns the segment that is hit by the specified point.
@param aPoint the point to test for a segment hit
@return the intersecting segment
@@ -589,7 +702,7 @@ CPSegmentSwitchTrackingMomentary = 2;
{
}
/*
/*!
Handles events for the segment
@param anEvent the event to handle
*/
@@ -600,6 +713,9 @@ CPSegmentSwitchTrackingMomentary = 2;
if (type == CPLeftMouseUp)
{
if (_trackingSegment == -1)
return;
if (CGRectContainsPoint(_segments[_trackingSegment].frame, location))
{
if (_trackingMode == CPSegmentSwitchTrackingSelectAny)
@@ -633,12 +749,15 @@ CPSegmentSwitchTrackingMomentary = 2;
{
_trackingHighlighted = YES;
_trackingSegment = [self testSegment:location];
[self drawSegmentBezel:_trackingSegment highlight:YES];
}
else if (type == CPLeftMouseDragged)
{
if (_trackingSegment == -1)
return;
var highlighted = CGRectContainsPoint(_segments[_trackingSegment].frame, location);
if (highlighted != _trackingHighlighted)
@@ -656,20 +775,150 @@ CPSegmentSwitchTrackingMomentary = 2;
{
[super setFont:aFont];
var count = _segmentCount;
if (!count)
return;
while (count--)
[_segments[count].labelView setFont:aFont];
[self tileWithChangedSegment:0];
}
@end
var _CPSegmentMake = function()
var CPSegmentedControlSegmentsKey = "CPSegmentedControlSegmentsKey",
CPSegmentedControlSelectedKey = "CPSegmentedControlSelectedKey",
CPSegmentedControlSegmentStyleKey = "CPSegmentedControlSegmentStyleKey",
CPSegmentedControlTrackingModeKey = "CPSegmentedControlTrackingModeKey";
@implementation CPSegmentedControl (CPCoding)
- (id)initWithCoder:(CPCoder)aCoder
{
return { width:0, image:nil, label:@"", menu:nil, selected:NO, enabled:NO, tag:0, labelView:nil, imageView:nil, frame:CGRectMakeZero() }
self = [super initWithCoder:aCoder];
if (self)
{
var frame = [self frame],
originalWidth = frame.size.width;
frame.size.width = 0;
[self setFrame:frame];
_segments = [aCoder decodeObjectForKey:CPSegmentedControlSegmentsKey];
_segmentStyle = [aCoder decodeIntForKey:CPSegmentedControlSegmentStyleKey];
_themeStates = [];
if ([aCoder containsValueForKey:CPSegmentedControlSelectedKey])
_selectedSegment = [aCoder decodeIntForKey:CPSegmentedControlSelectedKey];
else
_selectedSegment = -1;
if ([aCoder containsValueForKey:CPSegmentedControlTrackingModeKey])
_trackingMode = [aCoder decodeIntForKey:CPSegmentedControlTrackingModeKey];
else
_trackingMode = CPSegmentSwitchTrackingSelectOne;
// HACK
for (var i = 0; i < _segments.length; i++)
{
_themeStates[i] = _segments[i].selected ? CPThemeStateSelected : CPThemeStateNormal;
[self tileWithChangedSegment:i];
}
var difference = MAX(originalWidth - [self frame].size.width, 0.0),
remainingWidth = FLOOR(difference / _segments.length);
for (var i=0; i < _segments.length; i++)
[self setWidth:_segments[i].width + remainingWidth forSegment:i];
[self tileWithChangedSegment:0];
}
return self;
}
- (void)encodeWithCoder:(CPCoder)aCoder
{
[super encodeWithCoder:aCoder];
[aCoder encodeObject:_segments forKey:CPSegmentedControlSegmentsKey];
[aCoder encodeInt:_selectedSegment forKey:CPSegmentedControlSelectedKey];
[aCoder encodeInt:_segmentStyle forKey:CPSegmentedControlSegmentStyleKey];
[aCoder encodeInt:_trackingMode forKey:CPSegmentedControlTrackingModeKey];
}
@end
@implementation _CPSegmentItem : CPObject
{
CPImage image;
CPString label;
CPMenu menu;
BOOL selected;
BOOL enabled;
int tag;
int width;
CGRect frame;
}
- (id)init
{
if (self = [super init])
{
image = nil;
label = @"";
menu = nil;
selected = NO;
enabled = NO;
tag = 0;
width = 0;
frame = CGRectMakeZero();
}
return self;
}
@end
var CPSegmentItemImageKey = "CPSegmentItemImageKey",
CPSegmentItemLabelKey = "CPSegmentItemLabelKey",
CPSegmentItemMenuKey = "CPSegmentItemMenuKey",
CPSegmentItemSelectedKey = "CPSegmentItemSelectedKey",
CPSegmentItemEnabledKey = "CPSegmentItemEnabledKey",
CPSegmentItemTagKey = "CPSegmentItemTagKey",
CPSegmentItemWidthKey = "CPSegmentItemWidthKey";
@implementation _CPSegmentItem (CPCoding)
- (id)initWithCoder:(CPCoder)aCoder
{
self = [super init];
if (self)
{
image = [aCoder decodeObjectForKey:CPSegmentItemImageKey];
label = [aCoder decodeObjectForKey:CPSegmentItemLabelKey];
menu = [aCoder decodeObjectForKey:CPSegmentItemMenuKey];
selected = [aCoder decodeBoolForKey:CPSegmentItemSelectedKey];
enabled = [aCoder decodeBoolForKey:CPSegmentItemEnabledKey];
tag = [aCoder decodeIntForKey:CPSegmentItemTagKey];
width = [aCoder decodeFloatForKey:CPSegmentItemWidthKey];
frame = CGRectMakeZero();
}
return self;
}
- (void)encodeWithCoder:(CPCoder)aCoder
{
[aCoder encodeObject:image forKey:CPSegmentItemImageKey];
[aCoder encodeObject:label forKey:CPSegmentItemLabelKey];
[aCoder encodeObject:menu forKey:CPSegmentItemMenuKey];
[aCoder encodeBool:selected forKey:CPSegmentItemSelectedKey];
[aCoder encodeBool:enabled forKey:CPSegmentItemEnabledKey];
[aCoder encodeInt:tag forKey:CPSegmentItemTagKey];
[aCoder encodeFloat:width forKey:CPSegmentItemWidthKey];
}
@end
+11 -7
View File
@@ -20,9 +20,13 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
import <Foundation/CPObject.j>
@import <Foundation/CPObject.j>
/*!
@deprecated
@class CPShadow
/*
Instances of this class contain the attributes of a drop shadow used in Cappuccino.
*/
@implementation CPShadow : CPObject
@@ -34,7 +38,7 @@ import <Foundation/CPObject.j>
CPString _cssString;
}
/*
/*!
Creates a shadow with the specified attributes.
@param anOffset the shadow's offset
@param aBlurRadius the shadow's blur radius
@@ -63,7 +67,7 @@ import <Foundation/CPObject.j>
return self;
}
/*
/*!
Returns the shadow's offset.
*/
- (CGSize)shadowOffset
@@ -71,7 +75,7 @@ import <Foundation/CPObject.j>
return _offset;
}
/*
/*!
Returns the shadow's blur radius
*/
- (float)shadowBlurRadius
@@ -79,7 +83,7 @@ import <Foundation/CPObject.j>
return _blurRadius;
}
/*
/*!
Returns the shadow's color.
*/
- (CPColor)shadowColor
@@ -87,7 +91,7 @@ import <Foundation/CPObject.j>
return _color;
}
/*
/*!
Returns a CSS string representation of the shadow.
*/
- (CPString)cssString
+10 -5
View File
@@ -20,12 +20,13 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
import <Foundation/CPBundle.j>
@import <Foundation/CPBundle.j>
@import "CGGeometry.j"
@import "CPImage.j"
@import "CPImageView.j"
@import "CPView.j"
import "CGGeometry.j"
import "CPImage.j"
import "CPImageView.j"
import "CPView.j"
#include "CoreGraphics/CGGeometry.h"
@@ -45,6 +46,10 @@ var LIGHT_LEFT_INSET = 3.0,
HEAVY_TOP_INSET = 5.0,
HEAVY_BOTTOM_INSET = 5.0;
/*!
@ingroup appkit
*/
@implementation CPShadowView : CPView
{
CPShadowWeight _weight;
+342 -306
View File
@@ -3,7 +3,7 @@
* AppKit
*
* Created by Francisco Tolmasky.
* Copyright 2008, 280 North, Inc.
* Copyright 2009, 280 North, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -20,393 +20,429 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
import "CPControl.j"
@import "CPControl.j"
var CPSliderHorizontalKnobImage = nil,
CPSliderHorizontalBarLeftImage = nil,
CPSliderHorizontalBarRightImage = nil,
CPSliderHorizontalBarCenterImage = nil;
#include "CoreGraphics/CGGeometry.h"
/*
An <objj>CPSlider</objj> displays, and allows control of, some value in the application. It represents a continuous stream of values of type <code>float</code>, which can be retrieved by the method <code>floatValue</code> and set by the method <code>setFloatValue:</code>.
/*! SLIDER STATES */
CPLinearSlider = 0;
CPCircularSlider = 1;
/*!
@ingroup appkit
*/
@implementation CPSlider : CPControl
{
double _value;
double _minValue;
double _maxValue;
double _altIncrementValue;
CPView _bar;
CPView _knob;
double _minValue;
double _maxValue;
double _altIncrementValue;
BOOL _isVertical;
CPImageView _standardKnob;
CPView _standardVerticalBar;
CPView _standardHorizontalBar;
BOOL _isVertical;
}
/*
@ignore
*/
+ (void)initialize
+ (CPString)themeClass
{
if (self != [CPSlider class])
return;
return "slider";
}
var bundle = [CPBundle bundleForClass:self];
CPSliderKnobImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPSlider/CPSliderKnobRegular.png"] size:CPSizeMake(11.0, 11.0)],
CPSliderKnobPushedImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPSlider/CPSliderKnobRegularPushed.png"] size:CPSizeMake(11.0, 11.0)],
CPSliderHorizontalBarLeftImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPSlider/CPSliderTrackHorizontalLeft.png"] size:CPSizeMake(2.0, 4.0)],
CPSliderHorizontalBarRightImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPSlider/CPSliderTrackHorizontalRight.png"] size:CPSizeMake(2.0, 4.0)],
CPSliderHorizontalBarCenterImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPSlider/CPSliderTrackHorizontalCenter.png"] size:CPSizeMake(1.0, 4.0)];
+ (id)themeAttributes
{
return [CPDictionary dictionaryWithObjects:[nil, _CGSizeMakeZero(), 0.0, nil]
forKeys:[@"knob-color", @"knob-size", @"track-width", @"track-color"]];
}
- (id)initWithFrame:(CGRect)aFrame
{
self = [super initWithFrame:aFrame];
if (self)
{
_value = 50.0;
_minValue = 0.0;
_maxValue = 100.0;
_bar = [self bar];
_knob = [self knob];
_knobSize = [[self knobImage] size];
_isVertical = [self isVertical];
[_knob setFrameOrigin:[self knobPosition]];
[self setObjectValue:50.0];
[self addSubview:_bar];
[self addSubview:_knob];
[self setContinuous:YES];
[self _recalculateIsVertical];
}
return self;
}
- (void)setMinValue:(float)aMinimumValue
{
if (_minValue === aMinimumValue)
return;
- (void)setFrameSize:(CGSize)aSize
{
if(aSize.height > 21.0)
aSize.height = 21.0;
_minValue = aMinimumValue;
var doubleValue = [self doubleValue];
if (_isVertical != [self isVertical])
{
_isVertical = [self isVertical];
var bar = [self bar],
knob = [self knob];
if (_bar != bar)
[self replaceSubview:_bar = bar withView:_bar];
if (_knob != knob)
{
[self replaceSubview:knob withView:_knob];
_knob = knob;
[_knob setFrameOrigin:[self knobPosition]];
}
}
[super setFrameSize:aSize];
[_knob setFrameOrigin:[self knobPosition]];
if (doubleValue < _minValue)
[self setDoubleValue:_minValue];
}
/*
Returns the value by which the slider will be
incremented if the user holds down the <code>ALT</code>s key.
*/
- (double)altIncrementValue
{
return _altIncrementValue;
}
/*
Returns the thickness of the slider's knob. This value is in pixels,
and is the size of the knob along the slider's track.
*/
- (float)knobThickness
{
return CPRectGetWidth([_knob frame]);
}
/*
@ignore
*/
- (CPImage)leftTrackImage
{
return CPSliderHorizontalBarLeftImage;
}
/*
@ignore
*/
- (CPImage)rightTrackImage
{
return CPSliderHorizontalBarRightImage;
}
/*
@ignore
*/
- (CPImage)centerTrackImage
{
return CPSliderHorizontalBarCenterImage
}
/*
@ignore
*/
- (CPImage)knobImage
{
return CPSliderKnobImage;
}
/*
@ignore
*/
- (CPImage)pushedKnobImage
{
return CPSliderKnobPushedImage;
}
/*
Returns the slider's knob.
*/
- (CPView)knob
{
if (!_standardKnob)
{
var knobImage = [self knobImage],
knobSize = [knobImage size];
_standardKnob = [[CPImageView alloc] initWithFrame:CPRectMake(0.0, 0.0, knobSize.width, knobSize.height)];
[_standardKnob setImage:knobImage];
}
return _standardKnob;
}
/*
Returns the slider's bar.
*/
- (CPView)bar
{
// FIXME: veritcal.
if ([self isVertical])
return nil;
else
{
if (!_standardHorizontalBar)
{
var frame = [self frame],
barFrame = CPRectMake(0.0, 0.0, CPRectGetWidth(frame), 4.0);
_standardHorizontalBar = [[CPView alloc] initWithFrame:barFrame];
[_standardHorizontalBar setBackgroundColor:[CPColor colorWithPatternImage:[[CPThreePartImage alloc] initWithImageSlices:
[[self leftTrackImage], [self centerTrackImage], [self rightTrackImage]] isVertical:NO]]];
[_standardHorizontalBar setFrame:CPRectMake(0.0, (CPRectGetHeight(frame) - CPRectGetHeight(barFrame)) / 2.0, CPRectGetWidth(_isVertical ? barFrame : frame), CPRectGetHeight(_isVertical ? frame : barFrame))];
[_standardHorizontalBar setAutoresizingMask:_isVertical ? CPViewHeightSizable : CPViewWidthSizable];
}
return _standardHorizontalBar;
}
}
/*
Sets the value the slider will be incremented if the user holds the <code>ALT</code> key.
*/
- (void)setAltIncrementValue:(double)anIncrementValue
{
_altIncrementValue = anIncrementValue;
}
/*
Returns <code>YES</code> if the slider is vertical.
*/
- (BOOL)isVertical
{
var frame = [self frame];
if (CPRectGetWidth(frame) == CPRectGetHeight(frame))
return -1;
return CPRectGetWidth(frame) < CPRectGetHeight(frame);
}
/*
Returns the slider's maximum value
*/
- (double)maxValue
{
return _maxValue;
}
/*
Returns the slider's minimum value
*/
- (double)minValue
- (float)minValue
{
return _minValue;
}
/*
Sets the slider's maximum value
@param aMaxValue the new maximum value
*/
- (void)setMaxValue:(double)aMaxValue
- (void)setMaxValue:(float)aMaximumValue
{
_maxValue = aMaxValue;
if (_maxValue === aMaximumValue)
return;
_maxValue = aMaximumValue;
var doubleValue = [self doubleValue];
if (doubleValue > _maxValue)
[self setDoubleValue:_maxValue];
}
/*
Sets the slider's minimum value
@param aMinValue the new minimum value
*/
- (void)setMinValue:(double)aMinValue
- (float)maxValue
{
_minValue = aMinValue;
return _maxValue;
}
/*
Sets the slider's value
@param aValue the new slider value
*/
- (void)setValue:(double)aValue
- (void)setObjectValue:(id)aValue
{
_value = aValue;
[super setObjectValue:MIN(MAX(aValue, _minValue), _maxValue)];
[_knob setFrameOrigin:[self knobPosition]];
[self setNeedsLayout];
[self setNeedsDisplay:YES];
}
/*
Returns the slider's value
*/
- (double)value
- (void)setSliderType:(CPSliderType)aSliderType
{
return _value;
}
/*
Returns the knob's position
@ignore
*/
- (CGPoint)knobPosition
{
if ([self isVertical])
return CPPointMake(0.0, 0.0);
if (aSliderType === CPCircularSlider)
[self setThemeState:CPThemeStateCircular];
else
return CPPointMake(
((_value - _minValue) / (_maxValue - _minValue)) * (CPRectGetWidth([self frame]) - CPRectGetWidth([_knob frame])),
(CPRectGetHeight([self frame]) - CPRectGetHeight([_knob frame])) / 2.0);
[self unsetThemeState:CPThemeStateCircular];
}
/*
@ignore
*/
- (float)valueForKnobPosition:(CGPoint)aPoint
- (CPSliderType)sliderType
{
if ([self isVertical])
return 0.0;
return [self hasThemeState:CPThemeStateCircular] ? CPCircularSlider : CPLinearSlider;
}
- (CGRect)trackRectForBounds:(CGRect)bounds
{
if ([self hasThemeState:CPThemeStateCircular])
{
var originalBounds = CGRectCreateCopy(bounds);
bounds.size.width = MIN(bounds.size.width, bounds.size.height);
bounds.size.height = bounds.size.width;
if (bounds.size.width < originalBounds.size.width)
bounds.origin.x += (originalBounds.size.width - bounds.size.width) / 2.0;
else
bounds.origin.y += (originalBounds.size.height - bounds.size.height) / 2.0;
}
else
return MAX(MIN((aPoint.x) * (_maxValue - _minValue) / ( CPRectGetWidth([self frame]) - CPRectGetWidth([_knob frame]) ) + _minValue, _maxValue), _minValue);
{
var trackWidth = [self currentValueForThemeAttribute:@"track-width"];
if (trackWidth <= 0)
return _CGRectMakeZero();
if ([self isVertical])
{
bounds.origin.x = (_CGRectGetWidth(bounds) - trackWidth) / 2.0;
bounds.size.width = trackWidth;
}
else
{
bounds.origin.y = (_CGRectGetHeight(bounds) - trackWidth) / 2.0;
bounds.size.height = trackWidth;
}
}
return bounds;
}
- (CGPoint)constrainKnobPosition:(CGPoint)aPoint
- (CGRect)knobRectForBounds:(CGRect)bounds
{
//FIXME
aPoint.x -= _knobSize.width / 2.0;
return CPPointMake(MAX(MIN(CPRectGetWidth([self bounds]) - _knobSize.width, aPoint.x), 0.0), (CPRectGetHeight([self bounds]) - CPRectGetHeight([_knob frame])) / 2.0);
var knobSize = [self currentValueForThemeAttribute:@"knob-size"];
if (knobSize.width <= 0 || knobSize.height <= 0)
return _CGRectMakeZero();
var knobRect = _CGRectMake(0.0, 0.0, knobSize.width, knobSize.height),
trackRect = [self trackRectForBounds:bounds];
// No track, do our best to approximate a place for this thing.
if (!trackRect || _CGRectIsEmpty(trackRect))
trackRect = bounds;
if ([self hasThemeState:CPThemeStateCircular])
{
var angle = 3*PI_2 - (1.0 - [self doubleValue] - _minValue) / (_maxValue - _minValue) * PI2,
radius = CGRectGetWidth(trackRect) / 2.0 - 8.0;
knobRect.origin.x = radius * COS(angle) + CGRectGetMidX(trackRect) - 3.0;
knobRect.origin.y = radius * SIN(angle) + CGRectGetMidY(trackRect) - 2.0;
}
else if ([self isVertical])
{
knobRect.origin.x = _CGRectGetMidX(trackRect) - knobSize.width / 2.0;
knobRect.origin.y = (([self doubleValue] - _minValue) / (_maxValue - _minValue)) * (_CGRectGetHeight(trackRect) - knobSize.height);
}
else
{
knobRect.origin.x = (([self doubleValue] - _minValue) / (_maxValue - _minValue)) * (_CGRectGetWidth(trackRect) - knobSize.width);
knobRect.origin.y = _CGRectGetMidY(trackRect) - knobSize.height / 2.0;
}
return knobRect;
}
- (void)mouseUp:(CPEvent)anEvent
- (CGRect)rectForEphemeralSubviewNamed:(CPString)aName
{
[[self knob] setImage: [self knobImage]];
if (aName === "track-view")
return [self trackRectForBounds:[self bounds]];
else if (aName === "knob-view")
return [self knobRectForBounds:[self bounds]];
return [super rectForEphemeralSubviewNamed:aName];
}
- (CPView)createEphemeralSubviewNamed:(CPString)aName
{
if (aName === "track-view" || aName === "knob-view")
{
var view = [[CPView alloc] init];
[view setHitTests:NO];
return view;
}
return [super createEphemeralSubviewNamed:aName];
}
- (void)setAltIncrementValue:(float)anAltIncrementValue
{
_altIncrementValue = anAltIncrementValue;
}
- (float)altIncrementValue
{
return _altIncrementValue;
}
- (void)setFrameSize:(CGSize)aSize
{
[super setFrameSize:aSize];
[self _recalculateIsVertical];
}
- (void)_recalculateIsVertical
{
// Recalculate isVertical.
var bounds = [self bounds],
width = _CGRectGetWidth(bounds),
height = _CGRectGetHeight(bounds);
_isVertical = width < height ? 1 : (width > height ? 0 : -1);
if (_isVertical === 1)
[self setThemeState:CPThemeStateVertical];
else if (_isVertical === 0)
[self unsetThemeState:CPThemeStateVertical];
}
- (int)isVertical
{
return _isVertical;
}
- (void)layoutSubviews
{
var trackView = [self layoutEphemeralSubviewNamed:@"track-view"
positioned:CPWindowBelow
relativeToEphemeralSubviewNamed:@"knob-view"];
if (trackView)
[trackView setBackgroundColor:[self currentValueForThemeAttribute:@"track-color"]];
var knobView = [self layoutEphemeralSubviewNamed:@"knob-view"
positioned:CPWindowAbove
relativeToEphemeralSubviewNamed:@"track-view"];
if (knobView)
[knobView setBackgroundColor:[self currentValueForThemeAttribute:"knob-color"]];
}
- (BOOL)tracksMouseOutsideOfFrame
{
return YES;
}
- (float)_valueAtPoint:(CGPoint)aPoint
{
var bounds = [self bounds],
knobRect = [self knobRectForBounds:bounds],
trackRect = [self trackRectForBounds:bounds];
if ([self hasThemeState:CPThemeStateCircular])
{
var knobWidth = _CGRectGetWidth(knobRect);
trackRect.origin.x += knobWidth / 2;
trackRect.size.width -= knobWidth;
var minValue = [self minValue],
dx = aPoint.x - _CGRectGetMidX(trackRect),
dy = aPoint.y - _CGRectGetMidY(trackRect);
return MAX(0.0, MIN(1.0, 1.0 - (3 * PI_2 - ATAN2(dy, dx)) % PI2 / PI2)) * ([self maxValue] - minValue) + minValue;
}
else if ([self isVertical])
{
var knobHeight = _CGRectGetHeight(knobRect);
trackRect.origin.y += knobHeight / 2;
trackRect.size.height -= knobHeight;
var minValue = [self minValue];
return MAX(0.0, MIN(1.0, (aPoint.y - _CGRectGetMinY(trackRect)) / _CGRectGetHeight(trackRect))) * ([self maxValue] - minValue) + minValue;
}
else
{
var knobWidth = _CGRectGetWidth(knobRect);
trackRect.origin.x += knobWidth / 2;
trackRect.size.width -= knobWidth;
var minValue = [self minValue];
return MAX(0.0, MIN(1.0, (aPoint.x - _CGRectGetMinX(trackRect)) / _CGRectGetWidth(trackRect))) * ([self maxValue] - minValue) + minValue;
}
}
- (BOOL)startTrackingAt:(CGPoint)aPoint
{
var bounds = [self bounds],
knobRect = [self knobRectForBounds:_CGRectMakeCopy(bounds)];
if (_CGRectContainsPoint(knobRect, aPoint))
_dragOffset = _CGSizeMake(_CGRectGetMidX(knobRect) - aPoint.x, _CGRectGetMidY(knobRect) - aPoint.y);
else
{
var trackRect = [self trackRectForBounds:bounds];
if (trackRect && _CGRectContainsPoint(trackRect, aPoint))
{
_dragOffset = _CGSizeMakeZero();
[self setObjectValue:[self _valueAtPoint:aPoint]];
}
else
return NO;
}
[self setHighlighted:YES];
[self setNeedsLayout];
[self setNeedsDisplay:YES];
return YES;
}
- (BOOL)continueTracking:(CGPoint)lastPoint at:(CGPoint)aPoint
{
[self setObjectValue:[self _valueAtPoint:_CGPointMake(aPoint.x + _dragOffset.width, aPoint.y + _dragOffset.height)]];
return YES;
}
- (void)stopTracking:(CGPoint)lastPoint at:(CGPoint)aPoint mouseIsUp:(BOOL)mouseIsUp
{
[self setHighlighted:NO];
if ([_target respondsToSelector:@selector(sliderDidFinish:)])
[_target sliderDidFinish:self];
[self setNeedsLayout];
[self setNeedsDisplay:YES];
}
- (void)mouseDown:(CPEvent)anEvent
/*!
@ignore
shoudl we have _continuous?
*/
- (void)setContinuous:(BOOL)flag
{
[_knob setFrameOrigin:[self constrainKnobPosition:[self convertPoint:[anEvent locationInWindow] fromView:nil]]];
_value = [self valueForKnobPosition:[_knob frame].origin];
[[self knob] setImage: [self pushedKnobImage]];
[self sendAction:_action to:_target];
}
- (void)mouseDragged:(CPEvent)anEvent
{
[_knob setFrameOrigin:[self constrainKnobPosition:[self convertPoint:[anEvent locationInWindow] fromView:nil]]];
_value = [self valueForKnobPosition:[_knob frame].origin];
[self sendAction:_action to:_target];
if (flag)
_sendActionOn |= CPLeftMouseDraggedMask;
else
_sendActionOn &= ~CPLeftMouseDraggedMask;
}
@end
var CPSliderMinValueKey = @"CPSliderMinValueKey",
CPSliderMaxValueKey = @"CPSliderMaxValueKey",
CPSliderValueKey = @"CPSliderValueKey";
var CPSliderMinValueKey = "CPSliderMinValueKey",
CPSliderMaxValueKey = "CPSliderMaxValueKey",
CPSliderAltIncrValueKey = "CPSliderAltIncrValueKey";
@implementation CPSlider (CPCoding)
/*
Initializes the slider from the data in a coder.
@param aCoder the coder from which to read the data
@return the initialized slider
*/
- (id)initWithCoder:(CPCoder)aCoder
{
_minValue = [aCoder decodeDoubleForKey:CPSliderMinValueKey];
_maxValue = [aCoder decodeDoubleForKey:CPSliderMaxValueKey];
self = [super initWithCoder:aCoder];
if (self)
{
_value = [aCoder decodeDoubleForKey:CPSliderValueKey];
_minValue = [aCoder decodeDoubleForKey:CPSliderMinValueKey];
_maxValue = [aCoder decodeDoubleForKey:CPSliderMaxValueKey];
_bar = [self bar];
_knob = [self knob];
_knobSize = [[self knobImage] size];
_isVertical = [self isVertical];
[_knob setFrameOrigin:[self knobPosition]];
[self addSubview:_bar];
[self addSubview:_knob];
_altIncrementValue = [aCoder decodeDoubleForKey:CPSliderAltIncrValueKey];
[self setContinuous:YES];
[self _recalculateIsVertical];
[self setNeedsLayout];
[self setNeedsDisplay:YES];
}
return self;
}
/*
Writes out the slider's instance information to a coder.
@param aCoder the coder to which to write the data
*/
- (void)encodeWithCoder:(CPCoder)aCoder
{
var subviews = _subviews;
_subviews = [];
[super encodeWithCoder:aCoder];
_subviews = subviews;
[aCoder encodeDouble:_value forKey:CPSliderValueKey];
[aCoder encodeDouble:_minValue forKey:CPSliderMinValueKey];
[aCoder encodeDouble:_maxValue forKey:CPSliderMaxValueKey];
[aCoder encodeDouble:_altIncrementValue forKey:CPSliderAltIncrValueKey];
}
@end
@implementation CPSlider (Deprecated)
- (id)value
{
CPLog.warn("[CPSlider value] is deprecated, use doubleValue or objectValue instead.");
return [self doubleValue];
}
- (void)setValue:(id)aValue
{
CPLog.warn("[CPSlider setValue:] is deprecated, use setDoubleValue: or setObjectValue: instead.");
[self setObjectValue:aValue];
}
@end
+66 -57
View File
@@ -20,12 +20,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
import <Foundation/Foundation.j>
import <AppKit/CPView.j>
import <AppKit/CPSlider.j>
import <AppKit/CPColorPicker.j>
import <AppKit/CPColorPanel.j>
@import "CPColorPicker.j"
/*
@ignore
@@ -68,15 +63,17 @@ import <AppKit/CPColorPanel.j>
-(id)initView
{
aFrame = CPRectMake(0, 0, CPColorPickerViewWidth, CPColorPickerViewHeight);
_contentView = [[CPView alloc] initWithFrame:aFrame];
[_contentView setAutoresizingMask:CPViewWidthSizable|CPViewHeightSizable];
_rgbLabel = [[CPTextField alloc] initWithFrame: CPRectMake(0, 10, 100, 20)];
[_rgbLabel setStringValue: "RGB"];
[_rgbLabel setTextColor:[CPColor whiteColor]];
[_rgbLabel setStringValue: "Red, Green, Blue"];
[_rgbLabel setTextColor:[CPColor blackColor]];
_redLabel = [[CPTextField alloc] initWithFrame: CPRectMake(0, 35, 15, 20)];
[_redLabel setStringValue: "R"];
[_redLabel setTextColor:[CPColor whiteColor]];
[_redLabel setTextColor:[CPColor blackColor]];
_redSlider = [[CPSlider alloc] initWithFrame: CPRectMake(15, 35, aFrame.size.width - 70, 20)];
[_redSlider setMaxValue: 1.0];
@@ -92,28 +89,28 @@ import <AppKit/CPColorPanel.j>
switch(this)
{
case _redValue: [_redSlider setValue: MAX(MIN(ROUND(this.value), 255) / 255.0, 0)];
[self sliderChanged: _redSlider];
case _redValue: [_redSlider setFloatValue:MAX(MIN(ROUND(this.value), 255) / 255.0, 0)];
//[self sliderChanged: _redSlider];
break;
case _greenValue: [_greenSlider setValue: MAX(MIN(ROUND(this.value), 255) / 255.0, 0)];
[self sliderChanged: _greenSlider];
case _greenValue: [_greenSlider setFloatValue:MAX(MIN(ROUND(this.value), 255) / 255.0, 0)];
//[self sliderChanged: _greenSlider];
break;
case _blueValue: [_blueSlider setValue: MAX(MIN(ROUND(this.value), 255) / 255.0, 0)];
[self sliderChanged: _blueSlider];
case _blueValue: [_blueSlider setFloatValue:MAX(MIN(ROUND(this.value), 255) / 255.0, 0)];
//[self sliderChanged: _blueSlider];
break;
case _hueValue: [_hueSlider setValue: MAX(MIN(ROUND(this.value), 360), 0)];
[self sliderChanged: _hueSlider];
case _hueValue: [_hueSlider setFloatValue:MAX(MIN(ROUND(this.value), 360), 0)];
//[self sliderChanged: _hueSlider];
break;
case _saturationValue: [_saturationSlider setValue: MAX(MIN(ROUND(this.value), 100), 0)];
[self sliderChanged: _saturationSlider];
case _saturationValue: [_saturationSlider setFloatValue:MAX(MIN(ROUND(this.value), 100), 0)];
//[self sliderChanged: _saturationSlider];
break;
case _brightnessValue: [_brightnessSlider setValue: MAX(MIN(ROUND(this.value), 100), 0)];
[self sliderChanged: _brightnessSlider];
case _brightnessValue: [_brightnessSlider setFloatValue:MAX(MIN(ROUND(this.value), 100), 0)];
//[self sliderChanged: _brightnessSlider];
break;
}
@@ -141,8 +138,8 @@ import <AppKit/CPColorPanel.j>
_redValue = document.createElement("input");
_redValue.style.width = "40px";
_redValue.style.backgroundColor = "transparent";
_redValue.style.border = "1px solid white";
_redValue.style.color = "white";
_redValue.style.border = "1px solid black";
_redValue.style.color = "black";
_redValue.style.position = "absolute";
_redValue.style.top = "0px";
_redValue.style.left = "0px";
@@ -153,7 +150,7 @@ import <AppKit/CPColorPanel.j>
_greenLabel = [[CPTextField alloc] initWithFrame: CPRectMake(0, 58, 15, 20)];
[_greenLabel setStringValue: "G"];
[_greenLabel setTextColor:[CPColor whiteColor]];
[_greenLabel setTextColor:[CPColor blackColor]];
_greenSlider = [[CPSlider alloc] initWithFrame: CPRectMake(15, 58, aFrame.size.width - 70, 20)];
[_greenSlider setMaxValue: 1.0];
@@ -174,7 +171,7 @@ import <AppKit/CPColorPanel.j>
_blueLabel = [[CPTextField alloc] initWithFrame: CPRectMake(0, 81, 15, 20)];
[_blueLabel setStringValue: "B"];
[_blueLabel setTextColor:[CPColor whiteColor]];
[_blueLabel setTextColor:[CPColor blackColor]];
_blueSlider = [[CPSlider alloc] initWithFrame: CPRectMake(15, 81, aFrame.size.width - 70, 20)];
[_blueSlider setMaxValue: 1.0];
@@ -193,13 +190,13 @@ import <AppKit/CPColorPanel.j>
blueValue._DOMElement.appendChild(_blueValue);
[_contentView addSubview: blueValue];
_hsbLabel = [[CPTextField alloc] initWithFrame: CPRectMake(0, 120, 100, 20)];
[_hsbLabel setStringValue: "HSB"];
[_hsbLabel setTextColor:[CPColor whiteColor]];
_hsbLabel = [[CPTextField alloc] initWithFrame: CPRectMake(0, 120, 190, 20)];
[_hsbLabel setStringValue: "Hue, Saturation, Brightness"];
[_hsbLabel setTextColor:[CPColor blackColor]];
_hueLabel = [[CPTextField alloc] initWithFrame: CPRectMake(0, 145, 15, 20)];
[_hueLabel setStringValue: "H"];
[_hueLabel setTextColor:[CPColor whiteColor]];
[_hueLabel setTextColor:[CPColor blackColor]];
_hueSlider = [[CPSlider alloc] initWithFrame: CPRectMake(15, 145, aFrame.size.width - 70, 20)];
[_hueSlider setMaxValue: 359.0];
@@ -220,7 +217,7 @@ import <AppKit/CPColorPanel.j>
_saturationLabel = [[CPTextField alloc] initWithFrame: CPRectMake(0, 168, 15, 20)];
[_saturationLabel setStringValue: "S"];
[_saturationLabel setTextColor:[CPColor whiteColor]];
[_saturationLabel setTextColor:[CPColor blackColor]];
_saturationSlider = [[CPSlider alloc] initWithFrame: CPRectMake(15, 168, aFrame.size.width - 70, 20)];
[_saturationSlider setMaxValue: 100.0];
@@ -241,7 +238,7 @@ import <AppKit/CPColorPanel.j>
_brightnessLabel = [[CPTextField alloc] initWithFrame: CPRectMake(0, 191, 15, 20)];
[_brightnessLabel setStringValue: "B"];
[_brightnessLabel setTextColor:[CPColor whiteColor]];
[_brightnessLabel setTextColor:[CPColor blackColor]];
_brightnessSlider = [[CPSlider alloc] initWithFrame: CPRectMake(15, 191, aFrame.size.width - 70, 20)];
[_brightnessSlider setMaxValue: 100.0];
@@ -260,15 +257,15 @@ import <AppKit/CPColorPanel.j>
brightnessValue._DOMElement.appendChild(_brightnessValue);
[_contentView addSubview: brightnessValue];
_hexLabel = [[CPTextField alloc] initWithFrame: CPRectMake(0, 230, 100, 20)];
_hexLabel = [[CPTextField alloc] initWithFrame: CPRectMake(0, 230, 30, 20)];
[_hexLabel setStringValue: "Hex"];
[_hexLabel setTextColor:[CPColor whiteColor]];
[_hexLabel setTextColor:[CPColor blackColor]];
//hex input box
_hexValue = _redValue.cloneNode(false);
_hexValue.style.top = "255px";
_hexValue.style.top = "228px";
_hexValue.style.width = "80px";
_hexValue.style.left = "0px";
_hexValue.style.left = "35px";
_hexValue.onkeypress = function(aDOMEvent)
{
aDOMEvent = aDOMEvent || window.event;
@@ -332,25 +329,28 @@ import <AppKit/CPColorPanel.j>
-(void)sliderChanged:(id)sender
{
var newColor;
var newColor,
colorPanel = [self colorPanel],
alpha = [colorPanel opacity];
switch(sender)
{
case _hueSlider:
case _saturationSlider:
case _brightnessSlider: newColor = [CPColor colorWithHue: [_hueSlider value]
saturation: [_saturationSlider value]
brightness: [_brightnessSlider value]];
case _brightnessSlider: newColor = [CPColor colorWithHue: [_hueSlider floatValue]
saturation: [_saturationSlider floatValue]
brightness: [_brightnessSlider floatValue]
alpha: alpha];
[self updateRGBSliders: newColor];
break;
case _redSlider:
case _greenSlider:
case _blueSlider: newColor = [CPColor colorWithCalibratedRed: [_redSlider value]
green: [_greenSlider value]
blue: [_blueSlider value]
alpha: 1.0];
case _blueSlider: newColor = [CPColor colorWithCalibratedRed: [_redSlider floatValue]
green: [_greenSlider floatValue]
blue: [_blueSlider floatValue]
alpha: alpha];
[self updateHSBSliders: newColor];
break;
@@ -358,7 +358,7 @@ import <AppKit/CPColorPanel.j>
[self updateLabels];
[self updateHex: newColor];
[[self colorPanel] setColor: newColor];
[colorPanel setColor: newColor];
}
-(void)setColor:(CPColor)aColor
@@ -373,9 +373,9 @@ import <AppKit/CPColorPanel.j>
{
var hsb = [aColor hsbComponents];
[_hueSlider setValue: hsb[0]];
[_saturationSlider setValue: hsb[1]];
[_brightnessSlider setValue: hsb[2]];
[_hueSlider setFloatValue:hsb[0]];
[_saturationSlider setFloatValue:hsb[1]];
[_brightnessSlider setFloatValue:hsb[2]];
}
- (void)updateHex:(CPColor)aColor
@@ -387,21 +387,30 @@ import <AppKit/CPColorPanel.j>
{
var rgb = [aColor components];
[_redSlider setValue: rgb[0]];
[_greenSlider setValue: rgb[1]];
[_blueSlider setValue: rgb[2]];
[_redSlider setFloatValue:rgb[0]];
[_greenSlider setFloatValue:rgb[1]];
[_blueSlider setFloatValue:rgb[2]];
}
- (void)updateLabels
{
_hueValue.value = ROUND([_hueSlider value]);
_saturationValue.value = ROUND([_saturationSlider value]);
_brightnessValue.value = ROUND([_brightnessSlider value]);
_hueValue.value = ROUND([_hueSlider floatValue]);
_saturationValue.value = ROUND([_saturationSlider floatValue]);
_brightnessValue.value = ROUND([_brightnessSlider floatValue]);
_redValue.value = ROUND([_redSlider value] * 255);
_greenValue.value = ROUND([_greenSlider value] * 255);
_blueValue.value = ROUND([_blueSlider value] * 255);
_redValue.value = ROUND([_redSlider floatValue] * 255);
_greenValue.value = ROUND([_greenSlider floatValue] * 255);
_blueValue.value = ROUND([_blueSlider floatValue] * 255);
}
- (CPImage)provideNewButtonImage
{
return [[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:CPColorPicker] pathForResource:"slider_button.png"] size:CGSizeMake(32, 32)];
}
- (CPImage)provideNewAlternateButtonImage
{
return [[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:CPColorPicker] pathForResource:"slider_button_h.png"] size:CGSizeMake(32, 32)];
}
@end
+68 -24
View File
@@ -20,8 +20,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
import "CPImage.j"
import "CPView.j"
@import "CPImage.j"
@import "CPView.j"
#include "CoreGraphics/CGGeometry.h"
#include "Platform/Platform.h"
@@ -34,6 +34,10 @@ CPSplitViewWillResizeSubviewsNotification = @"CPSplitViewWillResizeSubviewsNotif
var CPSplitViewHorizontalImage = nil,
CPSplitViewVerticalImage = nil;
/*!
@ingroup appkit
*/
@implementation CPSplitView : CPView
{
id _delegate;
@@ -190,9 +194,11 @@ var CPSplitViewHorizontalImage = nil,
{
var count = [_subviews count] - 1;
if (count > 0)
while (count--)
[self drawDividerInRect:[self rectOfDividerAtIndex:count]];
while ((count--) > 0)
{
_drawingDivider = count;
[self drawDividerInRect:[self rectOfDividerAtIndex:count]];
}
}
- (void)drawDividerInRect:(CGRect)aRect
@@ -367,6 +373,7 @@ var CPSplitViewHorizontalImage = nil,
- (void)mouseDown:(CPEvent)anEvent
{
// FIXME: This should not trap events if not on a divider!
[self trackDivider:anEvent];
}
@@ -382,10 +389,12 @@ var CPSplitViewHorizontalImage = nil,
- (float)minPossiblePositionOfDividerAtIndex:(int)dividerIndex
{
var frame = [_subviews[dividerIndex - 1] frame];
if (dividerIndex > 0)
{
var frame = [_subviews[dividerIndex - 1] frame];
return frame.origin[_originComponent] + frame.size[_sizeComponent] + [self dividerThickness];
}
else
return 0;
}
@@ -412,7 +421,7 @@ var CPSplitViewHorizontalImage = nil,
var frame = [self frame],
viewA = _subviews[dividerIndex],
frameA = [viewA frame],
viewB = _subviews[dividerIndex+1],
viewB = _subviews[dividerIndex + 1],
frameB = [viewB frame];
var realPosition = MAX(MIN(position, actualMax), actualMin);
@@ -451,25 +460,60 @@ var CPSplitViewHorizontalImage = nil,
[self _postNotificationWillResize];
var frame = [self frame];
var index = 0,
count = [_subviews count],
dividerThickness = [self dividerThickness];
for (; index < count; ++index)
bounds = [self bounds],
dividerThickness = [self dividerThickness],
totalDividers = count - 1,
totalSizableSpace = 0,
nonSizableSpace = 0,
lastSizableIndex = -1,
totalSizablePanes = 0,
isVertical = [self isVertical];
for (index = 0; index < count; ++index)
{
var view = _subviews[index],
newFrame = CGRectCreateCopy(frame);
if (index + 1 == count)
newFrame.size[_sizeComponent] = frame.size[_sizeComponent] - newFrame.origin[_originComponent];
else
newFrame.size[_sizeComponent] = frame.size[_sizeComponent] * ([view frame].size[_sizeComponent] / oldSize[_sizeComponent]);
frame.origin[_originComponent] += newFrame.size[_sizeComponent] + dividerThickness;
[view setFrame:newFrame];
isSizable = isVertical ? [view autoresizingMask] & CPViewWidthSizable : [view autoresizingMask] & CPViewHeightSizable;
if (isSizable)
{
totalSizableSpace += [view frame].size[_sizeComponent];
lastSizableIndex = index;
totalSizablePanes++;
}
}
if (totalSizablePanes === count)
totalSizableSpace = 0;
var nonSizableSpace = totalSizableSpace ? bounds.size[_sizeComponent] - totalSizableSpace : 0,
ratio = (bounds.size[_sizeComponent] - totalDividers*dividerThickness - nonSizableSpace) / (oldSize[_sizeComponent]- totalDividers*dividerThickness - nonSizableSpace),
remainingFlexibleSpace = bounds.size[_sizeComponent] - oldSize[_sizeComponent];
for (index = 0; index < count; ++index)
{
var view = _subviews[index],
viewFrame = CGRectMakeCopy(bounds),
isSizable = isVertical ? [view autoresizingMask] & CPViewWidthSizable : [view autoresizingMask] & CPViewHeightSizable;
if (index + 1 == count)
viewFrame.size[_sizeComponent] = bounds.size[_sizeComponent] - viewFrame.origin[_originComponent];
else if (totalSizableSpace && isSizable && lastSizableIndex === index)
viewFrame.size[_sizeComponent] = MAX(0, ROUND([view frame].size[_sizeComponent] + remainingFlexibleSpace))
else if (isSizable || !totalSizableSpace)
{
viewFrame.size[_sizeComponent] = MAX(0, ROUND(ratio * [view frame].size[_sizeComponent]));
remainingFlexibleSpace -= (viewFrame.size[_sizeComponent] - [view frame].size[_sizeComponent]);
}
else if (totalSizableSpace && !isSizable)
viewFrame.size[_sizeComponent] = [view frame].size[_sizeComponent];
else
alert("SHOULD NEVER GET HERE");
bounds.origin[_originComponent] += viewFrame.size[_sizeComponent] + dividerThickness;
[view setFrame:viewFrame];
}
[self _postNotificationDidResize];
@@ -516,7 +560,7 @@ var CPSplitViewDelegateKey = "CPSplitViewDelegateKey",
/*
Initializes the split view by unarchiving data from <code>aCoder</code>.
@param aCoder the coder containing the archived <objj>CPSplitView</objj>.
@param aCoder the coder containing the archived CPSplitView.
*/
- (id)initWithCoder:(CPCoder)aCoder
{
+55 -5
View File
@@ -20,14 +20,18 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
import <Foundation/CPString.j>
@import <Foundation/CPString.j>
#include "CoreGraphics/CGGeometry.h"
#include "Platform/Platform.h"
var CPStringReferenceElement = nil;
var CPStringReferenceElement = nil,
CPStringDefaultFont = nil;
@implementation CPString (CPStringDrawing)
/*
/*!
Returns the string
*/
- (CPString)cssString
@@ -37,6 +41,12 @@ var CPStringReferenceElement = nil;
- (CGSize)sizeWithFont:(CPFont)aFont
{
return [self sizeWithFont:aFont inWidth:NULL];
}
- (CGSize)sizeWithFont:(CPFont)aFont inWidth:(float)aWidth
{
#if PLATFORM(DOM)
if (!CPStringReferenceElement)
{
CPStringReferenceElement = document.createElement("span");
@@ -56,15 +66,55 @@ var CPStringReferenceElement = nil;
document.getElementsByTagName("body")[0].appendChild(CPStringReferenceElement);
}
if (!aFont)
{
if (!CPStringDefaultFont)
CPStringDefaultFont = [CPFont systemFontOfSize:12.0];
aFont = CPStringDefaultFont;
}
var style = CPStringReferenceElement.style;
CPStringReferenceElement.style.font = [aFont ? aFont : [CPFont systemFontOfSize:12.0] cssString];
if (aWidth === NULL)
{
style.width = "";
style.whiteSpace = "pre";
}
else
{
style.width = ROUND(aWidth) + "px";
if (document.attachEvent)
style.wordWrap = "break-word";
else
{
style.whiteSpace = "-o-pre-wrap";
style.whiteSpace = "-pre-wrap";
style.whiteSpace = "-moz-pre-wrap";
style.whiteSpace = "pre-wrap";
}
}
style.font = [aFont cssString];
if (CPFeatureIsCompatible(CPJavascriptInnerTextFeature))
CPStringReferenceElement.innerText = self;
else if (CPFeatureIsCompatible(CPJavascriptTextContentFeature))
CPStringReferenceElement.textContent = self;
return CGSizeMake(CPStringReferenceElement.clientWidth, CPStringReferenceElement.clientHeight);
return _CGSizeMake(CPStringReferenceElement.clientWidth, CPStringReferenceElement.clientHeight);
#endif
return _CGSizeMakeZero();
}
+ (void)_resetSize
{
CPStringReferenceElement = nil;
}
@end
+90 -34
View File
@@ -20,12 +20,13 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
import "CPImageView.j"
import "CPTabViewItem.j"
import "CPView.j"
@import "CPImageView.j"
@import "CPTabViewItem.j"
@import "CPView.j"
#include "CoreGraphics/CGGeometry.h"
/*
Places tabs on top with a bezeled border.
@global
@@ -68,15 +69,18 @@ var CPTabViewDidSelectTabViewItemSelector = 1,
CPTabViewWillSelectTabViewItemSelector = 4,
CPTabViewDidChangeNumberOfTabViewItemsSelector = 8;
/*
This class represents a view that has multiple subviews (<objj>CPTabViewItem</objj>) presented as individual tabs.
Only one <objj>CPTabViewItem</objj> is shown at a time, and other <objj>CPTabViewItem</objj>s can be made visible
(one at a time) by clicking on the <objj>CPTabViewItem</objj>'s tab at the top of the tab view.
/*!
@ingroup appkit
@class CPTabView
This class represents a view that has multiple subviews (CPTabViewItem) presented as individual tabs.
Only one CPTabViewItem is shown at a time, and other CPTabViewItems can be made visible
(one at a time) by clicking on the CPTabViewItem's tab at the top of the tab view.
THe currently selected <objj>CPTabViewItem</objj> is the view that is displayed.
THe currently selected CPTabViewItem is the view that is displayed.
*/
@implementation CPTabView : CPView
{
{
CPView _labelsView;
CPView _backgroundView;
CPView _separatorView;
@@ -219,8 +223,8 @@ var CPTabViewDidSelectTabViewItemSelector = 1,
}
// Adding and Removing Tabs
/*
Adds a <objj>CPTabViewItem</objj> to the tab view.
/*!
Adds a CPTabViewItem to the tab view.
@param aTabViewItem the item to add
*/
- (void)addTabViewItem:(CPTabViewItem)aTabViewItem
@@ -228,14 +232,17 @@ var CPTabViewDidSelectTabViewItemSelector = 1,
[self insertTabViewItem:aTabViewItem atIndex:[_tabViewItems count]];
}
/*
Inserts a <objj>CPTabViewItem</objj> into the tab view
/*!
Inserts a CPTabViewItem into the tab view
at the specified index.
@param aTabViewItem the item to insert
@param anIndex the index for the item
*/
- (void)insertTabViewItem:(CPTabViewItem)aTabViewItem atIndex:(unsigned)anIndex
{
if (!_labelsView && _tabViewType == CPTopTabsBezelBorder)
[self _createBezelBorder];
[_tabViewItems insertObject:aTabViewItem atIndex:anIndex];
[_labelsView tabView:self didAddTabViewItem:aTabViewItem];
@@ -247,7 +254,7 @@ var CPTabViewDidSelectTabViewItemSelector = 1,
[_delegate tabViewDidChangeNumberOfTabViewItems:self];
}
/*
/*!
Removes the specified tab view item from the tab view.
@param aTabViewItem the item to remove
*/
@@ -262,7 +269,7 @@ var CPTabViewDidSelectTabViewItemSelector = 1,
}
// Accessing Tabs
/*
/*!
Returns the index of the specified item
@param aTabViewItem the item to find the index for
*/
@@ -271,8 +278,8 @@ var CPTabViewDidSelectTabViewItemSelector = 1,
return [_tabViewItems indexOfObjectIdenticalTo:aTabViewItem];
}
/*
Returns the index of the <objj>CPTabViewItem</objj> with the specified identifier.
/*!
Returns the index of the CPTabViewItem with the specified identifier.
@param anIdentifier the identifier of the item
*/
- (int)indexOfTabViewItemWithIdentifier:(CPString)anIdentifier
@@ -281,13 +288,13 @@ var CPTabViewDidSelectTabViewItemSelector = 1,
count = [_tabViewItems count];
for (; index < count; ++index)
if ([[_tabViewItems[index] identifier] isEqualTo:anIdentifier])
if ([[_tabViewItems[index] identifier] isEqual:anIdentifier])
return index;
return index;
}
/*
/*!
Returns the number of items in the tab view.
*/
- (unsigned)numberOfTabViewItems
@@ -295,15 +302,15 @@ var CPTabViewDidSelectTabViewItemSelector = 1,
return [_tabViewItems count];
}
/*
Returns the <objj>CPTabViewItem</objj> at the specified index.
/*!
Returns the CPTabViewItem at the specified index.
*/
- (CPTabViewItem)tabViewItemAtIndex:(unsigned)anIndex
{
return _tabViewItems[anIndex];
}
/*
/*!
Returns the array of items that backs this tab view.
*/
- (CPArray)tabViewItems
@@ -312,7 +319,7 @@ var CPTabViewDidSelectTabViewItemSelector = 1,
}
// Selecting a Tab
/*
/*!
Sets the first tab view item in the array to be displayed to the user.
@param aSender the object making this request
*/
@@ -324,7 +331,7 @@ var CPTabViewDidSelectTabViewItemSelector = 1,
[self selectTabViewItemAtIndex:0];
}
/*
/*!
Sets the last tab view item in the array to be displayed to the user.
@param aSender the object making this request
*/
@@ -336,7 +343,7 @@ var CPTabViewDidSelectTabViewItemSelector = 1,
[self selectTabViewItemAtIndex:count - 1];
}
/*
/*!
Sets the next tab item in the array to be displayed.
@param aSender the object making this request
*/
@@ -351,7 +358,7 @@ var CPTabViewDidSelectTabViewItemSelector = 1,
[self selectTabViewItemAtIndex:index + 1 % count];
}
/*
/*!
Selects the previous item in the array for display.
@param aSender the object making this request
*/
@@ -366,7 +373,7 @@ var CPTabViewDidSelectTabViewItemSelector = 1,
[self selectTabViewItemAtIndex:index == 0 ? count : index - 1];
}
/*
/*!
Displays the specified item in the tab view.
@param aTabViewItem the item to display
*/
@@ -409,7 +416,7 @@ var CPTabViewDidSelectTabViewItemSelector = 1,
[_delegate tabView:self didSelectTabViewItem:aTabViewItem];
}
/*
/*!
Selects the item at the specified index.
@param anIndex the index of the item to display.
*/
@@ -418,7 +425,7 @@ var CPTabViewDidSelectTabViewItemSelector = 1,
[self selectTabViewItem:_tabViewItems[anIndex]];
}
/*
/*!
Returns the current item being displayed.
*/
- (CPTabViewItem)selectedTabViewItem
@@ -427,7 +434,7 @@ var CPTabViewDidSelectTabViewItemSelector = 1,
}
//
/*
/*!
Sets the tab view type.
@param aTabViewType the view type
*/
@@ -441,7 +448,7 @@ var CPTabViewDidSelectTabViewItemSelector = 1,
if (_tabViewType == CPNoTabsBezelBorder || _tabViewType == CPNoTabsLineBorder || _tabViewType == CPNoTabsNoBorder)
[_labelsView removeFromSuperview];
else if (![_labelsView superview])
[self addSubview:_lablesView];
[self addSubview:_labelsView];
if (_tabViewType == CPNoTabsLineBorder || _tabViewType == CPNoTabsNoBorder)
[_backgroundView removeFromSuperview];
@@ -451,7 +458,7 @@ var CPTabViewDidSelectTabViewItemSelector = 1,
[self layoutSubviews];
}
/*
/*!
Returns the tab view type.
*/
- (CPTabViewType)tabViewType
@@ -460,7 +467,7 @@ var CPTabViewDidSelectTabViewItemSelector = 1,
}
// Determining the Size
/*
/*!
Returns the content rectangle.
*/
- (CGRect)contentRect
@@ -483,7 +490,7 @@ var CPTabViewDidSelectTabViewItemSelector = 1,
return contentRect;
}
/*
/*!
Sets the delegate for this tab view.
@param aDelegate the tab view's delegate
*/
@@ -522,6 +529,55 @@ var CPTabViewDidSelectTabViewItemSelector = 1,
@end
var CPTabViewItemsKey = "CPTabViewItemsKey",
CPTabViewSelectedItemKey = "CPTabViewSelectedItemKey",
CPTabViewTypeKey = "CPTabViewTypeKey",
CPTabViewDelegateKey = "CPTabViewDelegateKey";
@implementation CPTabView (CPCoding)
- (id)initWithCoder:(CPCoder)aCoder
{
if (self = [super initWithCoder:aCoder])
{
_tabViewType = [aCoder decodeIntForKey:CPTabViewTypeKey];
_tabViewItems = [];
// FIXME: this is somewhat hacky
[self _createBezelBorder];
var items = [aCoder decodeObjectForKey:CPTabViewItemsKey];
for (var i = 0; items && i < items.length; i++)
[self insertTabViewItem:items[i] atIndex:i];
var selected = [aCoder decodeObjectForKey:CPTabViewSelectedItemKey];
if (selected)
[self selectTabViewItem:selected];
[self setDelegate:[aCoder decodeObjectForKey:CPTabViewDelegateKey]];
}
return self;
}
- (void)encodeWithCoder:(CPCoder)aCoder
{
var actualSubviews = _subviews;
_subviews = [];
[super encodeWithCoder:aCoder];
_subviews = actualSubviews;
[aCoder encodeObject:_tabViewItems forKey:CPTabViewItemsKey];;
[aCoder encodeObject:_selectedTabViewItem forKey:CPTabViewSelectedItemKey];
[aCoder encodeInt:_tabViewType forKey:CPTabViewTypeKey];
[aCoder encodeConditionalObject:_delegate forKey:CPTabViewDelegateKey];
}
@end
var _CPTabLabelsViewBackgroundColor = nil,
_CPTabLabelsViewInsideMargin = 10.0,
_CPTabLabelsViewOutsideMargin = 15.0;
+58 -19
View File
@@ -20,9 +20,10 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
import <Foundation/CPObject.j>
@import <Foundation/CPObject.j>
@import <AppKit/CPView.j>
import <AppKit/CPView.j>
/*
The tab is currently selected.
@@ -43,9 +44,12 @@ CPBackgroundTab = 1;
*/
CPPressedTab = 2;
/*
The class representation of an item in a <objj>CPTabView</objj>. One tab view item
can be shown at a time in a <objj>CPTabView</objj>.
/*!
@ingroup appkit
@class CPTabViewItem
The class representation of an item in a CPTabView. One tab view item
can be shown at a time in a CPTabView.
*/
@implementation CPTabViewItem : CPObject
{
@@ -56,9 +60,9 @@ CPPressedTab = 2;
CPView _auxiliaryView;
}
/*
/*!
Initializes the tab view item with the specified identifier.
@return the initialized <objj>CPTabViewItem</objj>
@return the initialized CPTabViewItem
*/
- (id)initWithIdentifier:(id)anIdentifier
{
@@ -71,8 +75,8 @@ CPPressedTab = 2;
}
// Working With Labels
/*
Sets the <objj>CPTabViewItem</objj>'s label.
/*!
Sets the CPTabViewItem's label.
@param aLabel the label for the item
*/
- (void)setLabel:(CPString)aLabel
@@ -80,8 +84,8 @@ CPPressedTab = 2;
_label = aLabel;
}
/*
Returns the <objj>CPTabViewItem</objj>'s label
/*!
Returns the CPTabViewItem's label
*/
- (CPString)label
{
@@ -89,7 +93,7 @@ CPPressedTab = 2;
}
// Checking the Tab Display State
/*
/*!
Returns the tab's current state.
*/
- (CPTabState)tabState
@@ -98,7 +102,7 @@ CPPressedTab = 2;
}
// Assigning an Identifier Object
/*
/*!
Sets the item's identifier.
@param anIdentifier the new identifier for the item
*/
@@ -107,7 +111,7 @@ CPPressedTab = 2;
_identifier = anIdentifier;
}
/*
/*!
Returns the tab's identifier.
*/
- (id)identifier
@@ -116,7 +120,7 @@ CPPressedTab = 2;
}
// Assigning a View
/*
/*!
Sets the view that gets displayed in this tab.
*/
- (void)setView:(CPView)aView
@@ -124,7 +128,7 @@ CPPressedTab = 2;
_view = aView;
}
/*
/*!
Returns the tab's view.
*/
- (CPView)view
@@ -133,7 +137,7 @@ CPPressedTab = 2;
}
// Assigning an Auxiliary View
/*
/*!
Sets the tab's auxillary view.
@param anAuxillaryView the new auxillary view
*/
@@ -142,7 +146,7 @@ CPPressedTab = 2;
_auxiliaryView = anAuxiliaryView;
}
/*
/*!
Returns the tab's auxillary view
*/
- (CPView)auxiliaryView
@@ -151,7 +155,7 @@ CPPressedTab = 2;
}
// Accessing the Parent Tab View
/*
/*!
Returns the tab view that contains this item.
*/
- (CPTabView)tabView
@@ -160,3 +164,38 @@ CPPressedTab = 2;
}
@end
var CPTabViewItemIdentifierKey = "CPTabViewItemIdentifierKey",
CPTabViewItemLabelKey = "CPTabViewItemLabelKey",
CPTabViewItemViewKey = "CPTabViewItemViewKey",
CPTabViewItemAuxViewKey = "CPTabViewItemAuxViewKey";
@implementation CPTabViewItem (CPCoding)
- (id)initWithCoder:(CPCoder)aCoder
{
self = [super init];
if (self)
{
_identifier = [aCoder decodeObjectForKey:CPTabViewItemIdentifierKey];
_label = [aCoder decodeObjectForKey:CPTabViewItemLabelKey];
_view = [aCoder decodeObjectForKey:CPTabViewItemViewKey];
_auxiliaryView = [aCoder decodeObjectForKey:CPTabViewItemAuxViewKey];
}
return self;
}
- (void)encodeWithCoder:(CPCoder)aCoder
{
[aCoder encodeObject:_identifier forKey:CPTabViewItemIdentifierKey];
[aCoder encodeObject:_label forKey:CPTabViewItemLabelKey];
[aCoder encodeObject:_view forKey:CPTabViewItemViewKey];
[aCoder encodeObject:_auxiliaryView forKey:CPTabViewItemAuxViewKey];
}
@end
+226 -30
View File
@@ -20,8 +20,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import <Foundation/Foundation.j>
import <Foundation/Foundation.j>
/*
@ignore
@@ -43,16 +43,24 @@ CPTableColumnAutoresizingMask = 1;
*/
CPTableColumnUserResizingMask = 2;
/*
An <objj>CPTableColumn</objj> object mainly keeps information about the width of the column, its minimum and maximum width; whether the column can be edited or resized; and the cells used to draw the column header and the data in the column. You can change all these attributes of the column by calling the appropriate methods. Please note that the table column does not hold nor has access to the data to be displayed in the column; this data is maintained in the table view's data source.</p>
#define PurgableInfoMake(aView, aRow) { view:(aView), row:(aRow) }
#define PurgableInfoView(anInfo) ((anInfo).view)
#define PurgableInfoRow(anInfo) ((anInfo).row)
/*!
@ingroup appkit
@class CPTableColumn
An CPTableColumn object mainly keeps information about the width of the column, its minimum and maximum width; whether the column can be edited or resized; and the cells used to draw the column header and the data in the column. You can change all these attributes of the column by calling the appropriate methods. Please note that the table column does not hold nor has access to the data to be displayed in the column; this data is maintained in the table view's data source.</p>
<p>Each <objj>CPTableColumn</objj> object is identified by a <objj>CPString</objj>, called the column identifier. The reason is that, after a column has been added to a table view, the user might move the columns around, so there is a need to identify the columns regardless of its position in the table.
<p>Each CPTableColumn object is identified by a CPString, called the column identifier. The reason is that, after a column has been added to a table view, the user might move the columns around, so there is a need to identify the columns regardless of its position in the table.
@ignore
*/
@implementation CPTableColumn : CPObject
{
CPString _identifier;
CPView _headerView;
CPTableView _tableView;
@@ -61,9 +69,15 @@ CPTableColumnUserResizingMask = 2;
float _maxWidth;
unsigned _resizingMask;
CPView _dataView; // default data view for this column
Object _dataViewData; // cache of data view archives (key=data view hash, value=data view archive)
Object _dataViewForView; // mapping from view instances back to their data view prototype (key=view instance hash, value=data view)
Object _purgableInfosForDataView; // (key=data view hash, value=)
}
/*
/*!
Initializes the table column with the specified identifier.
@param anIdentifier the identifier
@return the initialized table column
@@ -74,20 +88,34 @@ CPTableColumnUserResizingMask = 2;
if (self)
{
[self _init];
_identifier = anIdentifier;
_width = 40.0;
_minWidth = 8.0;
_maxWidth = 1000.0;
// FIXME
_dataCell = [[CPTextField alloc] initWithFrame:CPRectMakeZero()];
var dataView = [[CPTextField alloc] initWithFrame:CPRectMakeZero()];
[dataView setValue:[CPColor whiteColor] forThemeAttribute:"text-color" inState:CPThemeStateHighlighted];
[self setDataView:dataView];
_headerView = [[CPTextField alloc] initWithFrame:CPRectMakeZero()];
[_headerView setBackgroundColor:[CPColor greenColor]];
}
return self;
}
/*
- (void)_init
{
_dataViewData = {};
_dataViewForView = {};
_purgableInfosForDataView = {};
}
/*!
Sets the table column's identifier
@param anIdentifier the new identifier
*/
@@ -96,7 +124,7 @@ CPTableColumnUserResizingMask = 2;
_identifier = anIdentifier;
}
/*
/*!
Returns the table column's identifier
*/
- (CPString)identifier
@@ -105,7 +133,7 @@ CPTableColumnUserResizingMask = 2;
}
// Setting the CPTableView
/*
/*!
Sets the table's view. This is called automatically by Cappuccino.
@param aTableView the new table view
*/
@@ -114,7 +142,7 @@ CPTableColumnUserResizingMask = 2;
_tableView = aTableView;
}
/*
/*!
Returns the column's table view.
*/
- (CPTableView)tableView
@@ -123,7 +151,7 @@ CPTableColumnUserResizingMask = 2;
}
// Controlling size
/*
/*!
Sets the column's width.
@param aWidth the new column width
*/
@@ -132,7 +160,7 @@ CPTableColumnUserResizingMask = 2;
_width = aWidth;
}
/*
/*!
Returns the column's width
*/
- (float)width
@@ -140,7 +168,7 @@ CPTableColumnUserResizingMask = 2;
return _width;
}
/*
/*!
Sets column's minimum width.
@param aWidth the new minimum column width
*/
@@ -150,7 +178,7 @@ CPTableColumnUserResizingMask = 2;
[self setWidth:_minWidth];
}
/*
/*!
The column's minimum width
*/
- (float)minWidth
@@ -158,7 +186,7 @@ CPTableColumnUserResizingMask = 2;
return _minWidth;
}
/*
/*!
Sets the column's maximum width.
@param aWidth the new maximum width
*/
@@ -168,7 +196,7 @@ CPTableColumnUserResizingMask = 2;
[self setWidth:_maxWidth];
}
/*
/*!
Sets the resizing mask. The mask is one of:
<pre>
CPTableColumnNoResizing;
@@ -182,7 +210,7 @@ CPTableColumnUserResizingMask;
_resizingMask = aMask;
}
/*
/*!
Returns the column's resizing mask. One of:
<pre>
CPTableColumnNoResizing;
@@ -195,7 +223,7 @@ CPTableColumnUserResizingMask;
return _resizingMask;
}
/*
/*!
Resizes the column according to the min, max and set width.
*/
- (void)sizeToFit
@@ -211,7 +239,7 @@ CPTableColumnUserResizingMask;
[self setWidth:width];
}
/*
/*!
Sets whether the column in this data is editable.
@param aFlag <code>YES</code> means the column data is editable
*/
@@ -220,7 +248,7 @@ CPTableColumnUserResizingMask;
_isEditable = aFlag;
}
/*
/*!
Returns <code>YES</code> if the column data is editable.
*/
- (BOOL)isEditable
@@ -228,16 +256,19 @@ CPTableColumnUserResizingMask;
return _isEditable;
}
/*
//Setting the column header view
/*!
Sets the view that draws the column's header.
@param aHeaderView the view that will draws the column header
*/
- (void)setHeaderView:(CPView)aHeaderView
- (void)setHeaderView:(CPView)aView
{
_headerView = aHeaderView;
_headerView = aView;
}
/*
/*!
Return the view that draws the column's header
*/
- (CPView)headerView
@@ -245,23 +276,43 @@ CPTableColumnUserResizingMask;
return _headerView;
}
/*
/*!
Sets the data cell that draws rows in this column.
*/
- (void)setDataCell:(CPCell)aDataCell
- (void)setDataCell:(CPView <CPCoding>)aView
{
_dataCell = aDataCell;
[self setDataView:aView];
}
/*
Sets the data view that draws rows in this column.
*/
- (void)setDataView:(CPView <CPCoding>)aView
{
if (_dataView)
_dataViewData[[_dataView hash]] = nil;
_dataView = aView;
_dataViewData[[aView hash]] = [CPKeyedArchiver archivedDataWithRootObject:aView];
}
/*!
Returns the data cell that draws rows in this column
*/
- (CPCell)dataCell
{
return _dataCell;
return _dataView;
}
/*
Returns the data view that draws rows in this column
*/
- (CPView)dataView
{
return [self dataCell];
}
/*!
By default returns the value from <code>dataCell</code>. This can
be overridden by a subclass to return different cells for different
rows.
@@ -269,7 +320,152 @@ CPTableColumnUserResizingMask;
*/
- (CPCell)dataCellForRow:(int)aRowIndex
{
return [self dataCell];
return [self dataView];
}
- (CPView)dataViewForRow:(int)aRowIndex
{
return [self dataCellForRow:aRowIndex];
}
/*
- (void)_markViewAsPurgable:(CPView)aView
{
var viewHash = [aView hash],
dataViewHash = [_dataViewForView[viewHash] hash];
if (!_purgableInfosForDataView[dataViewHash])
_purgableInfosForDataView[dataViewHash] = [CPDictionary dictionary];
[_purgableInfosForDataView[dataViewHash] setObject:aView forKey:viewHash];
}
*/
- (void)_markView:(CPView)aView inRow:(unsigned)aRow asPurgable:(BOOL)isPurgable
{
var viewHash = [aView hash],
dataViewHash = [_dataViewForView[viewHash] hash];
if (!_purgableInfosForDataView[dataViewHash])
{
if (!isPurgable)
return;
_purgableInfosForDataView[dataViewHash] = {};
}
if (!isPurgable) {
if (_purgableInfosForDataView[dataViewHash][viewHash])
CPLog.warn("removing unpurgable " + _purgableInfosForDataView[dataViewHash][viewHash]);
delete _purgableInfosForDataView[dataViewHash][viewHash];
}
else
_purgableInfosForDataView[dataViewHash][viewHash] = PurgableInfoMake(aView, aRow);
}
- (CPView)_newDataViewForRow:(int)aRowIndex avoidingRows:(CPRange)rows
{
var view = [self dataViewForRow:aRowIndex],
viewHash = [view hash],
purgableInfos = _purgableInfosForDataView[viewHash];
if (purgableInfos)
{
for (var key in purgableInfos)
{
var info = purgableInfos[key];
//if (!CPLocationInRange(PurgableInfoRow(info), rows))
//{
//CPLog.debug("yes, a purged view is usable, its called: " + PurgableInfoView(info));
delete purgableInfos[key];
return PurgableInfoView(info);
//}
//else
// CPLog.warn("avoiding");
}
}
// if we haven't cached an archive of the data view, do it now
if (!_dataViewData[viewHash])
_dataViewData[viewHash] = [CPKeyedArchiver archivedDataWithRootObject:view];
// unarchive the data view cache
var newView = [CPKeyedUnarchiver unarchiveObjectWithData:_dataViewData[viewHash]];
// map the new view's hash to it's data view prototype
_dataViewForView[[newView hash]] = view;
CPLog.warn("creating cell: %s", newView);
return newView;
}
- (void)_purge
{
for (var viewHash in _purgableInfosForDataView)
{
var purgableInfos = _purgableInfosForDataView[viewHash];
for (var key in purgableInfos)
{
var view = PurgableInfoView(purgableInfos[key]);
if (!view)
CPLog.info("key="+key+" view=" + view + " purgableInfos[key]="+purgableInfos[key])
else if (view._superview) {
//CPLog.error("PURGING: (removing)" + view);
//[view removeFromSuperview];
[view setHidden:YES];
}
//else
// CPLog.warn("PURGING: (already removed)" + view);
//delete purgableInfos[key];
}
}
}
@end
var CPTableColumnIdentifierKey = @"CPTableColumnIdentifierKey",
CPTableColumnHeaderViewKey = @"CPTableColumnHeaderViewKey",
CPTableColumnDataViewKey = @"CPTableColumnDataViewKey",
CPTableColumnWidthKey = @"CPTableColumnWidthKey",
CPTableColumnMinWidthKey = @"CPTableColumnMinWidthKey",
CPTableColumnMaxWidthKey = @"CPTableColumnMaxWidthKey",
CPTableColumnResizingMaskKey = @"CPTableColumnResizingMaskKey";
@implementation CPTableColumn (CPCoding)
- (id)initWithCoder:(CPCoder)aCoder
{
[self _init];
_identifier = [aCoder decodeObjectForKey:CPTableColumnIdentifierKey];
[self setHeaderView:[aCoder decodeObjectForKey:CPTableColumnHeaderViewKey]];
[self setDataView:[aCoder decodeObjectForKey:CPTableColumnDataViewKey]];
_width = [aCoder decodeFloatForKey:CPTableColumnWidthKey];
_minWidth = [aCoder decodeFloatForKey:CPTableColumnMinWidthKey];
_maxWidth = [aCoder decodeFloatForKey:CPTableColumnMaxWidthKey];
_resizingMask = [aCoder decodeBoolForKey:CPTableColumnResizingMaskKey];
return self;
}
- (void)encodeWithCoder:(CPCoder)aCoder
{
[aCoder encodeObject:_identifier forKey:CPTableColumnIdentifierKey];
[aCoder encodeObject:_headerView forKey:CPTableColumnHeaderViewKey];
[aCoder encodeObject:_dataView forKey:CPTableColumnDataViewKey];
[aCoder encodeObject:_width forKey:CPTableColumnWidthKey];
[aCoder encodeObject:_minWidth forKey:CPTableColumnMinWidthKey];
[aCoder encodeObject:_maxWidth forKey:CPTableColumnMaxWidthKey];
[aCoder encodeObject:_resizingMask forKey:CPTableColumnResizingMaskKey];
}
@end
+982 -106
View File
File diff suppressed because it is too large Load Diff
+760 -346
View File
File diff suppressed because it is too large Load Diff
+557
View File
@@ -0,0 +1,557 @@
/*
* CPTheme.j
* AppKit
*
* Created by Francisco Tolmasky.
* Copyright 2009, 280 North, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import <Foundation/CPObject.j>
@import <Foundation/CPString.j>
var CPThemesByName = { },
CPThemeDefaultTheme = nil;
/*!
@ingroup appkit
*/
@implementation CPTheme : CPObject
{
CPString _name;
CPDictionary _attributes;
}
+ (void)setDefaultTheme:(CPTheme)aTheme
{
CPThemeDefaultTheme = aTheme;
}
+ (CPTheme)defaultTheme
{
return CPThemeDefaultTheme;
}
+ (CPTheme)themeNamed:(CPString)aName
{
return CPThemesByName[aName];
}
- (id)initWithName:(CPString)aName
{
self = [super init];
if (self)
{
_name = aName;
_attributes = [CPDictionary dictionary];
CPThemesByName[_name] = self;
}
return self;
}
- (CPString)name
{
return _name;
}
- (_CPThemeAttribute)_attributeWithName:(CPString)aName forClass:(CPString)aClass
{
var attributes = [_attributes objectForKey:aClass];
if (!attributes)
return nil;
return [attributes objectForKey:aName];
}
- (void)takeThemeFromObject:(id)anObject
{
var attributes = [anObject _themeAttributeDictionary],
attributeName = nil,
attributeNames = [attributes keyEnumerator],
objectThemeClass = [[anObject class] themeClass];
while (attributeName = [attributeNames nextObject])
[self _recordAttribute:[attributes objectForKey:attributeName] forClass:objectThemeClass];
}
- (void)_recordAttribute:(_CPThemeAttribute)anAttribute forClass:(CPString)aClass
{
if (![anAttribute hasValues])
return;
var attributes = [_attributes objectForKey:aClass];
if (!attributes)
{
attributes = [CPDictionary dictionary];
[_attributes setObject:attributes forKey:aClass];
}
var name = [anAttribute name],
existingAttribute = [attributes objectForKey:name];
if (existingAttribute)
[attributes setObject:[existingAttribute attributeMergedWithAttribute:anAttribute] forKey:name];
else
[attributes setObject:anAttribute forKey:name];
}
@end
var CPThemeNameKey = @"CPThemeNameKey",
CPThemeAttributesKey = @"CPThemeAttributesKey";
@implementation CPTheme (CPCoding)
- (id)initWithCoder:(CPCoder)aCoder
{
self = [super init];
if (self)
{
_name = [aCoder decodeObjectForKey:CPThemeNameKey];
_attributes = [aCoder decodeObjectForKey:CPThemeAttributesKey];
CPThemesByName[_name] = self;
}
return self;
}
- (void)encodeWithCoder:(CPCoder)aCoder
{
[aCoder encodeObject:_name forKey:CPThemeNameKey];
[aCoder encodeObject:_attributes forKey:CPThemeAttributesKey];
}
@end
@implementation _CPThemeKeyedUnarchiver : CPKeyedUnarchiver
{
CPBundle _bundle;
}
- (id)initForReadingWithData:(CPData)data bundle:(CPBundle)aBundle
{
self = [super initForReadingWithData:data];
if (self)
_bundle = aBundle;
return self;
}
- (CPBundle)bundle
{
return _bundle;
}
- (BOOL)awakenCustomResources
{
return YES;
}
@end
var CPThemeStates = {},
CPThemeStateNames = {},
CPThemeStateCount = 0;
function CPThemeState(aStateName)
{
var state = CPThemeStates[aStateName];
if (state === undefined)
{
if (aStateName.indexOf('+') === -1)
state = 1 << CPThemeStateCount++;
else
{
var state = 0,
states = aStateName.split('+'),
count = states.length;
while (count--)
{
var stateName = states[count],
individualState = CPThemeStates[stateName];
if (individualState === undefined)
{
individualState = 1 << CPThemeStateCount++;
CPThemeStates[stateName] = individualState;
CPThemeStateNames[individualState] = stateName;
}
state |= individualState;
}
}
CPThemeStates[aStateName] = state;
CPThemeStateNames[state] = aStateName;
}
return state;
}
function CPThemeStateName(aState)
{
var name = CPThemeStateNames[aState];
if (name !== undefined)
return name;
if (!(aState & (aState - 1)))
return "";
var state = 1,
name = "";
for (; state < aState; state <<= 1)
if (aState & state)
name += (name.length === 0 ? '' : '+') + CPThemeStateNames[state];
CPThemeStateNames[aState] = name;
return name;
}
CPThemeStateNames[0] = "normal";
CPThemeStateNormal = CPThemeStates["normal"] = 0;
CPThemeStateDisabled = CPThemeState("disabled");
CPThemeStateHighlighted = CPThemeState("highlighted");
CPThemeStateSelected = CPThemeState("selected");
CPThemeStateBezeled = CPThemeState("bezeled");
CPThemeStateBordered = CPThemeState("bordered");
CPThemeStateEditable = CPThemeState("editable");
CPThemeStateEditing = CPThemeState("editing");
CPThemeStateVertical = CPThemeState("vertical");
CPThemeStateDefault = CPThemeState("default");
CPThemeStateCircular = CPThemeState("circular");
@implementation _CPThemeAttribute : CPObject
{
CPString _name;
id _defaultValue;
CPDictionary _values;
JSObject _cache;
CPThemeAttribute _parentAttribute;
}
- (id)initWithName:(CPString)aName defaultValue:(id)aDefaultValue
{
self = [super init];
if (self)
{
_cache = { };
_name = aName;
_defaultValue = aDefaultValue;
_values = [CPDictionary dictionary];
}
return self;
}
- (CPString)name
{
return _name;
}
- (id)defaultValue
{
return _defaultValue;
}
- (BOOL)hasValues
{
return [_values count] > 0;
}
- (BOOL)isTrivial
{
return ([_values count] === 1) && (Number([_values allKeys][0]) === CPThemeStateNormal);
}
- (void)setValue:(id)aValue
{
_cache = {};
if (aValue === undefined || aValue === nil)
_values = [CPDictionary dictionary];
else
_values = [CPDictionary dictionaryWithObject:aValue forKey:String(CPThemeStateNormal)];
}
- (void)setValue:(id)aValue forState:(CPThemeState)aState
{
_cache = { };
if ((aValue === undefined) || (aValue === nil))
[_values removeObjectForKey:String(aState)];
else
[_values setObject:aValue forKey:String(aState)];
}
- (id)value
{
return [self valueForState:CPThemeStateNormal];
}
- (id)valueForState:(CPThemeState)aState
{
var value = _cache[aState];
// This can be nil.
if (value !== undefined)
return value;
value = [_values objectForKey:String(aState)];
// If we don't have a value, and we have a non-normal state...
if ((value === undefined || value === nil) && aState !== CPThemeStateNormal)
{
// If this is a composite state (not a power of 2), find the closest partial subset match.
if (aState & (aState - 1))
{
var highestOneCount = 0,
states = [_values allKeys],
count = states.length;
while (count--)
{
// states[count] is a string!
var state = Number(states[count]);
// A & B = A iff A < B
if ((state & aState) === state)
{
var oneCount = cachedNumberOfOnes[state];
if (oneCount === undefined)
oneCount = numberOfOnes(state);
if (oneCount > highestOneCount)
{
highestOneCount = oneCount;
value = [_values objectForKey:String(state)];
}
}
}
}
// Still don't have a value? OK, let's use the normal value.
if (value === undefined || value === nil)
value = [_values objectForKey:String(CPThemeStateNormal)];
}
if (value === undefined || value === nil)
value = [_parentAttribute valueForState:aState];
if (value === undefined || value === nil)
value = _defaultValue;
_cache[aState] = value;
return value;
}
- (void)setParentAttribute:(CPThemeAttribute)anAttribute
{
if (_parentAttribute === anAttribute)
return;
_cache = { };
_parentAttribute = anAttribute;
}
- (CPThemeAttribute)attributeMergedWithAttribute:(_CPThemeAttribute)anAttribute
{
var mergedAttribute = [[_CPThemeAttribute alloc] initWithName:_name defaultValue:_defaultValue];
mergedAttribute._values = [_values copy];
[mergedAttribute._values addEntriesFromDictionary:anAttribute._values];
return mergedAttribute;
}
@end
@implementation _CPThemeAttribute (CPCoding)
- (id)initWithCoder:(CPCoder)aCoder
{
self = [super init];
if (self)
{
_cache = {};
_name = [aCoder decodeObjectForKey:@"name"];
_values = [CPDictionary dictionary];
if ([aCoder containsValueForKey:@"value"])
{
var state = CPThemeStateNormal;
if ([aCoder containsValueForKey:@"state"])
state = CPThemeState([aCoder decodeObjectForKey:@"state"]);
[_values setObject:[aCoder decodeObjectForKey:"value"] forKey:state];
}
else
{
var encodedValues = [aCoder decodeObjectForKey:@"values"],
keys = [encodedValues allKeys],
count = keys.length;
while (count--)
{
var key = keys[count];
[_values setObject:[encodedValues objectForKey:key] forKey:CPThemeState(key)];
}
}
}
return self;
}
- (void)encodeWithCoder:(CPCoder)aCoder
{
[aCoder encodeObject:_name forKey:@"name"];
var keys = [_values allKeys],
count = keys.length;
if (count === 1)
{
var onlyKey = keys[0];
if (Number(onlyKey) !== CPThemeStateNormal)
[aCoder encodeObject:CPThemeStateName(Number(onlyKey)) forKey:@"state"];
[aCoder encodeObject:[_values objectForKey:onlyKey] forKey:@"value"];
}
else
{
var encodedValues = [CPDictionary dictionary];
while (count--)
{
var key = keys[count];
[encodedValues setObject:[_values objectForKey:key] forKey:CPThemeStateName(Number(key))];
}
[aCoder encodeObject:encodedValues forKey:@"values"];
}
}
@end
var cachedNumberOfOnes = [ 0 /*000000*/, 1 /*000001*/, 1 /*000010*/, 2 /*000011*/, 1 /*000100*/, 2 /*000101*/, 2 /*000110*/,
3 /*000111*/, 1 /*001000*/, 2 /*001001*/, 2 /*001010*/, 3 /*001011*/, 2 /*001100*/, 3 /*001101*/,
3 /*001110*/, 4 /*001111*/, 1 /*010000*/, 2 /*010001*/, 2 /*010010*/, 3 /*010011*/, 2 /*010100*/,
3 /*010101*/, 3 /*010110*/, 4 /*010111*/, 2 /*011000*/, 3 /*011001*/, 3 /*011010*/, 4 /*011011*/,
3 /*011100*/, 4 /*011101*/, 4 /*011110*/, 5 /*011111*/, 1 /*100000*/, 2 /*100001*/, 2 /*100010*/,
3 /*100011*/, 2 /*100100*/, 3 /*100101*/, 3 /*100110*/, 4 /*100111*/, 2 /*101000*/, 3 /*101001*/,
3 /*101010*/, 4 /*101011*/, 3 /*101100*/, 4 /*101101*/, 4 /*101110*/, 5 /*101111*/, 2 /*110000*/,
3 /*110001*/, 3 /*110010*/, 4 /*110011*/, 3 /*110100*/, 4 /*110101*/, 4 /*110110*/, 5 /*110111*/,
3 /*111000*/, 4 /*111001*/, 4 /*111010*/, 5 /*111011*/, 4 /*111100*/, 5 /*111101*/, 5 /*111110*/,
6 /*111111*/ ];
var numberOfOnes = function(aNumber)
{
var count = 0,
slot = aNumber;
while (aNumber)
{
++count;
aNumber &= (aNumber - 1);
}
cachedNumberOfOnes[slot] = count;
return count;
}
numberOfOnes.displayName = "numberOfOnes";
function CPThemeAttributeEncode(aCoder, aThemeAttribute)
{
var values = aThemeAttribute._values,
count = [values count],
key = "$a" + [aThemeAttribute name];
if (count === 1)
{
var state = [values allKeys][0];
if (Number(state) === 0)
{
[aCoder encodeObject:[values objectForKey:state] forKey:key];
return YES;
}
}
if (count >= 1)
{
[aCoder encodeObject:aThemeAttribute forKey:key];
return YES;
}
return NO;
}
function CPThemeAttributeDecode(aCoder, anAttributeName, aDefaultValue, aTheme, aClass)
{
var key = "$a" + anAttributeName;
if (![aCoder containsValueForKey:key])
var attribute = [[_CPThemeAttribute alloc] initWithName:anAttributeName defaultValue:aDefaultValue];
else
{
var attribute = [aCoder decodeObjectForKey:key];
if (!attribute.isa || ![attribute isKindOfClass:[_CPThemeAttribute class]])
{
var themeAttribute = [[_CPThemeAttribute alloc] initWithName:anAttributeName defaultValue:aDefaultValue];
[themeAttribute setValue:attribute];
attribute = themeAttribute;
}
}
if (aTheme && aClass)
[attribute setParentAttribute:[aTheme _attributeWithName:anAttributeName forClass:aClass]];
return attribute;
}
+85
View File
@@ -0,0 +1,85 @@
/*
* CPThemeBlend.j
* AppKit
*
* Created by Francisco Tolmasky.
* Copyright 2009, 280 North, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import <Foundation/CPObject.j>
@import <AppKit/CPTheme.j>
@import <AppKit/_CPCibCustomResource.j>
@import <AppKit/_CPCibKeyedUnarchiver.j>
/*!
@ingroup appkit
*/
@implementation CPThemeBlend : CPObject
{
CPBundle _bundle;
CPArray _themes @accessors(readonly, getter=themes);
id _loadDelegate;
}
- (id)initWithContentsOfURL:(CPURL)aURL
{
self = [super init];
if (self)
{
_bundle = [[CPBundle alloc] initWithPath:aURL + "/Info.plist"];
}
return self;
}
- (void)loadWithDelegate:(id)aDelegate
{
_loadDelegate = aDelegate;
[_bundle loadWithDelegate:self];
}
- (void)bundleDidFinishLoading:(CPBundle)aBundle
{
var paths = [_bundle objectForInfoDictionaryKey:@"CPBundleReplacedFiles"],
index = 0,
count = paths.length,
bundlePath = [_bundle bundlePath];
while (count--)
{
var path = paths[count];
if ([path pathExtension] === "keyedtheme")
{
var unarchiver = [[_CPThemeKeyedUnarchiver alloc]
initForReadingWithData:[CPData dataWithString:objj_files[bundlePath + '/' + path].contents]
bundle:_bundle];
[unarchiver decodeObjectForKey:@"root"];
[unarchiver finishDecoding];
}
}
[_loadDelegate blendDidFinishLoading:self];
}
@end
+244 -100
View File
@@ -2,6 +2,9 @@
* CPToolbar.j
* AppKit
*
* Portions based on NSToolbar.m (11/10/2008) in Cocotron (http://www.cocotron.org/)
* Copyright (c) 2006-2007 Christopher J. W. Lloyd
*
* Created by Francisco Tolmasky.
* Copyright 2008, 280 North, Inc.
*
@@ -20,10 +23,11 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
import <Foundation/CPObject.j>
@import <Foundation/CPObject.j>
@import "CPPopUpButton.j"
@import "CPToolbarItem.j"
import "CPPopUpButton.j"
import "CPToolbarItem.j"
/*
@global
@@ -49,25 +53,15 @@ CPToolbarDisplayModeLabelOnly = 3;
var CPToolbarsByIdentifier = nil;
var CPToolbarConfigurationsByIdentifier = nil;
/* @ignore */
var _CPToolbarItemVisibilityPriorityCompare = function(lhs, rhs)
{
var lhsVisibilityPriority = [lhs visibilityPriority],
rhsVisibilityPriority = [rhs visibilityPriority];
if (lhsVisibilityPriority == rhsVisibilityPriority)
return CPOrderedSame;
/*!
@ingroup appkit
@class CPToolbar
if (lhsVisibilityPriority > rhsVisibilityPriority)
return CPOrderedAscending;
return CPOrderedDescending;
}
/*
A <objj>CPToolbar</objj> is displayed at the top of a window with multiple
A CPToolbar is displayed at the top of a window with multiple
buttons (tools) that offer the user quick access to features.
@par Delegate Methods
@delegate -(CPArray)toolbarDefaultItemIdentifiers:(CPToolbar)toolbar;
Called to obtain the toolbar's default item identifiers. Required.
@param toolbar the toolbar to obtain identifiers for
@@ -93,18 +87,21 @@ var _CPToolbarItemVisibilityPriorityCompare = function(lhs, rhs)
BOOL _showsBaselineSeparator;
BOOL _allowsUserCustomization;
BOOL _isVisible;
BOOL _needsReloadOfItems;
id _delegate;
CPView _toolbarView;
CPArray _itemIdentifiers;
CPArray _allowedItemIdentifiers;
CPDictionary _identifiedItems;
CPArray _defaultItems;
CPArray _allowedItems;
CPArray _selectableItems;
CPArray _items;
CPArray _labels;
CPArray _itemsSortedByVisibilityPriority;
CPMutableDictionary _itemIndexes;
CPView _toolbarView;
CPWindow _window;
}
/* @ignore */
@@ -117,7 +114,21 @@ var _CPToolbarItemVisibilityPriorityCompare = function(lhs, rhs)
CPToolbarConfigurationsByIdentifier = [CPDictionary dictionary];
}
/*
/* @ignore */
+ (void)_addToolbar:(CPToolbar)toolbar forIdentifier:(CPString)identifier
{
var toolbarsSharingIdentifier = [CPToolbarsByIdentifier objectForKey:identifier];
if (!toolbarsSharingIdentifier)
{
toolbarsSharingIdentifier = []
[CPToolbarsByIdentifier setObject:toolbarsSharingIdentifier forKey:identifier];
}
[toolbarsSharingIdentifier addObject:toolbar];
}
/*!
Initializes the toolbar with the specified identifier.
@param anIdentifier the identifier for the toolbar
@return the initialized toolbar
@@ -129,26 +140,18 @@ var _CPToolbarItemVisibilityPriorityCompare = function(lhs, rhs)
if (self)
{
_items = [];
_labels = [];
_identifier = anIdentifier;
_isVisible = YES;
var toolbarsSharingIdentifier = [CPToolbarsByIdentifier objectForKey:_identifier];
if (!toolbarsSharingIdentifier)
{
toolbarsSharingIdentifier = []
[CPToolbarsByIdentifier setObject:toolbarsSharingIdentifier forKey:_identifier];
}
[toolbarsSharingIdentifier addObject:self];
[CPToolbar _addToolbar:self forIdentifier:_identifier];
}
return self;
}
/*
/*!
Sets the toolbar's display mode. NOT YET IMPLEMENTED.
*/
- (void)setDisplayMode:(CPToolbarDisplayMode)aDisplayMode
@@ -156,7 +159,7 @@ var _CPToolbarItemVisibilityPriorityCompare = function(lhs, rhs)
}
/*
/*!
Returns the toolbar's identifier
*/
- (CPString)identifier
@@ -164,7 +167,7 @@ var _CPToolbarItemVisibilityPriorityCompare = function(lhs, rhs)
return _identifier;
}
/*
/*!
Returns the toolbar's delegate
*/
- (id)delegate
@@ -172,7 +175,7 @@ var _CPToolbarItemVisibilityPriorityCompare = function(lhs, rhs)
return _delegate;
}
/*
/*!
Returns <code>YES</code> if the toolbar is currently visible
*/
- (BOOL)isVisible
@@ -180,22 +183,31 @@ var _CPToolbarItemVisibilityPriorityCompare = function(lhs, rhs)
return _isVisible;
}
/*
/*!
Sets whether the toolbar should be visible.
@param aFlag <code>YES</code> makes the toolbar visible
*/
- (void)setVisible:(BOOL)aFlag
{
if (_isVisible == aFlag)
if (_isVisible === aFlag)
return;
_isVisible = aFlag;
[_window _setToolbarVisible:_isVisible];
[self _reloadToolbarItems];
[_window _noteToolbarChanged];
}
/*
- (CPWindow)_window
{
return _window;
}
- (void)_setWindow:(CPWindow)aWindow
{
_window = aWindow;
}
/*!
Sets the delegate for the toolbar.
@param aDelegate the new toolbar delegate
*/
@@ -206,10 +218,6 @@ var _CPToolbarItemVisibilityPriorityCompare = function(lhs, rhs)
_delegate = aDelegate;
// When _delegate is nil, this will be cleared out.
_itemIdentifiers = nil;
_allowedItemIdentifiers = [_delegate toolbarAllowedItemIdentifiers:self];
[self _reloadToolbarItems];
}
@@ -225,9 +233,10 @@ var _CPToolbarItemVisibilityPriorityCompare = function(lhs, rhs)
if (!_toolbarView)
{
_toolbarView = [[_CPToolbarView alloc] initWithFrame:CPRectMake(0.0, 0.0, 1200.0, 59.0)];
[_toolbarView setAutoresizingMask:CPViewWidthSizable];
[_toolbarView setToolbar:self];
[_toolbarView setAutoresizingMask:CPViewWidthSizable];
[_toolbarView reloadToolbarItems];
}
return _toolbarView;
@@ -236,22 +245,18 @@ var _CPToolbarItemVisibilityPriorityCompare = function(lhs, rhs)
/* @ignore */
- (void)_reloadToolbarItems
{
if (![_toolbarView superview] || !_delegate)
if (!_delegate)
return;
var count = [_itemIdentifiers count];
if (!count)
{
_itemIdentifiers = [[_delegate toolbarDefaultItemIdentifiers:self] mutableCopy];
count = [_itemIdentifiers count];
_itemIdentifiers = [[_delegate toolbarDefaultItemIdentifiers:self] mutableCopy];
count = [_itemIdentifiers count];
}
[[_toolbarView subviews] makeObjectsPerformSelector:@selector(removeFromSuperview)];
_items = [];
_labels = [];
var index = 0;
@@ -261,14 +266,18 @@ var _CPToolbarItemVisibilityPriorityCompare = function(lhs, rhs)
item = [CPToolbarItem _standardItemWithItemIdentifier:identifier];
if (!item)
item = [[_delegate toolbar:self itemForItemIdentifier:identifier willBeInsertedIntoToolbar:YES] copy];
item = [_delegate toolbar:self itemForItemIdentifier:identifier willBeInsertedIntoToolbar:YES];
item = [item copy];
if (item == nil)
[CPException raise:CPInvalidArgumentException
format:@"_delegate %@ returned nil toolbar item returned for identifier %@", _delegate, identifier];
reason:sprintf(@"_delegate %s returned nil toolbar item returned for identifier %s", _delegate, identifier)];
[_items addObject:item];
}
// _items = [[self _defaultToolbarItems] mutableCopy];
// Store items sorted by priority. We want items to be removed first at the end of the array,
// items to be removed last at the front.
@@ -278,7 +287,7 @@ var _CPToolbarItemVisibilityPriorityCompare = function(lhs, rhs)
[_toolbarView reloadToolbarItems];
}
/*
/*!
Returns all the items in this toolbar.
*/
- (CPArray)items
@@ -286,7 +295,7 @@ var _CPToolbarItemVisibilityPriorityCompare = function(lhs, rhs)
return _items;
}
/*
/*!
Returns all the visible items in this toolbar
*/
- (CPArray)visibleItems
@@ -294,21 +303,7 @@ var _CPToolbarItemVisibilityPriorityCompare = function(lhs, rhs)
return [_toolbarView visibleItems];
}
/*
Returns the index of the specified toolbar item
@param anItem the item to obtain the index for
*/
- (int)indexOfItem:(CPToolbarItem)anItem
{
var info = [_itemIndexes objectForKey:[anItem hash]];
if (!info)
return CPNotFound;
return info.index;
}
/*
/*!
Returns the toolbar items sorted by their <code>visibilityPriority</code>(ies).
*/
- (CPArray)itemsSortedByVisibilityPriority
@@ -316,6 +311,113 @@ var _CPToolbarItemVisibilityPriorityCompare = function(lhs, rhs)
return _itemsSortedByVisibilityPriority;
}
/* @ignore */
- (id)_itemForItemIdentifier:(CPString)identifier willBeInsertedIntoToolbar:(BOOL)toolbar
{
var item = [_identifiedItems objectForKey:identifier];
if (!item)
{
item = [CPToolbarItem _standardItemWithItemIdentifier:identifier];
if (_delegate && !item)
{
item = [[_delegate toolbar:self itemForItemIdentifier:identifier willBeInsertedIntoToolbar:toolbar] copy];
if (!item)
[CPException raise:CPInvalidArgumentException
reason:sprintf(@"_delegate %s returned nil toolbar item returned for identifier %s", _delegate, identifier)];
}
[_identifiedItems setObject:item forKey:identifier];
}
return item;
}
/* @ignore */
- (id)_itemsWithIdentifiers:(CPArray)identifiers
{
var items = [];
for (var i = 0; i < identifiers.length; i++)
[items addObject:[self _itemForItemIdentifier:identifiers[i] willBeInsertedIntoToolbar:NO]];
return items;
}
/* @ignore */
-(id)_defaultToolbarItems
{
if (!_defaultItems)
if ([_delegate respondsToSelector:@selector(toolbarDefaultItemIdentifiers:)])
_defaultItems = [self _itemsWithIdentifiers:[_delegate toolbarDefaultItemIdentifiers:self]];
return _defaultItems;
}
@end
var CPToolbarIdentifierKey = "CPToolbarIdentifierKey",
CPToolbarDisplayModeKey = "CPToolbarDisplayModeKey",
CPToolbarShowsBaselineSeparatorKey = "CPToolbarShowsBaselineSeparatorKey",
CPToolbarAllowsUserCustomizationKey = "CPToolbarAllowsUserCustomizationKey",
CPToolbarIsVisibleKey = "CPToolbarIsVisibleKey",
CPToolbarDelegateKey = "CPToolbarDelegateKey",
CPToolbarIdentifiedItemsKey = "CPToolbarIdentifiedItemsKey",
CPToolbarDefaultItemsKey = "CPToolbarDefaultItemsKey",
CPToolbarAllowedItemsKey = "CPToolbarAllowedItemsKey",
CPToolbarSelectableItemsKey = "CPToolbarSelectableItemsKey";
@implementation CPToolbar (CPCoding)
/*
Initializes the toolbar by unarchiving data from <code>aCoder</code>.
@param aCoder the coder containing the archived CPToolbar.
*/
- (id)initWithCoder:(CPCoder)aCoder
{
self = [super init];
if (self)
{
_identifier = [aCoder decodeObjectForKey:CPToolbarIdentifierKey];
_displayMode = [aCoder decodeIntForKey:CPToolbarDisplayModeKey];
_showsBaselineSeparator = [aCoder decodeBoolForKey:CPToolbarShowsBaselineSeparatorKey];
_allowsUserCustomization = [aCoder decodeBoolForKey:CPToolbarAllowsUserCustomizationKey];
_isVisible = [aCoder decodeBoolForKey:CPToolbarIsVisibleKey];
_identifiedItems = [aCoder decodeObjectForKey:CPToolbarIdentifiedItemsKey];
_defaultItems = [aCoder decodeObjectForKey:CPToolbarDefaultItemsKey];
_allowedItems = [aCoder decodeObjectForKey:CPToolbarAllowedItemsKey];
_selectableItems = [aCoder decodeObjectForKey:CPToolbarSelectableItemsKey];
_items = [];
[CPToolbar _addToolbar:self forIdentifier:_identifier];
[self setDelegate:[aCoder decodeObjectForKey:CPToolbarDelegateKey]];
}
return self;
}
/*
Archives this toolbar into the provided coder.
@param aCoder the coder to which the toolbar's instance data will be written.
*/
- (void)encodeWithCoder:(CPCoder)aCoder
{
[aCoder encodeObject:_identifier forKey:CPToolbarIdentifierKey];
[aCoder encodeInt:_displayMode forKey:CPToolbarDisplayModeKey];
[aCoder encodeBool:_showsBaselineSeparator forKey:CPToolbarShowsBaselineSeparatorKey];
[aCoder encodeBool:_allowsUserCustomization forKey:CPToolbarAllowsUserCustomizationKey];
[aCoder encodeBool:_isVisible forKey:CPToolbarIsVisibleKey];
[aCoder encodeObject:_identifiedItems forKey:CPToolbarIdentifiedItemsKey];
[aCoder encodeObject:_defaultItems forKey:CPToolbarDefaultItemsKey];
[aCoder encodeObject:_allowedItems forKey:CPToolbarAllowedItemsKey];
[aCoder encodeObject:_selectableItems forKey:CPToolbarSelectableItemsKey];
[aCoder encodeConditionalObject:_delegate forKey:CPToolbarDelegateKey];
}
@end
@@ -340,12 +442,16 @@ var _CPToolbarItemInfoMake = function(anIndex, aView, aLabel, aMinWidth)
CPIndexSet _flexibleWidthIndexes;
CPIndexSet _visibleFlexibleWidthIndexes;
CPMutableDictionary _itemInfos;
CPDictionary _itemInfos;
CPArray _visibleItems;
CPArray _invisibleItems;
CPPopUpButton _additionalItemsButton;
CPColor _labelColor;
CPColor _labelShadowColor;
float _minWidth;
}
+ (void)initialize
@@ -355,8 +461,6 @@ var _CPToolbarItemInfoMake = function(anIndex, aView, aLabel, aMinWidth)
var bundle = [CPBundle bundleForClass:self];
_CPToolbarViewBackgroundColor = [CPColor colorWithPatternImage:[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPToolbarView/_CPToolbarViewBackground.png"] size:CGSizeMake(1.0, 59.0)]];
_CPToolbarViewExtraItemsImage = [[CPImage alloc] initWithContentsOfFile: [bundle pathForResource:"_CPToolbarView/_CPToolbarViewExtraItemsImage.png"] size: CPSizeMake(10.0, 15.0)];
_CPToolbarViewExtraItemsAlternateImage = [[CPImage alloc] initWithContentsOfFile: [bundle pathForResource:"_CPToolbarView/_CPToolbarViewExtraItemsAlternateImage.png"] size:CGSizeMake(10.0, 15.0)];
@@ -370,7 +474,8 @@ var _CPToolbarItemInfoMake = function(anIndex, aView, aLabel, aMinWidth)
{
_minWidth = 0;
[self setBackgroundColor:_CPToolbarViewBackgroundColor];
_labelColor = [CPColor blackColor];
_labelShadowColor = [CPColor colorWithWhite:1.0 alpha:0.75];
_additionalItemsButton = [[CPPopUpButton alloc] initWithFrame:CGRectMake(0.0, 0.0, 10.0, 15.0) pullsDown:YES];
[_additionalItemsButton setBordered:NO];
@@ -394,6 +499,34 @@ var _CPToolbarItemInfoMake = function(anIndex, aView, aLabel, aMinWidth)
return _toolbar;
}
- (void)setLabelColor:(CPColor)aColor
{
if (_labelColor === aColor)
return;
_labelColor = aColor;
var items = [_toolbar items],
count = [items count];
while (count--)
[[self labelForItem:items[count]] setTextColor:_labelColor];
}
- (void)setLabelShadowColor:(CPColor)aColor
{
if (_labelShadowColor === aColor)
return;
_labelShadowColor = aColor;
var items = [_toolbar items],
count = [items count];
while (count--)
[[self labelForItem:items[count]] setTextShadowColor:_labelShadowColor];
}
// This *should* be roughly O(3N) = O(N)
- (void)resizeSubviewsWithOldSize:(CGSize)aSize
{
@@ -437,9 +570,10 @@ var _CPToolbarItemInfoMake = function(anIndex, aView, aLabel, aMinWidth)
[[self labelForItem:item] setHidden:YES];
}
}
// Determine all the items that have flexible width.
// Also determine the height of the toolbar.
// NOTE: height is height without top margin, and bottom margin/label.
var index = _visibleItems.length,
height = 0.0;
@@ -521,7 +655,7 @@ var _CPToolbarItemInfoMake = function(anIndex, aView, aLabel, aMinWidth)
itemWidth = MAX([self minWidthForItem:item], viewWidth),
viewHeight = MAX([item minSize].height, MIN([item maxSize].height, height));
viewHeight = CGRectGetHeight(viewFrame);
// itemWidth != viewWidth. itemWidth is MAX(size of view, size of label). If the label is larger,
// *center* the view, don't resize it.
@@ -589,16 +723,6 @@ var _CPToolbarItemInfoMake = function(anIndex, aView, aLabel, aMinWidth)
}
- (int)indexOfItem:(CPToolbarItem)anItem
{
var info = [_itemInfos objectForKey:[anItem hash]];
if (!info)
return CPNotFound;
return info.index;
}
- (CPView)viewForItem:(CPToolbarItem)anItem
{
var info = [_itemInfos objectForKey:[anItem hash]];
@@ -636,8 +760,8 @@ var _CPToolbarItemInfoMake = function(anIndex, aView, aLabel, aMinWidth)
count = subviews.length;
while (count--)
[subviews removeObjectAtIndex:count];
[subviews[count] removeFromSuperview];
// Populate with new subviews.
var items = [_toolbar items],
index = 0;
@@ -664,10 +788,12 @@ var _CPToolbarItemInfoMake = function(anIndex, aView, aLabel, aMinWidth)
[view setTarget:[item target]];
[view setAction:[item action]];
[view setTag:[item tag]];
[view setImagePosition:CPImageOnly];
}
[self addSubview:view];
// Create a lable for this item.
@@ -675,6 +801,9 @@ var _CPToolbarItemInfoMake = function(anIndex, aView, aLabel, aMinWidth)
[label setStringValue:[item label]];
[label setFont:[CPFont systemFontOfSize:11.0]];
[label setTextColor:_labelColor];
[label setTextShadowColor:_labelShadowColor];
[label setTextShadowOffset:CGSizeMake(0, 1)];
[label sizeToFit];
[label setTarget:[item target]];
@@ -698,3 +827,18 @@ var _CPToolbarItemInfoMake = function(anIndex, aView, aLabel, aMinWidth)
}
@end
/* @ignore */
var _CPToolbarItemVisibilityPriorityCompare = function(lhs, rhs)
{
var lhsVisibilityPriority = [lhs visibilityPriority],
rhsVisibilityPriority = [rhs visibilityPriority];
if (lhsVisibilityPriority == rhsVisibilityPriority)
return CPOrderedSame;
if (lhsVisibilityPriority > rhsVisibilityPriority)
return CPOrderedAscending;
return CPOrderedDescending;
}
+159 -79
View File
@@ -20,11 +20,12 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
import <Foundation/CPObject.j>
import <Foundation/CPString.j>
@import <Foundation/CPObject.j>
@import <Foundation/CPString.j>
@import <AppKit/CPImage.j>
@import <AppKit/CPView.j>
import <AppKit/CPImage.j>
import <AppKit/CPView.j>
/*
@global
@@ -55,10 +56,11 @@ CPToolbarShowFontsItemIdentifier = @"CPToolbarShowFontsItemIdentifier";
CPToolbarCustomizeToolbarItemIdentifier = @"CPToolbarCustomizeToolbarItemIdentifier";
CPToolbarPrintItemIdentifier = @"CPToolbarPrintItemIdentifier";
var _CPToolbarSeparatorItemView = nil;
/*!
@ingroup appkit
@class CPToolbarItem
/*
A representation of an item in a <objj>CPToolbar</objj>.
A representation of an item in a CPToolbar.
*/
@implementation CPToolbarItem : CPObject
{
@@ -75,7 +77,9 @@ var _CPToolbarSeparatorItemView = nil;
BOOL _isEnabled;
CPImage _image;
CPImage _alternateImage;
CPView _view;
CGSize _minSize;
CGSize _maxSize;
@@ -83,7 +87,7 @@ var _CPToolbarSeparatorItemView = nil;
}
// Creating a Toolbar Item
/*
/*!
Initializes the toolbar item with a specified identifier.
@param anItemIdentifier the item's identifier
@return the initialized toolbar item
@@ -96,6 +100,9 @@ var _CPToolbarSeparatorItemView = nil;
{
_itemIdentifier = anItemIdentifier;
_tag = 0;
_isEnabled = YES;
_minSize = CGSizeMakeZero();
_maxSize = CGSizeMakeZero();
@@ -106,7 +113,7 @@ var _CPToolbarSeparatorItemView = nil;
}
// Managing Attributes
/*
/*!
Returns the item's identifier.
*/
- (CPString)itemIdentifier
@@ -114,7 +121,7 @@ var _CPToolbarSeparatorItemView = nil;
return _itemIdentifier;
}
/*
/*!
Returns the toolbar of which this item is a part.
*/
- (CPToolbar)toolbar
@@ -122,7 +129,7 @@ var _CPToolbarSeparatorItemView = nil;
return _toolbar;
}
/*
/*!
Returns the item's label
*/
- (CPString)label
@@ -130,7 +137,7 @@ var _CPToolbarSeparatorItemView = nil;
return _label;
}
/*
/*!
Sets the item's label.
@param aLabel the new label for the item
*/
@@ -139,7 +146,7 @@ var _CPToolbarSeparatorItemView = nil;
_label = aLabel;
}
/*
/*!
Returns the palette label.
*/
- (CPString)paletteLabel
@@ -147,7 +154,7 @@ var _CPToolbarSeparatorItemView = nil;
return _paletteLabel;
}
/*
/*!
Sets the palette label
@param aPaletteLabel the new palette label
*/
@@ -156,148 +163,188 @@ var _CPToolbarSeparatorItemView = nil;
_paletteLabel = aPaletteLabel;
}
/*
/*!
Returns the item's tooltip. A tooltip pops up
next to the cursor when the user hovers over
the item with the mouse.
*/
- (CPString)toolTip
{
if ([_view respondsToSelector:@selector(toolTip)])
return [_view toolTip];
return _toolTip;
}
/*
/*!
Sets the item's tooltip. A tooltip pops up next to the cursor when the user hovers over the item with the mouse.
@param aToolTip the new item tool tip
*/
- (void)setToolTip:(CPString)aToolTip
{
if ([_view respondsToSelector:@selector(setToolTip:)])
[view setToolTip:aToolTip];
_toolTip = aToolTip;
}
/*
/*!
Returns the item's tag.
*/
- (int)tag
{
if ([_view respondsToSelector:@selector(tag)])
return [_view tag];
return _tag;
}
/*
/*!
Sets the item's tag.
@param aTag the new tag for the item
*/
- (void)setTag:(int)aTag
{
if ([_view respondsToSelector:@selector(setTag:)])
[_view setTag:aTag];
_tag = aTag;
}
/*
/*!
Returns the item's action target.
*/
- (id)target
{
if (_view)
return [_view respondsToSelector:@selector(target)] ? [_view target] : nil;
return _target;
}
/*
/*!
Sets the target of the action that is triggered when the user clicks this item. <code>nil</code> will cause
the action to be passed on to the first responder.
@param aTarget the new target
*/
- (void)setTarget:(id)aTarget
{
_target = aTarget;
if (!_view)
_target = aTarget;
else if ([_view respondsToSelector:@selector(setTarget:)])
[_view setTarget:aTarget];
}
/*
/*!
Returns the action that is triggered when the user clicks this item.
*/
- (SEL)action
{
if (_view)
return [_view respondsToSelector:@selector(action)] ? [_view action] : nil;
return _action;
}
/*
/*!
Sets the action that is triggered when the user clicks this item.
@param anAction the new action
*/
- (void)setAction:(SEL)anAction
{
_action = anAction;
if (!_view)
_action = anAction;
else if ([_view respondsToSelector:@selector(setAction:)])
[_view setAction:anAction];
}
/*
/*!
Returns <code>YES</code> if the item is enabled.
*/
- (BOOL)isEnabled
{
if ([_view respondsToSelector:@selector(isEnabled)])
return [_view isEnabled];
return _isEnabled;
}
/*
/*!
Sets whether the item is enabled.
@param aFlag <code>YES</code> enables the item
*/
- (void)setEnabled:(BOOL)aFlag
- (void)setEnabled:(BOOL)shouldBeEnabled
{
_isEnabled = aFlag;
if ([_view respondsToSelector:@selector(setEnabled:)])
[_view setEnabled:shouldBeEnabled];
_isEnabled = shouldBeEnabled;
}
/*
/*!
Returns the item's image
*/
- (CPImage)image
{
if ([_view respondsToSelector:@selector(image)])
return [_view image];
return _image;
}
/*
/*!
Sets the item's image.
@param anImage the new item image
*/
- (void)setImage:(CPImage)anImage
{
if ([_view respondsToSelector:@selector(setImage:)])
[_view setImage:anImage];
_image = anImage;
// FIXME: We can't keep assuming this.
[_view setImage:anImage];
if (!_image)
return;
var imageSize = [_image size];
if (_minSize.width == 0 && _minSize.height == 0 &&
_maxSize.width == 0 && _maxSize.height == 0 &&
(imageSize.width > 0 || imageSize.height > 0))
_maxSize.width == 0 && _maxSize.height == 0)
{
[self setMinSize:imageSize];
[self setMaxSize:imageSize];
var imageSize = [_image size];
if (imageSize.width > 0 || imageSize.height > 0)
{
[self setMinSize:imageSize];
[self setMaxSize:imageSize];
}
}
}
/*
/*!
Sets the alternate image. This image is displayed on the item when the user is clicking it.
@param anImage the new alternate image
*/
- (void)setAlternateImage:(CPImage)anImage
{
_alternateImage = anImage;
if ([_view respondsToSelector:@selector(setAlternateImage:)])
[_view setAlternateImage:anImage];
// FIXME: We can't keep assuming this.
[_view setAlternateImage:anImage];
_alternateImage = anImage;
}
/*
/*!
Returns the alternate image. This image is displayed on the item when the user is clicking it.
*/
- (CPImage)alternateImage
{
if ([_view respondsToSelector:@selector(alternateIamge)])
return [_view alternateImage];
return _alternateImage;
}
/*
/*!
Returns the item's view.
*/
- (CPView)view
@@ -305,16 +352,29 @@ var _CPToolbarSeparatorItemView = nil;
return _view;
}
/*
/*!
Sets the item's view
@param aView the item's new view
*/
- (void)setView:(CPView)aView
{
if (_view == aView)
return;
_view = aView;
if (_view)
{
// Tags get forwarded.
if (_tag !== 0 && [_view respondsToSelector:@selector(setTag:)])
[_view setTag:_tag];
_target = nil;
_action = nil;
}
}
/*
/*!
Returns the item's minimum size.
*/
- (CGSize)minSize
@@ -322,7 +382,7 @@ var _CPToolbarSeparatorItemView = nil;
return _minSize;
}
/*
/*!
Sets the item's minimum size.
@param aMinSize the new minimum size
*/
@@ -334,7 +394,7 @@ var _CPToolbarSeparatorItemView = nil;
_maxSize = CGSizeMake(MAX(_minSize.width, _maxSize.width), MAX(_minSize.height, _maxSize.height));
}
/*
/*!
Returns the item's maximum size.
*/
- (CGSize)maxSize
@@ -342,7 +402,7 @@ var _CPToolbarSeparatorItemView = nil;
return _maxSize;
}
/*
/*!
Sets the item's new maximum size.
@param aMaxSize the new maximum size
*/
@@ -355,7 +415,7 @@ var _CPToolbarSeparatorItemView = nil;
}
// Visibility Priority
/*
/*!
Returns the item's visibility priority. The value will be one of:
<pre>
CPToolbarItemVisibilityPriorityStandard
@@ -369,7 +429,7 @@ CPToolbarItemVisibilityPriorityUser
return _visibilityPriority;
}
/*
/*!
Sets the item's visibility priority. The value must be one of:
<pre>
CPToolbarItemVisibilityPriorityStandard
@@ -392,20 +452,21 @@ CPToolbarItemVisibilityPriorityUser
{
var copy = [[[self class] alloc] initWithItemIdentifier:_itemIdentifier];
[copy setLabel:_label];
[copy setPaletteLabel:_paletteLabel];
[copy setToolTip:_toolTip];
[copy setTag:_tag];
[copy setTarget:_target];
[copy setAction:_action];
[copy setEnabled:_isEnabled];
[copy setImage:_image];
[copy setAlternateImage:_alternateImage];
if (_view)
[copy setView:[CPKeyedUnarchiver unarchiveObjectWithData:[CPKeyedArchiver archivedDataWithRootObject:_view]]];
[copy setLabel:_label];
[copy setPaletteLabel:_paletteLabel];
[copy setToolTip:[self toolTip]];
[copy setTag:[self tag]];
[copy setTarget:[self target]];
[copy setAction:[self action]];
[copy setEnabled:[self isEnabled]];
[copy setImage:[self image]];
[copy setAlternateImage:[self alternateImage]];
[copy setMinSize:_minSize];
[copy setMaxSize:_maxSize];
@@ -419,8 +480,33 @@ CPToolbarItemVisibilityPriorityUser
// Standard toolbar identifiers
var _CPToolbarSeparatorItemView = nil,
_CPToolbarSpaceItemView = nil;
@implementation CPToolbarItem (Standard)
+ (CPView)_separatorItemView
{
if (!_CPToolbarSeparatorItemView)
{
_CPToolbarSeparatorItemView = [[CPView alloc] initWithFrame:CGRectMake(0.0, 0.0, 2.0, 32.0)];
sizes = {};
sizes[@"CPToolbarItemSeparator"] = [CGSizeMake(2.0, 26.0), CGSizeMake(2.0, 1.0), CGSizeMake(2.0, 26.0)];
[_CPToolbarSeparatorItemView setBackgroundColor:_CPControlThreePartImagePattern(YES, sizes, @"CPToolbarItem", @"Separator")];
}
return _CPToolbarSeparatorItemView;
}
+ (CPView)_spaceItemView
{
if (!_CPToolbarSpaceItemView)
_CPToolbarSpaceItemView = [[CPView alloc] initWithFrame:CGRectMakeZero()];
return _CPToolbarSpaceItemView;
}
/* @ignore */
+ (CPToolbarItem)_standardItemWithItemIdentifier:(CPString)anItemIdentifier
{
@@ -428,29 +514,23 @@ CPToolbarItemVisibilityPriorityUser
switch (anItemIdentifier)
{
case CPToolbarSeparatorItemIdentifier: [item setMinSize:CGSizeMake(2.0, 0.0)];
case CPToolbarSeparatorItemIdentifier: [item setView:[self _separatorItemView]];
[item setMinSize:CGSizeMake(2.0, 0.0)];
[item setMaxSize:CGSizeMake(2.0, 100000.0)];
if (!_CPToolbarSeparatorItemView)
{
_CPToolbarSeparatorItemView = [[CPView alloc] initWithFrame:CGRectMake(0.0, 0.0, 2.0, 32.0)];
sizes = {};
sizes[@"CPToolbarItemSeparator"] = [CGSizeMake(2.0, 26.0), CGSizeMake(2.0, 1.0), CGSizeMake(2.0, 26.0)];
[_CPToolbarSeparatorItemView setBackgroundColor:_CPControlThreePartImagePattern(YES, sizes, @"CPToolbarItem", @"Separator")];
}
[item setView:_CPToolbarSeparatorItemView];
return item;
case CPToolbarSpaceItemIdentifier: [item setMinSize:CGSizeMake(32.0, 32.0)];
case CPToolbarSpaceItemIdentifier: [item setView:[self _spaceItemView]];
[item setMinSize:CGSizeMake(32.0, 32.0)];
[item setMaxSize:CGSizeMake(32.0, 32.0)];
return item;
case CPToolbarFlexibleSpaceItemIdentifier: [item setMinSize:CGSizeMake(32.0, 32.0)];
case CPToolbarFlexibleSpaceItemIdentifier: [item setView:[self _spaceItemView]];
[item setMinSize:CGSizeMake(32.0, 32.0)];
[item setMaxSize:CGSizeMake(10000.0, 32.0)];
return item;
+797 -235
View File
File diff suppressed because it is too large Load Diff
+328 -87
View File
@@ -20,7 +20,10 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
import "CPView.j"
@import <AppKit/CPView.j>
#include "Platform/Platform.h"
// FIXME: implement these where possible:
/*
@@ -34,16 +37,27 @@ CPWebViewProgressEstimateChangedNotification = "CPWebViewProgressEstimateChan
CPWebViewProgressStartedNotification = "CPWebViewProgressStartedNotification";
CPWebViewProgressFinishedNotification = "CPWebViewProgressFinishedNotification";
CPWebViewScrollAppKit = 1;
CPWebViewScrollNative = 2;
// FIXME: somehow make CPWebView work with CPScrollView instead of native scrollbars (is this even possible?)
/*!
@ingroup appkit
*/
@implementation CPWebView : CPView
{
CPScrollView _scrollView;
CPView _frameView;
IFrame _iframe;
CPString _mainFrameURL;
CPArray _backwardStack;
CPArray _forwardStack;
BOOL _ignoreLoadEvent;
BOOL _ignoreLoadStart;
BOOL _ignoreLoadEnd;
id _downloadDelegate;
id _frameLoadDelegate;
@@ -52,6 +66,14 @@ CPWebViewProgressFinishedNotification = "CPWebViewProgressFinishedNoti
id _UIDelegate;
CPWebScriptObject _wso;
CPString _url;
CPString _html;
Function _loadCallback;
int _scrollMode;
CGSize _scrollSize;
}
- (id)initWithFrame:(CPRect)frameRect frameName:(CPString)frameName groupName:(CPString)groupName
@@ -67,69 +89,218 @@ CPWebViewProgressFinishedNotification = "CPWebViewProgressFinishedNoti
{
if (self = [super initWithFrame:aFrame])
{
_mainFrameURL = nil;
_backwardStack = [];
_forwardStack = [];
_ignoreLoadEvent = NO;
_mainFrameURL = nil;
_backwardStack = [];
_forwardStack = [];
_scrollMode = CPWebViewScrollNative;
_iframe = document.createElement("iframe");
_iframe.name = "iframe_" + Math.floor(Math.random()*10000);
_iframe.style.width = "100%";
_iframe.style.height = "100%";
_iframe.style.borderWidth = "0px";
var loadCallback = function() {
// HACK: this block handles the case where we don't know about loads initiated by the user clicking a link
if (!_ignoreLoadEvent)
{
// post the start load notification
[self _startedLoading];
if (_mainFrameURL)
[_backwardStack addObject:_mainFrameURL];
// FIXME: this doesn't actually get the right URL for different domains. Probably not be possible due to browser security restrictions.
_mainFrameURL = _iframe.src;
[_forwardStack removeAllObjects];
}
_ignoreLoadEvent = NO;
[self _finishedLoading]
}
if (_iframe.addEventListener)
_iframe.addEventListener("load", loadCallback, false);
else if (_iframe.attachEvent)
_iframe.attachEvent("onload", loadCallback);
_DOMElement.appendChild(_iframe);
[self _initDOMWithFrame:aFrame];
}
return self;
}
- (BOOL)drawsBackground
- (id)_initDOMWithFrame:(CPRect)aFrame
{
return _iframe.style.backgroundColor != "";
_ignoreLoadStart = YES;
_ignoreLoadEnd = YES;
_iframe = document.createElement("iframe");
_iframe.name = "iframe_" + Math.floor(Math.random()*10000);
_iframe.style.width = "100%";
_iframe.style.height = "100%";
_iframe.style.borderWidth = "0px";
[self setDrawsBackground:YES];
_loadCallback = function() {
// HACK: this block handles the case where we don't know about loads initiated by the user clicking a link
if (!_ignoreLoadStart)
{
// post the start load notification
[self _startedLoading];
if (_mainFrameURL)
[_backwardStack addObject:_mainFrameURL];
// FIXME: this doesn't actually get the right URL for different domains. Not possible due to browser security restrictions.
_mainFrameURL = _iframe.src;
_mainFrameURL = _iframe.src;
// clear the forward
[_forwardStack removeAllObjects];
}
else
_ignoreLoadStart = NO;
if (!_ignoreLoadEnd)
{
[self _finishedLoading];
}
else
_ignoreLoadEnd = NO;
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
}
if (_iframe.addEventListener)
_iframe.addEventListener("load", _loadCallback, false);
else if (_iframe.attachEvent)
_iframe.attachEvent("onload", _loadCallback);
_frameView = [[CPView alloc] initWithFrame:[self bounds]];
_scrollView = [[CPScrollView alloc] initWithFrame:[self bounds]];
[_scrollView setAutoresizingMask:CPViewWidthSizable|CPViewHeightSizable];
[_scrollView setDocumentView:_frameView];
_frameView._DOMElement.appendChild(_iframe);
[self _setScrollMode:_scrollMode];
[self addSubview:_scrollView];
}
- (void)setDrawsBackground:(BOOL)drawsBackround
{
_iframe.style.backgroundColor = drawsBackround ? "white" : "";
- (void)setFrameSize:(CPSize)aSize
{
[super setFrameSize:aSize];
[self _resizeWebFrame];
}
- (CPString)mainFrameURL
- (BOOL)_resizeWebFrame
{
return _mainFrameURL;
if (_scrollMode === CPWebViewScrollAppKit)
{
if (_scrollSize)
{
[_frameView setFrameSize:_scrollSize];
}
else
{
[_frameView setFrameSize:[_scrollView bounds].size];
// try to get the document size so we can correctly set the frame
var win = null;
try { win = [self DOMWindow]; } catch (e) {}
if (win && win.document)
{
var width = win.document.body.scrollWidth,
height = win.document.body.scrollHeight;
_iframe.setAttribute("width", width);
_iframe.setAttribute("height", height);
[_frameView setFrameSize:CGSizeMake(width, height)];
}
else
{
CPLog.warn("using default size 800*1600");
[_frameView setFrameSize:CGSizeMake(800, 1600)];
}
}
}
}
- (void)setScrollMode:(int)aScrollMode
{
if (_scrollMode == aScrollMode)
return;
[self _setScrollMode:aScrollMode];
}
- (void)_setScrollMode:(int)aScrollMode
{
_scrollMode = aScrollMode;
_ignoreLoadStart = YES;
_ignoreLoadEnd = YES;
var parent = _iframe.parentNode;
parent.removeChild(_iframe);
if (_scrollMode === CPWebViewScrollAppKit)
{
[_scrollView setHasHorizontalScroller:YES];
[_scrollView setHasVerticalScroller:YES];
_iframe.setAttribute("scrolling", "no");
}
else
{
[_scrollView setHasHorizontalScroller:NO];
[_scrollView setHasVerticalScroller:NO];
_iframe.setAttribute("scrolling", "auto");
[_frameView setFrameSize:[_scrollView bounds].size];
}
parent.appendChild(_iframe);
}
- (void)loadHTMLString:(CPString)aString
{
[self loadHTMLString:aString baseURL:nil];
}
- (void)loadHTMLString:(CPString)aString baseURL:(CPURL)URL
{
// FIXME: do something with baseURL?
[self _setScrollMode:CPWebViewScrollAppKit];
[self _startedLoading];
_ignoreLoadStart = YES;
_ignoreLoadEnd = NO;
_url = null;
_html = aString;
[self _load];
}
- (void)_loadMainFrameURL
{
[self _setScrollMode:CPWebViewScrollNative];
[self _startedLoading];
_ignoreLoadEvent = YES;
_iframe.src = _mainFrameURL;
_ignoreLoadStart = YES;
_ignoreLoadEnd = NO;
_url = _mainFrameURL;
_html = null;
[self _load];
}
- (void)_load
{
if (_url)
{
_iframe.src = _url;
}
else if (_html)
{
// clear the iframe
_iframe.src = "";
// need to give the browser a chance to reset iframe, otherwise we'll be document.write()-ing the previous document
window.setTimeout(function() {
var win = [self DOMWindow];
win.document.write(_html);
window.setTimeout(_loadCallback, 1);
}, 0);
}
}
- (void)_startedLoading
@@ -142,25 +313,27 @@ CPWebViewProgressFinishedNotification = "CPWebViewProgressFinishedNoti
- (void)_finishedLoading
{
[self _resizeWebFrame];
[[CPNotificationCenter defaultCenter] postNotificationName:CPWebViewProgressFinishedNotification object:self];
if ([_frameLoadDelegate respondsToSelector:@selector(webView:didFinishLoadForFrame:)])
[_frameLoadDelegate webView:self didFinishLoadForFrame:nil]; // FIXME: give this a frame somehow?
}
- (CPString)mainFrameURL
{
return _mainFrameURL;
}
- (void)setMainFrameURL:(CPString)URLString
{
if (_mainFrameURL)
[_backwardStack addObject:_mainFrameURL];
_mainFrameURL = URLString;
[_forwardStack removeAllObjects];
[self _loadMainFrameURL];
}
- (IBAction)takeStringURLFrom:(id)sender
{
[self setMainFrameURL:[sender stringValue]];
[self _loadMainFrameURL];
}
- (BOOL)goBack
@@ -195,16 +368,6 @@ CPWebViewProgressFinishedNotification = "CPWebViewProgressFinishedNoti
return NO;
}
- (IBAction)goBack:(id)sender
{
[self goBack];
}
- (IBAction)goForward:(id)sender
{
[self goForward];
}
- (BOOL)canGoBack
{
return (_backwardStack.length > 0);
@@ -223,17 +386,17 @@ CPWebViewProgressFinishedNotification = "CPWebViewProgressFinishedNoti
- (void)close
{
_DOMElement.removeChild(_iframe);
_iframe.parentNode.removeChild(_iframe);
}
- (Window)window
- (DOMWindow)DOMWindow
{
return (_iframe.contentDocument && _iframe.contentDocument.defaultView) || _iframe.contentWindow;
}
- (CPWebScriptObject)windowScriptObject
{
var win = [self window];
var win = [self DOMWindow];
if (!_wso || win != [_wso window])
{
if (win)
@@ -266,6 +429,60 @@ CPWebViewProgressFinishedNotification = "CPWebViewProgressFinishedNoti
return nil;
}
- (BOOL)drawsBackground
{
return _iframe.style.backgroundColor != "";
}
- (void)setDrawsBackground:(BOOL)drawsBackround
{
_iframe.style.backgroundColor = drawsBackround ? "white" : "";
}
// IBActions
- (IBAction)takeStringURLFrom:(id)sender
{
[self setMainFrameURL:[sender stringValue]];
}
- (IBAction)goBack:(id)sender
{
[self goBack];
}
- (IBAction)goForward:(id)sender
{
[self goForward];
}
- (IBAction)stopLoading:(id)sender
{
// FIXME: what to do?
}
- (IBAction)reload:(id)sender
{
[self _loadMainFrameURL];
}
- (IBAction)print:(id)sender
{
try
{
[self DOMWindow].print();
}
catch (e)
{
alert('Please click the webpage and select "Print" from the "File" menu');
}
}
// Delegates:
// FIXME: implement more delegates, though most of these will likely never work with the iframe implementation
@@ -311,26 +528,6 @@ CPWebViewProgressFinishedNotification = "CPWebViewProgressFinishedNoti
_UIDelegate = anObject;
}
- (void)loadHTMLString:(CPString)aString
{
[self loadHTMLString:aString baseURL:nil];
}
- (void)loadHTMLString:(CPString)aString baseURL:(CPURL)URL
{
// FIXME: do something with baseURL?
// clear the iframe
_iframe.src = "";
// need to give the browser a chance to reset iframe, otherwise we'll be document.write()-ing the previous document
window.setTimeout(function() {
var win = [self window];
win.document.write(aString);
}, 0);
}
@end
@@ -343,7 +540,7 @@ CPWebViewProgressFinishedNotification = "CPWebViewProgressFinishedNoti
{
if (self = [super init])
{
_window = aWindow
_window = aWindow;
}
return self;
}
@@ -376,3 +573,47 @@ CPWebViewProgressFinishedNotification = "CPWebViewProgressFinishedNoti
}
@end
@implementation CPWebView (CPCoding)
/*!
Initializes the web view from the data in a coder.
@param aCoder the coder from which to read the data
@return the initialized web view
*/
- (id)initWithCoder:(CPCoder)aCoder
{
self = [super initWithCoder:aCoder];
if (self)
{
// FIXME: encode/decode these?
_mainFrameURL = nil;
_backwardStack = [];
_forwardStack = [];
_scrollMode = CPWebViewScrollNative;
#if PLATFORM(DOM)
[self _initDOMWithFrame:[self frame]];
#endif
[self setBackgroundColor:[CPColor whiteColor]];
}
return self;
}
/*!
Writes out the web view's instance information to a coder.
@param aCoder the coder to which to write the data
*/
- (void)encodeWithCoder:(CPCoder)aCoder
{
var actualSubviews = _subviews;
_subviews = [];
[super encodeWithCoder:aCoder];
_subviews = actualSubviews;
}
@end
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,77 @@
/*
* _CPBorderlessWindowView.j
* AppKit
*
* Created by Francisco Tolmasky.
* Copyright 2008, 280 North, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "_CPWindowView.j"
var _CPToolbarViewBackgroundColor = nil;
@implementation _CPBorderlessBridgeWindowView : _CPWindowView
{
CPView _toolbarBackgroundView;
}
+ (CPColor)toolbarBackgroundColor
{
if (!_CPToolbarViewBackgroundColor)
_CPToolbarViewBackgroundColor = [CPColor colorWithPatternImage:[[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:[_CPBorderlessBridgeWindowView class]] pathForResource:@"_CPToolbarView/_CPToolbarViewBackground.png"] size:CGSizeMake(1.0, 59.0)]];
return _CPToolbarViewBackgroundColor;
}
- (void)tile
{
[super tile];
var theWindow = [self window],
bounds = [self bounds];
[[theWindow contentView] setFrame:CGRectMake(0.0, [self toolbarMaxY], CGRectGetWidth(bounds), CGRectGetHeight(bounds) - [self toolbarMaxY])];
if (![[theWindow toolbar] isVisible])
{
[_toolbarBackgroundView removeFromSuperview];
_toolbarBackgroundView = nil;
return;
}
if (!_toolbarBackgroundView)
{
_toolbarBackgroundView = [[CPView alloc] initWithFrame:CGRectMakeZero()];
[_toolbarBackgroundView setBackgroundColor:[[self class] toolbarBackgroundColor]];
[_toolbarBackgroundView setAutoresizingMask:CPViewWidthSizable];
[self addSubview:_toolbarBackgroundView positioned:CPWindowBelow relativeTo:nil];
}
var frame = CGRectMakeZero();
frame.origin = CGPointMakeCopy([self toolbarOffset]);
frame.size = [_toolbarView frame].size;
[_toolbarBackgroundView setFrame:frame];
}
@end
+29
View File
@@ -0,0 +1,29 @@
/*
* _CPBorderlessWindowView.j
* AppKit
*
* Created by Francisco Tolmasky.
* Copyright 2008, 280 North, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "_CPWindowView.j"
@implementation _CPBorderlessWindowView : _CPWindowView
{
}
@end
+214
View File
@@ -0,0 +1,214 @@
/*
* _CPHUDWindowView.j
* AppKit
*
* Created by Francisco Tolmasky.
* Copyright 2008, 280 North, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
var _CPHUDWindowViewBackgroundColor = nil,
CPHUDCloseButtonImage = nil;
var HUD_TITLEBAR_HEIGHT = 26.0;
@implementation _CPHUDWindowView : _CPWindowView
{
CPView _toolbarView;
CPTextField _titleField;
CPButton _closeButton;
}
+ (void)initialize
{
if (self != [_CPHUDWindowView class])
return;
var bundle = [CPBundle bundleForClass:self];
_CPHUDWindowViewBackgroundColor = [CPColor colorWithPatternImage:[[CPNinePartImage alloc] initWithImageSlices:
[
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPWindow/HUD/CPWindowHUDBackground0.png"] size:CPSizeMake(6.0, 78.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPWindow/HUD/CPWindowHUDBackground1.png"] size:CPSizeMake(1.0, 78.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPWindow/HUD/CPWindowHUDBackground2.png"] size:CPSizeMake(6.0, 78.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPWindow/HUD/CPWindowHUDBackground3.png"] size:CPSizeMake(6.0, 1.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPWindow/HUD/CPWindowHUDBackground4.png"] size:CPSizeMake(1.0, 1.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPWindow/HUD/CPWindowHUDBackground5.png"] size:CPSizeMake(6.0, 1.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPWindow/HUD/CPWindowHUDBackground6.png"] size:CPSizeMake(6.0, 6.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPWindow/HUD/CPWindowHUDBackground7.png"] size:CPSizeMake(6.0, 6.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPWindow/HUD/CPWindowHUDBackground8.png"] size:CPSizeMake(6.0, 6.0)]
]]];
_CPHUDWindowViewCloseImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"HUDTheme/WindowClose.png"] size:CPSizeMake(20.0, 20.0)];
_CPHUDWindowViewCloseActiveImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"HUDTheme/WindowCloseActive.png"] size:CPSizeMake(20.0, 20.0)];
}
+ (CGRect)contentRectForFrameRect:(CGRect)aFrameRect
{
var contentRect = CGRectMakeCopy(aFrameRect),
titleBarHeight = HUD_TITLEBAR_HEIGHT;
contentRect.origin.y += titleBarHeight;
contentRect.size.height -= titleBarHeight;
return contentRect;
}
+ (CGRect)frameRectForContentRect:(CGRect)aContentRect
{
var frameRect = CGRectMakeCopy(aContentRect),
titleBarHeight = HUD_TITLEBAR_HEIGHT;
frameRect.origin.y -= titleBarHeight;
frameRect.size.height += titleBarHeight;
return frameRect;
}
- (CGRect)contentRectForFrameRect:(CGRect)aFrameRect
{
var contentRect = [[self class] contentRectForFrameRect:aFrameRect];
if ([[[self window] toolbar] isVisible])
{
toolbarHeight = CGRectGetHeight([[self toolbarView] frame]);
contentRect.origin.y += toolbarHeight;
contentRect.size.height -= toolbarHeight;
}
return contentRect;
}
- (CGRect)frameRectForContentRect:(CGRect)aContentRect
{
var frameRect = [[self class] frameRectForContentRect:aContentRect];
if ([[[self window] toolbar] isVisible])
{
toolbarHeight = CGRectGetHeight([[self toolbarView] frame]);
frameRect.origin.y -= toolbarHeight;
frameRect.size.height += toolbarHeight;
}
return frameRect;
}
- (id)initWithFrame:(CPRect)aFrame styleMask:(unsigned)aStyleMask
{
self = [super initWithFrame:aFrame styleMask:aStyleMask];
if (self)
{
var bounds = [self bounds];
[self setBackgroundColor:_CPHUDWindowViewBackgroundColor];
_titleField = [[CPTextField alloc] initWithFrame:CGRectMakeZero()];
[_titleField setHitTests:NO];
[_titleField setFont:[CPFont systemFontOfSize:11.0]];
[_titleField setTextColor:[CPColor whiteColor]];
[_titleField setTextShadowColor:[CPColor blackColor]];
[_titleField setTextShadowOffset:CGSizeMake(0.0, 1.0)];
[_titleField setAutoresizingMask:CPViewWidthSizable];
// FIXME: Make this to CPLineBreakByTruncatingMiddle once it's implemented.
[_titleField setLineBreakMode:CPLineBreakByTruncatingTail];
[_titleField setAlignment:CPCenterTextAlignment];
[_titleField setStringValue:@"Untitled"];
[_titleField sizeToFit];
[_titleField setAutoresizingMask:CPViewWidthSizable];
[_titleField setStringValue:@""];
[_titleField setFrame:CGRectMake(20.0, 3.0, CGRectGetWidth([self bounds]) - 40.0, CGRectGetHeight([_titleField frame]))];
[self addSubview:_titleField];
if (_styleMask & CPClosableWindowMask)
{
var closeSize = [_CPHUDWindowViewCloseImage size];
_closeButton = [[CPButton alloc] initWithFrame:CGRectMake(4.0, 4.0, closeSize.width, closeSize.height)];
[_closeButton setBordered:NO];
[_closeButton setImage:_CPHUDWindowViewCloseImage];
[_closeButton setAlternateImage:_CPHUDWindowViewCloseActiveImage];
[self addSubview:_closeButton];
}
[self setResizeIndicatorOffset:CGSizeMake(5.0, 5.0)];
}
return self;
}
- (void)viewDidMoveToWindow
{
[_closeButton setTarget:[self window]];
[_closeButton setAction:@selector(performClose:)];
}
- (void)setTitle:(CPString)aTitle
{
[_titleField setStringValue:aTitle];
}
- (_CPToolbarView)toolbarView
{
return _toolbarView;
}
- (CPColor)toolbarLabelColor
{
return [CPColor whiteColor];
}
- (CPColor)toolbarLabelShadowColor
{
return [CPColor blackColor];
}
- (CGSize)toolbarOffset
{
return CGSizeMake(0.0, HUD_TITLEBAR_HEIGHT);
}
- (void)tile
{
[super tile];
var theWindow = [self window],
bounds = [self bounds],
width = CGRectGetWidth(bounds);
[_titleField setFrame:CGRectMake(20.0, 3.0, width - 40.0, CGRectGetHeight([_titleField frame]))];
var maxY = [self toolbarMaxY];
[[theWindow contentView] setFrameOrigin:CGPointMake(0.0, maxY, width, CGRectGetHeight(bounds) - maxY)];
}
@end
+350
View File
@@ -0,0 +1,350 @@
/*
* _CPStandardWindowView.j
* AppKit
*
* Created by Francisco Tolmasky.
* Copyright 2008, 280 North, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "_CPWindowView.j"
var GRADIENT_HEIGHT = 41.0;
var _CPTexturedWindowHeadGradientColor = nil,
_CPTexturedWindowHeadSolidColor = nil;
@implementation _CPTexturedWindowHeadView : CPView
{
CPView _gradientView;
CPView _solidView;
CPView _dividerView;
}
+ (CPColor)gradientColor
{
if (!_CPTexturedWindowHeadGradientColor)
{
var bundle = [CPBundle bundleForClass:[_CPWindowView class]];
_CPTexturedWindowHeadGradientColor = [CPColor colorWithPatternImage:[[CPThreePartImage alloc] initWithImageSlices:
[
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPWindow/Standard/CPWindowStandardTop0.png"] size:CGSizeMake(6.0, 41.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPWindow/Standard/CPWindowStandardTop1.png"] size:CGSizeMake(1.0, 41.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPWindow/Standard/CPWindowStandardTop2.png"] size:CGSizeMake(6.0, 41.0)]
]
isVertical:NO
]];
}
return _CPTexturedWindowHeadGradientColor;
}
+ (CPColor)solidColor
{
if (!_CPTexturedWindowHeadSolidColor)
_CPTexturedWindowHeadSolidColor = [CPColor colorWithCalibratedRed:182.0 / 255.0 green:182.0 / 255.0 blue:182.0 / 255.0 alpha:1.0];
return _CPTexturedWindowHeadSolidColor;
}
- (id)initWithFrame:(CGRect)aFrame
{
self = [super initWithFrame:aFrame];
if (self)
{
var theClass = [self class],
bounds = [self bounds];
_gradientView = [[CPView alloc] initWithFrame:CGRectMake(0.0, 0.0, CGRectGetWidth(bounds), GRADIENT_HEIGHT)];
[_gradientView setBackgroundColor:[theClass gradientColor]];
[self addSubview:_gradientView];
_solidView = [[CPView alloc] initWithFrame:CGRectMake(0.0, GRADIENT_HEIGHT, CGRectGetWidth(bounds), CGRectGetHeight(bounds) - GRADIENT_HEIGHT)];
[_solidView setBackgroundColor:[theClass solidColor]];
[self addSubview:_solidView];
}
return self;
}
- (void)resizeSubviewsWithOldSize:(CGSize)aSize
{
var bounds = [self bounds];
[_gradientView setFrameSize:CGSizeMake(CGRectGetWidth(bounds), GRADIENT_HEIGHT)];
[_solidView setFrameSize:CGSizeMake(CGRectGetWidth(bounds), CGRectGetHeight(bounds) - GRADIENT_HEIGHT)];
}
@end
var _CPStandardWindowViewBodyBackgroundColor = nil,
_CPStandardWindowViewDividerBackgroundColor = nil,
_CPStandardWindowViewTitleBackgroundColor = nil,
_CPStandardWindowViewCloseButtonImage = nil,
_CPStandardWindowViewCloseButtonHighlightedImage = nil;
var STANDARD_GRADIENT_HEIGHT = 41.0;
STANDARD_TITLEBAR_HEIGHT = 25.0;
@implementation _CPStandardWindowView : _CPWindowView
{
_CPTexturedWindowHeadView _headView;
CPView _dividerView;
CPView _bodyView;
CPView _toolbarView;
CPTextField _titleField;
CPButton _closeButton;
}
+ (CPColor)bodyBackgroundColor
{
if (!_CPStandardWindowViewBodyBackgroundColor)
_CPStandardWindowViewBodyBackgroundColor = [CPColor colorWithWhite:0.96 alpha:1.0];
return _CPStandardWindowViewBodyBackgroundColor;
}
+ (CPColor)dividerBackgroundColor
{
if (!_CPStandardWindowViewDividerBackgroundColor)
_CPStandardWindowViewDividerBackgroundColor = [CPColor colorWithCalibratedRed:125.0 / 255.0 green:125.0 / 255.0 blue:125.0 / 255.0 alpha:1.0];
return _CPStandardWindowViewDividerBackgroundColor;
}
+ (CPColor)titleColor
{
if (!_CPStandardWindowViewTitleBackgroundColor)
_CPStandardWindowViewTitleBackgroundColor = [CPColor colorWithCalibratedRed:44.0 / 255.0 green:44.0 / 255.0 blue:44.0 / 255.0 alpha:1.0];
return _CPStandardWindowViewTitleBackgroundColor;
}
+ (CGRect)contentRectForFrameRect:(CGRect)aFrameRect
{
var contentRect = CGRectMakeCopy(aFrameRect),
titleBarHeight = [self titleBarHeight] + 1.0;
contentRect.origin.y += titleBarHeight;
contentRect.size.height -= titleBarHeight;
return contentRect;
}
+ (CGRect)frameRectForContentRect:(CGRect)aContentRect
{
var frameRect = CGRectMakeCopy(aContentRect),
titleBarHeight = [self titleBarHeight] + 1.0;
frameRect.origin.y -= titleBarHeight;
frameRect.size.height += titleBarHeight;
return frameRect;
}
+ (float)titleBarHeight
{
return STANDARD_TITLEBAR_HEIGHT;
}
- (CGRect)contentRectForFrameRect:(CGRect)aFrameRect
{
var contentRect = [[self class] contentRectForFrameRect:aFrameRect],
theToolbar = [[self window] toolbar];
if ([theToolbar isVisible])
{
toolbarHeight = CGRectGetHeight([[theToolbar _toolbarView] frame]);
contentRect.origin.y += toolbarHeight;
contentRect.size.height -= toolbarHeight;
}
return contentRect;
}
- (CGRect)frameRectForContentRect:(CGRect)aContentRect
{
var frameRect = [[self class] frameRectForContentRect:aContentRect],
theToolbar = [[self window] toolbar];
if ([theToolbar isVisible])
{
toolbarHeight = CGRectGetHeight([[theToolbar _toolbarView] frame]);
frameRect.origin.y -= toolbarHeight;
frameRect.size.height += toolbarHeight;
}
return frameRect;
}
- (id)initWithFrame:(CPRect)aFrame styleMask:(unsigned)aStyleMask
{
self = [super initWithFrame:aFrame styleMask:aStyleMask];
if (self)
{
var theClass = [self class],
bounds = [self bounds];
_headView = [[_CPTexturedWindowHeadView alloc] initWithFrame:CGRectMake(0.0, 0.0, CGRectGetWidth(bounds), [[self class] titleBarHeight])];
[_headView setAutoresizingMask:CPViewWidthSizable];;
[_headView setHitTests:NO];
[self addSubview:_headView];
_dividerView = [[CPView alloc] initWithFrame:CGRectMake(0.0, CGRectGetMaxY([_headView frame]), CGRectGetWidth(bounds), 1.0)];
[_dividerView setAutoresizingMask:CPViewWidthSizable];
[_dividerView setBackgroundColor:[theClass dividerBackgroundColor]];
[_dividerView setHitTests:NO];
[self addSubview:_dividerView];
var y = CGRectGetMaxY([_dividerView frame]);
_bodyView = [[CPView alloc] initWithFrame:CGRectMake(0.0, y, CGRectGetWidth(bounds), CGRectGetHeight(bounds) - y)];
[_bodyView setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
[_bodyView setBackgroundColor:[theClass bodyBackgroundColor]];
[_bodyView setHitTests:NO];
[self addSubview:_bodyView];
[self setResizeIndicatorOffset:CGSizeMake(2.0, 2.0)];
_titleField = [[CPTextField alloc] initWithFrame:CGRectMakeZero()];
[_titleField setFont:[CPFont boldSystemFontOfSize:12.0]];
[_titleField setAutoresizingMask:CPViewWidthSizable];
// FIXME: Make this to CPLineBreakByTruncatingMiddle once it's implemented.
[_titleField setLineBreakMode:CPLineBreakByTruncatingTail];
[_titleField setAlignment:CPCenterTextAlignment];
[_titleField setTextShadowColor:[CPColor whiteColor]];
[_titleField setTextShadowOffset:CGSizeMake(0.0, 1.0)];
[_titleField setStringValue:@"Untitled"];
[_titleField sizeToFit];
[_titleField setAutoresizingMask:CPViewWidthSizable];
[_titleField setStringValue:@""];
[self addSubview:_titleField];
if (_styleMask & CPClosableWindowMask)
{
if (!_CPStandardWindowViewCloseButtonImage)
{
var bundle = [CPBundle bundleForClass:[CPWindow class]];
_CPStandardWindowViewCloseButtonImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPWindow/Standard/CPWindowStandardCloseButton.png"] size:CGSizeMake(16.0, 16.0)];
_CPStandardWindowViewCloseButtonHighlightedImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPWindow/Standard/CPWindowStandardCloseButtonHighlighted.png"] size:CGSizeMake(16.0, 16.0)];
}
_closeButton = [[CPButton alloc] initWithFrame:CGRectMake(8.0, 7.0, 16.0, 16.0)];
[_closeButton setBordered:NO];
[_closeButton setImage:_CPStandardWindowViewCloseButtonImage];
[_closeButton setAlternateImage:_CPStandardWindowViewCloseButtonHighlightedImage];
[self addSubview:_closeButton];
}
[self tile];
}
return self;
}
- (void)viewDidMoveToWindow
{
[_closeButton setTarget:[self window]];
[_closeButton setAction:@selector(performClose:)];
}
- (CGSize)toolbarOffset
{
return CGSizeMake(0.0, [[self class] titleBarHeight]);
}
- (void)tile
{
[super tile];
var theWindow = [self window],
bounds = [self bounds],
width = CGRectGetWidth(bounds);
[_headView setFrameSize:CGSizeMake(width, [self toolbarMaxY])];
[_dividerView setFrame:CGRectMake(0.0, CGRectGetMaxY([_headView frame]), width, 1.0)];
var dividerMaxY = CGRectGetMaxY([_dividerView frame]);
[_bodyView setFrame:CGRectMake(0.0, dividerMaxY, width, CGRectGetHeight(bounds) - dividerMaxY)];
[_titleField setFrame:CGRectMake(10.0, 3.0, width - 20.0, CGRectGetHeight([_titleField frame]))];
[[theWindow contentView] setFrameOrigin:CGPointMake(0.0, CGRectGetMaxY([_dividerView frame]))];
}
/*
- (void)setAnimatingToolbar:(BOOL)isAnimatingToolbar
{
[super setAnimatingToolbar:isAnimatingToolbar];
if ([self isAnimatingToolbar])
{
[[self toolbarView] setAutoresizingMask:CPViewHeightSizable];
[_headView setAutoresizingMask:CPViewHeightSizable];
[_dividerView setAutoresizingMask:CPViewMinYMargin];
[_bodyView setAutoresizingMask:CPViewMinYMargin];
[[[self window] contentView] setAutoresizingMask:CPViewNotSizable];
}
else
{
[[self toolbarView] setAutoresizingMask:CPViewWidthSizable];
[_headView setAutoresizingMask:CPViewWidthSizable];
[_dividerView setAutoresizingMask:CPViewWidthSizable];
[_bodyView setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
[[[self window] contentView] setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
}
}
*/
- (void)setTitle:(CPString)aTitle
{
[_titleField setStringValue:aTitle];
}
- (void)mouseDown:(CPEvent)anEvent
{
if (CGRectContainsPoint([_headView frame], [self convertPoint:[anEvent locationInWindow] fromView:nil]))
return [self trackMoveWithEvent:anEvent];
[super mouseDown:anEvent];
}
@end
+354
View File
@@ -0,0 +1,354 @@
/*
* _CPWindowView.j
* AppKit
*
* Created by Francisco Tolmasky.
* Copyright 2008, 280 North, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "CPView.j"
@import "CPImageView.j"
#include "../CoreGraphics/CGGeometry.h"
var _CPWindowViewResizeIndicatorImage = nil;
@implementation _CPWindowView : CPView
{
unsigned _styleMask;
CPImageView _resizeIndicator;
CGSize _resizeIndicatorOffset;
CPView _toolbarView;
// BOOL _isAnimatingToolbar;
CGRect _resizeFrame;
CGPoint _mouseDraggedPoint;
CGRect _cachedScreenFrame;
}
+ (void)initialize
{
if (self != [_CPWindowView class])
return;
_CPWindowViewResizeIndicatorImage = [[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:[CPWindow class]] pathForResource:@"_CPWindowView/_CPWindowViewResizeIndicator.png"] size:CGSizeMake(12.0, 12.0)];
}
+ (CGRect)contentRectForFrameRect:(CGRect)aFrameRect
{
return CGRectMakeCopy(aFrameRect);
}
+ (CGRect)frameRectForContentRect:(CGRect)aContentRect
{
return CGRectMakeCopy(aContentRect);
}
- (CGRect)contentRectForFrameRect:(CGRect)aFrameRect
{
return [[self class] contentRectForFrameRect:aFrameRect];
}
- (CGRect)frameRectForContentRect:(CGRect)aContentRect
{
return [[self class] frameRectForContentRect:aContentRect];
}
- (id)initWithFrame:(CPRect)aFrame styleMask:(unsigned)aStyleMask
{
self = [super initWithFrame:aFrame];
if (self)
{
_styleMask = aStyleMask;
_resizeIndicatorOffset = CGSizeMake(0.0, 0.0);
_toolbarOffset = CGSizeMake(0.0, 0.0);
[self setShowsResizeIndicator:!(_styleMask & CPBorderlessBridgeWindowMask) && (_styleMask & CPResizableWindowMask)];
}
return self;
}
- (void)setTitle:(CPString)aTitle
{
}
- (BOOL)acceptsFirstMouse:(CPEvent)anEvent
{
return YES;
}
- (void)mouseDown:(CPEvent)anEvent
{
var theWindow = [self window];
if ((_styleMask & CPResizableWindowMask) && _resizeIndicator)
{
// FIXME: This should be better
var frame = [_resizeIndicator frame];
if (CGRectContainsPoint(frame, [self convertPoint:[anEvent locationInWindow] fromView:nil]))
return [self trackResizeWithEvent:anEvent];
}
if ([theWindow isMovableByWindowBackground])
[self trackMoveWithEvent:anEvent];
else
[super mouseDown:anEvent];
}
- (void)trackResizeWithEvent:(CPEvent)anEvent
{
var location = [anEvent locationInWindow],
type = [anEvent type];
if (type === CPLeftMouseUp)
return;
var theWindow = [self window];
if (type === CPLeftMouseDown)
{
var frame = [theWindow frame];
_resizeFrame = CGRectMake(location.x, location.y, CGRectGetWidth(frame), CGRectGetHeight(frame));
}
else if (type === CPLeftMouseDragged)
[theWindow setFrameSize:CGSizeMake(CGRectGetWidth(_resizeFrame) + location.x - CGRectGetMinX(_resizeFrame), CGRectGetHeight(_resizeFrame) + location.y - CGRectGetMinY(_resizeFrame))];
[CPApp setTarget:self selector:@selector(trackResizeWithEvent:) forNextEventMatchingMask:CPLeftMouseDraggedMask | CPLeftMouseUpMask untilDate:nil inMode:nil dequeue:YES];
}
- (CGPoint)_pointWithinScreenFrame:(CGPoint)aPoint
{
var visibleFrame = _cachedScreenFrame;
if (!visibleFrame)
visibleFrame = [[CPDOMWindowBridge sharedDOMWindowBridge] visibleFrame];
var restrictedPoint = CGPointMake(0, 0);
restrictedPoint.x = MIN(MAX(aPoint.x, -_frame.size.width + 4.0), CGRectGetMaxX(visibleFrame) - 4.0);
restrictedPoint.y = MIN(MAX(aPoint.y, 0.0), CGRectGetMaxY(visibleFrame) - 8.0);
return restrictedPoint;
}
- (void)trackMoveWithEvent:(CPEvent)anEvent
{
var type = [anEvent type];
if (type === CPLeftMouseUp)
{
_cachedScreenFrame = nil;
return;
}
else if (type === CPLeftMouseDown)
{
_mouseDraggedPoint = [[self window] convertBaseToBridge:[anEvent locationInWindow]];
_cachedScreenFrame = [[CPDOMWindowBridge sharedDOMWindowBridge] visibleFrame];
}
else if (type === CPLeftMouseDragged)
{
var theWindow = [self window],
frame = [theWindow frame],
location = [theWindow convertBaseToBridge:[anEvent locationInWindow]],
origin = [self _pointWithinScreenFrame:CGPointMake(_CGRectGetMinX(frame) + (location.x - _mouseDraggedPoint.x),
_CGRectGetMinY(frame) + (location.y - _mouseDraggedPoint.y))];
[theWindow setFrameOrigin:origin];
_mouseDraggedPoint = [self _pointWithinScreenFrame:location];
}
[CPApp setTarget:self selector:@selector(trackMoveWithEvent:) forNextEventMatchingMask:CPLeftMouseDraggedMask | CPLeftMouseUpMask untilDate:nil inMode:nil dequeue:YES];
}
- (void)setShowsResizeIndicator:(BOOL)shouldShowResizeIndicator
{
if (shouldShowResizeIndicator)
{
var size = [_CPWindowViewResizeIndicatorImage size],
boundsSize = [self frame].size;
_resizeIndicator = [[CPImageView alloc] initWithFrame:CGRectMake(boundsSize.width - size.width - _resizeIndicatorOffset.width, boundsSize.height - size.height - _resizeIndicatorOffset.height, size.width, size.height)];
[_resizeIndicator setImage:_CPWindowViewResizeIndicatorImage];
[_resizeIndicator setAutoresizingMask:CPViewMinXMargin | CPViewMinYMargin];
[self addSubview:_resizeIndicator];
}
else
{
[_resizeIndicator removeFromSuperview];
_resizeIndicator = nil;
}
}
- (CPImage)showsResizeIndicator
{
return _resizeIndicator !== nil;
}
- (void)setResizeIndicatorOffset:(CGSize)anOffset
{
if (CGSizeEqualToSize(_resizeIndicatorOffset, anOffset))
return;
_resizeIndicatorOffset = anOffset;
if (!_resizeIndicator)
return;
var size = [_resizeIndicator frame].size,
boundsSize = [self frame].size;
[_resizeIndicator setFrameOrigin:CGPointMake(boundsSize.width - size.width - anOffset.width, boundsSize.height - size.height - anOffset.height)];
}
- (CGSize)resizeIndicatorOffset
{
return _resizeIndicatorOffset;
}
- (void)windowDidChangeDocumentEdited
{
}
- (void)windowDidChangeDocumentSaving
{
}
- (BOOL)showsToolbar
{
return YES;
}
- (CGSize)toolbarOffset
{
return CGSizeMakeZero();
}
- (CPColor)toolbarLabelColor
{
return [CPColor blackColor];
}
- (float)toolbarMaxY
{
if (!_toolbarView || [_toolbarView isHidden])
return [self toolbarOffset].height;
return CGRectGetMaxY([_toolbarView frame]);
}
- (_CPToolbarView)toolbarView
{
return _toolbarView;
}
- (void)tile
{
var theWindow = [self window],
bounds = [self bounds],
width = CGRectGetWidth(bounds);
if ([[theWindow toolbar] isVisible])
{
var toolbarView = [self toolbarView],
toolbarOffset = [self toolbarOffset];
[toolbarView setFrame:CGRectMake(toolbarOffset.width, toolbarOffset.height, width, CGRectGetHeight([toolbarView frame]))];
}
if ([self showsResizeIndicator])
{
var size = [_resizeIndicator frame].size,
boundsSize = [self bounds].size;
[_resizeIndicator setFrameOrigin:CGPointMake(boundsSize.width - size.width - _resizeIndicatorOffset.width, boundsSize.height - size.height - _resizeIndicatorOffset.height)];
}
}
- (void)noteToolbarChanged
{
var theWindow = [self window],
toolbar = [theWindow toolbar],
toolbarView = [toolbar _toolbarView];
if (_toolbarView !== toolbarView)
{
[_toolbarView removeFromSuperview];
if (toolbarView)
{
[toolbarView removeFromSuperview];
[toolbarView setLabelColor:[self toolbarLabelColor]];
if ([self respondsToSelector:@selector(toolbarLabelShadowColor)])
[toolbarView setLabelShadowColor:[self toolbarLabelShadowColor]];
[self addSubview:toolbarView];
}
_toolbarView = toolbarView;
}
[toolbarView setHidden:![self showsToolbar] || ![toolbar isVisible]];
if (theWindow)
{
var contentRect = [self convertRect:[[theWindow contentView] frame] toView:nil];
contentRect.origin = [theWindow convertBaseToBridge:contentRect.origin];
[self setAutoresizesSubviews:NO];
[theWindow setFrame:[theWindow frameRectForContentRect:contentRect]];
[self setAutoresizesSubviews:YES];
}
[self tile];
}
/*
- (void)setAnimatingToolbar:(BOOL)isAnimatingToolbar
{
_isAnimatingToolbar = isAnimatingToolbar;
}
- (BOOL)isAnimatingToolbar
{
return _isAnimatingToolbar;
}
*/
- (void)didAddSubview:(CPView)aView
{
if (!_resizeIndicator || aView === _resizeIndicator)
return;
[self addSubview:_resizeIndicator];
}
@end
+29 -25
View File
@@ -20,20 +20,24 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
import <Foundation/CPObject.j>
import <Foundation/CPString.j>
@import <Foundation/CPObject.j>
@import <Foundation/CPString.j>
import "CPResponder.j"
import "CPWindow.j"
import "CPDocument.j"
@import "CPResponder.j"
@import "CPWindow.j"
@import "CPDocument.j"
#include "Platform/Platform.h"
/*
An instance of a <objj>CPWindowController</objj> manages a <objj>CPWindow</objj>. It has methods
/*!
@ingroup appkit
@class CPWindowController
An instance of a CPWindowController manages a CPWindow. It has methods
that get called when the window is loading, and after the window has loaded. In the
Model-View-Controller method of program design, the <objj>CPWindowController</objj> would be
considered the 'Controller' and the <objj>CPWindow</objj> the 'Model.'
Model-View-Controller method of program design, the CPWindowController would be
considered the 'Controller' and the CPWindow the 'Model.'
*/
@implementation CPWindowController : CPResponder
{
@@ -43,7 +47,7 @@ import "CPDocument.j"
CPString _windowCibName;
}
/*
/*!
Initializes the controller with a window.
@param aWindow the window to control
@return the initialzed window controller
@@ -62,7 +66,7 @@ import "CPDocument.j"
return self;
}
/*
/*!
Initializes the controller with a Capppuccino Interface Builder name.
@param aWindowCibName the cib name of the window to control
@return the initialized window controller
@@ -72,7 +76,7 @@ import "CPDocument.j"
return [self initWithWindowCibName:aWindowCibName owner:self];
}
/*
/*!
Initializes the controller with a cafe name.
@param aWindowCibName the cib name of the window to control
@param anOwner the owner of the cib file
@@ -93,7 +97,7 @@ import "CPDocument.j"
return self;
}
/*
/*!
Loads the window
*/
- (void)loadWindow
@@ -105,7 +109,7 @@ import "CPDocument.j"
[self windowDidLoad];
}
/*
/*!
Shows the window.
@param aSender the object requesting the show
*/
@@ -119,16 +123,16 @@ import "CPDocument.j"
[theWindow makeKeyAndOrderFront:aSender];
}
/*
/*!
Returns <code>YES</code> if the window has been loaded. Specifically,
if <objj>loadWindow</objj> has been called.
if loadWindow has been called.
*/
- (BOOL)isWindowLoaded
{
return _window;
}
/*
/*!
Returns the window this object controls.
*/
- (CPWindow)window
@@ -139,7 +143,7 @@ import "CPDocument.j"
return _window;
}
/*
/*!
Sets the window to be controlled.
@param aWindow the new window to control
*/
@@ -151,7 +155,7 @@ import "CPDocument.j"
[_window setNextResponder:self];
}
/*
/*!
The method notifies the controller that it's window has loaded.
*/
- (void)windowDidLoad
@@ -161,7 +165,7 @@ import "CPDocument.j"
[self synchronizeWindowTitleWithDocumentName];
}
/*
/*!
The method notifies the controller that it's window is about to load.
*/
- (void)windowWillLoad
@@ -169,7 +173,7 @@ import "CPDocument.j"
[_document windowControllerWillLoadNib:self];
}
/*
/*!
Sets the document that is inside the controlled window.
@param aDocument the document in the controlled window
*/
@@ -238,7 +242,7 @@ import "CPDocument.j"
[[self window] setDocumentSaving:NO];
}
/*
/*!
Returns the document in the controlled window.
*/
- (CPDocument)document
@@ -246,7 +250,7 @@ import "CPDocument.j"
return _document;
}
/*
/*!
Sets whether the document has unsaved changes. The window can use this as a hint to
@param isEdited <code>YES</code> means the document has unsaved changes.
*/
@@ -257,7 +261,7 @@ import "CPDocument.j"
// Setting and Getting Window Attributes
/*
/*!
Sets the title of the window as the name of the document.
*/
- (void)synchronizeWindowTitleWithDocumentName
@@ -269,7 +273,7 @@ import "CPDocument.j"
[_window setTitle:[self windowTitleForDocumentDisplayName:[_document displayName]]];
}
/*
/*!
Returns the window title based on the document's name.
@param aDisplayName the document's filename
*/
+126 -64
View File
@@ -20,101 +20,163 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
import <Foundation/CPObject.j>
import <Foundation/CPURLConnection.j>
import <Foundation/CPURLRequest.j>
@import <Foundation/CPObject.j>
@import <Foundation/CPURLConnection.j>
@import <Foundation/CPURLRequest.j>
@import "_CPCibClassSwapper.j"
@import "_CPCibCustomObject.j"
@import "_CPCibCustomResource.j"
@import "_CPCibCustomView.j"
@import "_CPCibKeyedUnarchiver.j"
@import "_CPCibObjectData.j"
@import "_CPCibWindowTemplate.j"
import "_CPCibCustomObject.j"
import "_CPCibCustomView.j"
import "_CPCibKeyedUnarchiver.j"
import "_CPCibObjectData.j"
import "_CPCibWindowTemplate.j"
CPCibOwner = @"CPCibOwner",
CPCibTopLevelObjects = @"CPCibTopLevelObjects";
CPCibTopLevelObjects = @"CPCibTopLevelObjects",
CPCibReplacementClasses = @"CPCibReplacementClasses";
var CPCibObjectDataKey = @"CPCibObjectDataKey";
/*!
@ingroup appkit
*/
@implementation CPCib : CPObject
{
CPData _data;
CPData _data;
CPBundle _bundle;
BOOL _awakenCustomResources;
id _loadDelegate;
}
- (id)initWithContentsOfURL:(CPURL)aURL
{
self = [super init];
if (self)
{
_data = [CPURLConnection sendSynchronousRequest:[CPURLRequest requestWithURL:aURL] returningResponse:nil error:nil];
_awakenCustomResources = YES;
}
return self;
}
- (id)initWithContentsOfURL:(CPURL)aURL loadDelegate:(id)aLoadDelegate
{
self = [super init];
if (self)
{
[CPURLConnection connectionWithRequest:[CPURLRequest requestWithURL:aURL] delegate:self];
_awakenCustomResources = YES;
_loadDelegate = aLoadDelegate;
}
return self;
}
- (id)initWithCibNamed:(CPString)aName bundle:(CPBundle)aBundle loadDelegate:(id)aLoadDelegate
{
if (![aName hasSuffix:@".cib"])
aName = [aName stringByAppendingString:@".cib"];
// If aBundle is nil, use mainBundle, but ONLY for searching for the nib, not for resources later.
self = [self initWithContentsOfURL:[aBundle || [CPBundle mainBundle] pathForResource:aName] loadDelegate:aLoadDelegate];
if (self)
_bundle = aBundle;
return self;
}
- (void)_setAwakenCustomResources:(BOOL)shouldAwakenCustomResources
{
_awakenCustomResources = shouldAwakenCustomResources;
}
- (BOOL)_awakenCustomResources
{
return _awakenCustomResources;
}
- (BOOL)instantiateCibWithExternalNameTable:(CPDictionary)anExternalNameTable
{
var unarchiver = [[_CPCibKeyedUnarchiver alloc] initForReadingWithData:_data],
objectData = [unarchiver decodeObjectForKey:CPCibObjectDataKey];
var bundle = _bundle,
owner = [anExternalNameTable objectForKey:CPCibOwner];
if (!bundle && owner)
bundle = [CPBundle bundleForClass:[owner class]];
var unarchiver = [[_CPCibKeyedUnarchiver alloc] initForReadingWithData:_data bundle:bundle awakenCustomResources:_awakenCustomResources],
replacementClasses = [anExternalNameTable objectForKey:CPCibReplacementClasses];
if (replacementClasses)
{
var key = nil,
keyEnumerator = [replacementClasses keyEnumerator];
while (key = [keyEnumerator nextObject])
[unarchiver setClass:[replacementClasses objectForKey:key] forClassName:key];
}
var objectData = [unarchiver decodeObjectForKey:CPCibObjectDataKey];
if (!objectData || ![objectData isKindOfClass:[_CPCibObjectData class]])
return NO;
[objectData establishConnectionsWithExternalNameTable:anExternalNameTable];
var owner = [anExternalNameTable objectForKey:CPCibOwner],
topLevelObjects = [anExternalNameTable objectForKey:CPCibTopLevelObjects];
/*
// [objectData establishConnectionsWithOwner:owner topLevelObjects:topLevelObjects];
// [objectData cibInstantiateWithOwner:owner topLevelObjects:topLevelObjects];
// alert([objectData description]);
// alert([unarchiver._archive description]);
NSMutableArray *t;
NSEnumerator *e;
id o;
id owner;
id rootObject;
#if 0
NSLog(@"instantiateCibWithExternalNameTable=%@", table);
#endif
if(![decoded isKindOfClass:[NSIBObjectData class]])
return NO;
owner=[table objectForKey:NSCibOwner];
rootObject=[decoded rootObject];
#if 0
NSLog(@"establishConnections");
#endif
[decoded establishConnectionsWithExternalNameTable:table];
#if 0
NSLog(@"awakeFromCib %d objects", [decodedObjects count]);
#endif
#if 0
NSLog(@"objects 2=%@", decodedObjects);
#endif
// FIXME: shouldn't be accessing private variables.
var objects = unarchiver._objects,
count = [objects count];
// The order in which objects receive the awakeFromCib message is not guaranteed.
while (count--)
var topLevelObjects = [anExternalNameTable objectForKey:CPCibTopLevelObjects];
[objectData instantiateWithOwner:owner topLevelObjects:topLevelObjects]
[objectData establishConnectionsWithOwner:owner topLevelObjects:topLevelObjects];
[objectData awakeWithOwner:owner topLevelObjects:topLevelObjects];
var menu;
if ((menu = [objectData mainMenu]) != nil)
{
var object = objects[count];
if ([object respondsToSelector:@selector(awakeFromCib)])
[object awakeFromCib];
[CPApp setMainMenu:menu];
[CPMenu setMenuBarVisible:YES];
}
// if ([owner respondsToSelector:@selector(awakeFromCib)])
// [owner awakeFromCib];
// Display visible windows.
return YES;*/
// Display Visible Windows.
[objectData displayVisibleWindows];
return YES;
}
- (BOOL)instantiateCibWithOwner:(id)anOwner topLevelObjects:(CPArray)topLevelObjects
{
[CPDictionary dictionaryWithObjectsAndKeys:anOwner, CPCibOwner, topLevelObjects, CPCibTopLevelObjects];
return [self instantiate];
return [self instantiateCibWithExternalNameTable:[CPDictionary dictionaryWithObjectsAndKeys:anOwner, CPCibOwner, topLevelObjects, CPCibTopLevelObjects]];
}
@end
@implementation CPCib (CPURLConnectionDelegate)
- (void)connection:(CPURLConnection)aConnection didReceiveData:(CPString)data
{
_data = [CPData dataWithString:data];
}
- (void)connection:(CPURLConnection)aConnection didFailWithError:(CPError)anError
{
alert("cib: connection failed.");
_loadDelegate = nil;
}
- (void)connectionDidFinishLoading:(CPURLConnection)aConnection
{
if ([_loadDelegate respondsToSelector:@selector(cibDidFinishLoading:)])
[_loadDelegate cibDidFinishLoading:self];
_loadDelegate = nil;
}
@end
+76
View File
@@ -0,0 +1,76 @@
/*
* _CPCibLoading.j
* AppKit
*
* Created by Francisco Tolmasky.
* Copyright 2008, 280 North, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import <Foundation/CPBundle.j>
@import <Foundation/CPDictionary.j>
@import <Foundation/CPString.j>
var CPCibOwner = @"CPCibOwner";
var LoadInfoForCib = {};
@implementation CPObject (CPCibLoading)
- (void)awakeFromCib
{
}
@end
@implementation CPBundle (CPCibLoading)
+ (void)loadCibFile:(CPString)anAbsolutePath externalNameTable:(CPDictionary)aNameTable loadDelegate:aDelegate
{
var cib = [[CPCib alloc] initWithContentsOfURL:anAbsolutePath loadDelegate:self];
LoadInfoForCib[[cib hash]] = { loadDelegate:aDelegate, externalNameTable:aNameTable };
}
+ (void)loadCibNamed:(CPString)aName owner:(id)anOwner loadDelegate:(id)aDelegate
{
// Path is based solely on anOwner:
var bundle = anOwner ? [CPBundle bundleForClass:[anOwner class]] : [CPBundle mainBundle],
path = [bundle pathForResource:aName];
[self loadCibFile:path externalNameTable:[CPDictionary dictionaryWithObject:anOwner forKey:CPCibOwner] loadDelegate:aDelegate];
}
- (void)loadCibFile:(CPString)aFileName externalNameTable:(CPDictionary)aNameTable loadDelegate:(id)aDelegate
{
var cib = [[CPCib alloc] initWithCibNamed:aFileName bundle:self loadDelegate:[self class]];
LoadInfoForCib[[cib hash]] = { loadDelegate:aDelegate, externalNameTable:aNameTable };
}
+ (void)cibDidFinishLoading:(CPCib)aCib
{
var loadInfo = LoadInfoForCib[[aCib hash]];
delete LoadInfoForCib[[aCib hash]];
[aCib instantiateCibWithExternalNameTable:loadInfo.externalNameTable];
[loadInfo.loadDelegate cibDidFinishLoading:aCib];
}
@end
+76
View File
@@ -0,0 +1,76 @@
/*
* _CPCibClassSwapper.j
* AppKit
*
* Created by Francisco Tolmasky.
* Copyright 2009, 280 North, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import <Foundation/CPObject.j>
@import <Foundation/CPString.j>
var _CPCibClassSwapperClassNameKey = @"_CPCibClassSwapperClassNameKey",
_CPCibClassSwapperOriginalClassNameKey = @"_CPCibClassSwapperOriginalClassNameKey";
@implementation _CPCibClassSwapper : CPObject
{
}
+ (void)allocObjectWithCoder:(CPCoder)aCoder className:(CPString)aClassName
{
// FIXME: Also check class classForClassName:
var theClass = [aCoder classForClassName:aClassName];
if (!theClass)
{
theClass = objj_lookUpClass(aClassName);
if (!theClass)
return nil;
}
return [theClass alloc];
}
+ (id)allocWithCoder:(CPCoder)aCoder
{
if ([aCoder respondsToSelector:@selector(usesOriginalClasses)] && [aCoder usesOriginalClasses])
{
var theClassName = [aCoder decodeObjectForKey:_CPCibClassSwapperOriginalClassNameKey],
object = [self allocObjectWithCoder:aCoder className:theClassName];
}
else
{
var theClassName = [aCoder decodeObjectForKey:_CPCibClassSwapperClassNameKey],
object = [self allocObjectWithCoder:aCoder className:theClassName];
if (!object)
{
CPLog.error("Unable to find class " + theClassName + " in cib file.");
object = [self allocObjectWithCoder:aCoder className:[aCoder decodeObjectForKey:_CPCibClassSwapperOriginalClassNameKey]];
}
}
if (!object)
[CPException raise:CPInvalidArgumentException reason:@"Unable to find class " + theClassName + " in cib file."];
return object;
}
@end
+12 -21
View File
@@ -1,6 +1,6 @@
import <Foundation/CPObject.j>
import <Foundation/CPKeyValueCoding.j>
@import <Foundation/CPObject.j>
@import <Foundation/CPKeyValueCoding.j>
var _CPCibConnectorSourceKey = @"_CPCibConnectorSourceKey",
@@ -14,13 +14,17 @@ var _CPCibConnectorSourceKey = @"_CPCibConnectorSourceKey",
CPString _label;
}
- (void)replaceObject:(id)anObject withObject:(id)anotherObject
- (void)replaceObjects:(JSObject)replacementObjects
{
if (_source == anObject)
_source = anotherObject;
else if (_destination == anObject)
_destination = anotherObject;
var replacement = replacementObjects[[_source hash]];
if (replacement !== undefined)
_source = replacement;
replacement = replacementObjects[[_destination hash]];
if (replacement !== undefined)
_destination = replacement;
}
@end
@@ -36,10 +40,6 @@ var _CPCibConnectorSourceKey = @"_CPCibConnectorSourceKey",
_source = [aCoder decodeObjectForKey:_CPCibConnectorSourceKey];
_destination = [aCoder decodeObjectForKey:_CPCibConnectorDestinationKey];
_label = [aCoder decodeObjectForKey:_CPCibConnectorLabelKey];
#if DEBUG
CPLog("Connection from " + [_source description] + " to " + [_destination description] + " and label " + _label + " decoded.");
#endif
}
return self;
@@ -60,11 +60,6 @@ var _CPCibConnectorSourceKey = @"_CPCibConnectorSourceKey",
- (void)establishConnection
{
#if DEBUG
CPLog('[' + [_source description] + " setTarget: " + [_destination description] + ']');
CPLog('[' + [_source description] + " setAction: " + _label + ']');
#endif
var selectorName = _label;
if (![selectorName hasSuffix:@":"])
@@ -102,10 +97,6 @@ var _CPCibConnectorSourceKey = @"_CPCibConnectorSourceKey",
- (void)establishConnection
{
#if DEBUG
CPLog([_source description] + " setValue: " + [_destination description] + " forKey: " + _label);
#endif
[_source setValue:_destination forKey:_label];
}
+17 -2
View File
@@ -1,5 +1,5 @@
import <Foundation/CPObject.j>
@import <Foundation/CPObject.j>
var _CPCibCustomObjectClassName = @"_CPCibCustomObjectClassName";
@@ -9,6 +9,16 @@ var _CPCibCustomObjectClassName = @"_CPCibCustomObjectClassName";
CPString _className;
}
- (CPString)customClassName
{
return _className;
}
- (CPString)description
{
return [super description] + " (" + [self customClassName] + ')';
}
@end
@implementation _CPCibCustomObject (CPCoding)
@@ -31,9 +41,14 @@ var _CPCibCustomObjectClassName = @"_CPCibCustomObjectClassName";
- (id)_cibInstantiate
{
var theClass = CPClassFromString(_className);
#if DEBUG
if (!theClass)
CPLog("Unknown class \"" + _className + "\" in cib file");
#endif
if (theClass === [CPApplication class])
return [CPApplication sharedApplication];
return [[theClass alloc] init];
}
+115
View File
@@ -0,0 +1,115 @@
/*
* _CPCibCustomResource.j
* AppKit
*
* Portions based on NSCustomResource.m (01/08/2009) in Cocotron (http://www.cocotron.org/)
* Copyright (c) 2006-2007 Christopher J. W. Lloyd
*
* Created by Francisco Tolmasky.
* Copyright 2009, 280 North, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import <Foundation/CPObject.j>
@import <Foundation/CPString.j>
var _CPCibCustomResourceClassNameKey = @"_CPCibCustomResourceClassNameKey",
_CPCibCustomResourceResourceNameKey = @"_CPCibCustomResourceResourceNameKey",
_CPCibCustomResourcePropertiesKey = @"_CPCibCustomResourcePropertiesKey";
@implementation _CPCibCustomResource : CPObject
{
CPString _className;
CPString _resourceName;
CPDictionary _properties;
}
+ (id)imageResourceWithName:(CPString)aResourceName size:(CGSize)aSize
{
return [[self alloc] initWithClassName:@"CPImage" resourceName:aResourceName properties:[CPDictionary dictionaryWithObject:aSize forKey:@"size"]];
}
- (id)initWithClassName:(CPString)aClassName resourceName:(CPString)aResourceName properties:(CPDictionary)properties
{
self = [super init];
if (self)
{
_className = aClassName;
_resourceName = aResourceName;
_properties = properties;
}
return self;
}
- (id)initWithCoder:(CPCoder)aCoder
{
self = [super init];
if (self)
{
_className = [aCoder decodeObjectForKey:_CPCibCustomResourceClassNameKey];
_resourceName = [aCoder decodeObjectForKey:_CPCibCustomResourceResourceNameKey];
_properties = [aCoder decodeObjectForKey:_CPCibCustomResourcePropertiesKey];
}
return self;
}
- (void)encodeWithCoder:(CPCoder)aCoder
{
[aCoder encodeObject:_className forKey:_CPCibCustomResourceClassNameKey];
[aCoder encodeObject:_resourceName forKey:_CPCibCustomResourceResourceNameKey];
[aCoder encodeObject:_properties forKey:_CPCibCustomResourcePropertiesKey];
}
- (id)awakeAfterUsingCoder:(CPCoder)aCoder
{
if ([aCoder respondsToSelector:@selector(bundle)] &&
(![aCoder respondsToSelector:@selector(awakenCustomResources)] || [aCoder awakenCustomResources]))
if (_className === @"CPImage")
return [[CPImage alloc] initWithContentsOfFile:[[aCoder bundle] pathForResource:_resourceName] size:[_properties objectForKey:@"size"]];
return self;
}
@end
@implementation _CPCibCustomResource (CPImage)
- (CPString)filename
{
return [[CPBundle mainBundle] pathForResource:_resourceName];
}
- (CGSize)size
{
return [_properties objectForKey:@"size"];
}
- (BOOL)isThreePartImage
{
return NO;
}
- (BOOL)isNinePartImage
{
return NO;
}
@end
+35 -5
View File
@@ -20,7 +20,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
import "CPView.j"
@import "CPView.j"
/* @ignore */
@@ -30,6 +30,11 @@ import "CPView.j"
CPString _className;
}
- (CPString)customClassName
{
return _className;
}
@end
var _CPCibCustomViewClassNameKey = @"_CPCibCustomViewClassNameKey";
@@ -42,7 +47,7 @@ var _CPCibCustomViewClassNameKey = @"_CPCibCustomViewClassNameKey";
if (self)
_className = [aCoder decodeObjectForKey:_CPCibCustomViewClassNameKey];
return self;
}
@@ -53,6 +58,18 @@ var _CPCibCustomViewClassNameKey = @"_CPCibCustomViewClassNameKey";
[aCoder encodeObject:_className forKey:_CPCibCustomViewClassNameKey];
}
- (void)drawRect:(CGRect)aRect
{
var bounds = [self bounds],
context = [[CPGraphicsContext currentContext] graphicsPort];
CGContextSetLineWidth(context, 1.0);
CGContextSetStrokeColor(context, [CPColor colorWithCalibratedRed:169.0 / 255.0 green:173.0 / 255.0 blue:178.0 / 255.0 alpha:1.0]);
CGContextStrokeRect(context, CGRectInset(CGRectIntegral(bounds), 0.5, 0.5));
CGContextSetFillColor(context, [CPColor colorWithCalibratedRed:224.0 / 255.0 green:236.0 / 255.0 blue:250.0 / 255.0 alpha:1.0]);
CGContextFillRect(context, CGRectInset(bounds, 2.0, 2.0));
}
- (id)_cibInstantiate
{
var theClass = CPClassFromString(_className);
@@ -61,10 +78,19 @@ var _CPCibCustomViewClassNameKey = @"_CPCibCustomViewClassNameKey";
// FIXME: Should we instead throw an exception?
if (!theClass)
{
#if DEBUG
CPLog("Unknown class \"" + _className + "\" in cib file, using CPView instead.");
#endif
theClass = [CPView class];
}
// Hey this is us!
if (theClass === [self class])
{
_className = @"CPView";
return self;
}
var view = [[theClass alloc] initWithFrame:[self frame]];
@@ -73,7 +99,9 @@ var _CPCibCustomViewClassNameKey = @"_CPCibCustomViewClassNameKey";
[view setBounds:[self bounds]];
// Since the object replacement logic hasn't had a chance to kick in yet, we need to do it manually:
var subviews = [self subviews],
// we need to copy subviews since each time we add a subview to a different view its removed from the original subviews array
var subviews = [[self subviews] copy],
index = 0,
count = subviews.length;
@@ -86,7 +114,9 @@ var _CPCibCustomViewClassNameKey = @"_CPCibCustomViewClassNameKey";
[view setHitTests:[self hitTests]];
[view setHidden:[self isHidden]];
[view setAlphaValue:[self alphaValue]];
[_superview replaceSubview:self with:view];
[view setBackgroundColor:[self backgroundColor]];
}
+16 -7
View File
@@ -1,27 +1,36 @@
import <Foundation/CPKeyedUnarchiver.j>
@import <Foundation/CPKeyedUnarchiver.j>
@implementation _CPCibKeyedUnarchiver : CPKeyedUnarchiver
{
CPBundle _bundle;
BOOL _awakenCustomResources;
}
- (id)initForReadingWithData:(CPData)data
- (id)initForReadingWithData:(CPData)data bundle:(CPBundle)aBundle awakenCustomResources:(BOOL)shouldAwakenCustomResources
{
self = [super initForReadingWithData:data];
if (self)
{
_bundle = aBundle;
_awakenCustomResources = shouldAwakenCustomResources;
[self setDelegate:self];
}
return self;
}
- (id)unarchiver:(CPKeyedUnarchiver)aKeyedUnarchiver didDecodeObject:(id)anObject
- (CPBundle)bundle
{
if ([anObject respondsToSelector:@selector(_cibInstantiate)])
return [anObject _cibInstantiate];
return _bundle;
}
return anObject;
- (BOOL)awakenCustomResources
{
return _awakenCustomResources;
}
- (void)replaceObjectAtUID:(int)aUID withObject:(id)anObject
@@ -34,4 +43,4 @@ import <Foundation/CPKeyedUnarchiver.j>
return _objects[aUID];
}
@end
@end
-69
View File
@@ -1,69 +0,0 @@
/*
* _CPCibLoading.j
* AppKit
*
* Created by Francisco Tolmasky.
* Copyright 2008, 280 North, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
import <Foundation/CPBundle.j>
import <Foundation/CPDictionary.j>
import <Foundation/CPString.j>
var CPCibOwner = @"CPCibOwner";
@implementation CPObject (CPCibLoading)
-(void)awakeFromCib
{
}
@end
@implementation CPBundle (CPCibLoading)
+ (BOOL)loadCibFile:(CPString)aPath externalNameTable:(CPDictionary)aNameTable
{
return [[[CPCib alloc] initWithContentsOfFile:aPath] instantiateCibWithExternalNameTable:aNameTable];
}
+ (BOOL)loadCibNamed:(CPString)aName owner:(id)anOwner
{
var bundle = [CPBundle bundleForClass:[anOwner class]];
/*NSString *path;
path=[bundle pathForResource:name ofType:@"cib"];
if(path==nil)
path=[[NSBundle mainBundle] pathForResource:name ofType:@"cib"];
if(path==nil)
return NO;
*/
var path = [bundle pathForResource:aName];
return [CPBundle loadCibFile:aPath externalNameTable:[CPDictionary dictionaryWithObject:anOwner forKey:CPCibOwner]];
}
- (BOOL)loadCibFile:(CPString)aPath externalNameTable:(CPDictionary)aNameTable
{
return [[[CPCib alloc] initWithContentsOfFile:aPath] instantiateCibWithExternalNameTable:aNameTable];
}
@end
+145 -39
View File
@@ -20,12 +20,12 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
import <Foundation/CPArray.j>
import <Foundation/CPObject.j>
import <Foundation/CPString.j>
@import <Foundation/CPArray.j>
@import <Foundation/CPObject.j>
@import <Foundation/CPString.j>
import "CPCib.j"
import "_CPCibConnector.j"
@import "CPCib.j"
@import "_CPCibConnector.j"
@implementation _CPCibObjectData : CPObject
@@ -57,27 +57,69 @@ import "_CPCibConnector.j"
_CPCibCustomObject _fileOwner;
CPSet _visibleWindows;
JSObject _replacementObjects;
}
- (CPArray)topLevelObjects
- (id)init
{
var count = [_objectsValues count],
topLevelObjects = [];
while (count--)
self = [super init];
if (self)
{
var eachObject = _objectsValues[count];
if (eachObject == _fileOwner)
{
var anObject = _objectsKeys[count];
if (anObject != _fileOwner)
topLevelObjects.push(anObject);
}
_namesKeys = [];
_namesValues = [];
//CPArray _accessibilityConnectors;
//CPArray _accessibilityOidsKeys;
//CPArray _accessibilityOidsValues;
_classesKeys = [];
_classesValues = [];
_connections = [];
//id _fontManager;
_framework = @"";
_nextOid = [];
_objectsKeys = [];
_objectsValues = [];
_oidKeys = [];
_oidValues = [];
_fileOwner = nil;
_visibleWindows = [CPSet set];
}
return topLevelObjects;
return self;
}
- (CPMenu)mainMenu
{
var index = [_namesValues indexOfObjectIdenticalTo:"MainMenu"];
if (index === CPNotFound)
{
index = [_namesValues indexOfObjectIdenticalTo:"Main Menu"];
if (index === CPNotFound)
return nil;
}
return _namesKeys[index];
}
- (void)displayVisibleWindows
{
var object = nil,
objectEnumerator = [_visibleWindows objectEnumerator];
while (object = [objectEnumerator nextObject])
[_replacementObjects[[object hash]] makeKeyAndOrderFront:self];
}
@end
@@ -114,9 +156,11 @@ var _CPCibObjectDataNamesKeysKey = @"_CPCibObjectDataNamesKeysKey
- (id)initWithCoder:(CPCoder)aCoder
{
self = [super init];
if (self)
{
_replacementObjects = {};
_namesKeys = [aCoder decodeObjectForKey:_CPCibObjectDataNamesKeysKey];
_namesValues = [aCoder decodeObjectForKey:_CPCibObjectDataNamesValuesKey];
@@ -129,22 +173,22 @@ var _CPCibObjectDataNamesKeysKey = @"_CPCibObjectDataNamesKeysKey
_connections = [aCoder decodeObjectForKey:_CPCibObjectDataConnectionsKey];
//id _fontManager;
_framework = [aCoder decodeObjectForKey:_CPCibObjectDataFrameworkKey];
_nextOid = [aCoder decodeIntForKey:_CPCibObjectDataNextOidKey];
_objectsKeys = [aCoder decodeObjectForKey:_CPCibObjectDataObjectsKeysKey];
_objectsValues = [aCoder decodeObjectForKey:_CPCibObjectDataObjectsValuesKey];
_oidKeys = [aCoder decodeObjectForKey:_CPCibObjectDataOidKeysKey];
_oidValues = [aCoder decodeObjectForKey:_CPCibObjectDataOidValuesKey];
_fileOwner = [aCoder decodeObjectForKey:_CPCibObjectDataFileOwnerKey];
// CPSet _visibleWindows;
_visibleWindows = [aCoder decodeObjectForKey:_CPCibObjectDataVisibleWindowsKey];
}
return self;
}
@@ -152,16 +196,16 @@ var _CPCibObjectDataNamesKeysKey = @"_CPCibObjectDataNamesKeysKey
{
[aCoder encodeObject:_namesKeys forKey:_CPCibObjectDataNamesKeysKey];
[aCoder encodeObject:_namesValues forKey:_CPCibObjectDataNamesValuesKey];
//CPArray _accessibilityConnectors;
//CPArray _accessibilityOidsKeys;
//CPArray _accessibilityOidsValues;
[aCoder encodeObject:_classesKeys forKey:_CPCibObjectDataClassesKeysKey];
[aCoder encodeObject:_classesValues forKey:_CPCibObjectDataClassesValuesKey];
[aCoder encodeObject:_connections forKey:_CPCibObjectDataConnectionsKey];
//id _fontManager;
[aCoder encodeObject:_framework forKey:_CPCibObjectDataFrameworkKey];
@@ -177,22 +221,84 @@ var _CPCibObjectDataNamesKeysKey = @"_CPCibObjectDataNamesKeysKey
[aCoder encodeObject:_fileOwner forKey:_CPCibObjectDataFileOwnerKey];
// CPCustomObject _fileOwner;
// CPSet _visibleWindows;
[aCoder encodeObject:_visibleWindows forKey:_CPCibObjectDataVisibleWindowsKey];
}
- (void)establishConnectionsWithExternalNameTable:(CPDictionary)anExternalNameTable
- (void)instantiateWithOwner:(id)anOwner topLevelObjects:(CPMutableArray)topLevelObjects
{
// _objectsValues -> parent
// _objectsKeys -> child
var count = [_objectsKeys count];
while (count--)
{
var object = _objectsKeys[count],
parent = _objectsValues[count],
instantiatedObject = object;
if ([object respondsToSelector:@selector(_cibInstantiate)])
{
var instantiatedObject = [object _cibInstantiate];
if (instantiatedObject !== object)
{
_replacementObjects[[object hash]] = instantiatedObject;
if ([instantiatedObject isKindOfClass:[CPView class]])
{
var clipView = [instantiatedObject superview];
if ([clipView isKindOfClass:[CPClipView class]])
{
var scrollView = [clipView superview];
if ([scrollView isKindOfClass:[CPScrollView class]])
[scrollView setDocumentView:instantiatedObject];
}
}
}
}
if (topLevelObjects && parent === _fileOwner && object !== _fileOwner)
topLevelObjects.push(instantiatedObject);
}
}
- (void)establishConnectionsWithOwner:(id)anOwner topLevelObjects:(CPMutableArray)topLevelObjects
{
_replacementObjects[[_fileOwner hash]] = anOwner;
var index = 0,
count = _connections.length,
cibOwner = [anExternalNameTable objectForKey:CPCibOwner];
count = _connections.length;
for (; index < count; ++index)
{
var connection = _connections[index];
[connection replaceObject:_fileOwner withObject:cibOwner];
[connection replaceObjects:_replacementObjects];
[connection establishConnection];
}
}
- (void)awakeWithOwner:(id)anOwner topLevelObjects:(CPMutableArray)topLevelObjects
{
var count = [_objectsKeys count];
while (count--)
{
var object = _objectsKeys[count],
instantiatedObject = _replacementObjects[[object hash]];
if (instantiatedObject)
object = instantiatedObject;
// Don't use _fileOwner, by this point its been replaced with anOwner.
if (object !== anOwner && [object respondsToSelector:@selector(awakeFromCib)])
[object awakeFromCib];
}
if ([anOwner respondsToSelector:@selector(awakeFromCib)])
[anOwner awakeFromCib];
}
@end
+49 -24
View File
@@ -1,31 +1,36 @@
import <Foundation/CPObject.j>
@import <Foundation/CPObject.j>
var _CPCibWindowTemplateMinSizeKey = @"_CPCibWindowTemplateMinSizeKey",
_CPCibWindowTemplateMaxSizeKey = @"_CPCibWindowTemplateMaxSizeKey",
var _CPCibWindowTemplateMinSizeKey = @"_CPCibWindowTemplateMinSizeKey",
_CPCibWindowTemplateMaxSizeKey = @"_CPCibWindowTemplateMaxSizeKey",
_CPCibWindowTemplateViewClassKey = @"_CPCibWindowTemplateWindowClassKey",
_CPCibWindowTemplateViewClassKey = @"_CPCibWindowTemplateViewClassKey",
_CPCibWindowTemplateWindowClassKey = @"_CPCibWindowTemplateWindowClassKey",
_CPCibWindowTemplateWindowRectKey = @"_CPCibWindowTemplateWindowRectKey",
_CPCibWindowTemplateWindowStyleMaskKey = @"_CPCibWindowTempatStyleMaskKey",
_CPCibWindowTemplateWindowTitleKey = @"_CPCibWindowTemplateWindowTitleKey",
_CPCibWindowTemplateWindowViewKey = @"_CPCibWindowTemplateWindowViewKey";
_CPCibWindowTemplateWindowRectKey = @"_CPCibWindowTemplateWindowRectKey",
_CPCibWindowTemplateWindowStyleMaskKey = @"_CPCibWindowTempatStyleMaskKey",
_CPCibWindowTemplateWindowTitleKey = @"_CPCibWindowTemplateWindowTitleKey",
_CPCibWindowTemplateWindowViewKey = @"_CPCibWindowTemplateWindowViewKey",
_CPCibWindowTemplateWindowIsFullBridgeKey = @"_CPCibWindowTemplateWindowIsFullBridgeKey";
@implementation _CPCibWindowTemplate : CPObject
{
CGSize _minSize;
CGSize _maxSize;
//CGSize _screenRect;
CPString _viewClass;
id _viewClass;
//unsigned _wtFlags;
CPString _windowClass;
CGRect _windowRect;
unsigned _windowStyleMask;
CPString _windowTitle;
CPView _windowView;
BOOL _windowIsFullBridge;
}
- (id)initWithCoder:(CPCoder)aCoder
@@ -34,17 +39,21 @@ var _CPCibWindowTemplateMinSizeKey = @"_CPCibWindowTemplateMinSizeKey",
if (self)
{
_minSize = [aCoder decodeSizeForKey:_CPCibWindowTemplateMinSizeKey];
_maxSize = [aCoder decodeSizeForKey:_CPCibWindowTemplateMaxSizeKey];
if ([aCoder containsValueForKey:_CPCibWindowTemplateMinSizeKey])
_minSize = [aCoder decodeSizeForKey:_CPCibWindowTemplateMinSizeKey];
if ([aCoder containsValueForKey:_CPCibWindowTemplateMaxSizeKey])
_maxSize = [aCoder decodeSizeForKey:_CPCibWindowTemplateMaxSizeKey];
_viewClass = [aCoder decodeObjectForKey:_CPCibWindowTemplateViewClassKey];
_windowClass = [aCoder decodeObjectForKey:_CPCibWindowTemplateViewClassKey];
_windowClass = [aCoder decodeObjectForKey:_CPCibWindowTemplateWindowClassKey];
_windowRect = [aCoder decodeRectForKey:_CPCibWindowTemplateWindowRectKey];
_windowStyleMask = [aCoder decodeIntForKey:_CPCibWindowTemplateWindowStyleMaskKey];
_windowTitle = [aCoder decodeObjectForKey:_CPCibWindowTemplateWindowTitleKey];
_windowView = [aCoder decodeObjectForKey:_CPCibWindowTemplateWindowViewKey];
_windowIsFullBridge = [aCoder decodeObjectForKey:_CPCibWindowTemplateWindowIsFullBridgeKey];
}
return self;
@@ -52,33 +61,42 @@ var _CPCibWindowTemplateMinSizeKey = @"_CPCibWindowTemplateMinSizeKey",
- (void)encodeWithCoder:(CPCoder)aCoder
{
[aCoder encodeSize:_minSize forKey:_CPCibWindowTemplateMinSizeKey];
[aCoder encodeSize:_maxSize forKey:_CPCibWindowTemplateMaxSizeKey];
if (_minSize)
[aCoder encodeSize:_minSize forKey:_CPCibWindowTemplateMinSizeKey];
if (_maxSize)
[aCoder encodeSize:_maxSize forKey:_CPCibWindowTemplateMaxSizeKey];
[aCoder encodeObject:_viewClass forKey:_CPCibWindowTemplateViewClassKey];
[aCoder encodeObject:_windowClass forKey:_CPCibWindowTemplateViewClassKey];
[aCoder encodeObject:_windowClass forKey:_CPCibWindowTemplateWindowClassKey];
[aCoder encodeRect:_windowRect forKey:_CPCibWindowTemplateWindowRectKey];
[aCoder encodeInt:_windowStyleMask forKey:_CPCibWindowTemplateWindowStyleMaskKey];
[aCoder encodeObject:_windowTitle forKey:_CPCibWindowTemplateWindowTitleKey];
[aCoder encodeObject:_windowView forKey:_CPCibWindowTemplateWindowViewKey];
[aCoder encodeObject:_windowIsFullBridge forKey:_CPCibWindowTemplateWindowIsFullBridgeKey];
}
- (CPString)windowClass
{
return _windowClass;
}
- (id)_cibInstantiate
{
var windowClass = CPClassFromString(_windowClass);
var windowClass = CPClassFromString([self windowClass]);
/* if (!windowClass)
[NSException raise:NSInvalidArgumentException format:@"Unable to locate NSWindow class %@, using NSWindow",_windowClass];
class=[NSWindow class];*/
var theWindow = [[windowClass alloc] initWithContentRect:_windowRect styleMask:CPHUDBackgroundWindowMask | CPClosableWindowMask];//styleMask:_windowStyleMask];
// alert(CPStringFromRect(_windowRect));
// alert(CPStringFromSize(_minSize));
// alert(CPStringFromSize(_maxSize));
//[theWindow setMinSize:_minSize];
//[theWindow setMaxSize:_maxSize];
var theWindow = [[windowClass alloc] initWithContentRect:_windowRect styleMask:_windowStyleMask];
if (_minSize)
[theWindow setMinSize:_minSize];
if (_maxSize)
[theWindow setMaxSize:_maxSize];
[theWindow setLevel:CPFloatingWindowLevel];
//[result setHidesOnDeactivate:(_wtFlags&0x80000000)?YES:NO];
@@ -91,6 +109,13 @@ var _CPCibWindowTemplateMinSizeKey = @"_CPCibWindowTemplateMinSizeKey",
[_windowView setAutoresizesSubviews:YES];
if ([_viewClass isKindOfClass:[CPToolbar class]])
{
[theWindow setToolbar:_viewClass];
}
[theWindow setFullBridge:_windowIsFullBridge];
return theWindow;
}
+25 -24
View File
@@ -20,10 +20,10 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
import <Foundation/CPObject.j>
import <Foundation/CPString.j>
@import <Foundation/CPObject.j>
@import <Foundation/CPString.j>
import "CAMediaTimingFunction.j"
@import "CAMediaTimingFunction.j"
/*
This is an animation class.
@@ -31,11 +31,12 @@ import "CAMediaTimingFunction.j"
@implementation CAAnimation : CPObject
{
BOOL _isRemovedOnCompletion;
id _delegate;
}
/*
Creates a new <objj>CAAnimation</objj> instance
@return a new <objj>CAAnimation</objj> instance
/*!
Creates a new CAAnimation instance
@return a new CAAnimation instance
*/
+ (id)animation
{
@@ -52,7 +53,7 @@ import "CAMediaTimingFunction.j"
return self;
}
/*
/*!
Returns <code>YES</code>
@return <code>YES</code>
*/
@@ -61,7 +62,7 @@ import "CAMediaTimingFunction.j"
return YES;
}
/*
/*!
Returns <code>nil</code>
@return <code>nil</code>
*/
@@ -70,7 +71,7 @@ import "CAMediaTimingFunction.j"
return nil;
}
/*
/*!
Specifies whether this animation should be removed after it has completed.
@param <code>YES</code> means the animation should be removed
*/
@@ -79,7 +80,7 @@ import "CAMediaTimingFunction.j"
_isRemovedOnCompletion = isRemovedOnCompletion;
}
/*
/*!
Returns <code>YES</code> if the animation is removed after completion
*/
- (BOOL)removedOnCompletion
@@ -87,7 +88,7 @@ import "CAMediaTimingFunction.j"
return _isRemovedOnCompletion;
}
/*
/*!
Returns <code>YES</code> if the animation is removed after completion
*/
- (BOOL)isRemovedOnCompletion
@@ -95,7 +96,7 @@ import "CAMediaTimingFunction.j"
return _isRemovedOnCompletion;
}
/*
/*!
Returns the animation's timing function. If <code>nil</code>, then it has a linear pacing.
*/
- (CAMediaTimingFunction)timingFunction
@@ -104,7 +105,7 @@ import "CAMediaTimingFunction.j"
return nil;
}
/*
/*!
Sets the animation delegate
@param aDelegate the new delegate
*/
@@ -113,7 +114,7 @@ import "CAMediaTimingFunction.j"
_delegate = aDelegate;
}
/*
/*!
Returns the animation's delegate
*/
- (id)delegate
@@ -143,7 +144,7 @@ import "CAMediaTimingFunction.j"
{
var animation = [self animation];
[animation setKeypath:aKeyPath];
[animation setKeyPath:aKeyPath];
return animation;
}
@@ -190,9 +191,9 @@ import "CAMediaTimingFunction.j"
@end
/*
A <objj>CABasicAnimation</objj> is a simple animation that moves a
<objj>CALayer</objj> from one point to another over a specified
/*!
A CABasicAnimation is a simple animation that moves a
CALayer from one point to another over a specified
period of time.
*/
@implementation CABasicAnimation : CAPropertyAnimation
@@ -202,7 +203,7 @@ import "CAMediaTimingFunction.j"
id _byValue;
}
/*
/*!
Sets the starting position for the animation.
@param aValue the animation starting position
*/
@@ -211,7 +212,7 @@ import "CAMediaTimingFunction.j"
_fromValue = aValue;
}
/*
/*!
Returns the animation's starting position.
*/
- (id)fromValue
@@ -219,7 +220,7 @@ import "CAMediaTimingFunction.j"
return _fromValue;
}
/*
/*!
Sets the ending position for the animation.
@param aValue the animation ending position
*/
@@ -228,7 +229,7 @@ import "CAMediaTimingFunction.j"
_toValue = aValue;
}
/*
/*!
Returns the animation's ending position.
*/
- (id)toValue
@@ -236,7 +237,7 @@ import "CAMediaTimingFunction.j"
return _toValue;
}
/*
/*!
Sets the optional byValue for animation interpolation.
@param aValue the byValue
*/
@@ -245,7 +246,7 @@ import "CAMediaTimingFunction.j"
_byValue = aValue;
}
/*
/*!
Returns the animation's byValue.
*/
- (id)byValue
+3 -2
View File
@@ -20,11 +20,12 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
import "CGGeometry.j"
import "CPCompatibility.j"
@import "CGGeometry.j"
@import "CPCompatibility.j"
#define PIXEL(pixels) pixels + "px";
function CABackingStoreGetContext(aBackingStore)
{
return aBackingStore.context;
+2 -2
View File
@@ -20,8 +20,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
import "CALayer.j"
import "CPFlashMovie.j"
@import "CALayer.j"
@import "CPFlashMovie.j"
@implementation CAFlashLayer : CALayer
+58 -57
View File
@@ -20,12 +20,12 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
import <Foundation/CPObject.j>
@import <Foundation/CPObject.j>
import <AppKit/CABackingStore.j>
@import <AppKit/CABackingStore.j>
import <AppKit/CGContext.j>
import <AppKit/CGGeometry.j>
@import <AppKit/CGContext.j>
@import <AppKit/CGGeometry.j>
#include "../CoreGraphics/CGGeometry.h"
#include "../CoreGraphics/CGAffineTransform.j"
@@ -49,12 +49,13 @@ var CALayerFrameOriginUpdateMask = 1,
var CALayerRegisteredRunLoopUpdates = nil;
/*
A <objj>CALayer</objj> is similar to a <objj>CPView</objj>, but with the ability
/*! @class CALayer
A CALayer is similar to a CPView, but with the ability
to have a transform applied to it.
@delegate -(void)drawLayer:(CALayer)layer inContext:(CGContextRef)ctx;
If the delegate implements this method, the <objj>CALayer</objj> will
If the delegate implements this method, the CALayer will
call this in place of its <code>drawInContext:</code>.
@param layer the layer to draw for
@param ctx the context to draw on
@@ -118,7 +119,7 @@ var CALayerRegisteredRunLoopUpdates = nil;
CGAffineTransform _transformFromLayer;
}
/*
/*!
Returns a new animation layer.
*/
+ (CALayer)layer
@@ -126,7 +127,7 @@ var CALayerRegisteredRunLoopUpdates = nil;
return [[[self class] alloc] init];
}
/*
/*!
Initializes the animation layer.
*/
- (id)init
@@ -172,7 +173,7 @@ var CALayerRegisteredRunLoopUpdates = nil;
}
// Modifying the Layer Geometry
/*
/*!
Sets the bounds (origin and size) of the rectangle.
@param aBounds the new bounds for the layer
*/
@@ -201,7 +202,7 @@ var CALayerRegisteredRunLoopUpdates = nil;
_CALayerRecalculateGeometry(self, CALayerGeometryBoundsMask);
}
/*
/*!
Returns the layer's bound.
*/
- (CGRect)bounds
@@ -209,7 +210,7 @@ var CALayerRegisteredRunLoopUpdates = nil;
return _bounds;
}
/*
/*!
Sets the layer's position.
@param aPosition the layer's new position
*/
@@ -223,7 +224,7 @@ var CALayerRegisteredRunLoopUpdates = nil;
_CALayerRecalculateGeometry(self, CALayerGeometryPositionMask);
}
/*
/*!
Returns the layer's position
*/
- (CGPoint)position
@@ -231,7 +232,7 @@ var CALayerRegisteredRunLoopUpdates = nil;
return _position;
}
/*
/*!
Sets the layer's z-ordering.
@param aZPosition the layer's new z-ordering
*/
@@ -245,7 +246,7 @@ var CALayerRegisteredRunLoopUpdates = nil;
[self registerRunLoopUpdateWithMask:CALayerZPositionUpdateMask];
}
/*
/*!
Sets the layer's anchor point. The default point is [0.5, 0.5].
@param anAnchorPoint the layer's new anchor point
*/
@@ -269,7 +270,7 @@ var CALayerRegisteredRunLoopUpdates = nil;
_CALayerRecalculateGeometry(self, CALayerGeometryAnchorPointMask);
}
/*
/*!
Returns the layer's anchor point.
*/
- (CGPoint)anchorPoint
@@ -277,7 +278,7 @@ var CALayerRegisteredRunLoopUpdates = nil;
return _anchorPoint;
}
/*
/*!
Sets the affine transform applied to this layer.
@param anAffineTransform the new affine transform
*/
@@ -291,7 +292,7 @@ var CALayerRegisteredRunLoopUpdates = nil;
_CALayerRecalculateGeometry(self, CALayerGeometryAffineTransformMask);
}
/*
/*!
Returns the layer's affine transform.
*/
- (CGAffineTransform)affineTransform
@@ -299,7 +300,7 @@ var CALayerRegisteredRunLoopUpdates = nil;
return _affineTransform;
}
/*
/*!
Sets the affine transform that gets applied to all the sublayers.
@param anAffineTransform the transform to apply to sublayers
*/
@@ -325,7 +326,7 @@ var CALayerRegisteredRunLoopUpdates = nil;
}
}
/*
/*!
Returns the affine transform applied to the sublayers.
*/
- (CGAffineTransform)sublayerTransform
@@ -342,7 +343,7 @@ var CALayerRegisteredRunLoopUpdates = nil;
return _transformToLayer;
}
/*
/*!
Sets the frame of the layer. The frame defines a bounding
rectangle in the superlayer's coordinate system.
@param aFrame the new frame rectangle
@@ -352,7 +353,7 @@ var CALayerRegisteredRunLoopUpdates = nil;
alert("FIXME IMPLEMENT");
}
/*
/*!
Returns the layer's frame.
The frame defines the bounding box of the layer: the smallest
@@ -367,7 +368,7 @@ var CALayerRegisteredRunLoopUpdates = nil;
return _frame;
}
/*
/*!
The Backing Store Frame specifies the frame of the actual backing
store used to contain this layer. Naturally, by default it is the
same as the frame, however, users can specify their own custom
@@ -380,7 +381,7 @@ var CALayerRegisteredRunLoopUpdates = nil;
return _backingStoreFrame;
}
/*
/*!
Sets the frame's backing store.
@param aFrame the new backing store.
*/
@@ -416,8 +417,8 @@ var CALayerRegisteredRunLoopUpdates = nil;
}
// Providing Layer Content
/*
Returns the <objj>CGImage</objj> contents of this layer.
/*!
Returns the CGImage contents of this layer.
The default contents are <code>nil</code>.
*/
- (CGImage)contents
@@ -425,7 +426,7 @@ var CALayerRegisteredRunLoopUpdates = nil;
return _contents;
}
/*
/*!
Sets the image contents of this layer.
@param contents the image to display
*/
@@ -479,7 +480,7 @@ var CALayerRegisteredRunLoopUpdates = nil;
CGContextRestoreGState(_context);
}
/*
/*!
Displays the contents of this layer.
*/
- (void)display
@@ -526,7 +527,7 @@ var CALayerRegisteredRunLoopUpdates = nil;
[self composite];
}
/*
/*!
Draws this layer's contents into the specified context.
@param aContext the context to draw the layer into
*/
@@ -544,7 +545,7 @@ var CALayerRegisteredRunLoopUpdates = nil;
// Style Attributes
/*
/*!
Returns the opacity of the layer. The value is between
<code>0.0</code> (transparent) and <code>1.0</code> (opaque).
*/
@@ -553,7 +554,7 @@ var CALayerRegisteredRunLoopUpdates = nil;
return _opacity;
}
/*
/*!
Sets the opacity for the layer.
@param anOpacity the new opacity (between <code>0.0</code> (transparent) and <code>1.0</code> (opaque)).
*/
@@ -568,7 +569,7 @@ var CALayerRegisteredRunLoopUpdates = nil;
_DOMElement.style.filter = "alpha(opacity=" + anOpacity * 100 + ")";
}
/*
/*!
Sets whether the layer is hidden.
@param isHidden <code>YES</code> means the layer will be hidden. <code>NO</code> means the layer will be visible.
*/
@@ -578,7 +579,7 @@ var CALayerRegisteredRunLoopUpdates = nil;
_DOMElement.style.display = isHidden ? "none" : "block";
}
/*
/*!
Returns <code>YES</code> if the layer is hidden.
*/
- (BOOL)hidden
@@ -586,7 +587,7 @@ var CALayerRegisteredRunLoopUpdates = nil;
return _isHidden;
}
/*
/*!
Returns <code>YES</code> if the layer is hidden.
*/
- (BOOL)isHidden
@@ -594,7 +595,7 @@ var CALayerRegisteredRunLoopUpdates = nil;
return _isHidden;
}
/*
/*!
Sets whether content that goes lies outside the bounds is hidden or visible.
@param masksToBounds <code>YES</code> hides the excess content. <code>NO</code> makes it visible.
*/
@@ -607,7 +608,7 @@ var CALayerRegisteredRunLoopUpdates = nil;
_DOMElement.style.overflow = _masksToBounds ? "hidden" : "visible";
}
/*
/*!
Sets the layer's background color.
@param aColor the new background color
*/
@@ -618,7 +619,7 @@ var CALayerRegisteredRunLoopUpdates = nil;
[self setNeedsDisplay];
}
/*
/*!
Returns the layer's background color.
*/
- (CPColor)backgroundColor
@@ -627,7 +628,7 @@ var CALayerRegisteredRunLoopUpdates = nil;
}
// Managing Layer Hierarchy
/*
/*!
Returns an array of the receiver's sublayers.
*/
- (CPArray)sublayers
@@ -635,7 +636,7 @@ var CALayerRegisteredRunLoopUpdates = nil;
return _sublayers;
}
/*
/*!
Returns the receiver's superlayer.
*/
- (CALayer)superlayer
@@ -647,7 +648,7 @@ var CALayerRegisteredRunLoopUpdates = nil;
if (_DOMContentsElement && aLayer._zPosition > _DOMContentsElement.style.zIndex)\
_DOMContentsElement.style.zIndex -= 100.0;\
/*
/*!
Adds the specified layer as a sublayer of the receiver.
*/
- (void)addSublayer:(CALayer)aLayer
@@ -660,7 +661,7 @@ if (_DOMContentsElement && aLayer._zPosition > _DOMContentsElement.style.zIndex)
_DOMElement.appendChild(DOM(aLayer));
}
/*
/*!
Removes the receiver from its superlayer.
*/
- (void)removeFromSuperlayer
@@ -677,7 +678,7 @@ if (_DOMContentsElement && aLayer._zPosition > _DOMContentsElement.style.zIndex)
_superlayer = nil;
}
/*
/*!
Inserts the specified layer as a sublayer into the specified index.
@param aLayer the layer to insert
@param anIndex the index to insert the layer at
@@ -719,7 +720,7 @@ if (_DOMContentsElement && aLayer._zPosition > _DOMContentsElement.style.zIndex)
_CALayerRecalculateGeometry(aLayer, 0xFFFFFFF);
}
/*
/*!
Inserts a layer below another layer.
@param aLayer the layer to insert
@param aSublayer the layer to insert below
@@ -732,7 +733,7 @@ if (_DOMContentsElement && aLayer._zPosition > _DOMContentsElement.style.zIndex)
[self insertSublayer:aLayer atIndex:index == CPNotFound ? _sublayers.length : index];
}
/*
/*!
Inserts a layer above another layer.
@param aLayer the layer to insert
@param aSublayer the layer to insert above
@@ -747,7 +748,7 @@ if (_DOMContentsElement && aLayer._zPosition > _DOMContentsElement.style.zIndex)
[_sublayers insertObject:aLayer atIndex:index == CPNotFound ? _sublayers.length : index + 1];
}
/*
/*!
Replaces a sublayer.
@param aSublayer the layer to insert
@param aLayer the layer to replace
@@ -823,7 +824,7 @@ if (_DOMContentsElement && aLayer._zPosition > _DOMContentsElement.style.zIndex)
[self registerRunLoopUpdateWithMask:CALayerCompositeUpdateMask];
}
/*
/*!
Marks the layer as needing to be redrawn.
*/
- (void)setNeedsDisplay
@@ -831,7 +832,7 @@ if (_DOMContentsElement && aLayer._zPosition > _DOMContentsElement.style.zIndex)
[self registerRunLoopUpdateWithMask:CALayerDisplayUpdateMask];
}
/*
/*!
Sets whether the layer needs to be redrawn when its bounds are changed.
@param needsDisplayOnBoundsChange <code>YES</code> means the display is redraw on a bounds change.
*/
@@ -840,7 +841,7 @@ if (_DOMContentsElement && aLayer._zPosition > _DOMContentsElement.style.zIndex)
_needsDisplayOnBoundsChange = needsDisplayOnBoundsChange;
}
/*
/*!
Returns <code>YES</code> if the display should be redrawn on a bounds change.
*/
- (BOOL)needsDisplayOnBoundsChange
@@ -848,7 +849,7 @@ if (_DOMContentsElement && aLayer._zPosition > _DOMContentsElement.style.zIndex)
return _needsDisplayOnBoundsChange;
}
/*
/*!
Marks the specified rectange as needing to be redrawn.
@param aRect the area that needs to be redrawn.
*/
@@ -859,7 +860,7 @@ if (_DOMContentsElement && aLayer._zPosition > _DOMContentsElement.style.zIndex)
}
// Mapping Between Coordinate and Time Spaces
/*
/*!
Converts the point from the specified layer's coordinate system into the receiver's coordinate system.
@param aPoint the point to convert
@param aLayer the layer coordinate system to convert from
@@ -870,7 +871,7 @@ if (_DOMContentsElement && aLayer._zPosition > _DOMContentsElement.style.zIndex)
return CGPointApplyAffineTransform(aPoint, _CALayerGetTransform(aLayer, self));
}
/*
/*!
Converts the point from the receiver's coordinate system to the specified layer's coordinate system.
@param aPoint the point to convert
@param aLayer the layer coordinate system to convert to
@@ -881,7 +882,7 @@ if (_DOMContentsElement && aLayer._zPosition > _DOMContentsElement.style.zIndex)
return CGPointApplyAffineTransform(aPoint, _CALayerGetTransform(self, aLayer));
}
/*
/*!
Converts the rectangle from the specified layer's coordinate system to the receiver's coordinate system.
@param aRect the rectangle to convert
@param aLayer the layer coordinate system to convert from
@@ -892,7 +893,7 @@ if (_DOMContentsElement && aLayer._zPosition > _DOMContentsElement.style.zIndex)
return CGRectApplyAffineTransform(aRect, _CALayerGetTransform(aLayer, self));
}
/*
/*!
Converts the rectangle from the receier's coordinate system to the specified layer's coordinate system.
@param aRect the rectange to convert
@param aLayer the layer coordinate system to convert to
@@ -904,7 +905,7 @@ if (_DOMContentsElement && aLayer._zPosition > _DOMContentsElement.style.zIndex)
}
// Hit Testing
/*
/*!
Returns <code>YES</code> if the layer contains the point.
@param aPoint the point to test
*/
@@ -913,7 +914,7 @@ if (_DOMContentsElement && aLayer._zPosition > _DOMContentsElement.style.zIndex)
return _CGRectContainsPoint(_bounds, aPoint);
}
/*
/*!
Returns the farthest descendant of this layer that contains the specified point.
@param aPoint the point to test
@return the containing layer or <code>nil</code> if there was no hit.
@@ -941,7 +942,7 @@ if (_DOMContentsElement && aLayer._zPosition > _DOMContentsElement.style.zIndex)
}
// Modifying the Delegate
/*
/*!
Sets the delegate for this layer.
@param aDelegate the delegate
*/
@@ -959,7 +960,7 @@ if (_DOMContentsElement && aLayer._zPosition > _DOMContentsElement.style.zIndex)
[self setNeedsDisplay];
}
/*
/*!
Returns the layer's delegate
*/
- (id)delegate
+4 -4
View File
@@ -20,9 +20,9 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
import <Foundation/CPObject.j>
import <Foundation/CPDictionary.j>
import <Foundation/CPString.j>
@import <Foundation/CPObject.j>
@import <Foundation/CPDictionary.j>
@import <Foundation/CPString.j>
kCAMediaTimingFunctionLinear = @"kCAMediaTimingFunctionLinear";
@@ -95,7 +95,7 @@ var CAMediaNamedTimingFunctions = nil;
else
{
reference[0] = 1.0;
reference[0] = 1.0;
reference[1] = 1.0;
}
}
+7 -6
View File
@@ -25,7 +25,8 @@
#define _function(inline) function inline { return _##inline; }
import "CGGeometry.j"
@import "CGGeometry.j"
_function(CGAffineTransformMake(a, b, c, d, tx, ty))
_function(CGAffineTransformMakeIdentity())
@@ -55,7 +56,7 @@ function CGAffineTransformCreateCopy(aTransform)
return _CGAffineTransformMakeCopy(aTransform);
}
/*
/*!
Returns a transform that rotates a coordinate system.
@param anAngle the amount in radians for the transform
to rotate a coordinate system
@@ -71,7 +72,7 @@ function CGAffineTransformMakeRotation(anAngle)
return _CGAffineTransformMake(cos, sin, -sin, cos, 0.0, 0.0);
}
/*
/*!
Rotates a transform.
@param aTransform the transform to rotate
@param anAngle the amount to rotate in radians
@@ -93,7 +94,7 @@ function CGAffineTransformRotate(aTransform, anAngle)
};
}
/*
/*!
Inverts a transform.
@param aTransform the transform to invert
@return CGAffineTransform an inverted transform
@@ -113,7 +114,7 @@ function CGAffineTransformInvert(aTransform)
};
}
/*
/*!
Applies a transform to the rectangle's points. The transformed rectangle
will be the smallest box that contains the transformed points.
@param aRect the rectangle to transform
@@ -139,7 +140,7 @@ function CGRectApplyAffineTransform(aRect, anAffineTransform)
return _CGRectMake(minX, minY, (maxX - minX), (maxY - minY));
}
/*
/*!
Creates and returns a string representation of an affine transform.
@param anAffineTransform the transform to represent as a string
@return CPString a string describing the transform
+30 -29
View File
@@ -21,7 +21,8 @@
*/
//import "CGPattern.j"
import "CGColorSpace.j"
@import "CGColorSpace.j"
// FIXME: Move this to Objective-J.js!!!
var CFTypeGlobalCount = 0;
@@ -45,7 +46,7 @@ function CGColorGetConstantColor(aColorName)
alert("FIX ME");
}
/*
/*!
This function is for source compatability.
*/
function CGColorRetain(aColor)
@@ -53,16 +54,16 @@ function CGColorRetain(aColor)
return aColor;
}
/*
/*!
This function is for source compatability.
*/
function CGColorRelease()
{
}
/*
Creates a new <objj>CGColor</objj>.
@param aColorSpace the <objj>CGColorSpace</objj> of the color
/*!
Creates a new CGColor.
@param aColorSpace the CGColorSpace of the color
@param components the color's intensity values plus alpha
@return CGColor the new color object
@group CGColor
@@ -84,11 +85,11 @@ function CGColorCreate(aColorSpace, components)
return _CGColorMap[UID] = { colorspace:aColorSpace, pattern:NULL, components:components };
}
/*
Creates a copy of a color... but not really. <objj>CGColor</objj>s
/*!
Creates a copy of a color... but not really. CGColors
are immutable, so to be efficient, this function will just
return the same object that was passed in.
@param aColor the <objj>CGColor</objj> to 'copy'
@param aColor the CGColor to 'copy'
@return CGColor the color copy
@group CGColor
*/
@@ -98,7 +99,7 @@ function CGColorCreateCopy(aColor)
return aColor;
}
/*
/*!
Creates a gray color object.
@param gray the value to use for the color intensities (<code>0.0-1.0</code>)
@param alpha the gray's alpha value (<code>0.0-1.0</code>)
@@ -110,7 +111,7 @@ function CGColorCreateGenericGray(gray, alpha)
return CGColorCreate(0, [gray, alpha]);
}
/*
/*!
Creates an RGB color.
@param red the red component (<code>0.0-1.0</code>)
@param green the green component (<code>0.0-1.0</code>)
@@ -124,7 +125,7 @@ function CGColorCreateGenericRGB(red, green, blue, alpha)
return CGColorCreate(0, [red, green, blue, alpha]);
}
/*
/*!
Creates a CMYK color.
@param cyan the cyan component (<code>0.0-1.0</code>)
@param magenta the magenta component (<code>0.0-1.0</code>)
@@ -139,7 +140,7 @@ function CGColorCreateGenericCMYK(cyan, magenta, yellow, black, alpha)
return CGColorCreate(0, [cyan, magenta, yellow, black, alpha]);
}
/*
/*!
Creates a copy of the color with a specified alpha.
@param aColor the color object to copy
@param anAlpha the new alpha component for the copy (<code>0.0-1.0</code>)
@@ -163,9 +164,9 @@ function CGColorCreateCopyWithAlpha(aColor, anAlpha)
return copy;
}
/*
/*!
Creates a color using the specified pattern.
@param aColorSpace the <objj>CGColorSpace</objj>
@param aColorSpace the CGColorSpace
@param aPattern the pattern image
@param components the color components plus the alpha component
@return CGColor the patterned color
@@ -179,10 +180,10 @@ function CGColorCreateWithPattern(aColorSpace, aPattern, components)
return { colorspace:aColorSpace, pattern:aPattern, components:components.slice() };
}
/*
/*!
Determines if two colors are the same.
@param lhs the first <objj>CGColor</objj>
@param rhs the second <objj>CGColor</objj>
@param lhs the first CGColor
@param rhs the second CGColor
@return <code>YES</code> if the two colors are equal.
<code>NO</code> otherwise.
*/
@@ -214,7 +215,7 @@ function CGColorEqualToColor(lhs, rhs)
return true;
}
/*
/*!
Returns the color's alpha component.
@param aColor the color
@return float the alpha component (<code>0.0-1.0</code>)
@@ -227,9 +228,9 @@ function CGColorGetAlpha(aColor)
return components[components.length - 1];
}
/*
Returns the <objj>CGColor</objj>'s color space.
@return <objj>CGColorSpace</objj>
/*!
Returns the CGColor's color space.
@return CGColorSpace
@group CGColor
*/
function CGColorGetColorSpace(aColor)
@@ -237,8 +238,8 @@ function CGColorGetColorSpace(aColor)
return aColor.colorspace;
}
/*
Returns the <objj>CGColor</objj>'s components
/*!
Returns the CGColor's components
including the alpha in an array.
@param aColor the color
@return CPArray the color's components
@@ -248,10 +249,10 @@ function CGColorGetComponents(aColor)
return aColor.components;
}
/*
/*!
Returns the number of color components
(including alpha) in the specified color.
@param aColor the <objj>CGColor</objj>
@param aColor the CGColor
@return CPNumber the number of components
@group CGColor
*/
@@ -260,9 +261,9 @@ function CGColorGetNumberOfComponents(aColor)
return aColor.components.length;
}
/*
Gets the <objj>CGColor</objj>'s pattern.
@param a <objj>CGColor</objj>
/*!
Gets the CGColor's pattern.
@param a CGColor
@return CGPatternFIXME the pattern image
@group CGColor
*/
+258 -197
View File
@@ -23,9 +23,9 @@
#include "CGGeometry.h"
#include "CGAffineTransform.h"
import "CGGeometry.j"
import "CGAffineTransform.j"
import "CGPath.j"
@import "CGGeometry.j"
@import "CGAffineTransform.j"
@import "CGPath.j"
kCGLineCapButt = 0;
kCGLineCapRound = 1;
@@ -41,148 +41,45 @@ kCGPathStroke = 2;
kCGPathFillStroke = 3;
kCGPathEOFillStroke = 4;
/*
@global
/*!
@group CGBlendMode
*/
kCGBlendModeNormal = 0;
/*
@global
@group CGBlendMode
*/
kCGBlendModeMultiply = 1;
/*
@global
@group CGBlendMode
*/
kCGBlendModeScreen = 2;
/*
@global
@group CGBlendMode
*/
kCGBlendModeOverlay = 3;
/*
@global
@group CGBlendMode
*/
kCGBlendModeDarken = 4;
/*
@global
@group CGBlendMode
*/
kCGBlendModeLighten = 5;
/*
@global
@group CGBlendMode
*/
kCGBlendModeColorDodge = 6;
/*
@global
@group CGBlendMode
*/
kCGBlendModeColorBurn = 7;
/*
@global
@group CGBlendMode
*/
kCGBlendModeSoftLight = 8;
/*
@global
@group CGBlendMode
*/
kCGBlendModeHardLight = 9;
/*
@global
@group CGBlendMode
*/
kCGBlendModeDifference = 10;
/*
@global
@group CGBlendMode
*/
kCGBlendModeExclusion = 11;
/*
@global
@group CGBlendMode
*/
kCGBlendModeHue = 12;
/*
@global
@group CGBlendMode
*/
kCGBlendModeSaturation = 13;
/*
@global
@group CGBlendMode
*/
kCGBlendModeColor = 14;
/*
@global
@group CGBlendMode
*/
kCGBlendModeLuminosity = 15;
/*
@global
@group CGBlendMode
*/
kCGBlendModeClear = 16;
/*
@global
@group CGBlendMode
*/
kCGBlendModeCopy = 17;
/*
@global
@group CGBlendMode
*/
kCGBlendModeSourceIn = 18;
/*
@global
@group CGBlendMode
*/
kCGBlendModeSourceOut = 19;
/*
@global
@group CGBlendMode
*/
kCGBlendModeSourceAtop = 20;
/*
@global
@group CGBlendMode
*/
kCGBlendModeDestinationOver = 21;
/*
@global
@group CGBlendMode
*/
kCGBlendModeDestinationIn = 22;
/*
@global
@group CGBlendMode
*/
kCGBlendModeDestinationOut = 23;
/*
@global
@group CGBlendMode
*/
kCGBlendModeDestinationAtop = 24;
/*
@global
@group CGBlendMode
*/
kCGBlendModeXOR = 25;
/*
@global
@group CGBlendMode
*/
kCGBlendModePlusDarker = 26;
/*
@global
@group CGBlendMode
*/
kCGBlendModePlusLighter = 27;
/*
/*!
@defgroup coregraphics CoreGraphics
@{
*/
/*!
This function is just here for source compatability.
It does nothing.
@group CGContext
@@ -191,7 +88,7 @@ function CGContextRelease()
{
}
/*
/*!
This function is just here for source compatability.
It does nothing.
@param aContext a CGContext
@@ -202,35 +99,64 @@ function CGContextRetain(aContext)
return aContext;
}
/*!
@cond
*/
// BEGIN CANVAS IF
if (!CPFeatureIsCompatible(CPHTMLCanvasFeature))
{
/*!
@endcond
*/
/*!
Creates a new graphics state, which describes all the current values for drawing.
@return a graphics state
*/
function CGGStateCreate()
{
return { strokeStyle:"#000", fillStyle:"#ccc", lineWidth:1.0, lineJoin:kCGLineJoinMiter, lineCap:kCGLineCapButt, miterLimit:10.0, globalAlpha:1.0,
return { alpha:1.0, strokeStyle:"#000", fillStyle:"#ccc", lineWidth:1.0, lineJoin:kCGLineJoinMiter, lineCap:kCGLineCapButt, miterLimit:10.0, globalAlpha:1.0,
blendMode:kCGBlendModeNormal,
shadowOffset:_CGSizeMakeZero(), shadowBlur:0.0, shadowColor:NULL, CTM:_CGAffineTransformMakeIdentity() };
}
/*!
Creates a copy of the given graphics state.
@param aGState the graphics state to copy
@return a copy of the given graphics state
*/
function CGGStateCreateCopy(aGState)
{
return { strokeStyle:aGState.strokeStyle, fillStyle:aGState.fillStyle, lineWidth:aGState.lineWidth,
return { alpha:aGState.alpha, strokeStyle:aGState.strokeStyle, fillStyle:aGState.fillStyle, lineWidth:aGState.lineWidth,
lineJoin:aGState.lineJoin, lineCap:aGState.lineCap, miterLimit:aGState.miterLimit, globalAlpha:aGState.globalAlpha,
blendMode:aGState.blendMode,
shadowOffset:aGState.shadowOffset, shadowBlur:aGState.shadowBlur, shadowColor:aGState.shadowColor, CTM:_CGAffineTransformMakeCopy(aGState.CTM) };
}
/*!
Returns a new graphics context.
@return CGContext a new graphics context which can be drawn into
*/
function CGBitmapGraphicsContextCreate()
{
return { DOMElement:document.createElement("div"), path:NULL, gState:CGGStateCreate(), gStateStack:[] };
}
/*!
Pushes the current graphics state of aContext onto the top of a stack.
@param aContext the CGContext to edit
@return void
*/
function CGContextSaveGState(aContext)
{
aContext.gStateStack.push(CGGStateCreateCopy(aContext.gState));
}
/*!
Pops the most recent graphics state of the top of the graphics stack and restores it.
@param aContext the CGContext to edit
@return void
*/
function CGContextRestoreGState(aContext)
{
aContext.gState = aContext.gStateStack.pop();
@@ -266,26 +192,67 @@ function CGContextAddArc(aContext, x, y, radius, startAngle, endAngle, clockwise
CGPathAddArc(aContext.path, aContext.gState.CTM, x, y, radius, startAngle, endAngle, clockwise);
}
/*!
Adds an arc to the current context that ends in the specified point.
@param aContext the CGContext to edit
@param x1 the x coordinate of the beginning of the arc
@param y1 the y coordinate of the beginning of the arc
@param x2 the x coordinate of the end of the arc
@param y2 the y coordinate of the end of the arc
@param radius the radius of the arc to be drawn
@return void
*/
function CGContextAddArcToPoint(aContext, x1, y1, x2, y2, radius)
{
CGPathAddArcToPoint(aContext.path, aContext.gState.CTM, x1, y1, x2, y2, radius);
}
/*!
Adds a cubic curve to the current context
@param aContext the CGContext to edit
@param cp1x the x coordinate of the first control point
@param cp1y the y coordinate of the first control point
@param cp2x the x coordinate of the second control point
@param cp2y the y coordinate of the second control point
@param x the x coordinate of the end of the curve
@param y the y coordinate of the end of the curve
@return void
*/
function CGContextAddCurveToPoint(aContext, cp1x, cp1y, cp2x, cp2y, x, y)
{
CGPathAddCurveToPoint(aContext.path, aContext.gState.CTM, cp1x, cp1y, cp2x, cp2y, x, y);
}
/*!
Adds a line to each element in the points array
@param aContext the CGContext to move
@param points an array of points that are to be consecutively executed as if they were individual addToPoint calls
@param count an upper bound on the number of points to use
@return void
*/
function CGContextAddLines(aContext, points, count)
{
CGPathAddLines(aContext.path, aContext.gState.CTM, points, count);
}
/*!
Adds a line from the current point to the x/y
@param aContext the CGContext to move
@param x the x coordinate of the end point of the line
@param y the y coordinate of the end point of the line
@return void
*/
function CGContextAddLineToPoint(aContext, x, y)
{
CGPathAddLineToPoint(aContext.path, aContext.gState.CTM, x, y);
}
/*!
Adds aPath to the current path in aContext
@param aContext the CGContext to add to
@param aPath the path to be added
@return void
*/
function CGContextAddPath(aContext, aPath)
{
if (!aContext || CGPathIsEmpty(aPath))
@@ -297,32 +264,71 @@ function CGContextAddPath(aContext, aPath)
CGPathAddPath(aContext.path, aContext.gState.CTM, aPath);
}
/*!
Adds a quadratic curve from the current point to the point specified by x/y, using the control point specified by cpx/cpy
@param aContext the CGContext to add the curve to
@param cpx the x coordinate for the curve's control point
@param cpy the y coordinate for the curve's control point
@param x the x coordinate for the end point of the curve
@param y the y coordinate for the end point of the curve
@return void
*/
function CGContextAddQuadCurveToPoint(aContext, cpx, cpy, x, y)
{
CGPathAddQuadCurveToPoint(aContext.path, aContext.gState.CTM, cpx, cpy, x, y);
}
/*!
Adds aRect to the current path in the given context
@param aContext the CGContext to add to
@param aRect the dimensions of the rectangle to add
@return void
*/
function CGContextAddRect(aContext, aRect)
{
CGPathAddRect(aContext.path, aContext.gState.CTM, aRect);
}
/*!
Adds up to count elements from rects to the current path in aContext
@param aContext the CGContext to add to
@param rects an array of CGRects to be added to the context's path
@param the upper bound of elements to be added
@return void
*/
function CGContextAddRects(aContext, rects, count)
{
CGPathAddRects(aContext.path, aContext.gState.CTM, rects, count);
}
/*!
Begins a new subpath in the given context
@param aContext the CGContext to create a new path in
@return void
*/
function CGContextBeginPath(aContext)
{
// This clears any previous path.
aContext.path = CGPathCreateMutable();
}
/*!
Closes the currently open subpath, if any, in aContext
@param aContext the CGContext to close a path in
@return void
*/
function CGContextClosePath(aContext)
{
CGPathCloseSubpath(aContext.path);
}
/*!
Moves the current location of aContext to the given x and y coordinates
@param aContext the CGContext to move
@param x the x location to move the context to
@param y the y location to move the context to
@return void
*/
function CGContextMoveToPoint(aContext, x, y)
{
if (!aContext.path)
@@ -331,14 +337,27 @@ function CGContextMoveToPoint(aContext, x, y)
CGPathMoveToPoint(aContext.path, aContext.gState.CTM, x, y);
}
/*!
Fills a rectangle in the given context with aRect dimensions, using the context's current fill color
@param aContext the CGContext to draw into
@param aRect the dimensions of the rectangle to fill
@return void
*/
function CGContextFillRect(aContext, aRect)
{
CGContextFillRects(aContext, [aRect], 1);
}
/*!
Fills a rectangle in the given context for each CGRect in the given array, up to a total of count rects
@param aContext the CGContext to draw into
@param rects an array of rects to fill
@param count the maximum number of rects from the given array to fill
@return void
*/
function CGContextFillRects(aContext, rects, count)
{
if (arguments["count"] == NULL)
if (arguments[2] === undefined)
var count = rects.length;
CGContextBeginPath(aContext);
@@ -348,6 +367,12 @@ function CGContextFillRects(aContext, rects, count)
CGContextDrawPath(aContext, kCGPathFill);
}
/*!
Strokes a rectangle with the given location into the given context, using the context's current width and color
@param aContext the CGContext to draw into
@param aRect a CGRect indicating the dimensions of the rectangle to be drawn
@return void
*/
function CGContextStrokeRect(aContext, aRect)
{
CGContextBeginPath(aContext);
@@ -357,6 +382,13 @@ function CGContextStrokeRect(aContext, aRect)
CGContextDrawPath(aContext, kCGPathStroke);
}
/*!
Strokes a rectangle with the given dimensions and the given stroke width
@param aContext the CGContext to draw into
@param aRect the CGRect indicating the bounds of the rect to be drawn
@param aWidth the width with which to stroke the rect
@return void
*/
function CGContextStrokeRectWithWidth(aContext, aRect, aWidth)
{
CGContextSaveGState(aContext);
@@ -367,6 +399,12 @@ function CGContextStrokeRectWithWidth(aContext, aRect, aWidth)
CGContextRestoreGState(aContext);
}
/*!
Concatenates the given transformation matrix onto the current transformation matrix in aContext
@param aContext the CGContext to transform
@param aTransform the CGAffineTransform to apply to the given context
@return void
*/
function CGContextConcatCTM(aContext, aTransform)
{
var CTM = aContext.gState.CTM;
@@ -374,11 +412,23 @@ function CGContextConcatCTM(aContext, aTransform)
_CGAffineTransformConcatTo(CTM, aTransform, CTM);
}
/*!
Returns the current transformation matrix for the given context
@param aContext the CGContext for which we are asking for the transform
@return CGAffineTransform the current transformation matrix of the given context
*/
function CGContextGetCTM(aContext)
{
return aContext.gState.CTM;
}
/*!
Rotates the current context by anAngle radians
@param aContext the CGContext to rotate
@param anAngle the amount to rotate, in radians
@return void
*/
function CGContextRotateCTM(aContext, anAngle)
{
var gState = aContext.gState;
@@ -386,6 +436,13 @@ function CGContextRotateCTM(aContext, anAngle)
gState.CTM = CGAffineTransformRotate(gState.CTM, anAngle);
}
/*!
Scales the current context by sx/sy
@param aContext the CGContext to scale
@param sx the amount to scale in the x direction
@param sy the amount to scale in the y direction
@return void
*/
function CGContextScaleCTM(aContext, sx, sy)
{
var gState = aContext.gState;
@@ -393,6 +450,13 @@ function CGContextScaleCTM(aContext, sx, sy)
gState.CTM = _CGAffineTransformScale(gState.CTM, sx, sy);
}
/*!
Translates the given context by tx in the x direction and ty in the y direction
@param aContext the CGContext to translate
@param tx the amount to move in the x direction
@param ty the amount to move in the y direction
@return void
*/
function CGContextTranslateCTM(aContext, tx, ty)
{
var gState = aContext.gState;
@@ -400,6 +464,14 @@ function CGContextTranslateCTM(aContext, tx, ty)
gState.CTM = _CGAffineTransformTranslate(gState.CTM, tx, ty);
}
/*!
Sets the current offset, and blur for shadows in core graphics drawing operations
@param aContext the CGContext of the shadow
@param aSize a CGSize indicating the offset of the shaodw
@param aBlur a float indicating the blur radius
@return void
*/
function CGContextSetShadow(aContext, aSize, aBlur)
{
var gState = aContext.gState;
@@ -409,6 +481,14 @@ function CGContextSetShadow(aContext, aSize, aBlur)
gState.shadowColor = [CPColor shadowColor];
}
/*!
Sets the current offset, blur, and color for shadows in core graphics drawing operations
@param aContext the CGContext of the shadow
@param aSize a CGSize indicating the offset of the shaodw
@param aBlur a float indicating the blur radius
@param aColor a CPColor object indicating the color of the shadow
@return void
*/
function CGContextSetShadowWithColor(aContext, aSize, aBlur, aColor)
{
var gState = aContext.gState;
@@ -418,25 +498,40 @@ function CGContextSetShadowWithColor(aContext, aSize, aBlur, aColor)
gState.shadowColor = aColor;
}
/*!
Sets the current alpha value for core graphics drawing operations in the given context .
@param aContext the CGContext who's alpha value should be updated
@param anAlpha the new alpha value. 1.0 is completely opaque, 0.0 is completely transparent.
@return void
*/
function CGContextSetAlpha(aContext, anAlpha)
{
aContext.gState.alpha = MAX(MIN(anAlpha, 1.0), 0.0);
}
/*!
@cond
*/
} // END CANVAS IF
/*!
@endcond
*/
// GOOD.
/*
/*!
Fills in the area of the current path, using the even-odd fill rule.
@param aContext the CGContext of the path
@return void
@group CGContext
*/
function CGContextEOFillPath(aContext)
{
CGContextDrawPath(aContext, kCGPathEOFill);
}
/*
/*!
Fills in the area of the current path, using the non-zero winding number rule.
@param aContext the CGContext of the path
@return void
@group CGContext
*/
function CGContextFillPath(aContext)
{
@@ -445,73 +540,56 @@ function CGContextFillPath(aContext)
var KAPPA = 4.0 * ((SQRT2 - 1.0) / 3.0);
/*
/*!
Draws the outline of an ellipse bounded by a rectangle.
@param aContext CGContext to draw on
@param aRect the rectangle bounding the ellipse
@return void
@group CGContext
*/
function CGContextAddEllipseInRect(aContext, aRect)
{
CGContextBeginPath(aContext);
if (_CGRectGetWidth(aRect) == _CGRectGetHeight(aRect))
CGContextAddArc(aContext, _CGRectGetMidX(aRect), _CGRectGetMidY(aRect), _CGRectGetWidth(aRect) / 2.0, 0.0, 2 * PI, YES);
else
{
var axis = _CGSizeMake(_CGRectGetWidth(aRect) / 2.0, _CGRectGetHeight(aRect) / 2.0),
center = _CGPointMake(_CGRectGetMinX(aRect) + axis.width, _CGRectGetMinY(aRect) + axis.height);
CGContextMoveToPoint(aContext, center.x, center.y - axis.height);
CGContextAddCurveToPoint(aContext, center.x + (KAPPA * axis.width), center.y - axis.height, center.x + axis.width, center.y - (KAPPA * axis.height), center.x + axis.width, center.y);
CGContextAddCurveToPoint(aContext, center.x + axis.width, center.y + (KAPPA * axis.height), center.x + (KAPPA * axis.width), center.y + axis.height, center.x, center.y + axis.height);
CGContextAddCurveToPoint(aContext, center.x - (KAPPA * axis.width), center.y + axis.height, center.x - axis.width, center.y + (KAPPA * axis.height), center.x - axis.width, center.y);
CGContextAddCurveToPoint(aContext, center.x - axis.width, center.y - (KAPPA * axis.height), center.x - (KAPPA * axis.width), center.y - axis.height, center.x, center.y - axis.height);
}
CGContextClosePath(aContext);
CGContextAddPath(aContext, CGPathWithEllipseInRect(aRect));
}
/*
/*!
Fills an ellipse bounded by a rectangle.
@param aContext CGContext to draw on
@param aRect the rectangle bounding the ellipse
@return void
@group CGContext
*/
function CGContextFillEllipseInRect(aContext, aRect)
{
CGContextBeginPath(aContext);
CGContextAddEllipseInRect(aContext, aRect);
CGContextClosePath(aContext);
CGContextFillPath(aContext);
}
/*
/*!
Strokes an ellipse bounded by the specified rectangle.
@param aContext CGContext to draw on
@param aRect the rectangle bounding the ellipse
@return void
@group CGContext
*/
function CGContextStrokeEllipseInRect(aContext, aRect)
{
CGContextBeginPath(aContext);
CGContextAddEllipseInRect(aContext, aRect);
CGContextClosePath(aContext);
CGContextStrokePath(aContext);
}
/*
/*!
Paints a line in the current path of the current context.
@param aContext CGContext to draw on
@return void
@group CGContext
*/
function CGContextStrokePath(aContext)
{
CGContextDrawPath(aContext, kCGPathStroke);
}
/*
/*!
Strokes multiple line segments.
@param aContext CGContext to draw on
@param points an array with an even number of points. The
@@ -520,7 +598,6 @@ function CGContextStrokePath(aContext)
the beginning of second line segment, etc.
@param count the number of points in the array
@return void
@group CGContext
*/
function CGContextStrokeLineSegments(aContext, points, count)
{
@@ -543,12 +620,11 @@ function CGContextStrokeLineSegments(aContext, points, count)
//FIXME: THIS IS WRONG!!!
/*
/*!
Sets the current fill color.
@param aContext the CGContext
@param aColor the new color for the fill
@return void
@group CGContext
*/
function CGContextSetFillColor(aContext, aColor)
@@ -557,12 +633,11 @@ function CGContextSetFillColor(aContext, aColor)
aContext.gState.fillStyle = [aColor cssString];
}
/*
/*!
Sets the current stroke color.
@param aContext the CGContext
@param aColor the new color for the stroke
@return void
@group CGContext
*/
function CGContextSetStrokeColor(aContext, aColor)
{
@@ -570,7 +645,7 @@ function CGContextSetStrokeColor(aContext, aColor)
aContext.gState.strokeStyle = [aColor cssString];
}
/*
/*!
Fills a rounded rectangle.
@param aContext the CGContext to draw into
@param aRect the base rectangle
@@ -580,54 +655,37 @@ function CGContextSetStrokeColor(aContext, aColor)
@param sw set it to <code>YES</code> for a rounded southwest corner
@param nw set it to <code>YES</code> for a rounded northwest corner
@return void
@group CGContext
*/
function CGContextFillRoundedRectangleInRect(aContext, aRect, aRadius, ne, se, sw, nw)
{
var xMin = _CGRectGetMinX(aRect),
xMax = _CGRectGetMaxX(aRect),
yMin = _CGRectGetMinY(aRect),
yMax = _CGRectGetMaxY(aRect);
CGContextBeginPath(aContext);
CGContextMoveToPoint(aContext, xMin + aRadius, yMin);
if (ne)
{
CGContextAddLineToPoint(aContext, xMax - aRadius, yMin);
CGContextAddCurveToPoint(aContext, xMax - aRadius, yMin, xMax, yMin, xMax, yMin + aRadius);
}
else
CGContextAddLineToPoint(aContext, xMax, yMin);
if (se)
{
CGContextAddLineToPoint(aContext, xMax, yMax - aRadius);
CGContextAddCurveToPoint(aContext, xMax, yMax - aRadius, xMax, yMax, xMax - aRadius, yMax);
}
else
CGContextAddLineToPoint(aContext, xMax, yMax);
if (sw)
{
CGContextAddLineToPoint(aContext, xMin + aRadius, yMax);
CGContextAddCurveToPoint(aContext, xMin + aRadius, yMax, xMin, yMax, xMin, yMax - aRadius);
}
else
CGContextAddLineToPoint(aContext, xMin, yMax);
if (nw)
{
CGContextAddLineToPoint(aContext, xMin, yMin + aRadius);
CGContextAddCurveToPoint(aContext, xMin, yMin + aRadius, xMin, yMin, xMin + aRadius, yMin);
} else
CGContextAddLineToPoint(aContext, xMin, yMin);
CGContextClosePath(aContext);
CGContextAddPath(aContext, CGPathWithRoundedRectangleInRect(aRect, aRadius, aRadius, ne, se, sw, nw));
CGContextFillPath(aContext);
}
/*!
Strokes a rounded rectangle.
@param aContext the CGContext to draw into
@param aRect the base rectangle
@param aRadius the distance from the rectange corner to the rounded corner
@param ne set it to <code>YES</code> for a rounded northeast corner
@param se set it to <code>YES</code> for a rounded southeast corner
@param sw set it to <code>YES</code> for a rounded southwest corner
@param nw set it to <code>YES</code> for a rounded northwest corner
@return void
*/
function CGContextStrokeRoundedRectangleInRect(aContext, aRect, aRadius, ne, se, sw, nw)
{
CGContextAddPath(aContext, CGPathWithRoundedRectangleInRect(aRect, aRadius, aRadius, ne, se, sw, nw));
CGContextStrokePath(aContext);
}
/*!
@}
*/
/*!
@cond
*/
if (CPFeatureIsCompatible(CPHTMLCanvasFeature))
{
#include "CGContextCanvas.j"
@@ -636,3 +694,6 @@ else if (CPFeatureIsCompatible(CPVMLFeature))
{
#include "CGContextVML.j"
}
/*!
@endcond
*/
+16 -1
View File
@@ -333,7 +333,20 @@ function eigen(anAffineTransform)
alert("IMPLEMENT ME!");
}
function CGContextConcatCTM(aContext, anAffineTransform)
if (CPFeatureIsCompatible(CPJavaScriptCanvasTransformFeature))
{
CGContextConcatCTM = function(aContext, anAffineTransform)
{
aContext.transform(anAffineTransform.a, anAffineTransform.b, anAffineTransform.c, anAffineTransform.d, anAffineTransform.tx, anAffineTransform.ty);
}
}
else
{
CGContextConcatCTM = function(aContext, anAffineTransform)
{
var a = anAffineTransform.a,
b = anAffineTransform.b,
@@ -399,6 +412,8 @@ function CGContextConcatCTM(aContext, anAffineTransform)
CGContextRotateCTM(aContext, a2);
}
}
function CGContextDrawImage(aContext, aRect, anImage)
{
aContext.drawImage(anImage._image, _CGRectGetMinX(aRect), _CGRectGetMinY(aRect), _CGRectGetWidth(aRect), _CGRectGetHeight(aRect));
+62 -2
View File
@@ -111,7 +111,7 @@ function CGContextDrawPath(aContext, aMode)
{
if (!aContext || CGPathIsEmpty(aContext.path))
return;
var opacity = 1.0;
var elements = aContext.path.elements,
i = 0,
@@ -120,6 +120,7 @@ var opacity = 1.0;
gState = aContext.gState,
fill = (aMode == kCGPathFill || aMode == kCGPathFillStroke) ? 1 : 0,
stroke = (aMode == kCGPathStroke || aMode == kCGPathFillStroke) ? 1 : 0,
opacity = gState.alpha,
vml = [ "<cg_vml_:shape",
" fillcolor=\"", gState.fillStyle,
"\" filled=\"", VML_TRUTH_TABLE[fill],
@@ -228,7 +229,10 @@ var opacity = 1.0;
vml.push("\">");
if (fill)
if (gState.gradient)
vml.push(gState.gradient)
else if (fill)
vml.push("<cg_vml_:fill color=\"", gState.fillStyle, "\" opacity=\"", opacity, "\" />");
if (stroke)
@@ -259,3 +263,59 @@ var opacity = 1.0;
aContext.DOMElement.insertAdjacentHTML("BeforeEnd", vml.join(""));
}
function to_string(aColor)
{
return "rgb(" + ROUND(aColor.components[0] * 255) + ", " + ROUND(aColor.components[1] * 255) + ", " + ROUND(255 * aColor.components[2]) + ")";
}
function CGContextDrawLinearGradient(aContext, aGradient, aStartPoint, anEndPoint, options)
{
if (!aContext || !aGradient)
return;
var vml = nil;
if (aGradient.vml_gradient)
{
var stops = [[aGradient.vml_gradient stops] sortedArrayUsingSelector:@selector(comparePosition:)],
count = [stops count];
vml = ["<cg_vml_:fill type=\"gradient\" method=\"linear sigma\" "];
vml.push("angle=\"" + ([aGradient.vml_gradient angle] + 90) +"\" ");
vml.push("colors=\"");
for (var i = 0; i < count; i++)
{
vml.push(([stops[i] position]*100).toFixed(0)+"% ");
vml.push([[[stops[i] color] colorForSlideBase:nil] cssString]);
if (i < count-1)
vml.push(",");
}
vml.push("\" />");
}
else
{
var colors = aGradient.colors,
count = colors.length;
vml = ["<cg_vml_:fill type=\"gradient\" "];
vml.push("colors=\"");
for (var i = 0; i < count; i++)
vml.push((aGradient.locations[i]*100).toFixed(0)+"% "+to_string(colors[i])+(i<count-1 ? "," : ""));
vml.push("\" />");
}
aContext.gState.gradient = vml.join("");
console.log(vml.join(""));
// if (aContext.buffer != nil)
// aContext.buffer += vml.join("");
// else
// aContext.DOMElement.innerHTML = vml.join("");
}
+5
View File
@@ -59,6 +59,11 @@
#define _CGRectContainsPoint(aRect, aPoint) (aPoint.x >= _CGRectGetMinX(aRect) && aPoint.y >= _CGRectGetMinY(aRect) && aPoint.x < _CGRectGetMaxX(aRect) && aPoint.y < _CGRectGetMaxY(aRect))
#define _CGInsetMake(_top, _right, _bottom, _left) { top:(_top), right:(_right), bottom:(_bottom), left:(_left) }
#define _CGInsetMakeCopy(anInset) _CGInsetMake(anInset.top, anInset.right, anInset.bottom, anInset.left)
#define _CGInsetMakeZero() _CGInsetMake(0, 0, 0, 0)
#define _CGInsetIsEmpty(anInset) ((anInset).top === 0 && (anInset).right === 0 && (anInset).bottom === 0 && (anInset).left === 0)
// DEPRECATED
#define _CGPointCreateCopy(aPoint) _CGPointMake(aPoint.x, aPoint.y)
#define _CGSizeCreateCopy(aSize) _CGSizeMake(aSize.width, aSize.height)
+40 -12
View File
@@ -65,12 +65,22 @@ _function(CGRectIsNull(aRect))
_function(CGRectContainsPoint(aRect, aPoint))
/*
Returns a <code>BOOL</code> indicating whether <objj>CGRect</objj> <code>lhsRect</code>
contains <objj>CGRect</objj> <code>rhsRect</code>.
_function(CGInsetMake(top, right, bottom, left))
_function(CGInsetMakeZero())
_function(CGInsetMakeCopy(anInset))
_function(CGInsetIsEmpty(anInset))
/*!
@addtogroup appkit
@{
*/
/*!
Returns a <code>BOOL</code> indicating whether CGRect <code>lhsRect</code>
contains CGRect <code>rhsRect</code>.
@group CGRect
@param lhsRect the <objj>CGRect</objj> to test if <code>rhsRect</code> is inside of
@param rhsRect the <objj>CGRect</objj> to test if it fits inside <code>lhsRect</code>.
@param lhsRect the CGRect to test if <code>rhsRect</code> is inside of
@param rhsRect the CGRect to test if it fits inside <code>lhsRect</code>.
@return BOOL <code>YES</code> if <code>rhsRect</code> fits inside <code>lhsRect</code>.
*/
function CGRectContainsRect(lhsRect, rhsRect)
@@ -80,11 +90,11 @@ function CGRectContainsRect(lhsRect, rhsRect)
return _CGRectEqualToRect(union, lhsRect);
}
/*
/*!
Returns <code>YES</code> if the two rectangles intersect
@group CGRect
@param lhsRect the first <objj>CGRect</objj>
@param rhsRect the second <objj>CGRect</objj>
@param lhsRect the first CGRect
@param rhsRect the second CGRect
@return BOOL <code>YES</code> if the two rectangles have any common spaces, and <code>NO</code>, otherwise.
*/
function CGRectIntersectsRect(lhsRect, rhsRect)
@@ -94,9 +104,9 @@ function CGRectIntersectsRect(lhsRect, rhsRect)
return !_CGRectIsEmpty(intersection);
}
/*
Makes the origin and size of a <objj>CGRect</objj> all integers. Specifically, by making
the southwest corner the origin (rounded down), and the northeast corner a <objj>CGSize</objj> (rounded up).
/*!
Makes the origin and size of a CGRect all integers. Specifically, by making
the southwest corner the origin (rounded down), and the northeast corner a CGSize (rounded up).
@param aRect the rectangle to operate on
@return CGRect the modified rectangle (same as the input)
@group CGRect
@@ -118,7 +128,7 @@ function CGRectIntegral(aRect)
return aRect;
}
/*
/*!
Returns the intersection of the two provided rectangles as a new rectangle.
@param lhsRect the first rectangle used for calculation
@param rhsRect the second rectangle used for calculation
@@ -203,3 +213,21 @@ function CGPointFromEvent(anEvent)
{
return _CGPointMake(anEvent.clientX, anEvent.clientY);
}
function CGInsetFromString(aString)
{
var numbers = aString.substr(1, aString.length - 2).split(',');
return _CGInsetMake(parseFloat(numbers[0]), parseFloat(numbers[1]), parseFloat(numbers[2]), parseFloat(numbers[3]));
}
CGInsetFromCPString = CGInsetFromString;
function CPStringFromCGInset(anInset)
{
return '{' + anInset.top + ", " + anInset.left + ", " + anInset.bottom + ", " + anInset.right + '}';
}
/*!
@}
*/
+3 -2
View File
@@ -20,8 +20,9 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
import "CGColor.j"
import "CGColorSpace.j"
@import "CGColor.j"
@import "CGColorSpace.j"
kCGGradientDrawsBeforeStartLocation = 1 << 0;
kCGGradientDrawsAfterEndLocation = 1 << 1;
+132 -20
View File
@@ -23,8 +23,9 @@
#include "CGGeometry.h"
#include "CGAffineTransform.h"
import "CGGeometry.j"
import "CGAffineTransform.j"
@import "CGGeometry.j"
@import "CGAffineTransform.j"
kCGPathElementMoveToPoint = 0;
kCGPathElementAddLineToPoint = 1;
@@ -35,11 +36,23 @@ kCGPathElementCloseSubpath = 4;
kCGPathElementAddArc = 5;
kCGPathElementAddArcToPoint = 6;
/*!
@addtogroup coregraphics
@{
*/
/*!
Returns a new CGPath object.
*/
function CGPathCreateMutable()
{
return { count:0, start:NULL, current:NULL, elements:[] };
}
/*!
Returns a copy of the given path object.
*/
function CGPathCreateMutableCopy(aPath)
{
var path = CGPathCreateMutable();
@@ -49,6 +62,10 @@ function CGPathCreateMutableCopy(aPath)
return path;
}
/*!
Returns a copy of the given path object.
*/
function CGPathCreateCopy(aPath)
{
return CGPathCreateMutableCopy(aPath);
@@ -70,20 +87,20 @@ function CGPathAddArc(aPath, aTransform, x, y, aRadius, aStartAngle, anEndAngle,
var center = _CGPointMake(x, y),
end = _CGPointMake(COS(anEndAngle), SIN(anEndAngle)),
start = _CGPointMake(COS(aStartAngle), SIN(aStartAngle));
end = _CGPointApplyAffineTransform(end, aTransform);
start = _CGPointApplyAffineTransform(start, aTransform);
center = _CGPointApplyAffineTransform(center, aTransform);
x = center.x;
y = center.y;
var oldEndAngle = anEndAngle,
oldStartAngle = aStartAngle;
anEndAngle = ATAN2(end.y - aTransform.ty, end.x - aTransform.tx);
aStartAngle = ATAN2(start.y - aTransform.ty, start.x - aTransform.tx);
// Angles that equal "modulo" 2 pi return as equal after transforming them,
// so we have to make sure to make them different again if they were different
// to start out with. It's the difference between no circle and a full circle.
@@ -92,7 +109,7 @@ function CGPathAddArc(aPath, aTransform, x, y, aRadius, aStartAngle, anEndAngle,
anEndAngle = anEndAngle - PI2;
else
aStartAngle = aStartAngle - PI2;
aRadius = _CGSizeMake(aRadius, 0);
aRadius = _CGSizeApplyAffineTransform(aRadius, aTransform);
aRadius = SQRT(aRadius.width * aRadius.width + aRadius.height * aRadius.height);
@@ -152,20 +169,38 @@ function CGPathAddLineToPoint(aPath, aTransform, x, y)
function CGPathAddPath(aPath, aTransform, anotherPath)
{
var i = 0,
count = anotherPath.count;
for (; i < count; ++i)
for (var i = 0, count = anotherPath.count; i < count; ++i)
{
var element = anotherPath[i];
aPath.elements[aPath.count++] = { type:element.type, points:element.point.slice() };
if (element.type == kCGPathElementAddArc || element.type == kCGPathElementAddArcToPoint)
aPath.elements[aPath.count - 1].radius = element.radius;
var element = anotherPath.elements[i];
switch (element.type)
{
case kCGPathElementAddLineToPoint: CGPathAddLineToPoint(aPath, aTransform, element.x, element.y);
break;
case kCGPathElementAddCurveToPoint: CGPathAddCurveToPoint(aPath, aTransform,
element.cp1x, element.cp1y,
element.cp2x, element.cp2y,
element.x, element.y);
break;
case kCGPathElementAddArc: CGPathAddArc(aPath, aTransform, element.x, element.y,
element.radius, element.startAngle,
element.endAngle, element.isClockwise);
break;
case kCGPathElementAddQuadCurveToPoint: CGPathAddQuadCurveToPoint(aPath, aTransform,
element.cpx, element.cpy,
element.x, element.y);
break;
case kCGPathElementMoveToPoint: CGPathMoveToPoint(aPath, aTransform, element.x, element.y);
break;
case kCGPathElementCloseSubpath: CGPathCloseSubpath(aPath);
break;
}
}
aPath.current = anotherPath.current;
}
function CGPathAddQuadCurveToPoint(aPath, aTransform, cpx, cpy, x, y)
@@ -230,6 +265,78 @@ function CGPathMoveToPoint(aPath, aTransform, x, y)
aPath.elements[aPath.count++] = { type:kCGPathElementMoveToPoint, x:point.x, y:point.y };
}
var KAPPA = 4.0 * ((SQRT2 - 1.0) / 3.0);
function CGPathWithEllipseInRect(aRect)
{
var path = CGPathCreateMutable();
if (_CGRectGetWidth(aRect) == _CGRectGetHeight(aRect))
CGPathAddArc(path, nil, _CGRectGetMidX(aRect), _CGRectGetMidY(aRect), _CGRectGetWidth(aRect) / 2.0, 0.0, 2 * PI, YES);
else
{
var axis = _CGSizeMake(_CGRectGetWidth(aRect) / 2.0, _CGRectGetHeight(aRect) / 2.0),
center = _CGPointMake(_CGRectGetMinX(aRect) + axis.width, _CGRectGetMinY(aRect) + axis.height);
CGPathMoveToPoint(path, nil, center.x, center.y - axis.height);
CGPathAddCurveToPoint(path, nil, center.x + (KAPPA * axis.width), center.y - axis.height, center.x + axis.width, center.y - (KAPPA * axis.height), center.x + axis.width, center.y);
CGPathAddCurveToPoint(path, nil, center.x + axis.width, center.y + (KAPPA * axis.height), center.x + (KAPPA * axis.width), center.y + axis.height, center.x, center.y + axis.height);
CGPathAddCurveToPoint(path, nil, center.x - (KAPPA * axis.width), center.y + axis.height, center.x - axis.width, center.y + (KAPPA * axis.height), center.x - axis.width, center.y);
CGPathAddCurveToPoint(path, nil, center.x - axis.width, center.y - (KAPPA * axis.height), center.x - (KAPPA * axis.width), center.y - axis.height, center.x, center.y - axis.height);
}
CGPathCloseSubpath(path);
return path;
}
function CGPathWithRoundedRectangleInRect(aRect, xRadius, yRadius/*not currently supported*/, ne, se, sw, nw)
{
var path = CGPathCreateMutable(),
xMin = _CGRectGetMinX(aRect),
xMax = _CGRectGetMaxX(aRect),
yMin = _CGRectGetMinY(aRect),
yMax = _CGRectGetMaxY(aRect);
CGPathMoveToPoint(path, nil, xMin + xRadius, yMin);
if (ne)
{
CGPathAddLineToPoint(path, nil, xMax - xRadius, yMin);
CGPathAddCurveToPoint(path, nil, xMax - xRadius, yMin, xMax, yMin, xMax, yMin + xRadius);
}
else
CGPathAddLineToPoint(path, nil, xMax, yMin);
if (se)
{
CGPathAddLineToPoint(path, nil, xMax, yMax - xRadius);
CGPathAddCurveToPoint(path, nil, xMax, yMax - xRadius, xMax, yMax, xMax - xRadius, yMax);
}
else
CGPathAddLineToPoint(path, nil, xMax, yMax);
if (sw)
{
CGPathAddLineToPoint(path, nil, xMin + xRadius, yMax);
CGPathAddCurveToPoint(path, nil, xMin + xRadius, yMax, xMin, yMax, xMin, yMax - xRadius);
}
else
CGPathAddLineToPoint(path, nil, xMin, yMax);
if (nw)
{
CGPathAddLineToPoint(path, nil, xMin, yMin + xRadius);
CGPathAddCurveToPoint(path, nil, xMin, yMin + xRadius, xMin, yMin, xMin + xRadius, yMin);
} else
CGPathAddLineToPoint(path, nil, xMin, yMin);
CGPathCloseSubpath(path);
return path;
}
function CGPathCloseSubpath(aPath)
{
var count = aPath.count;
@@ -283,3 +390,8 @@ function CGPathIsEmpty(aPath)
{
return !aPath || aPath.count == 0;
}
/*!
@}
*/
+4
View File
@@ -4,6 +4,10 @@
<dict>
<key>CPBundleIdentifier</key>
<string>com.280n.AppKit</string>
<key>Default Themes Path</key>
<string>Default.cptheme</string>
<key>Default Theme Name</key>
<string>Default</string>
<key>CPBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CPBundleName</key>
+2 -1
View File
@@ -20,7 +20,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
import <Foundation/CPRunLoop.j>
@import <Foundation/CPRunLoop.j>
#include "../../CoreGraphics/CGAffineTransform.h"
#include "CPDOMDisplayServer.h"
@@ -152,6 +152,7 @@ CPDOMDisplayServerViewsContext = {};
delete CPDOMDisplayServerViewsContext[[view hash]];
[view layoutIfNeeded];
[view displayIfNeeded];
}
}
+163 -65
View File
@@ -20,13 +20,13 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
import <Foundation/CPObject.j>
import <Foundation/CPRunLoop.j>
@import <Foundation/CPObject.j>
@import <Foundation/CPRunLoop.j>
import "CPEvent.j"
import "CPCompatibility.j"
@import "CPEvent.j"
@import "CPCompatibility.j"
import "CPDOMWindowLayer.j"
@import "CPDOMWindowLayer.j"
#import "../../CoreGraphics/CGGeometry.h"
@@ -35,6 +35,11 @@ CPSharedDOMWindowBridge = nil;
var ExcludedDOMElements = [];
// Define up here so compressor knows about em.
var CPDOMWindowGetFrame,
CPDOMEventGetClickCount,
CPDOMEventStop;
@implementation CPDOMWindowBridge : CPObject
{
CPArray _orderedWindows;
@@ -54,8 +59,6 @@ var ExcludedDOMElements = [];
CPTimeInterval _lastMouseUp;
CPTimeInterval _lastMouseDown;
CPPoint _currentMousePosition;
JSObject _charCodes;
unsigned _keyCode;
@@ -68,7 +71,7 @@ var ExcludedDOMElements = [];
CPString _overriddenEventType;
}
/*
/*!
Returns the shared DOMWindowBridge.
*/
+ (id)sharedDOMWindowBridge
@@ -100,7 +103,10 @@ var ExcludedDOMElements = [];
_DOMBodyElement = document.getElementsByTagName("body")[0];
_DOMBodyElement.innerHTML = ""; // Get rid of anything that might be lingering in the body element.
_DOMBodyElement.style.overflow = "hidden";
_DOMBodyElement.style.webkitTouchCallout = "none";
[CPString _resetSize];
if (document.documentElement)
document.documentElement.style.overflow = "hidden";
@@ -146,6 +152,10 @@ var ExcludedDOMElements = [];
resizeEventImplementation = class_getMethodImplementation(theClass, resizeEventSelector),
resizeEventCallback = function (anEvent) { resizeEventImplementation(self, nil, anEvent); },
touchEventSelector = @selector(_bridgeTouchEvent:),
touchEventImplementation = class_getMethodImplementation(theClass, touchEventSelector),
touchEventCallback = function (anEvent) { touchEventImplementation(self, nil, anEvent); },
theDocument = _DOMWindow.document;
if (document.addEventListener)
@@ -160,6 +170,12 @@ var ExcludedDOMElements = [];
theDocument.addEventListener(CPDOMEventKeyDown, keyEventCallback, NO);
theDocument.addEventListener(CPDOMEventKeyPress, keyEventCallback, NO);
theDocument.addEventListener(CPDOMEventTouchStart, touchEventCallback, NO);
theDocument.addEventListener(CPDOMEventTouchEnd, touchEventCallback, NO);
theDocument.addEventListener(CPDOMEventTouchMove, touchEventCallback, NO);
theDocument.addEventListener(CPDOMEventTouchCancel, touchEventCallback, NO);
//FIXME: does firefox really need a different value?
_DOMWindow.addEventListener("DOMMouseScroll", scrollEventCallback, NO);
_DOMWindow.addEventListener(CPDOMEventScrollWheel, scrollEventCallback, NO);
@@ -220,6 +236,16 @@ var ExcludedDOMElements = [];
return CPRectCreateCopy(_contentBounds);
}
- (CPArray)orderedWindowsAtLevel:(int)aLevel
{
var layer = [self layerAtLevel:aLevel create:NO];
if (!layer)
return [];
return [layer orderedWindows];
}
- (CPDOMWindowLayer)layerAtLevel:(int)aLevel create:(BOOL)aFlag
{
var layer = [_windowLayers objectForKey:aLevel];
@@ -272,14 +298,13 @@ var ExcludedDOMElements = [];
}
/* @ignore */
- (CPView)_dragHitTest:(CPPoint)aPoint pasteboard:(CPPasteboard)aPasteboard
- (id)_dragHitTest:(CPPoint)aPoint pasteboard:(CPPasteboard)aPasteboard
{
var view = nil,
levels = _windowLevels,
var levels = _windowLevels,
layers = _windowLayers,
levelCount = levels.length;
while (levelCount-- && !view)
while (levelCount--)
{
// Skip any windows above or at the dragging level.
if (levels[levelCount] >= CPDraggingWindowLevel)
@@ -290,18 +315,14 @@ var ExcludedDOMElements = [];
while (windowCount--)
{
var theWindow = windows[windowCount],
frame = theWindow._frame;
var theWindow = windows[windowCount];
if (CPRectContainsPoint(frame, aPoint))
if (view = [theWindow._windowView _dragHitTest:CGPointMake(aPoint.x - frame.origin.x, aPoint.y - frame.origin.y) pasteboard:aPasteboard])
return view;
else
return nil;
if ([theWindow containsPoint:aPoint])
return [theWindow _dragHitTest:aPoint pasteboard:aPasteboard];
}
}
return view;
return nil;
}
/* @ignore */
@@ -323,10 +344,14 @@ var ExcludedDOMElements = [];
windowCount = windows.length;
while (windowCount-- && !theWindow)
if (CPRectContainsPoint(windows[windowCount]._frame, location))
theWindow = windows[windowCount];
{
var candidateWindow = windows[windowCount];
if (!candidateWindow._ignoresMouseEvents && [candidateWindow containsPoint:location])
theWindow = candidateWindow;
}
}
return theWindow;
}
@@ -375,7 +400,7 @@ var CTRL_KEY_CODE = 17;
@implementation CPDOMWindowBridge (Events)
/*
/*!
When using command (mac) or control (windows), keys are propagated to the browser by default.
To prevent a character key from propagating (to prevent its default action, and instead use it
in your own application), use these methods. These methods are additive -- the list builds until you clear it.
@@ -388,7 +413,7 @@ var CTRL_KEY_CODE = 17;
CharacterKeysToPrevent[""+characters[i-1].toLowerCase()] = YES;
}
/*
/*!
@param character a character to stop propagating keypresses to the browser.
*/
- (void)preventCharacterKeyFromPropagating:(CPString)character
@@ -396,7 +421,7 @@ var CTRL_KEY_CODE = 17;
CharacterKeysToPrevent[character.toLowerCase()] = YES;
}
/*
/*!
Clear the list of characters for which we are not sending keypresses to the browser.
*/
- (void)clearCharacterKeysToPreventFromPropagating
@@ -404,7 +429,7 @@ var CTRL_KEY_CODE = 17;
CharacterKeysToPrevent = {};
}
/*
/*!
Prevent these keyCodes from sending their keypresses to the browser.
@param keyCodes an array of keycodes to prevent propagation.
*/
@@ -414,7 +439,7 @@ var CTRL_KEY_CODE = 17;
KeyCodesToPrevent[keyCodes[i-1]] = YES;
}
/*
/*!
Prevent this keyCode from sending its key events to the browser.
@param keyCode a keycode to prevent propagation.
*/
@@ -423,7 +448,7 @@ var CTRL_KEY_CODE = 17;
KeyCodesToPrevent[keyCode] = YES;
}
/*
/*!
Clear the list of keyCodes for which we are not sending keypresses to the browser.
*/
- (void)clearKeyCodesToPreventFromPropagating
@@ -437,7 +462,7 @@ var CTRL_KEY_CODE = 17;
var theType = _overriddenEventType || aDOMEvent.type;
// IE's event order is down, up, up, dblclick, so we have create these events artificially.
if (theType == CPDOMEventDoubleClick)
if (theType === CPDOMEventDoubleClick)
{
_overriddenEventType = CPDOMEventMouseDown;
[self _bridgeMouseEvent:aDOMEvent];
@@ -470,7 +495,7 @@ var CTRL_KEY_CODE = 17;
{
var theWindow = [self hitTest:location];
if (aDOMEvent.type == CPDOMEventMouseDown && theWindow)
if ((aDOMEvent.type === CPDOMEventMouseDown) && theWindow)
_mouseDownWindow = theWindow;
windowNumber = [theWindow windowNumber];
@@ -485,12 +510,10 @@ var CTRL_KEY_CODE = 17;
}
switch (theType)
{
{
case CPDOMEventMouseUp: if(_mouseIsDown)
{
event = [CPEvent mouseEventWithType:CPLeftMouseUp location:location modifierFlags:modifierFlags
timestamp:timestamp windowNumber:windowNumber context:nil eventNumber:-1
clickCount:CPDOMEventGetClickCount(_lastMouseUp, timestamp, location) pressure:0];
event = _CPEventFromNativeMouseEvent(aDOMEvent, CPLeftMouseUp, location, modifierFlags, timestamp, windowNumber, nil, -1, CPDOMEventGetClickCount(_lastMouseUp, timestamp, location), 0);
_mouseIsDown = NO;
_lastMouseUp = event;
@@ -522,9 +545,7 @@ var CTRL_KEY_CODE = 17;
return;
}
event = [CPEvent mouseEventWithType:CPLeftMouseDown location:location modifierFlags:modifierFlags
timestamp:timestamp windowNumber:windowNumber context:nil eventNumber:-1
clickCount:CPDOMEventGetClickCount(_lastMouseDown, timestamp, location) pressure:0];
event = _CPEventFromNativeMouseEvent(aDOMEvent, CPLeftMouseDown, location, modifierFlags, timestamp, windowNumber, nil, -1, CPDOMEventGetClickCount(_lastMouseDown, timestamp, location), 0);
_mouseIsDown = YES;
_lastMouseDown = event;
@@ -533,12 +554,8 @@ var CTRL_KEY_CODE = 17;
case CPDOMEventMouseMoved: if (_DOMEventMode)
return;
event = [CPEvent mouseEventWithType:_mouseIsDown ? CPLeftMouseDragged : CPMouseMoved
location:location modifierFlags:modifierFlags timestamp:timestamp
windowNumber:windowNumber context:nil eventNumber:-1 clickCount:1 pressure:0];
_currentMousePosition = _CGPointMake(aDOMEvent.clientX, aDOMEvent.clientY);
event = _CPEventFromNativeMouseEvent(aDOMEvent, _mouseIsDown ? CPLeftMouseDragged : CPMouseMoved, location, modifierFlags, timestamp, windowNumber, nil, -1, 1, 0);
break;
}
@@ -552,8 +569,8 @@ var CTRL_KEY_CODE = 17;
if (StopDOMEventPropagation)
CPDOMEventStop(aDOMEvent);
[[CPRunLoop currentRunLoop] performSelectors];
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
}
catch (anException)
{
@@ -644,7 +661,7 @@ var CTRL_KEY_CODE = 17;
{
_pasteboardKeyDownEvent = event;
window.setTimeout(function () { [self _checkPasteboardElement] }, 0);
window.setNativeTimeout(function () { [self _checkPasteboardElement] }, 0);
return;
}
@@ -689,7 +706,7 @@ var CTRL_KEY_CODE = 17;
_DOMPasteboardElement.select();
window.setTimeout(function() { [self _clearPasteboardElement]; }, 0);
window.setNativeTimeout(function() { [self _clearPasteboardElement]; }, 0);
}
return;
@@ -698,8 +715,8 @@ var CTRL_KEY_CODE = 17;
if (StopDOMEventPropagation)
CPDOMEventStop(aDOMEvent);
[[CPRunLoop currentRunLoop] performSelectors];
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
}
catch (anException)
{
@@ -715,10 +732,32 @@ var CTRL_KEY_CODE = 17;
try
{
if (CPFeatureIsCompatible(CPJavaScriptMouseWheelValues_8_15))
{
var x = 0.0,
y = 0.0,
element = aDOMEvent.target;
while (element.nodeType !== 1)
element = element.parentNode;
if (element.offsetParent)
{
do
{
x += element.offsetLeft;
y += element.offsetTop;
} while (element = element.offsetParent);
}
var location = _CGPointMake((x + ((aDOMEvent.clientX - 8) / 15)), (y + ((aDOMEvent.clientY - 8) / 15)));}
else
var location = _CGPointMake(aDOMEvent.clientX, aDOMEvent.clientY);
var deltaX = 0.0,
deltaY = 0.0,
windowNumber = 0,
location = CGPointMake(_currentMousePosition.x, _currentMousePosition.y),
timestamp = aDOMEvent.timeStamp ? aDOMEvent.timeStamp : new Date(),
modifierFlags = (aDOMEvent.shiftKey ? CPShiftKeyMask : 0) |
(aDOMEvent.ctrlKey ? CPControlKeyMask : 0) |
@@ -769,8 +808,8 @@ var CTRL_KEY_CODE = 17;
if (StopDOMEventPropagation)
CPDOMEventStop(aDOMEvent);
[[CPRunLoop currentRunLoop] performSelectors];
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
}
catch (anException)
{
@@ -802,15 +841,14 @@ var CTRL_KEY_CODE = 17;
{
var windows = [layers objectForKey:levels[levelCount]]._windows,
windowCount = windows.length;
while (windowCount--)
[windows[windowCount] resizeWithOldBridgeSize:oldSize];
}
//window.liveResize = NO;
[[CPRunLoop currentRunLoop] performSelectors];
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
}
catch (anException)
{
@@ -818,13 +856,77 @@ var CTRL_KEY_CODE = 17;
}
}
// DOM event properties used in mouse bridge code
// type
// clientX
// clientY
// timestamp
// target/srcElement
// shiftKey,ctrlKey,altKey,metaKey
/* @ignore */
- (void)_bridgeTouchEvent:(DOMEvent)aDOMEvent
{
try
{
if (aDOMEvent.touches && (aDOMEvent.touches.length == 1 || (aDOMEvent.touches.length == 0 && aDOMEvent.changedTouches.length == 1)))
{
var newEvent = {};
switch(aDOMEvent.type)
{
case CPDOMEventTouchStart: newEvent.type = CPDOMEventMouseDown;
break;
case CPDOMEventTouchEnd: newEvent.type = CPDOMEventMouseUp;
break;
case CPDOMEventTouchMove: newEvent.type = CPDOMEventMouseMoved;
break;
case CPDOMEventTouchCancel: newEvent.type = CPDOMEventMouseUp;
break;
}
var touch = aDOMEvent.touches.length ? aDOMEvent.touches[0] : aDOMEvent.changedTouches[0];
newEvent.clientX = touch.clientX;
newEvent.clientY = touch.clientY;
newEvent.timestamp = aDOMEvent.timestamp;
newEvent.target = aDOMEvent.target;
newEvent.shiftKey = newEvent.ctrlKey = newEvent.altKey = newEvent.metaKey = false;
newEvent.preventDefault = function(){if(aDOMEvent.preventDefault) aDOMEvent.preventDefault()};
newEvent.stopPropagation = function(){if(aDOMEvent.stopPropagation) aDOMEvent.stopPropagation()};
[self _bridgeMouseEvent:newEvent];
return;
}
else
{
if (aDOMEvent.preventDefault)
aDOMEvent.preventDefault();
if (aDOMEvent.stopPropagation)
aDOMEvent.stopPropagation();
}
}
catch(e)
{
objj_exception_report(e, {path:@"CPDOMWindowBridge.j"});
}
// handle touch cases specifically
}
/* @ignore */
- (void)_checkPasteboardElement
{
try
{
var value = _DOMPasteboardElement.value;
if ([value length])
{
var pasteboard = [CPPasteboard generalPasteboard];
@@ -843,7 +945,7 @@ var CTRL_KEY_CODE = 17;
_pasteboardKeyDownEvent = nil;
[[CPRunLoop currentRunLoop] performSelectors];
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
}
catch (anException)
{
@@ -880,21 +982,17 @@ var CPDOMEventStop = function(aDOMEvent)
// IE Model
aDOMEvent.cancelBubble = true;
aDOMEvent.returnValue = false;
// W3C Model
if (aDOMEvent.preventDefault)
aDOMEvent.preventDefault();
if (aDOMEvent.stopPropagation)
aDOMEvent.stopPropagation();
if (aDOMEvent.type == CPDOMEventMouseDown)
if (aDOMEvent.type === CPDOMEventMouseDown)
{
CPSharedDOMWindowBridge._DOMFocusElement.focus();
CPSharedDOMWindowBridge._DOMFocusElement.blur();
}
}
/*
*/
+12 -4
View File
@@ -20,8 +20,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
import <Foundation/CPArray.j>
import <Foundation/CPObject.j>
@import <Foundation/CPArray.j>
@import <Foundation/CPObject.j>
#include "CPDOMDisplayServer.h"
@@ -61,6 +61,9 @@ import <Foundation/CPObject.j>
- (void)removeWindow:(CPWindow)aWindow
{
if (!aWindow._isVisible)
return;
var index = aWindow._index,
count = _windows.length - 1;
@@ -111,9 +114,14 @@ import <Foundation/CPObject.j>
aWindow._isVisible = YES;
if ([aWindow styleMask] & CPBorderlessBridgeWindowMask)
[aWindow setFrame:[aWindow._bridge contentBounds]];
if ([aWindow isFullBridge])
[aWindow setFrame:[aWindow._bridge visibleFrame]];
}
}
- (CPArray)orderedWindows
{
return _windows;
}
@end
+78
View File
@@ -0,0 +1,78 @@
#!/usr/bin/env ruby
require 'rake'
require '../common'
require 'objective-j'
require 'objective-j/bundletask'
$BUILD_PATH = File.join($BUILD_DIR, $CONFIGURATION, 'AppKit')
$ENVIRONMENT_PRODUCT = File.join($ENVIRONMENT_FRAMEWORKS_DIR, 'AppKit')
$THEME_PRODUCT = File.join($BUILD_PATH, 'Resources', 'Aristo.blend')
$ENVIRONMENT_THEME_PRODUCT = File.join($ENVIRONMENT_PRODUCT, 'Resources', 'Aristo.blend')
AppKitFiles = FileList['**/*.j'].exclude('CoreGraphics/CGContextCanvas.j', 'CoreGraphics/CGContextVML.j', 'Themes/**', 'Tools/**')
ObjectiveJ::BundleTask.new(:AppKit) do |t|
t.name = 'AppKit'
t.identifier = 'com.280n.AppKit'
t.version = '0.7.1'
t.author = '280 North, Inc.'
t.email = 'feedback @nospam@ 280north.com'
t.summary = 'AppKit classes for Cappuccino'
t.sources = AppKitFiles
t.resources = FileList['Resources/*']
t.license = ObjectiveJ::License::LGPL_v2_1
t.build_path = $BUILD_PATH
t.flag = '-DDEBUG -g' if $CONFIGURATION == 'Debug'
t.flag = '-O' if $CONFIGURATION == 'Release'
t.platforms = [ObjectiveJ::Platform::Browser, ObjectiveJ::Platform::Rhino]
t.type = ObjectiveJ::Bundle::Type::Framework
end
# It would be nice to just have ENVIRONMENT_PRODUCT depend on THEME_PRODUCT,
# but this would be a circular dependency because THEME_PRODUCT needs
# ENVIRONMENT_PRODUCT up-to-date since it runs an objj application that uses
# AppKit.
file_d $ENVIRONMENT_PRODUCT => [:AppKit] do
cp_r(File.join($BUILD_PATH, '.'), $ENVIRONMENT_PRODUCT)
end
file_d $ENVIRONMENT_THEME_PRODUCT => $THEME_PRODUCT do
cp_r(File.join($THEME_PRODUCT, '.'), $ENVIRONMENT_THEME_PRODUCT)
end
ThemeFiles = FileList['Themes/Aristo/*']
file_d $THEME_PRODUCT => ThemeFiles << $ENVIRONMENT_PRODUCT do
File.popen("blend -d Themes/Aristo/ThemeDescriptors.j -o #{$THEME_PRODUCT} -R Themes/Aristo/Resources") do |blend|
blend.sync = true
while str = blend.gets
puts str
end
end
end
task :build => [:build_subprojects, :AppKit, $ENVIRONMENT_PRODUCT, $THEME_PRODUCT, $ENVIRONMENT_THEME_PRODUCT]
task :clean => :clean_suprojects
task :clobber => :clobber_subprojects
subprojects = %w{Tools}
task :build_subprojects do
subrake(subprojects, :build)
end
task :clean_suprojects do
subrake(subprojects, :clean)
end
task :clobber_subprojects do
subrake(subprojects, :clobber)
end
CLOBBER.include($ENVIRONMENT_PRODUCT)

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