Compare commits

...
1797 Commits
Author SHA1 Message Date
Alexander Ljungberg 0821794bcc This will be Cappuccino 0.9.7-alpha1. 2013-01-30 14:52:48 +00:00
Alexander Ljungberg da47161e1a Fixed: nib2cib error on case sensitive filesystems.
Before this fix, nib2cib compilation would fail with `require error: couldn't find "OS"`.
2013-01-30 11:52:28 +00:00
Alexander Ljungberg 450081ee3e Fixed: 'cannot run program "ulimit"' error.
When running on certain platforms the `ulimit` command is not available, which would crash the build script.

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

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

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

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

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

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

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

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

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

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

This fix prints such errors and avoids crashing later when the result of the compilation is undefined.
2013-01-21 01:08:28 +00:00
Alexander Ljungberg 806c7935c5 Lint. 2013-01-20 19:10:41 +00:00
Alexander Ljungberg e7f0400580 Formatting. 2013-01-20 18:24:48 +00:00
Alexander Ljungberg ad109532be It's enough to read flattensSources once. 2013-01-20 18:09:55 +00:00
Alexander Ljungberg 9dbfa99284 Lint. 2013-01-20 17:14:44 +00:00
Alexander Ljungberg 3c684404ed Eliminate mystery CGPointPointer. 2013-01-20 16:44:40 +00:00
Alexander Ljungberg d818615472 Missing import. 2013-01-20 16:35:48 +00:00
Alexander Ljungberg 06694061d2 Fix nib2cib error introduced by c3d8f4f.
This fixes `- [NSWindowTemplate setFullBridge:] unrecognized selector sent to instance` errors when running nib2cib.
2013-01-20 16:05:06 +00:00
Alexander Ljungberg 75c305ae0f Clean up manual CPBox test. 2013-01-20 16:03:56 +00:00
Alexander Ljungberg cb786a0166 Small CPBox optimisation.
No need to call `setNeedsDisplay:` after `setValue:forThemeAttribute:`.
2013-01-20 13:19:29 +00:00
Aparajita Fishman e292bf01d7 Fixed mouse down within the resize slop outside a window not resizing 2013-01-20 09:13:17 +07:00
Aparajita Fishman 17f07ee888 capp_lint will not flag CPRectEdge, more linking 2013-01-20 07:24:00 +07:00
Antoine Mercadal 51c09a1b02 Merge branch 'CPRuleEditor-fixes' of https://github.com/cacaodev/cappuccino into pr-1718 2013-01-19 11:48:18 -08:00
cacaodev fe7befa845 Fix missing @end 2013-01-19 17:11:11 +01:00
cacaodev eca5ef6f84 Fix textfield in rules croped 2013-01-19 17:08:34 +01:00
cacaodev c023a38544 Remove unused code 2013-01-19 17:07:11 +01:00
Aparajita Fishman 7c831fa19d capp_lint flags deprecated CPPoint/Rect/Size types/functions
- Changed to corresponding CG types/functions in all files
- Fixed some demo app bugs
2013-01-19 16:51:56 +07:00
Aparajita Fishman 24c0f2aedc Merge branch 'refs/heads/inactive-window'
Conflicts:
	AppKit/Themes/Aristo/ThemeDescriptors.j
	AppKit/Themes/Aristo2/ThemeDescriptors.j
2013-01-19 15:15:51 +07:00
Antoine Mercadal 6170a274d7 Merge branch 'master' of https://github.com/cappuccino/cappuccino 2013-01-18 23:24:22 -08:00
Antoine Mercadal 155796b0e0 Linting Aristo1 2013-01-18 23:24:00 -08:00
Aparajita Fishman 3b7262681c Added inactive state to window title bar
- When a window is neither key nor main the title bar is clearly different
- capp_lint ThemeDescriptors.j
- Renamed some layers in Aristo2 PSD to be more descriptive
- New artwork files for window close buttons
- Removed stray Aristo2 image
2013-01-19 14:20:51 +07:00
Antoine Mercadal 988ab9722c Linting 2013-01-18 23:20:44 -08:00
Alexander Ljungberg 8eae427591 Merge branch 'master' of github.com:cappuccino/cappuccino 2013-01-19 02:27:55 +00:00
Alexander Ljungberg b4fe13dfb1 Merge branch 'refs/heads/0.9.6' 2013-01-19 02:27:43 +00:00
Alexander Ljungberg c0b5ed6b3f New demos repository. 2013-01-19 02:21:12 +00:00
Alexander Ljungberg dfad18e047 New website location. 2013-01-19 02:11:37 +00:00
Alexander Ljungberg 7f93173b33 This will be the final v0.9.6. 2013-01-19 01:00:05 +00:00
Martin Carlberg f435a15b43 Merge branch 'experimental_class_and_global_implementation' of https://github.com/cappuccino/cappuccino into objj_compiler2
Conflicts:
	Tools/capp/Configuration.j
2013-01-18 23:51:36 +01:00
Martin Carlberg 08d5be5ce3 Fixed imports in Tools/capp 2013-01-18 23:49:22 +01:00
Antoine Mercadal c3d8f4f80b Fix bug in NSWindowTemplate.j where using a non existing ivar 2013-01-18 14:46:49 -08:00
Antoine Mercadal bbb8bdb687 Fix other small bugs 2013-01-18 14:38:37 -08:00
Antoine Mercadal 4138a6d6dc Merge branch 'objj_compiler2' into experimental_class_and_global_implementation 2013-01-18 14:35:03 -08:00
Antoine Mercadal 6b172cd3a6 remove useless usage of self. in NSWindowTemplate.j 2013-01-18 14:34:22 -08:00
Antoine Mercadal 86e0282011 Fix nib2cib warnings 2013-01-18 14:29:25 -08:00
Martin Carlberg f1250ae5eb Merge branch 'experimental_class_and_global_implementation' of https://github.com/cappuccino/cappuccino into objj_compiler2 2013-01-18 22:27:54 +01:00
Martin Carlberg 586c9d3139 Fixed "Can't find superclass 'MyClass' <Context File: Accessors>" problem when
compiling accessors to class with superclass in same file.
2013-01-18 21:23:11 +01:00
Antoine Mercadal 6b0edaecc6 Move the editable property to _CPRuleEditorViewSlice.j as it is used in this class 2013-01-18 10:38:35 -08:00
Antoine Mercadal a4bfd2c9f7 Add missing imports 2013-01-18 10:38:03 -08:00
Antoine Mercadal 7a419c262e Add missing @class 2013-01-18 10:37:51 -08:00
Antoine Mercadal 40ac3210c4 Add missing import 2013-01-18 10:37:37 -08:00
Antoine Mercadal 3bb9e234d8 Add missing import 2013-01-18 10:37:27 -08:00
Antoine Mercadal 75a4ef99c9 Add some missing globals in CPTextField 2013-01-18 10:37:16 -08:00
Antoine Mercadal 1e4b6b6c49 Add missing import 2013-01-18 10:30:13 -08:00
Antoine Mercadal c9eeab09a1 Add missing import in _CPWindow.j 2013-01-18 10:17:19 -08:00
Antoine Mercadal 1a61fc832e Fix a bug in wrong code order in _CPMenuManager.j making usage of undeclared variable. Also add some missing imports 2013-01-18 10:16:55 -08:00
Antoine Mercadal 1d232fd263 Add missing import in BKShowcaseController.j 2013-01-18 10:03:11 -08:00
Martin Carlberg 197f3665bc Fixed removed import 2013-01-18 17:33:09 +01:00
Martin Carlberg 6fbab322cf Fixed warning messages in compiler 2013-01-18 14:25:05 +01:00
Martin Carlberg 458fa9d02e Fixed a lot of small bugs found by new warning message from compiler 2013-01-18 14:24:37 +01:00
Martin Carlberg ff20822b47 Merge branch 'master' of https://github.com/cappuccino/cappuccino into objj_compiler2_experiment 2013-01-17 18:20:07 +01:00
Aparajita Fishman eff0621966 Formatting 2013-01-17 15:32:53 +07:00
Antoine Mercadal 6aeb6199f7 Restore line 2013-01-16 18:10:46 -08:00
Alexandre Wilhelm 072fac837c Merge branch 'master' of github.mv.usa.alcatel.com:amercada/Cappuccino 2013-01-16 18:06:59 -08:00
Alexandre Wilhelm f1fa185383 Fixed bug about sheet/titled/window 2013-01-16 18:06:42 -08:00
Antoine Mercadal c471bc0f82 Update CPScrollView manual test to be able to switch scroller mode 2013-01-16 14:21:08 -08:00
Alexandre Wilhelm 37e29949ef Merge branch 'master' of github.mv.usa.alcatel.com:amercada/Cappuccino 2013-01-16 14:12:13 -08:00
Alexandre Wilhelm e840e4a547 Fixed bug about the width of legacy scrollView 2013-01-16 14:12:07 -08:00
Antoine Mercadal 82bb9a6008 Remove useless code in simple line CPBox 2013-01-16 13:42:46 -08:00
Antoine Mercadal 15ed959da7 Merge branch 'master' of github.mv.usa.alcatel.com:amercada/Cappuccino 2013-01-16 13:35:07 -08:00
Antoine Mercadal a0f4c46cb5 Add missing import 2013-01-16 13:35:01 -08:00
Alexandre Wilhelm 71d5655ab2 Increased the content-inset left in textField 2013-01-16 11:57:04 -08:00
Alexandre Wilhelm 29d56b63f7 Fixed bug about border in CPBox lineBorder 2013-01-16 11:48:23 -08:00
Alexandre Wilhelm 35f495ef5b Fixed bug about tableview row height in Aristo1 2013-01-16 11:16:04 -08:00
Antoine Mercadal 1006890b6e Add missing import in nib2cib. 2013-01-16 10:50:33 -08:00
Antoine Mercadal 083d7304fd Fix some adjustment of the tokenfields. Still need to tweak a little the image files for the tokens 2013-01-15 10:45:08 -08:00
Antoine Mercadal 2d8f651674 Merge branch 'objj_compiler2' 2013-01-15 10:20:10 -08:00
Antoine Mercadal e8ee370499 Merge branch 'master' into objj2integration 2013-01-15 09:49:25 -08:00
Alexander Ljungberg 5c3d71258d Merge branch 'master' of github.com:cappuccino/cappuccino 2013-01-15 16:08:49 +00:00
Alexander Ljungberg 519031a10e Merge branch 'refs/heads/0.9.6' 2013-01-15 16:08:40 +00:00
Alexander Ljungberg 821961fc26 Argument check CPIndexSet indexSetWithIndex:.
Without this check, an index set could be initialised with NaN which would later lead to an infinite loop when enumerating the index set.

This error makes the error early and explicit.
2013-01-15 16:08:17 +00:00
Alexander Ljungberg 4021eae002 Fixed: CPApplicationTest.
A recent commit broke it.
2013-01-15 16:06:44 +00:00
Martin Carlberg 0799ce190d Merge branch 'master' of https://github.com/cappuccino/cappuccino into objj_compiler2 2013-01-15 08:48:30 +01:00
Antoine Mercadal a7c4802446 Merge branch 'master' into objj2integration 2013-01-14 18:22:30 -08:00
Antoine Mercadal 094c6fd273 Update Aristo2 to correctly render CPComboxBoxes 2013-01-14 18:22:12 -08:00
Antoine Mercadal 72a601371e Merge branch 'master' into objj2integration 2013-01-14 17:34:36 -08:00
Antoine Mercadal 2a80ad8344 Fix bezel inset of focused textfields 2013-01-14 17:34:09 -08:00
Alexandre WilhelmandAntoine Mercadal 7e502fffe6 Fixed bug in CPStepper for the automatic size of it when calling a static constructor 2013-01-14 15:54:14 -08:00
Antoine Mercadal e5de031423 Merge branch 'objj_compiler2' into objj2integration
Conflicts:
	AppKit/CPWindow/CPWindow.j
2013-01-14 11:43:24 -08:00
Martin Carlberg d064ecd842 Merge branch 'master' of https://github.com/cappuccino/cappuccino into objj_compiler2
Conflicts:
	AppKit/CPWindow/CPWindow.j
2013-01-14 20:39:08 +01:00
Antoine Mercadal c0d33a1a19 Merge branch 'master' into Aristo2
Conflicts:
	AppKit/CPAlert.j
2013-01-14 10:57:03 -08:00
Martin Carlberg e78f211e8a Added @class and @global declaration and will now make a warning if class or global is not declared. 2013-01-14 18:36:39 +01:00
Martin Carlberg 77d66fa0c9 Fix for: Track spaces will take the spaces after the next token instead of the current. Also do "delete" of property instead of setting it to null for cleaner AST tree. 2013-01-13 22:08:42 +01:00
Martin Carlberg a652fdf8d2 Fix for: Track comments will take the comment after the next token instead of the current. Also do "delete" of property instead of setting it to null for cleaner AST tree. 2013-01-13 22:08:29 +01:00
Aparajita FishmanandMartin Carlberg 85481225a3 Use a better error message for missing semicolons, trailing whitespace elimination 2013-01-13 22:06:18 +01:00
Martin Carlberg 6210bd2e6d Merge branch 'master' of https://github.com/cappuccino/cappuccino into objj_compiler2
Conflicts:
	AppKit/CPWindow/CPWindow.j
2013-01-13 22:01:43 +01:00
Antoine Mercadal 7dd7dca99a Update some HUD art files 2013-01-12 13:37:16 -08:00
Antoine Mercadal 48991e6c3b Update some HUD slices 2013-01-12 13:37:05 -08:00
Antoine Mercadal 825d045143 Remove bg in textfield slices 2013-01-12 11:35:11 -08:00
Antoine Mercadal 86593cc0f4 Update art files for textfields 2013-01-12 11:24:18 -08:00
Antoine Mercadal d987bcf0d0 Add missing slices in PSD 2013-01-12 11:24:04 -08:00
Aparajita Fishman 0e82504daf Formatting 2013-01-12 16:57:59 +07:00
Aparajita Fishman 7fdc3abd30 Missing semicolon 2013-01-12 16:24:26 +07:00
Antoine Mercadal c52a72ec90 small update in art files 2013-01-11 18:38:16 -08:00
Aparajita Fishman e464900f8b Merge branch 'key-view-loop'
Conflicts:
	AppKit/CPWindow/CPWindow.j
2013-01-12 09:38:07 +07:00
Antoine Mercadal b82f7061a0 Small fixes in psd 2013-01-11 18:38:04 -08:00
Antoine Mercadal 55d651ad27 Readd missing art file 2013-01-11 18:14:45 -08:00
Antoine Mercadal 5239749580 Optimize all images 2013-01-11 18:01:49 -08:00
Antoine Mercadal fe5b6d40ac Update art files 2013-01-11 17:59:27 -08:00
Antoine Mercadal 5fa42279bd CLeanup PSD 2013-01-11 17:59:13 -08:00
Alexandre Wilhelm b7a2ab57cc Updated Aristo1 and 2 2013-01-11 17:39:11 -08:00
Alexandre Wilhelm 78949f3620 Changed the way to theme the head of a window 2013-01-11 17:38:54 -08:00
Alexandre Wilhelm 924bf07950 Added missing picturs for toolbar in Aristo1 2013-01-11 17:16:02 -08:00
Alexandre Wilhelm 181f7acbb8 Changed the attribute theme background selected menu bar to _CPMenuView 2013-01-11 17:13:58 -08:00
Alexandre Wilhelm d331de6683 Merge branch 'Aristo2' of github.mv.usa.alcatel.com:amercada/Cappuccino into Aristo2 2013-01-11 16:27:57 -08:00
Alexandre Wilhelm 41dbc66d24 Added disabled token field 2013-01-11 16:27:43 -08:00
Antoine Mercadal 6230319f63 Merge branch 'Aristo2' of 172.21.51.218:amercada/Cappuccino into Aristo2 2013-01-11 16:14:03 -08:00
Antoine Mercadal b7e768820f Tweak theme 2013-01-11 16:13:51 -08:00
Antoine Mercadal 5dc2595159 Add missing HUD Slices 2013-01-11 16:13:43 -08:00
Antoine Mercadal 919aa2622d Add some HUD art 2013-01-11 16:13:28 -08:00
Alexandre Wilhelm 025c66db7e Fixed disable stepper 2013-01-11 16:01:55 -08:00
Alexandre Wilhelm b3361100da Updated Aristo2 2013-01-11 15:38:58 -08:00
Alexandre Wilhelm e0ffde1614 Fuxed bug with disabled combobox 2013-01-11 15:38:43 -08:00
Alexandre Wilhelm 4bfe607f64 Fixed bug with disabled popup 2013-01-11 15:38:20 -08:00
Alexandre Wilhelm c0cbe8e0ab Fixed bug with disabled knob 2013-01-11 15:37:42 -08:00
Alexandre Wilhelm 1e6d41e113 Fixed bug with disabled CPSegmentedButton 2013-01-11 15:14:01 -08:00
Alexandre Wilhelm 54f0a49281 Merge branch 'Aristo2' of github.mv.usa.alcatel.com:amercada/Cappuccino into Aristo2 2013-01-11 14:10:25 -08:00
Alexandre Wilhelm 618f5360ae Added disbaled textField for Aristo2 2013-01-11 14:10:15 -08:00
Antoine Mercadal 6f8b5afd56 Merge branch 'Aristo2' of 172.21.51.218:amercada/Cappuccino into Aristo2 2013-01-11 14:05:54 -08:00
Antoine Mercadal 6432528d37 Merge branch 'master' into Aristo2
Conflicts:
	AppKit/CPWindow/CPWindow.j
2013-01-11 14:05:27 -08:00
Alexandre Wilhelm b62e2c0b78 Merge branch 'Aristo2' of github.mv.usa.alcatel.com:amercada/Cappuccino into Aristo2 2013-01-11 13:54:27 -08:00
Alexandre Wilhelm f30e846f09 Added theme value to set the position of the buttons relative to the type of window 2013-01-11 13:54:18 -08:00
Alexandre Wilhelm 0a9b4bdc11 Fixed bug in CPAlert theme 2013-01-11 13:53:51 -08:00
Antoine Mercadal 0102e99d3c Show actual progress bar in indeterminate state 2013-01-11 12:28:42 -08:00
Antoine Mercadal 19548c196e Add some missing slices in Aristo2 HUD 2013-01-11 12:25:56 -08:00
Antoine Mercadal 46ee987742 Merge branch 'Aristo2' of 172.21.51.218:amercada/Cappuccino into Aristo2 2013-01-11 12:25:18 -08:00
Antoine Mercadal 34428d82c7 Add missing art files 2013-01-11 12:25:12 -08:00
Antoine Mercadal bab27b8be1 Update Art for HUD progress bar in Aristo2 2013-01-11 12:24:41 -08:00
Alexandre Wilhelm 6d06970c0f Merge branch 'Aristo2' of github.mv.usa.alcatel.com:amercada/Cappuccino into Aristo2 2013-01-11 12:08:53 -08:00
Alexandre Wilhelm c16a965eb7 Added head window Aristo1 2013-01-11 12:08:33 -08:00
Alexandre Wilhelm 5cb7b82415 Added standard window Aristo1 2013-01-11 11:56:48 -08:00
Alexandre Wilhelm 4d9a4267f4 Removed unused images 2013-01-11 11:56:23 -08:00
Antoine Mercadal fdbc7cc585 Add showcase for HUD progress indicators 2013-01-11 11:49:55 -08:00
Martin Carlberg ed6c35a59f Merge branch 'master' of https://github.com/cappuccino/cappuccino into objj_compiler2
Conflicts:
	AppKit/CPWindow/CPWindow.j
2013-01-11 20:40:35 +01:00
Antoine Mercadal eca14a8868 Add missing art files 2013-01-11 11:39:31 -08:00
Antoine Mercadal fc719cb1c2 Backport art for new themable CPProgressIndicator, CPToolbar, CPMenu, CPMenuBar 2013-01-11 11:39:16 -08:00
Martin Carlberg 3dc6a30c4c Code clean up 2013-01-11 20:36:19 +01:00
Martin Carlberg 3e93e180f1 Turn off test case that don't apply to the new compiler 2013-01-11 20:36:12 +01:00
Alexandre Wilhelm 3446f8f6ae Added modal window for Aristo1 2013-01-11 11:33:06 -08:00
Alexandre Wilhelm 541dd9eac7 Added shadow window 2013-01-11 11:19:04 -08:00
Alexandre Wilhelm 62d866b60f Upadted Aristo1 with HUD window 2013-01-11 11:17:07 -08:00
Antoine Mercadal f8f0444503 Add missing @end 2013-01-11 11:02:35 -08:00
Antoine Mercadal 7eaf84d066 Backport Aristo2 descriptors to Aristo1 2013-01-11 11:00:34 -08:00
Aparajita Fishman 95511b5311 Window resize tweak...
- If a window is fixed width or fixed height, then no resize cursor is shown and no resize area is active on the edges that cannot be resized.
- Optimized CG calls in CPWindow.
- Added fixed height window to test app.
2013-01-11 21:56:04 +07:00
Alexander Ljungberg 23817a04e1 Unit test HTTP response header parsing. 2013-01-11 12:28:14 +00:00
Alexander Ljungberg 2b90d6244f Merge branch 'master' of github.com:cappuccino/cappuccino 2013-01-11 11:02:12 +00:00
Alexander Ljungberg 7485c4eb7a New: -CPHTTPURLResponse allHeaderFields.
When a CPURLConnection response is of the CPHTTPURLResponse type, the raw HTTP headers can now be retrieved through the allHeaderFields message.
2013-01-11 10:53:42 +00:00
Antoine Mercadal 317e9881b8 Make text fields bigger in the showcase 2013-01-10 23:11:36 -08:00
Martin Carlberg c4e06bd2f7 Merge branch 'master' of https://github.com/cappuccino/cappuccino into objj_compiler2 2013-01-11 08:09:12 +01:00
Antoine Mercadal fb1532be1c Re-add the BKLearnMore* keys in Info.plist 2013-01-10 23:08:15 -08:00
Martin Carlberg f076b05e7e More information: Shows that the new compiler is used when doing "objjc --help". New output: "Usage (objjc 2.0):…" 2013-01-11 08:06:51 +01:00
Antoine Mercadal 71f502a8e8 Fix some ivar masking in tests 2013-01-10 23:04:12 -08:00
Antoine Mercadal 5e1ac06375 Merge branch 'master' into Aristo2 2013-01-10 22:42:20 -08:00
Antoine Mercadal 341eb26c62 Merge branch 'master' of https://github.com/cappuccino/cappuccino 2013-01-10 22:41:31 -08:00
Antoine Mercadal 18f8294fa9 Update order of variable to tets in assert 2013-01-10 22:40:15 -08:00
Antoine Mercadal 959a8e7594 Add some widgets in the showcase 2013-01-10 22:33:22 -08:00
Antoine Mercadal 4fde060510 readd modified art files 2013-01-10 20:14:45 -08:00
Antoine Mercadal 6da4c54f9e Add Aristo2 HUD art files 2013-01-10 19:49:30 -08:00
Antoine Mercadal ad0e3441a1 Add missing slices for HUD theme 2013-01-10 19:49:05 -08:00
Antoine Mercadal 56e9e436cf Add theme descriptors for rounded buttons 2013-01-10 19:11:48 -08:00
Antoine Mercadal 6fde1e459d Add rounded button artwork 2013-01-10 19:11:35 -08:00
Antoine Mercadal fa314611bc Merge branch 'Aristo2' of 172.21.51.218:amercada/Cappuccino into Aristo2 2013-01-10 18:23:20 -08:00
Antoine Mercadal c34ebfa2e8 Add rounded button theme descriptors 2013-01-10 18:23:08 -08:00
Alexandre Wilhelm c6f0589ed5 Merge branch 'Aristo2' of github.mv.usa.alcatel.com:amercada/Cappuccino into Aristo2 2013-01-10 18:15:03 -08:00
Alexandre Wilhelm 8ffa8b6657 Fixed bug in _CPMenuView 2013-01-10 18:14:56 -08:00
Antoine Mercadal 0a92b98110 Comment out non-implemented HUD descriptors 2013-01-10 18:13:02 -08:00
Antoine Mercadal b6c31757a7 fix a bug in CPWindow using old AppKit resource 2013-01-10 17:55:06 -08:00
Antoine Mercadal 676efe247f make toolbar art pixel perfect 2013-01-10 17:50:51 -08:00
Antoine Mercadal f6defc091c cleanup 2013-01-10 17:50:25 -08:00
Alexandre Wilhelm 8bb779ea9e Merge branch 'Aristo2' of github.mv.usa.alcatel.com:amercada/Cappuccino into Aristo2 2013-01-10 17:32:55 -08:00
Alexandre Wilhelm 18d0cf51ef Removed unused code 2013-01-10 17:32:47 -08:00
Alexandre Wilhelm 8b7b363440 Changed default color 2013-01-10 17:32:22 -08:00
Antoine Mercadal 6ba77c146b Backport Aristo2 changes to Aristo1 2013-01-10 17:26:12 -08:00
Antoine Mercadal 54ab7ea9ee use _CPMenuItemView to get general open/save/new icons 2013-01-10 17:23:22 -08:00
Antoine Mercadal b9c0e96933 Add theme descriptors for new/open/save icons 2013-01-10 17:23:03 -08:00
Antoine Mercadal 41650d58a2 Add new theme attribute to get general open/save/new icons 2013-01-10 17:22:34 -08:00
Antoine Mercadal 3519f4f9c7 Remove unused AppKit resources 2013-01-10 17:07:05 -08:00
Alexandre Wilhelm 991e40e089 Fixed bug about the color of the colorPanel 2013-01-10 16:59:50 -08:00
Alexander Ljungberg 1a54aadff0 Merge branch 'master' of github.com:cappuccino/cappuccino 2013-01-11 00:48:28 +00:00
Alexander Ljungberg 6e3f82299f Add missing source header. 2013-01-11 00:48:18 +00:00
Alexandre Wilhelm 9e845ec580 Updated psd 2013-01-10 16:31:49 -08:00
Alexandre Wilhelm c95fb32d0a Fixed bug with size of highlighted menuItem 2013-01-10 16:31:38 -08:00
Alexandre Wilhelm bfe64ea153 Merge branch 'Aristo2' of github.mv.usa.alcatel.com:amercada/Cappuccino into Aristo2 2013-01-10 16:14:04 -08:00
Alexandre Wilhelm 146d641f97 Updated Aristo2 2013-01-10 16:13:48 -08:00
Alexandre Wilhelm 6a94ea066d Added support for _CPMenuBarWindow theme 2013-01-10 16:13:36 -08:00
Alexandre Wilhelm 477ec44b75 Added support for _CPMenuWindow 2013-01-10 16:12:12 -08:00
Antoine Mercadal 284b00fa78 Add missing import 2013-01-10 15:31:37 -08:00
Antoine Mercadal 0f94ba3d39 Merge branch 'Aristo2' of 172.21.51.218:amercada/Cappuccino into Aristo2 2013-01-10 14:12:15 -08:00
Antoine Mercadal 2e157dd969 Starting to backport new themeable stuff from Aristo2. Missing art will follow 2013-01-10 14:12:09 -08:00
Antoine Mercadal f945845a77 Style fix 2013-01-10 14:11:35 -08:00
Alexandre Wilhelm 457cf98089 Merge branch 'Aristo2' of github.mv.usa.alcatel.com:amercada/Cappuccino into Aristo2 2013-01-10 13:58:20 -08:00
Alexandre Wilhelm ab65b53201 Updated Aristo2 2013-01-10 13:58:12 -08:00
Alexandre Wilhelm 3da4daeed5 Removed unused code 2013-01-10 13:57:57 -08:00
Alexandre Wilhelm f9c5f89595 Added support for _CPMenuItemStandardView 2013-01-10 13:57:32 -08:00
Antoine Mercadal d71947cb63 Remove unused AppKit Resource 2013-01-10 11:57:49 -08:00
Antoine Mercadal cdf29b6c56 Add missing theme descriptors for CPTableView 2013-01-10 11:57:39 -08:00
Antoine Mercadal 73ddadc0f0 Add missing theme attribute in CPTableView 2013-01-10 11:57:17 -08:00
Antoine Mercadal bd8431504d Merge branch 'Aristo2' of 172.21.51.218:amercada/Cappuccino into Aristo2 2013-01-10 11:49:01 -08:00
Antoine Mercadal efcee75f30 Remove unused AppKit resource 2013-01-10 11:48:56 -08:00
Antoine Mercadal b283e05f9c Fix bug in CPButtonTest 2013-01-10 11:48:45 -08:00
Antoine Mercadal d15757755a use themed minus and plus button image in _CPCibResource 2013-01-10 11:47:20 -08:00
Antoine Mercadal b3259e4b49 Add theme for CPButtonBar plus, minus and action button 2013-01-10 11:42:38 -08:00
Antoine Mercadal cebf8d3579 Make image plus, minus and action themable 2013-01-10 11:42:08 -08:00
Alexandre Wilhelm 9451a6a1ec Merge branch 'Aristo2' of github.mv.usa.alcatel.com:amercada/Cappuccino into Aristo2 2013-01-10 11:42:07 -08:00
Alexandre Wilhelm 5d3321839d Updated Aristo2 2013-01-10 11:41:59 -08:00
Alexandre Wilhelm 594458235b Added support for theme in_CPMenuItemMenuBarView 2013-01-10 11:41:41 -08:00
Antoine Mercadal a3273dedc1 Remove unused art 2013-01-10 11:29:33 -08:00
Antoine Mercadal 42824713e3 Add application's menu default icon in theme 2013-01-10 11:29:24 -08:00
Antoine Mercadal 4ad40ee00d Pull menu default icon from theme instead of AppKit resource 2013-01-10 11:28:43 -08:00
Antoine Mercadal ddf33a13cd Use new CPThemeBlend bundle accessor 2013-01-10 11:28:25 -08:00
Antoine Mercadal 4ce8ea9ce9 make CPThemeBlend's bundle property readonly 2013-01-10 11:27:52 -08:00
Antoine Mercadal 5b84fd6e40 Remove unused AppKit resources 2013-01-10 11:15:41 -08:00
Antoine Mercadal d7af63877e Add system cursors in theme 2013-01-10 11:15:19 -08:00
Antoine Mercadal 844ed59dd8 CPCursor will now look in the theme to get system cursors 2013-01-10 11:14:59 -08:00
Antoine Mercadal 35e29a0615 Fix bug introducing during previous merge 2013-01-10 10:38:10 -08:00
Martin Carlberg 7c71cd1f80 The new compiler takes care of hoisted variables 2013-01-10 19:30:34 +01:00
Martin Carlberg 74ad0faffa Merge branch 'master' of https://github.com/cappuccino/cappuccino into objj_compiler2
Conflicts:
	AppKit/CPWindow/CPWindow.j
2013-01-10 19:28:42 +01:00
Antoine Mercadal e13948957c Merge branch 'master' into Aristo2
Conflicts:
	AppKit/CPWindow/CPWindow.j
	AppKit/CPWindow/_CPWindowView.j
2013-01-10 10:24:33 -08:00
aparajita 64915f18ff Merge pull request #1711 from slevenbits/new-window-resize
This commit provides resizing of windows from all sides. The legacy style, which displays a resize thumb in the lower right, can be restored with [CPWindow setGlobalResizeStyle:CPWindowResizeStyleLegacy].
2013-01-10 09:53:07 -08:00
Aparajita Fishman 1f8306d2b3 Hooked up the edit menu 2013-01-11 00:38:43 +07:00
Aparajita Fishman cdc88dbe18 Key view...
- Factored out blur handler from CPTokenField into CPTextField.
- CPTextField will no longer lose focus unnecessarily.
- Changed switch style in CPWindow -sendEvent.
- Added menu bar to KeyViewLoop test app.
2013-01-11 00:18:38 +07:00
Aparajita Fishman b59f96d238 Key view loop enhancements...
- Nested views are now handled recursively as they are in Cocoa.
- Added a nested view test in the test app.
2013-01-10 21:49:54 +07:00
Alexander Ljungberg 110bd20600 Fix return value type. 2013-01-10 11:48:52 +00:00
Martin Carlberg 0d6a962344 Merge branch 'master' of https://github.com/cappuccino/cappuccino into objj_compiler2 2013-01-10 11:22:41 +01:00
Martin Carlberg c192f3b47b Fix to make the Cappuccino framework compile with rhino 2013-01-10 11:21:45 +01:00
Antoine Mercadal 53fa384608 make nib2cib work either with Aristo1 or Aristo2 for dynamic widget adjustment 2013-01-09 20:25:32 -08:00
Antoine Mercadal 1448791fcd Declare default row height 2013-01-09 20:25:02 -08:00
Antoine Mercadal a66a4210c3 Use theme attribute for default row height 2013-01-09 20:24:42 -08:00
Antoine Mercadal b1ffd8d556 Make default row height a theme attribute 2013-01-09 20:24:27 -08:00
Antoine Mercadal 4548696c73 Remove unused AppKit resources 2013-01-09 19:43:12 -08:00
Antoine Mercadal 0d460dd6b1 Add missing art for toolbar item separator 2013-01-09 19:42:31 -08:00
Antoine Mercadal 4333e3da67 Add theme for CPToolbarItemSeparator 2013-01-09 19:41:56 -08:00
Antoine Mercadal 352ccb21ff Make CPToolbarItemSeparator themable 2013-01-09 19:41:22 -08:00
Antoine Mercadal 2ac57642a4 Remove PSD from ressource folder 2013-01-09 19:01:32 -08:00
Antoine Mercadal af1ddf2fc6 Remove unused AppKit Ressources 2013-01-09 18:59:30 -08:00
Antoine Mercadal e23c519fac Merge branch 'Aristo2' of 172.21.51.218:amercada/Cappuccino into Aristo2 2013-01-09 18:58:05 -08:00
Antoine Mercadal 664a31fc87 Remove unused AppKit Resource 2013-01-09 18:57:58 -08:00
Antoine Mercadal cbcc988625 Add theme for CPBrowser 2013-01-09 18:57:45 -08:00
Antoine Mercadal ce33737a38 Make CPBrowser themable 2013-01-09 18:57:18 -08:00
Alexandre Wilhelm f4e243255a Merge branch 'Aristo2' of github.mv.usa.alcatel.com:amercada/Cappuccino into Aristo2 2013-01-09 18:53:37 -08:00
Alexandre Wilhelm 8df8479716 Updated Aristo2 2013-01-09 18:53:23 -08:00
Alexandre Wilhelm f28ac43446 Added support for _CPBorderlessBridgeWindowView.j theme 2013-01-09 18:53:09 -08:00
Antoine Mercadal 263df059a4 Remove another unused AppKit ressource 2013-01-09 18:30:25 -08:00
Antoine Mercadal 64d1e9ca46 Remove unused AppKit ressource 2013-01-09 18:29:56 -08:00
Antoine Mercadal 286ec29f91 Remove unused AppKit ressource 2013-01-09 18:29:18 -08:00
Antoine Mercadal 66ca5c0d34 Merge branch 'Aristo2' of 172.21.51.218:amercada/Cappuccino into Aristo2 2013-01-09 18:26:50 -08:00
Antoine Mercadal 919335b4f5 Remove unused ressource 2013-01-09 18:25:46 -08:00
Antoine Mercadal c5a4b2605c Add missing theme attributes for CPSearchField 2013-01-09 18:25:11 -08:00
Antoine Mercadal 2da0142387 Make find/search/cancel buttons themable 2013-01-09 18:24:41 -08:00
Alexandre Wilhelm 7ba759b08a Updated Aristo2 for toolBar 2013-01-09 18:24:32 -08:00
Alexandre Wilhelm fdd5aa0a5a Removed unused comments 2013-01-09 18:24:06 -08:00
Alexandre Wilhelm 6ee80f6182 Added support for theme 2013-01-09 18:23:09 -08:00
Aparajita Fishman af2e0348c1 More key view loop madness
- It turns out Cocoa DOES recalculate the loop when calling recalculateKeyViewLoop. It does not wait until selectNext/PreviousKeyView is called.
- Cocoa calculates the key view loop for nibs that do not have one, but does not call recalculateKeyViewLoop.
- If there is no first responder and no initial first responder when a window first becomes key, use the first valid key view, not the first geometric key view.
- Made allViews function a method, not sure why it was a function.
- Unit tests now pass.
2013-01-10 09:11:58 +07:00
Alexandre Wilhelm d4bf45a8b8 Moved psd to Artwork 2013-01-09 17:54:07 -08:00
Alexandre Wilhelm d30425b2bd Merge branch 'Aristo2' of github.mv.usa.alcatel.com:amercada/Cappuccino into Aristo2 2013-01-09 17:51:22 -08:00
Antoine Mercadal cff8fbbd79 Remove unused artwork 2013-01-09 17:49:53 -08:00
Antoine Mercadal 8b52c99604 Improve CPImageViewTest to test heavy shadow view too 2013-01-09 17:49:42 -08:00
Antoine Mercadal 5dee254fca Add theme for CPShadowView 2013-01-09 17:49:22 -08:00
Antoine Mercadal 2ab0f494b4 Make CPShadowView themable 2013-01-09 17:49:11 -08:00
Alexandre Wilhelm b4a58b47b3 Updated Aristo2 2013-01-09 17:35:59 -08:00
Alexandre Wilhelm b19450684b Fixed bug with toolBar 2013-01-09 17:34:32 -08:00
Antoine Mercadal 6451e3b3e3 Remove another Ressources not used anymore 2013-01-09 17:04:48 -08:00
Antoine Mercadal 14e2a169e4 Remove unused AppKit Ressources (moved to theme) 2013-01-09 17:03:54 -08:00
Alexandre Wilhelm f809919561 Update Aristo2 2013-01-09 16:02:37 -08:00
Alexandre Wilhelm 68d4b9d2cd Fixed bug with indicator 2013-01-09 16:02:24 -08:00
Alexandre Wilhelm 5e1c6ae30d Added class method for the title height 2013-01-09 16:01:51 -08:00
Alexandre Wilhelm e1ba234a76 Fixed bug about the position of closable buttons. Fixed bug about theme attribute for sheet window 2013-01-09 16:01:18 -08:00
Alexandre Wilhelm b9b84fe692 Improved code. Removed comments 2013-01-09 16:00:28 -08:00
Alexandre Wilhelm a3f5c461c3 Removed comments 2013-01-09 15:59:50 -08:00
Alexandre Wilhelm 91479543fa Removed unused theme attribute 2013-01-09 15:59:17 -08:00
Alexandre Wilhelm 4dfa724972 Removed comments 2013-01-09 15:58:47 -08:00
Alexandre Wilhelm f8e72504e5 Fixed bug with closable button in CPWindow 2013-01-09 14:43:33 -08:00
Alexandre Wilhelm 51d6ba98d7 Updated aristo2 2013-01-09 14:21:53 -08:00
Alexandre Wilhelm 2309e18eb7 Added themable support for shadow window 2013-01-09 14:21:41 -08:00
Alexandre Wilhelm 6ddb891c29 Fixed import 2013-01-09 14:19:56 -08:00
Alexandre Wilhelm 5100f6cb72 Updated psd with slices 2013-01-09 13:14:15 -08:00
Alexandre Wilhelm 73e56d820b Merge branch 'Aristo2' of github.mv.usa.alcatel.com:amercada/Cappuccino into Aristo2 2013-01-09 13:10:15 -08:00
Alexandre Wilhelm 803cbae1dc Updated Aristo2 2013-01-09 13:09:59 -08:00
Alexandre Wilhelm 9b9f877942 Added themable _CPWindowView 2013-01-09 13:09:43 -08:00
Alexandre Wilhelm 0e6df9d299 Added themable _CPDocModalWindowView 2013-01-09 13:09:20 -08:00
Antoine Mercadal 1cbe1cfaeb Merge branch 'master' into Aristo2 2013-01-09 11:59:01 -08:00
Antoine Mercadal 295eedc0b9 Add missing import in NSMenuItem.j 2013-01-09 11:58:42 -08:00
Antoine Mercadal 97a766517b Set content-margin size to zero for CPBox 2013-01-09 10:54:51 -08:00
Alexandre Wilhelm 42868ecbee Merge branch 'Aristo2' of github.mv.usa.alcatel.com:amercada/Cappuccino into Aristo2 2013-01-09 10:35:02 -08:00
Alexandre Wilhelm 4fd4b145d7 Updated Aristo2 2013-01-09 10:34:44 -08:00
Alexandre Wilhelm d5f7dc851e Themable _CPStandardWindowView 2013-01-09 10:34:10 -08:00
Antoine Mercadal 06fae21c76 Merge branch 'master' into Aristo2 2013-01-09 09:55:20 -08:00
Antoine Mercadal 29fe631ce6 small style fix 2013-01-09 09:54:43 -08:00
Andrew Hankinson 40ab25d2a6 Minor formatting changes 2013-01-09 11:30:20 -05:00
Andrew Hankinson 0f9a2dc9d3 Fixed: XCodeCapp reads the user's shell environment
Before this fix, XCodeCapp always ran under /bin/bash, causing problems when trying to source the files from other shells, like /bin/zsh

This fix reads the shell information directly from the user's environment and XCC to run using that shell.
2013-01-09 11:27:47 -05:00
Martin Carlberg 89da16afec Fixed objjc to output compiled source not the input source 2013-01-09 14:58:22 +01:00
Martin Carlberg 1dfc77a4ba Fixed objjc to use new acorn based compiler 2013-01-09 14:12:58 +01:00
Martin Carlberg 4fb8fa1311 Code clean up 2013-01-09 14:03:38 +01:00
Aparajita Fishman 782f47a30b Key view loop fixes/improvements
- Removed unnecessary code at beginning of CPTextField -becomeFirstResponder that might have been a hack to get around a bug I fixed.
- Fixed race condition in setTimeout closure in CPTextField -becomeFirstResponder.
- CPWindow -setInitialFirstResponder now works reliably and follows Cocoa behavior in that if -makeFirstResponder is called with something other than the window before the window is first shown, it will override the initial first responder.
- Like Cocoa, until the first responder is set during window load, the first responder is the window by default, not the content view.
- Optimized search for any view that has a previous/next key view set.
- Sheets can become key windows again.
- CPWindow -recalculateKeyViewLoop now just marks the loop as dirty, per Cocoa docs.
- CPWindow -autorecalculatesKeyViewLoop now behaves per Cocoa, it only has an effect when views are added or removed.
- If the first responder does not have a valid previous/next key view, it does not resign to nil, per Cocoa behavior.
- Code optimization and cleanup.
- Test app (KeyViewLoopTest) that demonstrates various scenarios.
2013-01-09 18:02:07 +07:00
Martin Carlberg 7eba982278 Merge branch 'master' of https://github.com/cappuccino/cappuccino into objj_compiler2 2013-01-09 11:11:45 +01:00
Martin Carlberg df78df5908 Fixed class method that access isa property 2013-01-09 10:37:33 +01:00
Martin Carlberg 0dd98b56bc "self." is only added to instance variables when compiling an instance method 2013-01-09 10:21:16 +01:00
Martin Carlberg 0a573f9da1 Removed unused 6th parameter 2013-01-09 09:29:43 +01:00
Antoine Mercadal 6d43387c55 Remove actually useless chunck of code in NSSearchField.j 2013-01-08 22:23:08 -08:00
Antoine Mercadal ed4094016b Update nib2cib NSSearchField.j to use correct field height 2013-01-08 22:21:51 -08:00
Antoine Mercadal 56100f150d Merge branch 'master' into Aristo2 2013-01-08 18:43:25 -08:00
Antoine Mercadal 6284f29a96 Fix regexp in XcodeCapp parser. Thanks to Andrew Hankinson 2013-01-08 18:43:09 -08:00
Antoine Mercadal 4e06ed80d1 Merge branch 'Aristo2' of 172.21.51.218:amercada/Cappuccino into Aristo2 2013-01-08 18:09:35 -08:00
Antoine Mercadal a0c294f689 Merge branch 'master' into Aristo2 2013-01-08 18:09:24 -08:00
Antoine Mercadal 19f668f4f6 use the [CPPlatformWindow primaryPlatformWindow] to position the tooltips. 2013-01-08 18:09:07 -08:00
Alexandre Wilhelm 02bd640aab Merge branch 'Aristo2' of github.mv.usa.alcatel.com:amercada/Cappuccino into Aristo2 2013-01-08 17:59:29 -08:00
Alexandre Wilhelm 06b1060a45 Fixed bug in scrollview 2013-01-08 17:59:19 -08:00
Antoine Mercadal 0f0dcb9eae Remove old static theme for CPSplitView 2013-01-08 17:22:19 -08:00
Antoine Mercadal 5ec6d571eb Improve theme for CPSplitView 2013-01-08 17:22:10 -08:00
Antoine Mercadal 347de2cb8b CPSplitView is now fully themable 2013-01-08 17:21:32 -08:00
Antoine Mercadal f6a923ad56 remove old non themable CPProgressIndicator art files 2013-01-08 17:09:38 -08:00
Antoine Mercadal 43455ee661 Remove old CPLevelIndicator ressources 2013-01-08 17:06:13 -08:00
Antoine Mercadal 911df72aeb Add theme for CPLevelIndicator 2013-01-08 17:05:58 -08:00
Antoine Mercadal b82225e279 Make CPLevelIndicator themable 2013-01-08 17:05:33 -08:00
Antoine Mercadal bb3cc58ad0 Merge branch 'Aristo2' of 172.21.51.218:amercada/Cappuccino into Aristo2 2013-01-08 16:30:24 -08:00
Antoine Mercadal 804a345fec Merge branch 'master' into Aristo2 2013-01-08 16:29:52 -08:00
Antoine Mercadal 7816510fdf Merge branch 'master' of https://github.com/cappuccino/cappuccino 2013-01-08 16:29:33 -08:00
Antoine Mercadal 50031dbc89 Remove wrong import string 2013-01-08 16:29:06 -08:00
Alexandre Wilhelm 7f05164a7f Merge branch 'Aristo2' of github.mv.usa.alcatel.com:amercada/Cappuccino into Aristo2 2013-01-08 16:24:24 -08:00
Alexandre Wilhelm 52a6806022 Update Aristo2 2013-01-08 16:23:51 -08:00
Alexandre Wilhelm 1a9d47c554 Fixed bug about scroller-width attribute theme 2013-01-08 16:22:49 -08:00
Antoine Mercadal 2c3b3be3ee Adjust menubar height 2013-01-08 15:51:53 -08:00
Antoine Mercadal cdaed50939 Readd Aristo1 build process
Cappuccino will now continue to support Aristo1
By default Aristo2 will be used, unless you add in your Info.plist

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

In that case Aristo2 will be use.

If you put

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

It will use your custom theme as usual from your app's Resource folder
2013-01-08 15:03:14 -08:00
Antoine Mercadal 5a155020e6 Merge branch 'master' into Aristo2 2013-01-08 15:02:50 -08:00
Martin Carlberg 957b34d169 Added the option trackSpaces to attach spacesBefore and spacesAfter properties to AST nodes. 2013-01-08 22:23:34 +01:00
Martin Carlberg 79d2ac0566 Fixed some comments and removed unwanted spaces 2013-01-08 22:19:55 +01:00
Martin Carlberg 547f9ff61f Merge with latest from Acorn master 2013-01-08 22:18:19 +01:00
Martin Carlberg 9f0da2ec41 Fixed spelling error 2013-01-08 22:13:36 +01:00
Alexander Ljungberg 32eafb7708 Fix import. 2013-01-08 18:21:29 +00:00
Alexander Ljungberg c81b8fb3c3 Formatting. 2013-01-08 18:07:15 +00:00
Antoine Mercadal a9be167146 Add missing import 2013-01-08 10:05:25 -08:00
Martin Carlberg c755dc3ed9 Added some more detailed error messages in parser 2013-01-08 17:00:54 +01:00
Martin Carlberg d20fb2039a Missed some lines in manual merge 2013-01-08 14:34:29 +01:00
Martin Carlberg 1c3411f808 Merge remote-tracking branch 'upstream/master' into objj_compiler2
Conflicts:
	AppKit/CPWindow/CPWindow.j
2013-01-08 09:25:54 +01:00
Antoine Mercadal 7357be3c35 Finish Aristo HUD 2013-01-07 20:03:20 -08:00
Antoine Mercadal 5dd1bed913 Add the HUD version of Aristo2 2013-01-07 18:40:34 -08:00
Antoine Mercadal 18eda8aade Add the HUD version of Aristo2 2013-01-07 17:34:43 -08:00
Antoine Mercadal 8e16e6266e Fix a bug where CPURL was not encoding self._baseURL and self._string 2013-01-07 16:04:08 -08:00
Martin Carlberg 8100cdb17f Fixed "Can't find variable: ObjJCompiler" error 2013-01-07 23:13:54 +01:00
Antoine Mercadal 7fa01fa4f3 Merge branch 'master' into Aristo2
Conflicts:
	Tests/Manual/CPPopover/Resources/MainMenu.cib
2013-01-07 13:23:05 -08:00
Martin Carlberg d49e78c43e Removal of old compiler 2013-01-07 20:29:56 +01:00
Martin Carlberg cf46768ac7 Removal of logs 2013-01-07 20:29:45 +01:00
Martin Carlberg cfe718f4ef Handle preprocessor lines like "#pragma" 2013-01-07 20:29:35 +01:00
Martin Carlberg bf32b90702 Allow signed, unsigned, char, short, int and long to be an identifier 2013-01-07 20:29:13 +01:00
Martin Carlberg 9cb14d6db3 Added new faster compiler based on acorn parser 2013-01-07 09:59:10 +01:00
Martin Carlberg 140cf0debe Code cleanup 2013-01-07 09:55:12 +01:00
Aparajita Fishman 45ad5375a2 Full platform windows and popovers can become main 2013-01-07 07:07:27 +08:00
Alexander Ljungberg 259adda77d Merge pull request #1713 from milestinsley/CPBrowserStyleProperty-fix
Improved support for converting CSS properties to their JS equivalent in CPBrowserStyleProperty
2013-01-06 17:31:08 +00:00
Miles Tinsley 964f3fe06d Improved the reliability of CPBrowserCSSProperty by checking for the browser prefix *before* hyphenating the camel-cased string.
This has the added benefit of ignoring unknown/unsupported prefixes, providing the property itself is camel-cased.

For example:

"LinearBackground" -> "linear-background"
"Linear-Background" -> "linear-background"
"linear-background" -> "linear-background"
"fooLinearBackground" -> "linear-background"

and

"WebkitLinearBackground" -> "-webkit-linear-background"
"MozLinearBackground" -> "-moz-linear-background"
etc..
2013-01-06 17:20:37 +00:00
Miles Tinsley 002c49b32f Updated CPBrowserCSSProperty to support camel cased style property names and convert them into valid browser-aware CSS properties. 2013-01-06 16:57:31 +00:00
Alexander Ljungberg d4313be406 Merge pull request #1713 from milestinsley/CPBrowserStyleProperty-fix
Improved support for converting CSS properties to their JS equivalent in CPBrowserStyleProperty
2013-01-06 15:48:49 +00:00
Miles Tinsley 76a4ded128 Improved support for converting CSS properties to their JS equivalent in CPBrowserStyleProperty
For example, the following CSS property names all resolve to the same correct JS equivalent for the current browser:

 * CPBrowserStyleProperty('TransformOrigin') -> 'WebkitTransformOrigin'
 * CPBrowserStyleProperty('transform-origin') -> 'WebkitTransformOrigin'
2013-01-06 13:26:01 +00:00
Aparajita Fishman 8d68e805f4 Fix CPWindow -canBecomeKeyWindow and -canBecomeMainWindow to match Cocoa behavior (and misleading documentation)
Minor code formatting cleanup as well
2013-01-06 16:21:10 +08:00
Aparajita Fishman f1a171a94c Window resize fixes
- Track mouse exit from window resize rect instead of unconditionally setting arrow cursor.
- Don't show the resize cursors for full platform windows.
- Show the resize down cursor if the top of a window is being resized and it has reached the bottom of the menubar.
- Make windows in CPToolbarTest resizable to test resizing behavior with toolbars.
- Added a full platform window and menubar to the test app.
2013-01-05 11:13:53 +08:00
Antoine Mercadal 7e9b12b475 Update and improve CPBoxTest manual test 2013-01-04 18:46:16 -08:00
Antoine Mercadal 63a3a8a731 Use API to set themable attribute in nib2cib for CPBox 2013-01-04 18:45:53 -08:00
Antoine Mercadal c95421f307 Add theme for CPBox (and it's an improved look) 2013-01-04 18:45:28 -08:00
Antoine Mercadal edc62449f6 Make CPBox themable 2013-01-04 18:45:05 -08:00
Antoine Mercadal a7f1192402 Ignore .XcodeSupport folder 2013-01-04 18:22:08 -08:00
Antoine Mercadal 6bbda8a8e7 Merge branch 'Aristo2' of 172.21.51.218:amercada/Cappuccino into Aristo2 2013-01-04 12:21:07 -08:00
Antoine Mercadal 2431dbc16f rerun nib2cib on CPSegmentedControlTest's MainMenu.xib 2013-01-04 12:20:57 -08:00
Antoine Mercadal d87f86b2a4 Adjust CPSegmentedControl height to match new Aristo2 art 2013-01-04 12:20:36 -08:00
Antoine Mercadal 55a0652c2b Merge branch 'master' into Aristo2 2013-01-04 12:15:51 -08:00
Antoine Mercadal 3e6517849e Add manual test for CPSegmentedControl 2013-01-04 12:15:09 -08:00
Antoine Mercadal deacdde521 Fix bug in CPSegmentedControl not reducing his size when removing segments 2013-01-04 12:14:22 -08:00
Alexandre Wilhelm aa1559b159 Added missing images 2013-01-04 11:57:12 -08:00
Alexandre Wilhelm 88dd2f1495 Fixed bug with tokenfield 2013-01-04 11:52:36 -08:00
Alexandre Wilhelm eb2cd75370 Fixed bug in BKShowcasController with popUpButtons size 2013-01-04 10:32:35 -08:00
Alexander Ljungberg d072f17896 Optimisation. 2013-01-04 11:28:09 +00:00
Alexander Ljungberg 0d31f79f53 Constrain window resize to usable area of platform window. 2013-01-04 11:28:09 +00:00
Aparajita Fishman b869312e4f Finished full window resize support
- The main run loop resets the cursor if it falls outside of all windows during a mouse move.
- Added cursors supported by CSS that are not in NSCursor.
- Code cleanup in CPCursor.
- Cursors now indicate available resize directions if there is a window min/max size.
- Reduced slop to 3, what it is in Cocoa.
- Added a second non-min/max window to the demo.
2013-01-04 15:19:00 +08:00
Aparajita Fishman deb6224cf8 Support for resizing windows on all sides 2013-01-04 15:17:29 +08:00
Alexandre Wilhelm 4757648349 CPAlert can be moved now 2013-01-03 18:34:22 -08:00
Alexandre Wilhelm a1f166942c Added new modal window 2013-01-03 18:14:13 -08:00
Antoine Mercadal 7dbe0c2899 readd removed art.. 2013-01-03 18:01:36 -08:00
Antoine Mercadal 9bc4873721 Update the menubar art 2013-01-03 17:55:06 -08:00
Antoine Mercadal 15005f5754 Update selection color 2013-01-03 16:59:10 -08:00
Antoine Mercadal c959ca9821 Update static art to match Aristo2 2013-01-03 16:51:10 -08:00
Antoine Mercadal 26687226f4 Merge branch 'Aristo2' of 172.21.51.218:amercada/Cappuccino into Aristo2 2013-01-03 15:04:58 -08:00
Antoine Mercadal 408b5b517b Run ImageOptim on all Aristo2 ressources 2013-01-03 15:04:31 -08:00
Alexandre Wilhelm f403699fb2 Fixed bug with content-inset in textField 2013-01-03 14:51:23 -08:00
Alexandre Wilhelm 193b289e8e CPButtonBar Aristo2 2013-01-03 14:46:05 -08:00
Antoine Mercadal 533fd0574a Merge branch 'master' into Aristo2 2013-01-03 14:25:42 -08:00
Antoine Mercadal 48ffdf419f Restore art for ButtonBar 2013-01-03 14:16:50 -08:00
Antoine Mercadal 93e931e2b6 Fix Aristo2 Build process 2013-01-03 13:47:50 -08:00
Alexandre Wilhelm 6561e4f84e Init of Aristo2 2013-01-03 11:22:46 -08:00
Alexander Ljungberg dcdcd8e41a Fixed: CPPanel could not always become the key window.
Without this fix, `CPPanel` followed the same rules as `CPWindow` with regards to becoming the key window. But `CPPanel` is supposed to always be willing to become the key window, as stated in its documentation.

This change makes `CPPanel` always return `YES` for `canBecomeKeyWindow`.
2012-12-31 14:53:04 +00:00
Alexander Ljungberg 24443221f2 Merge pull request #1708 from imageoptimiser/optimised-images
Optimise images (94 KB reduction)
2012-12-27 16:12:46 +00:00
imageoptimiserandAdam Howard 787dd10c69 Optimised images 2012-12-24 12:10:02 +00:00
Alexander Ljungberg 9705f1fe28 Commit message guidelines. 2012-12-21 11:25:13 +00:00
Martin Carlberg d5748474d0 Forgot some more lines 2012-12-20 22:55:58 +01:00
Martin Carlberg 2277fb04b9 Missed to commit some stuff for scope handling 2012-12-20 18:19:39 +01:00
Martin Carlberg 78b2d30905 Added better support for scope 2012-12-20 18:01:47 +01:00
Martin Carlberg ed81d75815 Removes #pragma lines 2012-12-20 17:49:23 +01:00
Martin Carlberg ac3a399df3 Set to use new compiler when compiling with jake 2012-12-20 15:20:38 +01:00
Martin Carlberg 619f90c677 Removed debug stuff 2012-12-20 15:20:12 +01:00
Martin Carlberg 0f3d5f4b10 Added support to choose which compiler should be used when compiling in the browser. Default is old compiler but add "ObjJCompilerSetUsedVersion("objj_compiler2");" in the index.html (and/or index-debug.html) to use new compiler in browser. 2012-12-20 14:26:49 +01:00
Martin Carlberg 26be5bf264 Better error message when importing file that is not found 2012-12-20 14:23:54 +01:00
Martin Carlberg 227c696750 Removed circular imports in CPToolbarItem.j 2012-12-20 14:22:09 +01:00
Martin Carlberg b1cec9480e New test cases to test ivar handling in new compiler 2012-12-20 09:37:52 +01:00
Martin Carlberg 982da962e5 Fixed problems due to the removal of with(self) 2012-12-19 23:51:42 +01:00
Alexander Ljungberg 2a11bdb7ef Fixup: previous fix undid penultimate fix. 2012-12-18 00:34:14 +00:00
Alexander Ljungberg 3775c3fb2e Fixed: CPAlert was a CPView.
Before this fix, CPAlert subclassed CPView, causing an API mismatch with Cocoa and exposing unexpected methods in the public API which made no sense for a CPAlert such as autoresizing masks. It also lead to CPAlert mistakingly shadowing _window from its CPView superclass.

This fix makes CPAlert inherit from CPObject as it should. The theming, which needs to be applied to a view, was moved to an internal view.
2012-12-18 00:22:19 +00:00
Alexander Ljungberg cea120945c Fixed: CPAlert sheet crash.
Without this fix, CPAlert windows would not finish closing before sending the `alertDidEnd:returnCode:` delegate message. This would lead to a crash if the delegate method tried to open a new sheet.

This fix makes sure to fully order out the alert sheet before sending the delegate message.
2012-12-18 00:19:04 +00:00
Martin Carlberg 803c8ce6b5 A little code clean up. 2012-12-17 17:14:33 +01:00
Martin Carlberg ca99114b16 Forgot to add one file 2012-12-17 15:12:02 +01:00
Martin Carlberg 897adf27f0 Fixed import statements in nib2cib, bug in load system and some more fixes to test cases 2012-12-17 14:57:18 +01:00
Martin Carlberg fd59efe41f Bug fixes for failing test cases 2012-12-17 11:15:50 +01:00
Martin Carlberg b52217e8a0 Tried to make the import mess a little better. Fixed a lot of bugs. Changed some class names in the test cases. Looks like all the tests are being run in the same space. Has to look into this….. 2012-12-17 00:40:26 +01:00
Martin Carlberg 0280a10832 More changes now when we don't have with(self) 2012-12-16 19:20:59 +01:00
Martin Carlberg c297e926f9 Compiler now works with jake and can compiler the whole Cappuccino framework. A lot of test cases still fail 2012-12-16 17:38:47 +01:00
Martin Carlberg 59fa5c27b6 Added support for new compiler when loading objj files in the browsers 2012-12-15 23:35:36 +01:00
Alexander Ljungberg a202cfbbe9 Skip check-missing-imports in standard jake test to make the load on travis-ci lighter.
"detect-missing-imports" takes a long, long time to run. Since it only emits warnings it can't affect the result of the continuous integration builds.

Until it can be made a little faster it's probably best to run it by hand with `jake check-missing-imports`.
2012-12-15 12:36:00 +00:00
Alexander Ljungberg 848c893b9e Fixed: CPApplicationTest setArguments.
Without this change, CPApplicationTest's manipulation of window.location.hash was ignored by CPApplication in recent versions, since CPApp in a unit test normally does not have access to the window object.

This change makes it so that CPApp does try to access the window object, even in a unit test scenario (non PLATFORM(DOM)).
2012-12-15 11:50:47 +00:00
Alexander Ljungberg 252b8f5ca5 Fixed: [CPApp windows] contained nil.
Before this fix, CPApp tried to add nil to its internal list of windows, even that nil should not be added to a CPArray. Second, that nil was actually returned by [CPApp windows] rather than an expected list of only CPWindow instances.

This fix makes [CPApp windows] return only actual windows, replaces the internal _windows[0] placeholder with CPNull, and ensures this CPNull is never actually exposed outside of the class.
2012-12-15 11:48:15 +00:00
Alexander Ljungberg d82da5d571 Fix 7070fe9b2e. 2012-12-15 01:36:05 +00:00
Alexander Ljungberg 1ebdd8ed8e Try to make travis output more to the point. 2012-12-15 01:32:06 +00:00
Alexander Ljungberg 7070fe9b2e --quiet and --verbose boostrap.sh options.
Without this change, bootstrap.sh outputs a great deal of often superfluous information, like precisely which files are unzipped.

Also, curl and wget display progress information by default.

With this change, by default unzipping is quiet, unless --verbose is specified. curl and wget still display progress information, but --quiet can be specified to prevent this.
2012-12-15 01:31:28 +00:00
Alexander Ljungberg 7b2464a740 Fix tab view test to work after 2758454.
Now that we use layoutSubviews in CPTabView we have to make sure it's called in a unit test scenario.
2012-12-15 01:12:29 +00:00
Alexander Ljungberg e2f19c30f1 Whitespace. 2012-12-15 01:03:52 +00:00
Alexander Ljungberg 5408df40f5 Merge pull request #1698 from ahankinson/travis-ci
Travis CI Integration
2012-12-15 00:46:49 +00:00
Alexander Ljungberg 79894781b1 Merge pull request #1707 from slevenbits/slevenbits-tokenfield-value-fix
Fixed: if any token field was being edited, the object value of all other token fields contained the partial value.
2012-12-15 00:40:07 +00:00
Alexander Ljungberg e798842dee Merge pull request #1706 from slevenbits/slevenbits-tokenfield-scroll-fix
Fixed: token field autocomplete scrollbars unresponsive to mouse.
2012-12-15 00:40:04 +00:00
Alexander Ljungberg 98ff6c1279 Merge pull request #1705 from slevenbits/slevenbits-popover-firefox-fix
Fixed: popoverDidShow in Firefox. New: popover animation support in Firefox, Opera and IE10.
2012-12-15 00:40:02 +00:00
Alexander Ljungberg 59fb04321d Merge pull request #1704 from slevenbits/slevenbits-key-popover-fix
Fixed: CPPopovers could not become key windows in recent versions.
2012-12-15 00:37:28 +00:00
Alexander Ljungberg 81d537fa24 Merge pull request #1703 from slevenbits/slevenbits-editable-tokenfield-fix
Fixed: tokens could be deleted in an non editable token field.
2012-12-15 00:37:23 +00:00
Alexander Ljungberg 6488ab2375 Merge pull request #1702 from slevenbits/slevenbits-settimeout-fix
Allow setTimeout(f) to support some JS libraries such as PDF.js.
2012-12-15 00:37:20 +00:00
Alexander Ljungberg a10f36e3a2 Merge pull request #1701 from slevenbits/slevenbits-tab-view-resize-fix
Fixed: tab views added in IB didn't resize properly.
2012-12-15 00:37:18 +00:00
Alexander Ljungberg eed37a0f81 Fixed: if any token field was being edited, the object value of all other token fields contained the partial value.
Without this fix, token fields generally assumed that if there was anything in the shared editor buffer, it belonged to the current field, even if it wasn't the field that was being edited.

With this fix only the token field actually being edited considers the editor contents.
2012-12-14 15:12:44 +00:00
Alexander Ljungberg 0781a4153e Fixed: popoverDidShow in Firefox. New: popover animation support in Firefox, Opera and IE10.
Before this fix, popoverDidShow: would not be sent to popover delegates when the app ran in Firefox due to Firefox now recognising the -webkit-transition property, but not the webkitTransitionEnd event.

Also, before this fix popover animation was only implemented for Webkit based browsers.

This fix resolves that issue and in addition adds full support for animated popovers in all browsers that support CSS transitions. The fix also improves Cappuccino's general support for CSS3 animations.
2012-12-13 14:04:36 +00:00
Alexander Ljungberg 8ec1325aff Fixed: CPPopovers could not become key windows in recent versions.
This prevented text fields and token fields from accepting input when placed in a pop over.

This fix allows the underlying popover window to become the key window.
2012-12-12 18:17:20 +00:00
Alexander Ljungberg 947b116c06 Manual test for non-editable token fields. 2012-12-12 17:50:05 +00:00
Alexander Ljungberg 095858d3d5 Fixed: token field autocomplete scrollbars unresponsive to mouse.
Without this fix, the scroll handle in the token field autocomplete menu could not be moved using the mouse. Only scroll wheel or keyboard based scrolling was possible.

This fix enables regular mouse interaction with the scrollbar.
2012-12-12 17:47:50 +00:00
Alexander Ljungberg 2b1b1ea33b Fixed: CPScrollView setGlobalScrollerStyle: return value. 2012-12-12 17:45:59 +00:00
Alexander Ljungberg bd1f64bfde Only show token delete button on hover, and only when token field is editable.
Before this change the close button showed at all times, even for token fields which weren't even editable.

This change brings us closer to Cocoa in that there's no token delete button most of the time, and just like in Cocoa there are more controls available on hover. (Although in Cocoa there's a disclosure arrow and we have a close button instead.)
2012-12-11 17:27:13 +00:00
Alexander Ljungberg d27e333941 Fixed: tokens could be deleted in an non editable token field.
Prior to this fix, clicking the (X) button on a token would delete the token even if the field was not actually editable.
2012-12-11 17:19:02 +00:00
Alexander Ljungberg c2bf47eca2 Support CPThemeStateEditable for text fields. 2012-12-11 17:15:24 +00:00
Alexander Ljungberg 9035439f61 Fixed: token field first responder flicker when clicking tokens.
Without this change, clicking a token in a first responder token field would cause it to momentarily lose first responder status and then immediately gain it back.

This fix makes it so that tokens never try to become the first responder, resulting in a more stable token field as tokens are selected and deselected.
2012-12-11 16:43:06 +00:00
Alexander Ljungberg 77955f4e2b Allow setTimeout(f) to support some JS libraries such as PDF.js.
Without this change some 3rd party JS libraries such as PDF.js, which rely on the nonstandard setTimeout(f), will not operate correctly.

According to MDN the delay argument is required. However browsers seem to treat setTimeout without delay argument the same as a delay of 0. This fix makes it so that Cappuccino apps do the same.
2012-12-11 00:57:42 +00:00
Andrew Hankinson f5bb8abfe0 Updating paths for integration into mainline cappuccino 2012-12-03 19:24:14 -05:00
Andrew Hankinson a24f33ad93 Add .travis.yml for Travis-CI support 2012-12-03 19:11:35 -05:00
Alexander Ljungberg ad5f0a7f7d Avoid touching the window object in CPApplication of non-DOM apps. 2012-12-03 22:45:53 +00:00
Alexander Ljungberg 2611e867b3 Fixed: ce9534c too negative with canBecomeKeyWindow.
Due to a typo in ce9534c, even standard titled windows returned NO for `canBecomeKeyWindow`. This triggered errors in `CPApplicationTest`.

The fix returns the correct YES for `canBecomeKeyWindow` of titled windows.
2012-12-03 22:44:12 +00:00
Alexander Ljungberg c9434ec4dc Fixed: CPFontManager attempt to access DOM in non-DOM apps.
The DOM access caused `CPFontManagerTest` when executed with rhino.
2012-12-03 22:22:16 +00:00
Alexander Ljungberg 282e96649a Formatting. 2012-12-03 22:21:01 +00:00
Alexander Ljungberg 71b93a2b4c Merge pull request #1696 from slevenbits/slevenbits-tokenfield-autocomplete-position
Fixed: token field autocomplete menu placed incorrectly.
2012-11-29 23:51:52 +00:00
Alexander Ljungberg 86b302491a Merge pull request #1695 from slevenbits/slevenbits-tabbing-fix
Fixed: tabbing to token fields.
2012-11-29 23:50:00 +00:00
Alexander Ljungberg e28a78afd3 Merge pull request #1693 from mrcarlberg/nib2cib_correct_height_for_button_subclasses
nib2cib will now adjust to the correct themed height for subclasses of CPButton
2012-11-29 12:34:29 +00:00
Martin Carlberg 7dd034e56c nib2cib will now adjust to the correct themed height for subclasses of CPButton.
For examples CPPopUpButton can get another height then CPButton.
2012-11-29 13:25:53 +01:00
cacaodev b97a07630d CPStepper : Adds binding support for CPValueBinding, CPMinValueBinding, CPMaxValueBinding. Placehoders defaults are minValue, minValue, maxValue.
CPStepperBindings : Example for these bindings. Shows behavior when input is a marker.
2012-11-27 15:52:38 +01:00
Alexander Ljungberg 990aeca0ba Merge pull request #1681 from mockingbird/master
Make all validations by the framework be autovalidations
2012-11-26 23:44:22 +00:00
Alexander Ljungberg 3c5284f081 Merge pull request #1691 from cacaodev/CPBinder-_updatePlaceholdersWithOptions
CPBinder -_updatePlaceholdersWithOptions:  add a reference to the binding.
2012-11-26 23:36:55 +00:00
cacaodev da01d3aaaa do it right 2012-11-26 18:31:08 +01:00
Alexander Ljungberg 9d4e8164b7 Fixed: token field autocomplete selection by mouse.
After recent changes clicking on an autocomplete item in the pop up did nothing. Now this works and in conjunction with the new non-key-window-change update it's likely to work better than before.
2012-11-26 15:39:41 +00:00
Alexander Ljungberg ce9534cdea Fixed: canBecomeKeyWindow response for auxiliary windows.
Without this fix Cappuccino always returned YES for `canBecomeKeyWindow` for every window. But in Cocoa, only "standard" windows with a title bar and/or resizing return YES.

With this fix Cappuccino better matches Cocoa's behaviour.
2012-11-26 14:01:33 +00:00
Alexander Ljungberg 2236e7d2da Unused variable. 2012-11-26 13:48:45 +00:00
Alexander Ljungberg 632e226b51 Manual test to demo/test fixed position text with and without bezel. 2012-11-25 11:12:37 +00:00
cacaodev 6c4d1e5ce1 CPBinder _updatePlaceholdersWithOptions : Added forBinding:(CPString)aBinding argument.
If a binder instance can manage several bindings, you may want to set placeholders depending on the binding name.
2012-11-22 15:33:01 +01:00
Alexander Ljungberg 4ef5dc83bb Fixed: token field autocomplete menu placed incorrectly.
If the token field was in a window not placed in the upper left corner of the screen (like regular platform windows are), the autocomplete menu would show up in the wrong spot.
2012-11-19 15:08:17 +00:00
Alexander Ljungberg 9ebc78773d Put half a vertical spacing above the first row of tokens.
This means there'll be 1 px of spacing both above and below tokens in multi-row configurations. It also places the token much better in the field both in single and multi-row configurations, at least for the Aristo theme.
2012-11-19 12:14:28 +00:00
Alexander Ljungberg e2f8d77f67 Fixed: white line when scrolling between tokens.
Without this fix there'd be a white line visible on top of the token field when scrolling between multiple lines of tokens in a short field.

In addition the scroll view was 1 px short which made it possible to scroll tokens up and down by 1 px even when there was only a single row of tokens which should fit in the field.

This fix expands the clip rect upwards by 1 px to bring it all the way up to the first row of bezel pixels, ensuring sure a single row of tokens fits fully in a 1 row token field.
2012-11-19 11:54:05 +00:00
Alexander Ljungberg 256d36320a Fixed: token fields lost first responder status when switching between windows.
E.g. in a two window application, if a token field was the first responder and another window was made active and then the original window made active again, the token field would no longer be the first responder.
2012-11-19 00:40:26 +00:00
Alexander Ljungberg 6bc8ad0e2c Add a token field to attached sheet test for first responder testing in multi window situations. 2012-11-18 22:34:08 +00:00
Alexander Ljungberg fd3ad76db3 Fixed: after tabbing to a token field it'd immediately lose first responder status.
Without this fix, the tab key press would be propagated to the browser, which would blur the focused input element, even when that input element was the one the new first responder intended to use.
2012-11-18 22:32:41 +00:00
Alexander Ljungberg 8a39561ddb Extend tab view test with different tab view types.
Resizing for all tab view types can now be tested by clicking "Cycle Tab View Type" up to 6 times and resizing the window for each mode. (Some modes are not implemented.)
2012-11-18 19:33:58 +00:00
Alexander Ljungberg 27584544d9 Fixed: tab views added in IB didn't resize properly.
IB sets `autoresizesSubviews` to NO for tab views by default. In Cocoa this doesn't make any difference because `NSTabView` ignores this setting.

This fix makes it so that Cappuccino's tab view also works with `autoresizesSubviews` off.
2012-11-18 19:24:13 +00:00
Alexander Ljungberg 788ee6cd90 Merge branch 'master' of github.com:cappuccino/cappuccino 2012-11-17 11:45:20 +00:00
Alexander Ljungberg 97f3ab23b7 Merge pull request #1689 from slevenbits/slevenbits-content-rect-toolbar-fix
Fixed: incorrect `- CPWindow contentRectForFrameRect:` and  `frameRectForContentRect:` for borderless windows with toolbars.
2012-11-17 11:40:53 +00:00
Alexander Ljungberg 074e9f70a0 Fixed: incorrect - CPWindow contentRectForFrameRect: and frameRectForContentRect: for borderless windows with toolbars.
The window views driving non standard windows (such as borderless or bridge windows) did not take the toolbar into account when calculating the content rect.

Apart from being wrong, this could lead to the content view overlapping the toolbar if the content view was set after the toolbar was prepared.

Perhaps the thought was that the base _CPWindowView shouldn't make assumptions about the placement and sizing of a toolbar and leave that up to subclasses, but the _CPWindowView tile method already did.
2012-11-17 10:06:08 +00:00
Antoine Mercadal 621f1f1d61 Merge branch 'master' of https://github.com/cappuccino/cappuccino 2012-11-15 15:33:49 -08:00
Antoine Mercadal ba338036f9 improve CPPopover's popoverDidShow: management
Before, the popoverDidShow: delegate methods was called during the CSS animation (if any)
Problem is that is we are processing big amount of data, the animation may hang for a bit in the middle, giving an impression of jerkiness.

Now, popoverDidShow: is called at the end of the CSS animation if popover is animated.
2012-11-15 15:31:20 -08:00
Alexander Ljungberg c896101a30 Fixed: a recent internal method rename broke CPTabViewItem setView:. 2012-11-15 10:05:14 +00:00
Alexander Ljungberg 7fab75216f Fixed: text field responder error when using a formatter.
If the formatter rejected a change and prevented the first responder status from being surrendered, the text field would still stop listening to key window changes and break first responder behaviour when switching between windows.
2012-11-13 16:34:47 +00:00
Alexander Ljungberg 6c265fee30 With the NSMatrix->CPRadioGroup change the selectedRadio is easier to get. 2012-11-13 16:31:52 +00:00
Alexander Ljungberg f1c6a8bc12 Fixed: Error: Permission denied to access property '_childAppIsStarting' in Firefox.
This error would occur when running an app in an iframe which could not access its parent frame.
2012-11-08 17:30:17 +00:00
Antoine Mercadal 0fa499bd61 Makes CPAlert above popovers 2012-10-30 11:09:38 -07:00
Antoine Mercadal c747a79db9 Merge branch 'master' of https://github.com/cappuccino/cappuccino 2012-10-29 16:10:15 -07:00
Antoine Mercadal a1751cc981 Improve Popover's content view resizing 2012-10-29 16:09:09 -07:00
Alexander Ljungberg 797bfeec98 Implement CPPointInRect.
This improves source code compatibility with Cocoa when replacing NS with CP.
2012-10-24 15:35:42 +01:00
Alexander Ljungberg c3c61e1889 - CPBox titleView.
This method is the Cappuccino analog to `- NSBox titleCell`.
2012-10-24 15:32:45 +01:00
Alexander Ljungberg 0d9973abb9 Fixed: out of place table headers and other text positioning errors.
A line breaking, vertically centred or bottom aligned `_CPImageAndTextView` would not properly recalculate text position when the height of the text changed due to the width of the field changing.

This could cause, for example, table header text to be misaligned if the table was initialised with a zero height.
2012-10-23 16:19:11 +01:00
Alexander Ljungberg 7de4fe7afa Fixed: automatic table view sort descriptors didn't work for deeper bindings.
If a table view column showed for example `arrangedObjects.user.name`, it would try to sort arranged objects by `name` instead of `user.name`.
2012-10-23 15:24:10 +01:00
Alexander Ljungberg fb155dec58 Allow non-string tooltips.
Technically the tooltip should be a `CPString` but if a date or a number is passed this will now work without a crash.
2012-10-23 11:44:21 +01:00
Alexander Ljungberg 90d27133b0 Fixed: relative URLs were deemed to fail the SOP test by web views. 2012-10-23 11:22:24 +01:00
Alexander Ljungberg 0f5d459ed8 Fixed: collection view crash on unepexted drag events. 2012-10-23 11:21:42 +01:00
Alexander Ljungberg f4dc08f1f8 Merge branch 'master' of github.com:cappuccino/cappuccino 2012-10-22 23:14:08 +01:00
Alexander Ljungberg 4bedd52e16 CPGraphicsContext saveGraphicsState and restoreGraphicsState. 2012-10-22 15:03:32 +01:00
Alexander Ljungberg 391701fdc7 - CPBezierPath addClip and setClip.
This enables e.g. a `CPGradient` to be drawn clipped by an arbitrary bezier path.
2012-10-22 15:02:28 +01:00
Antoine Mercadal a973be2566 fix bad import 2012-10-18 15:26:15 -07:00
Antoine Mercadal 298fd49c55 Merge branch 'master' of https://github.com/cappuccino/cappuccino 2012-10-18 14:23:22 -07:00
Antoine Mercadal 23adbd4407 Improve tooltips API and avoid some sticky tooltips 2012-10-18 14:22:47 -07:00
Alexander Ljungberg eba3e95b81 CPBezierPath controlPointBounds and CGPathGetBoundingBox. 2012-10-15 11:10:23 +01:00
Alexander Ljungberg 8819fd5fd7 Improve nib2cib support for NSMatrix based radio groups.
Without this fix, a matrix with a target-action pair would crash when the cib was loaded due to the matrix having been replaced with a `CPView` (which cannot take a target-action pair).

Now if the matrix is for radio buttons, the action connection for the matrix is made to the `CPRadioGroup` instead and works as expected when radio selections are made.
2012-10-15 02:55:04 +01:00
Alexander Ljungberg 9c2cb393c2 CGContextIsPathEmpty for non-canvas based platforms.
Unfortunately there doesn't seem to be a way to get the current path from a canvas context so this function only works in VML mode for now.
2012-10-15 02:49:11 +01:00
Alexander Ljungberg ca4e034a3b CPBezierPath appendBezierPathWithArcFromPoint:toPoint:radius: and CGPathAddArcToPoint. 2012-10-15 02:47:37 +01:00
Alexander Ljungberg fd138cfae7 - CPBox setTitleFont support. 2012-10-15 01:10:08 +01:00
Alexander Ljungberg e530831b81 + CPFont systemFontSizeForControlSize:. 2012-10-15 01:09:21 +01:00
Alexander Ljungberg 7c56ea47dd Skeleton CPColor colorUsingColorSpaceName:.
The method does nothing but is provided for API compatibility with `NSColor`.
2012-10-15 01:00:29 +01:00
Alexander Ljungberg adb6404a0f Support Cib/Interface Builder window positioning masks.
Without this feature windows could easily end up being placed outside of the screen/browser when loaded in Cappuccino due to e.g. the window position being 100 px from the bottom of a 1418 px tall screen but the browser only being 800 px.

This commit adds support for all "initial position" window masks in Interface Builder except "centre". Position can be specified in current screen space coordinates and then adjusted proportionally to the browser size, or adjusted while preserving a left or right margin and a top or bottom margin.
2012-10-15 00:20:22 +01:00
Alexander Ljungberg 084e0a315f Clean up.
Put `_CPCibWindowTemplate` coding support in its own category to match most Cappuccino classes.
2012-10-14 20:18:48 +01:00
Alexander Ljungberg c2f9b91fe2 Implicit sort descriptor binding support.
Sort descriptor bindings are now automatically established when a table view has a column value binding (normally to an array controller).
2012-10-14 19:39:39 +01:00
Alexander Ljungberg b629b882b4 Clean up and fix ArrayController1 test.
Use `CPValueBinding` instead of `@"value"` in case someone reads this as an example.
2012-10-14 19:32:47 +01:00
Alexander Ljungberg da91ab9879 Fixed: implicitly set selectionIndexes.
`CPTableView`'s `selectionIndexes` binding shouldn't be set automatically unless the content binding was also set automatically (through a table column binding).

Assume that manual content binding implies a desire to manually bind selection indexes (and sort descriptors) as well.
2012-10-14 19:31:53 +01:00
Alexander Ljungberg a70bc7d953 "Creates Sort Descriptors" CPTableColumn value binding option.
With this option an array controller driven table view can be sorted by clicking the table column headers without manually setting up sort descriptor prototypes.

If `CPCreatesSortDescriptorBindingOption` is enabled on a table column value binding, sort descriptors will be created automatically. The default value for this option is YES.
2012-10-14 18:27:25 +01:00
Aparajita Fishman 7614c18fea Merge branch 'master' of github.com:cappuccino/cappuccino 2012-10-11 12:35:01 -04:00
Aparajita Fishman c37783c895 Fixed table column header styling
- Attributes set in IB are now obeyed.
- Added accessor methods to programmatically style _CPTableColumnHeaderView.

Since we don't have an NSCell and _CPImageAndTextView is supposed to be private, it's better to have the styling methods in _CPTableColumnHeaderView.
2012-10-11 12:34:55 -04:00
Antoine Mercadal 905d23d159 small graphical fix in CPPredicateEditor 2012-10-10 15:33:53 -07:00
Antoine Mercadal 7bf46cb40b Add support for disabling sudo action
you can set CAPP_NOSUDO=1 in your environment to disable any sudo action.
This means that if a command failed as current user, jake
will not try to run it with sudo,and will simply return the error code
2012-10-10 12:24:36 -07:00
Aparajita Fishman 385de88e2f Merge branch 'master' of github.com:cappuccino/cappuccino 2012-10-08 17:30:40 -04:00
Aparajita Fishman c2da96e311 CPWebView should be converted to WebView* in the shadow header 2012-10-08 17:30:28 -04:00
Saikat Chakrabarti e46cd1478b Fix syntax of validateVisibleItems 2012-10-07 14:45:23 -04:00
Antoine Mercadal 8bbb3d30b2 Merge branch 'master' of https://github.com/cappuccino/cappuccino 2012-10-05 17:59:57 -07:00
Antoine Mercadal 1edcc511d6 Allow custom action for search button
If there is no menu, and search button has a target/action, then
send the action.
2012-10-05 17:58:54 -07:00
aparajita 9b22b33616 Merge pull request #1682 from slevenbits/clickedColumn
Implemented CPTableView -clickedColumn
2012-10-02 14:21:51 -07:00
Aparajita Fishman 3fd8d3e5be Implemented CPTableView -clickedColumn 2012-10-02 17:20:39 -04:00
Aparajita Fishman ce167cf92d Removed unused variable 2012-10-02 08:41:57 -04:00
Saikat Chakrabarti d718c292f5 Combine the _autovalidate and validateVisibleItems methods. 2012-10-01 21:21:01 -07:00
Aparajita Fishman 3ccaa4de50 Button types can be set in IB, no need for code 2012-09-28 18:04:31 -04:00
aparajita 5cd137b745 Merge pull request #1680 from slevenbits/tag-fix
Fix tag reading from IB
2012-09-28 14:46:35 -07:00
Aparajita Fishman 95246d73c1 Fixed xib to work correctly with smaller screens 2012-09-28 17:44:56 -04:00
Aparajita Fishman 8ff2a32b47 Fix tag reading from IB
Both controls and cells can have tags in IB, but Cappuccino has no cells. If the control has a tag, that takes precedence. Tag reading was moved to NSControl from NSView, since NSView does not have a tag in Cocoa.
2012-09-28 16:20:55 -04:00
Aparajita Fishman 90d52a8bb4 Don't show environment vars when building 2012-09-28 14:55:33 -04:00
Alexander Ljungberg a337bc28f9 Reduce number of divs used by typical apps.
Without this optimisation nil or 0x0 sized image slices in three part and nine part images result in useless empty divs.

Eliminating these divs should improve performance and reduce memory usage.

Although exact memory usage is hard to measure, in a large app the number of divs on screen went from 1012 to 984, a reduction of about 2.7%.
2012-09-26 12:32:09 +01:00
Alexander Ljungberg 8a5923527f Mention our trailing whitespace policy. 2012-09-24 17:14:37 +01:00
Alexander Ljungberg 59ad8499df Refs #1676. Whitespace. 2012-09-24 17:05:35 +01:00
Alexander Ljungberg 566cd6c6e8 Merge pull request #1676 from deltaprojects/master
CPNumberFormatterPercentStyle and CPTableView hidden column bug fix
2012-09-24 16:56:18 +01:00
Johan Stille 02a885eb09 Added test for initially hidden table column fix. 2012-09-24 14:22:39 +02:00
Johan Stille 632fba9dd5 Null check when laying out columns in CPTableView. 2012-09-24 13:17:24 +02:00
Johan Stille eb2bb24c19 Added support for CPNumberFormatterPercentStyle in CPNumberFormatter. 2012-09-24 12:08:31 +02:00
Alexander Ljungberg c8a37b4f99 Improve readability. 2012-09-17 19:46:36 +01:00
Alexander Ljungberg 117d946ed3 Contributing guidelines.
These will be shown in GitHub: https://github.com/blog/1184-contributing-guidelines.
2012-09-17 18:54:25 +01:00
Antoine Mercadal d4b0e2a124 fix some paths using non unicode chars causing xcc_general_include.h import problems 2012-09-15 12:17:43 -07:00
Antoine Mercadal 4acda0c447 fix and update css for documentation when using doxygen 1.8 2012-09-14 14:33:13 -07:00
Antoine Mercadal a7b40a5cdd XcodeCapp now uses both .m and .h shadow files in addition of the general include .h. Seems to fix most of the problems + refactoring 2012-09-13 19:07:46 -07:00
Antoine Mercadal ad5b9b658e take care of the .h and .m 2012-09-13 19:06:34 -07:00
Antoine Mercadal df28a4696e parser.j now generate both header and implementation files 2012-09-13 19:06:00 -07:00
Antoine Mercadal c30a6fb843 import the general include file to allow XCode to understand custom class inheritance 2012-09-13 14:09:30 -07:00
Antoine Mercadal 2e7afc3ca1 when managin the project, create a file containing includes of all projects files 2012-09-13 14:09:02 -07:00
Antoine Mercadal 2f428fa389 test item visibility when expanding/collapsing items 2012-09-10 15:19:32 -07:00
Antoine Mercadal 0a189906cd notify delegate that item did collapse after reloading them 2012-09-10 15:17:45 -07:00
Antoine Mercadal e4a6d8520c CPOutlineView notify for items expanded after having reloaded them 2012-09-10 13:49:40 -07:00
Alexander Ljungberg fe138be7ae Merge pull request #1668 from BlairDuncan/SelectionCompatibility
Windows selection compatibility. Fix for issue 1390
2012-09-04 13:45:31 +01:00
Alexander Ljungberg ff51263671 Merge pull request #1669 from slevenbits/cpscrollview-frame
Fix frame of CPScrollView is calculated incorrectly.
2012-09-04 13:34:08 +01:00
Blair Duncan 04f650dde7 Windows selection compatibility. Fix for issue 1390 2012-09-03 23:47:11 -04:00
Alexander Ljungberg 48e797a80d Minor hit test optimisation. 2012-09-03 20:20:23 +01:00
Alexander Ljungberg bf3a152946 Whitespace. 2012-09-03 20:20:05 +01:00
Alexander Ljungberg 7264692a0a Optimise CPSegmentedButton setEnabled:forSegment:.
Don't relayout the segmented button if the enabled state of a segment is not changed.
2012-09-02 23:33:56 +01:00
Alexander Ljungberg b5776445ec Significantly optimise CPToolbar validation.
Avoid sending notifications about toolbar items' enabled state needlessly.

Tiling is expensive, but even if the toolbar item ignores redundant `setEnabled:` calls, the cost of notifications alone can really add up when there are many toolbar items.
2012-09-02 23:08:14 +01:00
Ilya Kulakov ee1c5478b1 Fix frame of CPScrollView is calculated incorrectly. 2012-09-03 03:41:14 +07:00
Alexander Ljungberg 63bad1dae0 Setting _data just once is enough. 2012-09-02 17:28:34 +01:00
Alexander Ljungberg d0fa16b96b Fix NSPopUpButton in previous commit. 2012-08-31 23:19:24 +01:00
Alexander Ljungberg 3dacb4a5ef Fix nib2cib alignment ofCPColorWell, CPComboBox, CPPopUpButton and CPSegmentedControl. 2012-08-31 22:31:40 +01:00
Alexander Ljungberg ce80ee1739 Merge pull request #1667 from slevenbits/stepper-visuals
Visual `CPStepper` fixes.
2012-08-31 22:11:19 +01:00
Alexander Ljungberg 4e6b9978ce Adjust size in NSStepper to CPStepper. 2012-08-31 22:09:11 +01:00
Alexander Ljungberg 31d5ddb20a Improve CPStepper graphics.
* Disabled `CPStepper` looked larger than the regular stepper due to the outline becoming white.
* Wrong pixels at bottom corners.
2012-08-31 22:08:25 +01:00
Alexander Ljungberg 2355b7a38b Fixes #1666: since 5763ebd extremely slow double clicks would be accepted.
`CPEvent timestamp` is now in seconds so the double click delay has to be adjusted. Also slightly increased double click interval to account for lower precision.
2012-08-31 13:56:14 +01:00
Alexander Ljungberg 0e68729d7f Fixed: dragged table view columns ignored custom column header views. 2012-08-29 16:41:43 +01:00
Alexander Ljungberg b33763caeb Fixed: popovers could only properly open relative to views in the main window.
This would make the popover open with the wrong coordinates if the positioning view was in a window different than the main window, such as a utility window which can't become the main window.
2012-08-28 16:25:41 +01:00
Alexander Ljungberg 5b19c967f4 Merge branch 'master' of github.com:cappuccino/cappuccino 2012-08-28 14:33:45 +01:00
Alexander Ljungberg acd98b5c88 Clarify CPTabView code. 2012-08-28 14:32:04 +01:00
Alexander Ljungberg ff93262873 Work around rendering bugs in WebKit when moving canvas backed views.
This bug would cause errors such as the subviews of a CPBox not drawing properly as the box moved (e.g. due to animation).
2012-08-28 14:31:35 +01:00
Alexander Ljungberg f535a6a242 Minor CPTabView optimisation. 2012-08-28 11:42:38 +01:00
Antoine Mercadal d1c978669b run ImageOptim on all images. Saved around 30% of original size 2012-08-24 11:48:55 -07:00
Alexander Ljungberg b28673d23d Eliminate some debug output from jake test runs. 2012-08-24 17:26:27 +01:00
Alexander Ljungberg 46848562d0 Improve describe format of CPDictionary and CPArray to be more like literals.
E.g. a dictionary is expressed as @{key1: value1}, an array like @[value2, value2], a string like @"<value>".

Also don't put all child objects into quotation marks - that makes them all look like strings.
2012-08-24 17:25:37 +01:00
Alexander Ljungberg 9cbc52e858 Cappuccino v0.9.6 RC2. 2012-08-22 22:35:53 +01:00
Alexander Ljungberg 3cdf4fbc88 RC2 bootstrap. 2012-08-21 23:18:24 +01:00
Alexander Ljungberg b032c9e455 Fixed: objcc --includeTypeSignatures typo. 2012-08-21 22:37:08 +01:00
Alexander Ljungberg 6d4ce10150 Formatting. 2012-08-21 01:24:36 +01:00
Alexander Ljungberg 8b227798e1 Merge branch 'master' of github.com:cappuccino/cappuccino 2012-08-19 17:32:09 +01:00
Alexander Ljungberg 1514e8e981 Fixed: don't crash in unit tests if using Rhino.
Apparently Rhino doesn't have `<input element>.setAttribute` and an error would be thrown in `CPCompatibility.j`: `Cannot find function setAttribute in object [object Object].`
2012-08-19 17:16:09 +01:00
Alexander Ljungberg 4fbd0fdc42 Unit test KVCArray setArray: behaviour. 2012-08-19 16:50:09 +01:00
Antoine Mercadal fea31d54f8 Update comments to remove references to .xCodeSupport 2012-08-17 20:14:26 -07:00
Alexander Ljungberg 3dffbd6071 Refs #1001. Make it easy to test text field cut/paste behaviour. 2012-08-16 19:13:59 +01:00
Alexander Ljungberg 876757e748 Refs #1001. Don't use old cut/paste workaround if oninput fix is available. 2012-08-16 19:13:30 +01:00
Alexander Ljungberg 7abaa30526 Refs #1001. Fixed: text field cut/paste by context menu would not trigger a change notification.
Also just regular copy and paste could fail to trigger notifications.
2012-08-16 19:03:18 +01:00
Alexander Ljungberg 1a467f9208 Test text fields with various sizes. 2012-08-15 18:31:39 +01:00
Alexander Ljungberg 54d5f4b0a4 Fixed: horizontal text jump when editing text fields in some browsers.
We were compensating for a bug in Safari, older versions of Chrome and Firefox in our input placement. But new Chrome and neither IE 8 nor IE 9 needed it which resulted in the text being off in those browsers.
2012-08-15 18:31:20 +01:00
Alexander Ljungberg ca3a4f9b9c Fixed: text field font size while editing was wrong in Internet Explorer.
Tested in Internet Explorer 8 and 9.
2012-08-15 18:12:53 +01:00
Alexander Ljungberg d53b8c5b1f Fixed: in Firefox the text of edited text fields would "jump" down 1 px.
Locking down the line height and vertical alignment explicitly seems to work in Safari 6, Chrome 21, Firefox 14 and IE 8 (although Chrome and IE exhibit some unrelated horizontal jumping.)
2012-08-15 17:13:34 +01:00
Alexander Ljungberg 1e49704062 Fixed: the size with string fix broke metricsOfFont:. 2012-08-15 15:36:15 +01:00
Alexander Ljungberg d95268b548 Refs #1654. Fix up missing bits. 2012-08-15 13:38:49 +01:00
Alexander Ljungberg e9bafa8f13 Merge pull request #1654 from slevenbits/key-window-style
Inactive (non-key) window titles. Layout tweaks.
2012-08-15 02:07:11 +01:00
Alexander Ljungberg ef66334292 Inactive HUD window title.
Also fix close and title positioning.
2012-08-15 02:03:48 +01:00
Alexander Ljungberg aa17d8c700 Pull up window title code to a superclass for reuse. 2012-08-15 01:38:25 +01:00
Alexander Ljungberg 9f59ac96dd Inactive window title, start on window theming support.
Now the key window can be recognised by the window title.
2012-08-15 01:03:08 +01:00
Alexander Ljungberg 425888ee1f Fixed: in recent revisions vertical text centring was off by 1 upwards, including window titles.
This was caused by making text display generally 1 px taller to allow for fractional pixels at the bottom to show. This should however not be allowed to affect positioning (even if there is a fractional pixel below vertically centred text the text should not move up 0.5 px.)
2012-08-15 00:52:45 +01:00
Alexander Ljungberg f72615dcbe Fixed: non-key window text fields tried to receive input, looked active.
Only the first responder of the key window should receive text input. This is important in multi-window apps or windows with sheets.

In the multi window case it should be possible to switch between two windows with first responder text fields and keep right on typing. First responder status should not be lost, but new typing should always go into the first responder text field of the key window.

For sheets, a text field which was active when the sheet opened should not receive input nor look active while the sheet is open.
2012-08-14 23:41:09 +01:00
Alexander Ljungberg e3d0d69918 Refs #1364. Avoid repeated makeFirstResponder: calls within sheet parent.
If a window contained a text field which was the initial first responder, and the window was displaying a sheet, clicking on the window would cause the text field to alternate between being the first responder and not.

This was caused by the window `orderFront:` setting its first responder to the initial responder if there wasn't any responder yet. This would cause the text field to focus, even that the window wasn't the key window, and then on the next click the text field would blur which would make the text field automatically resign its first responder status.

The solution is to leave the first responder status alone if a window which isn't the key window is `orderFront:`ed. This appears to be more sensible UX in general. You don't expect the first responder of non-key windows to change when you click it's background.
2012-08-14 22:43:01 +01:00
Alexander Ljungberg 77266e0b3c Refs #1364. Don't orderFront: sheet parent view twice.
The sheet's orderFront: already calls the parent window's orderFront:, no need to call it by hand.
2012-08-14 03:10:08 +01:00
Alexander Ljungberg 64bbe0c641 Refs #1364. Fixed: incorrect key window change when displaying a sheet.
When the key window changes the previous window's resignKeyWindow must be called.
2012-08-14 02:39:18 +01:00
Alexander Ljungberg 120cea8734 Refs #1364. Fix CPTextField test to work with new sheet changes. 2012-08-14 00:15:03 +01:00
Alexander Ljungberg 5a8c94183a Refs #1364. Formatting, don't shadow window global. 2012-08-11 19:35:05 +01:00
Alexander Ljungberg de8e08f4f4 Refs #1364. Add an index-debug.html to test app. 2012-08-11 16:11:04 +01:00
Alexander Ljungberg 1e55b79b49 Merge pull request #1364 from walisser/master
Doc-modal/window-modal sheets and other sheet issues [+1]
2012-08-11 15:59:52 +01:00
aparajita dcdc7cef65 Merge pull request #1652 from slevenbits/stringValue-fix
stringValue fix
2012-08-09 20:33:31 -07:00
Aparajita Fishman 6e40020906 Allow nil value in presence of formatter, the formatter may want to format that 2012-08-09 20:31:26 -07:00
Alexander Ljungberg c4c7da3967 Merge pull request #1651 from slevenbits/stringsize-fix
Fixed: wrong text sizing across the board for custom fonts.
2012-08-10 03:47:36 +01:00
Alexander Ljungberg 580da9caef Fixed: wrong text sizing across the board for custom fonts.
If a custom font was used with the CSS @font-face syntax, Cappuccino would calculate the wrong sizes for strings throughout. This could result in e.g. cut off sizeToFit labels.

The sizing tests were being performed inside of an iframe and that iframe would not have the same CSS @font-face declarations. For maximum fidelity all string size tests are now performed in the main document, just off screen.
2012-08-10 03:46:09 +01:00
Antoine Mercadal 657baf9135 Merge branch 'master' of https://github.com/cappuccino/cappuccino 2012-08-09 12:52:11 -07:00
Antoine Mercadal 15c75f05e5 Update some labels 2012-08-09 12:51:43 -07:00
aparajita a8553c7c10 Merge pull request #1648 from slevenbits/fix-xcc-warnings
Fix compiler warnings
2012-08-09 12:19:16 -07:00
Aparajita Fishman 2b6d8697d5 Fix compiler warnings 2012-08-09 12:17:31 -07:00
Antoine Mercadal dcd3995230 remove old pbxproj sample 2012-08-09 11:42:05 -07:00
Antoine Mercadal ad88dabfd1 Update NativeHost.xcodeproj to build on new Xcode 2012-08-09 10:04:08 -07:00
Antoine Mercadal 4e13f3f2fd Add reference to .j too in a group called Sources 2012-08-08 22:35:35 -07:00
Antoine Mercadal 6a2d7bd2df Remove useless product group 2012-08-08 22:34:58 -07:00
Antoine Mercadal 81c1f0c7c9 don't be stupid 2012-08-08 22:34:40 -07:00
Antoine Mercadal cfd6928baa make XcodeSupport hidden 2012-08-08 21:56:33 -07:00
Antoine Mercadal 7b9582181c By default ignore *.xcodeproj and DS_Store 2012-08-08 21:53:25 -07:00
Antoine Mercadal 455ec8e3ae Simplify the FSEvent callback.
Events are not so reliable, there are many flaws and special cases (like trashing a folder etc)
In order to simplify the process is the following

- We receive an event
- We tidy up the shadow files
- We check if the given path exists
- If it's a folder, we continue
- If it's a file and it exists : we run handleFileModification
- If it's a file and it doesn't exist: we run handleFileRemoval
2012-08-08 21:51:38 -07:00
Antoine Mercadal ea31bd2be2 make XcodeCapp compatible with Xcode 4.4 2012-08-08 19:08:16 -07:00
Antoine Mercadal bf6c0c95eb Update Xcode project 2012-08-08 19:05:07 -07:00
Antoine Mercadal bb20a8f4ff pbxprojModifier.py now uses the mod_pbxproj 2012-08-08 19:04:52 -07:00
Antoine Mercadal cc18a5d3e2 Update default PBXProj 2012-08-08 19:04:30 -07:00
Antoine Mercadal 88287c6c2d add attribute to hold the pbxmodifier script 2012-08-08 19:04:04 -07:00
Antoine Mercadal 0fd0a05cd1 basic support for removing a reference of a file 2012-08-08 19:03:44 -07:00
Antoine Mercadal b0b084dbe8 add necessary imports 2012-08-08 16:02:00 -07:00
Antoine Mercadal 41a6621ac2 Make XCC generating .m files with @property for outlets
This is step 1 to have XCC working with Xcode 4.4.
2012-08-08 14:59:29 -07:00
Alexander Ljungberg 9fb73e26dc Merge pull request #1645 from slevenbits/isViewLoaded
Added CPViewController -isViewLoaded, fixed CPWindowController -setViewController to use that
2012-08-07 12:29:59 +01:00
Aparajita Fishman 59e8160f18 Added CPViewController -isViewLoaded, fixed CPWindowController -setViewController to use that
Before this fix, CPWindowController -setViewController was unconditionally loading the view, which should not happen.
2012-08-06 17:33:58 -07:00
Alexander Ljungberg fdf3e499be Merge pull request #1644 from slevenbits/CPArrayController-preserveSelectionFix
Fix wrong indexes are selected when removing arranged objects.
2012-08-06 13:53:31 +01:00
Ilya Kulakov c1ace9a7c3 Fix wrong indexes are selected when removing arranged objects. 2012-08-06 19:19:13 +07:00
Alexander Ljungberg f9a1d7240e Merge pull request #1643 from slevenbits/cpdecimalnumber-fix
fix CPDecimalMakeString to support '.003' and '-.003' style numbers
2012-08-05 12:34:40 +01:00
Eric Wong def8016f44 code style change 2012-08-05 09:35:44 +08:00
Eric Wong 175c70d99e fix a new bug in CPDecimalMakeWithString and remove some test cases 2012-08-05 08:37:44 +08:00
Darrell Walisser 872d65b824 -fix docs for new delegate methods 2012-08-04 14:06:11 -04:00
Darrell Walisser 339937a316 -support for tags on NSCell, useful for radio groups 2012-08-04 13:58:31 -04:00
Darrell Walisser eed93dc30d -capp_lint 2012-08-04 13:57:56 -04:00
Darrell Walisser bff22779ae -capp_lint 2012-08-04 13:53:05 -04:00
Darrell Walisser 24ef4d41d2 -capp_lint
-enable close buttons based on context
-remove stuff that doesn't work
2012-08-04 13:20:35 -04:00
Eric Wong 9f1a8fa7a2 enable '.003' or '-.003' style number in CPDecimalMakeWithString function and add new test cases 2012-08-04 23:04:40 +08:00
Alexander Ljungberg 729d2493cd Merge pull request #1642 from slevenbits/currency-formatter
`CPNumberFormatter` improvements.
2012-08-04 14:10:39 +01:00
Alexander Ljungberg 4d8758f755 Fix CPTextFieldTest. 2012-08-04 13:58:29 +01:00
Alexander Ljungberg 31ea0da526 CPNumberFormatter generatesDecimalNumbers support, enabled by default. 2012-08-04 13:45:45 +01:00
Alexander Ljungberg 3a2bf36359 Very basic CPNumberFormattercurrency style. 2012-08-04 13:37:42 +01:00
Alexander Ljungberg dc0c63ccc3 Extend CPNumberFormatter CPCoding support and fix rounding default. 2012-08-04 02:31:43 +01:00
Alexander Ljungberg 534635cbc2 Fix CPNumberFormatter maximum/minimum fraction digits property name. 2012-08-04 01:21:42 +01:00
Alexander Ljungberg a7f22a0c5a Correct CPNumberFormatter maximumFractionalDigits default. 2012-08-04 01:09:51 +01:00
Alexander Ljungberg b279a92e4c CPNumberFormatter setMinimumFractionDigits: support. 2012-08-04 00:55:41 +01:00
Alexander Ljungberg 055dd7229e Properly allow CPNumberFormatter to operate on most CPNumber types.
This only worked by accident before.
2012-08-04 00:48:45 +01:00
Antoine Mercadal 0922f3dab7 Merge pull request #1573 from mrcarlberg/binding_support_popup_button
Added key value binding support for CPPopupButton
2012-08-02 15:58:15 -07:00
Alexander Ljungberg b4cfa8cefb CPEvent description. 2012-08-02 15:53:27 +01:00
Alexander Ljungberg 6b660a0c76 Fixed: CPEvent data1 and data2 weren't stored right.
They were stored in globals instead of ivars, allowing only one data1 or data2 in the whole app.
2012-08-02 15:53:04 +01:00
Alexander Ljungberg 1ccd89ddd8 Refs #1640. Unit test. 2012-08-02 15:44:19 +01:00
Alexander Ljungberg cbb710cde7 Merge pull request #1640 from slevenbits/CPEvent-modifierFlags
Add +[CPEvent modifierFlags]
2012-08-02 14:36:17 +01:00
Ilya Kulakov d3b38ac5e8 Add +[CPEvent modifierFlags]. 2012-08-02 17:37:40 +07:00
Alexander Ljungberg 1fb09dcfae Fix typo. 2012-08-02 00:53:30 +01:00
Alexander Ljungberg f06be56fa3 Fixed: accidental global. 2012-08-02 00:45:33 +01:00
Alexander Ljungberg 9768ea4af9 Fixed: multiple rows of tokens in token fields wouldn't scroll right.
In recent versions, moving the cursor to a new row of tokens would place the scroll point somewhere halfway between the two rows of tokens.
2012-08-02 00:44:58 +01:00
Alexander Ljungberg 26c26914da Fixed: token field scrolling away from selected token.
Sometimes clicking a token would cause the token field to scroll to some other spot. This appears to have been caused by the inactive input element gaining focus.

We no longer need the input element for keyboard navigation so we can hide it entirely when it's not used to input a new token. Also, avoid focusing the input element needlessly.
2012-08-02 00:38:21 +01:00
Alexander Ljungberg 41783e87a3 Fixed: in recent builds token field text didn't align.
Text inside of tokens appeared 1 px higher than text typed in the text field area.
2012-08-01 21:12:53 +01:00
Alexander Ljungberg 299998b247 Merge pull request #1639 from slevenbits/tokenfield-fix
Fixed: token fields would sometimes unexpectedly steal first responder status.
2012-08-01 21:02:44 +01:00
Alexander Ljungberg 90ae5766e6 Fixed: token fields would sometimes unexpectedly steal first responder status.
If an autocomplete choice was made followed by immediately focusing on another control, the token field would reclaim first responder status a moment later.
2012-08-01 19:18:40 +01:00
Alexander Ljungberg 31ab70d6fc Refs #1530. Fixed: table views could not be interacted with if they couldn't become the first responder. 2012-08-01 18:59:54 +01:00
Alexander Ljungberg 7537f4d032 Eliminate some duplicate methods. 2012-08-01 16:35:34 +01:00
Darrell Walisser 32c5c82cb9 -removed unused import 2012-07-29 14:04:06 -04:00
Darrell Walisser 1c18862e0f -added manual test 2012-07-29 12:54:34 -04:00
Darrell Walisser 97b3679101 Merge remote-tracking branch 'upstream/master'
Conflicts:
	AppKit/CPApplication.j
	AppKit/CPWindow/_CPDocModalWindowView.j
2012-07-29 12:31:47 -04:00
Alexander Ljungberg 22b882648b Formatting. 2012-07-28 02:06:05 +01:00
Alexander Ljungberg a8150a84be Merge branch 'master' of github.com:cappuccino/cappuccino 2012-07-28 01:59:06 +01:00
Alexander Ljungberg df5a7104b1 Fixes #1638. The case of the incomplete optimisation. 2012-07-28 01:58:41 +01:00
aparajita 2400b6aeab Merge pull request #1637 from cacaodev/CPCib-initWithCibNamed
CPCib -initWithContentsOfURL: return nil if the requested data is nil.
2012-07-27 14:51:22 -07:00
cacaodev f42b241469 CPCib -initWithContentsOfURL: return nil if the requested data is nil 2012-07-27 20:19:20 +02:00
aparajita 4c86c75b5f Merge pull request #1635 from wmeddie/patch-1
Removed tailing comma from CPColorWithImages call.
2012-07-27 10:18:56 -07:00
Eduardo Gonzalez 9d2bdea8d9 Removed tailing comma from CPColorWithImages call.
The extra comma causes IE to think it was passed an array with 4
values and causes CPColorWithImages to return a NinePartImage even
though it only has three parts.
2012-07-27 20:51:29 +09:00
Alexander Ljungberg bd0114aa06 Refs #1632. Remove debug logging. 2012-07-26 13:42:01 +01:00
Alexander Ljungberg 43506e708d Merge branch 'master' of github.com:cappuccino/cappuccino 2012-07-26 13:32:20 +01:00
Alexander Ljungberg 3e218d6aec Refs #1632. Unit test for CPUndoManagerDidCloseUndoGroupNotification. 2012-07-26 13:32:01 +01:00
Alexander Ljungberg bf3c22f42c Merge pull request #1632 from slevenbits/cpundomanager-notification
Starting from 10.7 NSUndoManager posts NSUndoManagerDidCloseUndoGroupNotification
2012-07-26 13:05:40 +01:00
Antoine Mercadal dcee0e5057 Revert "small fix in theme to avoid 1px offset when editing a CPTextField"
This reverts commit fa1441cf71.
2012-07-25 18:19:15 -07:00
Antoine Mercadal 673c3c19f0 Merge branch 'master' of https://github.com/cappuccino/cappuccino 2012-07-25 12:00:36 -07:00
Antoine Mercadal fa1441cf71 small fix in theme to avoid 1px offset when editing a CPTextField 2012-07-25 12:00:09 -07:00
Ilya Kulakov c57ef67784 Starting from 10.7 NSUndoManager posts NSUndoManagerDidCloseUndoGroupNotification. 2012-07-25 17:02:06 +07:00
Alexander Ljungberg b1e519fd62 Merge branch 'master' of github.com:cappuccino/cappuccino 2012-07-24 20:09:58 +02:00
Alexander Ljungberg b51a2e25c2 Refs #1631. Unit test last index of index set with a single index. 2012-07-24 20:09:18 +02:00
aparajita 7b2835028a Merge pull request #1628 from cacaodev/CPCib-instantiateCibWithOwner_topLevelObjects_
CPCib -instantiateCibWithOwner:topLevelObjects:
2012-07-23 14:02:09 -07:00
Alexander Ljungberg 9eee7a214e Refs #1630. Add test. 2012-07-23 15:35:52 +02:00
Alexander Ljungberg d0b152c638 Merge pull request #1630 from slevenbits/cparray-fix
Fix CPArray should throw an exception when observer is added/removed.
2012-07-23 15:34:38 +02:00
Alexander Ljungberg 6d08f0d60b Formatting. 2012-07-23 15:26:03 +02:00
Alexander Ljungberg aab8ade15b Refs #1629. Fixed: aSet removeObject: for an object not a member is not an error. 2012-07-23 15:25:52 +02:00
cacaodev 5456bad23d Remove unwanted import in AppController test app 2012-07-23 14:59:48 +02:00
Alexander Ljungberg 8e6634168a Merge pull request #1629 from slevenbits/cpset-fix
Fix CPSet's member never checks equality of objects at Objj level.
2012-07-23 14:56:29 +02:00
Ilya Kulakov a3179080d3 Fix CPArray should throw an exception when observer is added/removed. 2012-07-23 19:48:05 +07:00
Ilya Kulakov 985759ce91 Fix CPSet's member never checks equality of objects at Objj level. 2012-07-23 19:34:40 +07:00
Martin Carlberg a688a3de79 Added test case for selectedIndex binding with CPInsertsNullPlaceholderBindingOption 2012-07-23 12:14:53 +02:00
Martin Carlberg 2184c7ca4d Fixed code format issues 2012-07-23 12:12:55 +02:00
Martin Carlberg f6b378513d Merge branch 'master' of https://github.com/cappuccino/cappuccino into binding_support_popup_button
Conflicts:
	AppKit/CPKeyValueBinding.j
	AppKit/CPPopUpButton.j
	Tests/AppKit/CPPopUpButtonTest.j
2012-07-23 11:19:21 +02:00
cacaodev 02a89e2343 CPCib -instantiateCibWithOwner:(id)anOwner topLevelObjects:(CPArray)topLevelObjects : allow anOwner to be nil 2012-07-22 22:08:31 +02:00
Alexander Ljungberg 8d1a5ac6b9 Format code. 2012-07-21 13:24:13 +01:00
Alexander Ljungberg 030bd9388b Merge branch 'master' of github.com:cappuccino/cappuccino 2012-07-21 13:13:28 +01:00
Alexander Ljungberg a78c1bf03a Refs #1624. Fix grouping separator support.
`perMillSymbol` was incorrectly used as the grouping separator.
2012-07-21 13:13:14 +01:00
Alexander Ljungberg 7e562fa3aa Fixes #1624. Fix grouping for CPNumberFormatter. 2012-07-21 13:08:54 +01:00
aparajita 5caf76fb3a Merge pull request #1536 from mrcarlberg/main_bundle_path_commonjs
Fixed mainBundle having no '/' at the end when running in CommonJS. This would make relative paths fail.
2012-07-20 17:18:16 -07:00
aparajita 30509823bb Merge pull request #1620 from ggsato/removingFirstObjectImprovement
fixed a bug that removeObject shows empty selection if an object at index 0 was removed
2012-07-20 16:24:15 -07:00
Alexander Ljungberg 835bd59330 Fixed: popovers in modal windows couldn't be interacted with.
This prevented e.g. date picker popovers in sheet dialogs.
2012-07-19 16:34:15 +01:00
Alexander Ljungberg e73cb7d363 Merge branch 'master' of github.com:cappuccino/cappuccino 2012-07-19 01:05:48 +01:00
Alexander Ljungberg 8aee458022 nib2cib support for button and radio button tags. 2012-07-19 01:05:09 +01:00
Aparajita Fishman 20eb62b3d2 Use the proper modern DOCTYPE 2012-07-18 14:48:23 -07:00
Alexander Ljungberg f4f9e8880c Merge branch 'master' of github.com:cappuccino/cappuccino 2012-07-18 19:21:43 +01:00
Alexander Ljungberg b0a56f1690 Fixed: removing selected CPPopUpButton item.
When the selected item of a `CPPopUpButton` is removed the first item should become selected. This matches Cocoa's behaviour.
2012-07-18 19:21:20 +01:00
Aparajita Fishman 8444f808f6 By default controls will track the system font size
Use current system font size elsewhere
2012-07-18 09:53:09 -07:00
Aparajita Fishman b959f13a0c Merge branch 'master' of github.com:cappuccino/cappuccino into upstream 2012-07-17 15:11:13 -07:00
Aparajita Fishman f0163e13c9 Added CGInsetMakeInvertedCopy 2012-07-17 15:10:58 -07:00
Alexander Ljungberg a89ca14abe Merge pull request #1622 from slevenbits/tableview-column-move-notify
Notify when a `CPTableView` column moves.
2012-07-17 22:59:53 +01:00
Alexander Ljungberg 9b77f1b7ac Notify when a CPTableView column moves.
Both through `CPNotificationCenter` and to the delegate.
2012-07-17 22:57:36 +01:00
Alexander Ljungberg e68077d159 Merge pull request #1621 from slevenbits/cpdictionary-enumerate
`CPDictionary enumerateKeysAndObjectsUsingBlock:`.
2012-07-17 20:51:22 +01:00
Alexander Ljungberg 5724dfe21d CPDictionary enumerateKeysAndObjectsUsingBlock:. 2012-07-17 20:48:52 +01:00
ggsato 364208e029 fixed a bug that removeObject shows empty selection if an object at index 0 was removed 2012-07-17 15:36:18 +09:00
Alexander Ljungberg fea0299033 Merge branch 'master' of github.com:cappuccino/cappuccino 2012-07-16 03:16:31 +01:00
Alexander Ljungberg c1dd821c6e Merge pull request #1618 from slevenbits/fontmanager
New `CPFontManager` methods.
2012-07-16 03:16:21 +01:00
Alexander Ljungberg 6a67243460 CPFontManager convertFont:toFace:. 2012-07-16 03:11:21 +01:00
Alexander Ljungberg 7f1b396ce8 CPFontManager weightOfFont: and traitsOfFont:. 2012-07-15 23:39:29 +01:00
Alexander Ljungberg 1e5bccd48e CPFontManager convertFont:, convertFont:toHaveTrait: and addFontTrait:. 2012-07-15 23:38:32 +01:00
Alexander Ljungberg d016e8a5e8 CPFontManager setSelectedFont:isMultiple: and other basic properties. 2012-07-15 21:45:50 +01:00
Alexander Ljungberg fc49574947 Test CPFontManager. 2012-07-15 21:01:29 +01:00
aparajita 2c0cf72a60 Merge pull request #1617 from slevenbits/dictionary-key-methods
CPDictionary key methods


keysOfEntriesPassingTest:
keysOfEntriesWithOptions:passingTest:
keysSortedByValueUsingComparator:
2012-07-15 09:30:31 -07:00
Aparajita Fishman c4dc9c8bdb CPDictionary key methods
keysOfEntriesPassingTest:
keysOfEntriesWithOptions:passingTest:
keysSortedByValueUsingComparator:
2012-07-15 09:27:04 -07:00
Aparajita Fishman dec7ca1e19 Make NSClipView obey the Draw Background checkbox in IB 2012-07-14 10:32:21 -07:00
Alexander Ljungberg ccb6b3b4a2 Code formatting. 2012-07-14 14:11:38 +01:00
Alexander Ljungberg 5658ea2c1e Merge pull request #1616 from slevenbits/kvo-willchange-fix-2
Fix crash if an observer is set between willChange…/didChange…
2012-07-14 13:58:18 +01:00
Ilya Kulakov 3886f27acd Fix crash if an observer is set between willChange…/didChange…
When you add an observer to an object first time, its class is
implicitly changed to a KVO_originalClassName (subclass of original
class). This subclass adds willChange…/didChange… methods for
observable properties.
If you send willChange… before you add an observer, it does nothing.
But if you send didChange… just after, the app will crash, because
new KVO_originalClassName nerver receives willChange…

The idea is to maintain counter of all received willChange… messages
(per key) and decrease it in didChange…
When KVO_originalClassName is created and didChange… is received
(without opening willChange… to new class), exception is not thrown
immediately, but the counter is checked first.
If it's greater than 0, then didChange… just closes
an unboserved willChange… Otherwise exception is thrown, as expected.
2012-07-14 19:32:25 +07:00
aparajita 76738a0208 Merge pull request #1615 from slevenbits/text-size-theming
Text size and theming enhancements

- _CPImageAndTextView adds extra pixels to allow for fractional pixels in -sizeToFit.

- NSButton now allows buttons that are not fixed height, if the theme allows it.

- Documented the mapping between bezel style constants and their IB style names.
2012-07-13 21:04:41 -07:00
Aparajita Fishman 32dc0826cb Text size and theming enhancements
- _CPImageAndTextView adds extra pixels to allow for fractional pixels in -sizeToFit.

- NSButton now allows buttons that are not fixed height, if the theme allows it.

- Documented the mapping between bezel style constants and their IB style names.
2012-07-13 21:00:02 -07:00
Aparajita Fishman 590b7ec704 format strings was not set in the xib 2012-07-13 20:26:57 -07:00
Aparajita Fishman 98b735b185 Install imagesize binary in both debug/release so that it works when install-debug-symlinks is used 2012-07-13 20:07:25 -07:00
Aparajita Fishman dd686a0fca Fixed spelling error in test app 2012-07-13 18:23:08 -07:00
aparajita 3fe2e4487e Merge pull request #1571 from tancred/xcodecapp_fix_wrong_format_specifier
Corrected the format specifier for a logging statement in XcodeCapp.
2012-07-13 07:51:07 -07:00
cacaodevandAparajita Fishman 2cf9fdf0d0 Check for sendsActionOnEndEditing 2012-07-13 07:45:08 -07:00
cacaodevandAparajita Fishman 7c01f14bfe Fix for #1593 2012-07-13 07:44:48 -07:00
Alexander Ljungberg 716c340825 Merge branch 'master' of github.com:cappuccino/cappuccino 2012-07-13 15:11:46 +01:00
aparajita 625e47a725 Merge pull request #1591 from claimable/master
Fix for CPPredicateEditor Action Bug

Make sure the predicate value editor sends its action when resigning, so the predicate is updated.
2012-07-13 07:07:25 -07:00
Alexander Ljungberg 2ca3f657f9 Refs #1530. Fix CPTableViewTest to work regardless of #1530 decision. 2012-07-13 13:24:43 +01:00
Alexander Ljungberg b038b6baf6 Fixed: browser propagation control when not in browser.
This would lead to a `[CPPlatformWindow _willPropagateCurrentDOMEvent] unrecognized selector sent to instance` error if an event was sent in a non DOM environment.
2012-07-13 12:41:26 +01:00
Alexander Ljungberg 9abb79d191 Merge pull request #1612 from slevenbits/cpgeometry-improvements
Cpgeometry improvements
2012-07-13 11:37:02 +01:00
Malte Tancred c3740c548d Corrected the corrected format specifier for the flags variable. 2012-07-13 08:11:24 +02:00
aparajita 629f12a851 Merge pull request #1543 from cacaodev/CPTableView-content-binding
Added support for using bindings with CPTableView content (as opposed to CPTableColumn value bindings)
2012-07-12 19:58:12 -07:00
aparajita e4de525a09 Merge pull request #1552 from mrcarlberg/outlineview_disclosure_width
Width of disclosure button determined by current disclosure control
2012-07-12 19:38:52 -07:00
aparajita 1a4e5a345d Merge pull request #1576 from ggsato/fixForOpeningExistingDocument
fixed needsUntitled evaluation

An untitled window will only open if ALL documents fail to load.
2012-07-12 19:29:07 -07:00
Alexander Ljungberg a4ae36929b Fix CPGeometry.j import.
CPGeometry.j is now in Foundation.
2012-07-13 01:29:01 +01:00
Alexander Ljungberg b9b98a39bb Avoid Foundation depending on AppKit.
CPGeometry.j and CGGeometry.j now share their implementation in two private API classes in the lower layer Foundation.
2012-07-13 01:28:38 +01:00
Alexander Ljungberg ae4b7cb58e Sort imports. 2012-07-13 01:26:14 +01:00
Aparajita Fishman f7d67e4b87 Cleanup, documented hacks 2012-07-12 17:20:30 -07:00
Antoine Mercadal 20c7ed0034 fix CPTextField baseline alignement 2012-07-12 15:23:17 -07:00
Antoine Mercadal 5c00ea627e Add manual test case for label baseline alignment 2012-07-12 15:10:04 -07:00
Vladimir Shevchenko ff074294ee mistakes corrected 2012-07-13 03:47:34 +07:00
Vladimir Shevchenko 028965e708 mistakes corrected 2012-07-13 03:43:12 +07:00
Vladimir Shevchenko 28b48edf02 Completed aliases and tests 2012-07-13 01:52:06 +07:00
Aparajita Fishman 86b83338c0 CPRuleEditor fixes
- Fixed case where no format strings are specified in xib (which ends up being an empty string).

- Fixed case where malformed strings file would not match regex.

- General cleanup.
2012-07-12 10:16:49 -07:00
aparajita 25f51eb5cd Merge pull request #1602 from mrcarlberg/sort_using_descriptors_with_key_path
Fixed sortUsingDescriptors: so it can handle sort descriptors with a key path
2012-07-12 08:19:46 -07:00
aparajita 7586af8f91 Merge pull request #1606 from slevenbits/system-font
Overhaul of system font handling

- System fonts now track the currently configured system font at runtime.
- You can specify CPFontCurrentSystemSize as a system font size to track the currently configured system font size at runtime.
- Theme fonts and nib2cib now determine face and size at runtime, there is no need to recompile if the system font is changed in Info.plist.
- All hard-coded references to 12.0 as a system font size have been replaced by the current system font size.
- Documented the font substitution algorithm and how to use custom fonts in the CPFont class docs.
- See Tests/Manual/FontEnhancementTest for a demo.
2012-07-12 07:01:30 -07:00
Vladimir Shevchenko d6b9daf7ca Fixed documentation & spaces 2012-07-12 02:47:12 +07:00
Vladimir Shevchenko 2905cd1586 Linked methods from CPGeometry to CGGeometry + added unit tests 2012-07-12 00:19:10 +07:00
aparajita 7a6009f2e3 Merge pull request #1610 from slevenbits/text-clip-fix
Text clip fix


Currently when controls and text fields size to fit text, they use a to determine the correct height/width. Some browsers do not account for fractional pixels that arise from antialiasing. Cappuccino views must clip their contents, so the fractional pixels get clipped, and depending on the font this can be quite noticeable.

This patch adds 1 pixel when necessary to ensure no clipping occurs.
2012-07-11 09:19:46 -07:00
Vladimir Shevchenko a6d6fb1a1e CPGeometry moved to Foundation 2012-07-11 16:29:30 +07:00
Aparajita Fishman 4af061516c CPTableColumn -setHidden documentation was backwards. 2012-07-10 21:53:51 -07:00
Aparajita Fishman df9611cc2c Cleanup 2012-07-10 18:53:41 -07:00
Aparajita Fishman 99cd246ed8 Fix clipping of text due to fractional pixels 2012-07-10 18:08:33 -07:00
Aparajita Fishman 872df9fe39 Fixed window positioning 2012-07-10 17:35:42 -07:00
Aparajita Fishman ec4bfa00ee Per Cocoa, 0 size means create a static font in the current system font size. Added tests. 2012-07-10 16:40:44 -07:00
Aparajita Fishman 68c001e0c0 Don't attempt show CPScrollView, CPScroller or tooltips in the showcase, it doesn't work 2012-07-10 15:36:33 -07:00
Aparajita Fishman 5e40d6702e jake clobber should only clobber the theme, not Cappuccino 2012-07-10 12:47:55 -07:00
Aparajita Fishman a3d4dc2f9a Wrap _DOMElement access in #if PLATFORM(DOM), cleanup 2012-07-09 22:19:26 -07:00
aparajita a8d1224097 Merge pull request #1607 from slevenbits/archive-formatter
CPControl archives/unarchives its formatter

This allows you to use a formatter with a table column's data view.
2012-07-09 21:32:24 -07:00
Aparajita Fishman 73fea44aa2 CPControl now archives/unarchives its formatter
This allows you to use a formatter with a table column's data view.
2012-07-09 21:30:09 -07:00
Aparajita Fishman 309463f15d Fixed parameter name 2012-07-09 16:50:31 -07:00
Aparajita Fishman 37a89a7b0a Cleanup 2012-07-09 15:47:26 -07:00
Aparajita Fishman 6b6f5d98e4 Overhaul of system font handling
- System fonts now track the currently configured system font at runtime.
- You can specify CPFontCurrentSystemSize as a system font size to track the currently configured system font size at runtime.
- Theme fonts and nib2cib now determine face and size at runtime, there is no need to recompile if the system font is changed in Info.plist.
- All hard-coded references to 12.0 as a system font size have been replaced by the current system font size.
2012-07-09 15:29:56 -07:00
Antoine Mercadal 2712a4d45c removed debug console.log 2012-07-09 15:05:03 -07:00
Antoine Mercadal d93fa98d1e Merge branch 'master' of https://github.com/cappuccino/cappuccino 2012-07-09 15:04:17 -07:00
Antoine Mercadal 63616cc50a fix enter key not working to select items in CPComboBox. With the help of @aparajita 2012-07-09 15:03:59 -07:00
Alexander Ljungberg eb643a2df8 Simplify code. 2012-07-09 20:31:29 +01:00
Alexander Ljungberg 81f958eee1 Merge pull request #1605 from slevenbits/colorwell-styling
`CPColorWell` and `CPColorPanel` updates.
2012-07-09 20:17:49 +01:00
Alexander Ljungberg 613f61a898 Unit test CPColorWell archiving. 2012-07-09 20:03:19 +01:00
Alexander Ljungberg 77a009c9a6 Highlighted and disabled looks for bordered CPColorWell. 2012-07-09 19:53:57 +01:00
Alexander Ljungberg 2d8a849d12 nib2cib size fix for bordered CPColorWell. 2012-07-09 19:19:38 +01:00
Alexander Ljungberg b09908e6af Themable CPColorWell with Aristo look when bordered. 2012-07-09 19:18:46 +01:00
Antoine Mercadal ad74e93ea2 use CPPopUpMenuWindowLevel for _CPPopUpList's window level 2012-07-09 10:20:18 -07:00
Alexander Ljungberg 754311d2e2 More colour panel clean up. 2012-07-09 16:06:09 +01:00
Alexander Ljungberg f6514f3c64 Fix CPColorPanel errors and code style. 2012-07-09 15:57:24 +01:00
Alexander Ljungberg f398185aad CGRectInsetByInset geometry function.
This operation appears again and again in Cappuccino.
2012-07-09 15:44:13 +01:00
Alexander Ljungberg 4390bea31f Simplify CPColorWell drawing and mouse handling.
Use standard CPControl mouse handling and highlighting.

Switch to setNeedsLayout based drawing and hook up first themed property.
2012-07-09 13:01:44 +01:00
Alexander Ljungberg 660c98d6e5 Use theme system for CPColorWell bordered state.
This is more consistent with the rest of Cappuccino and prepares for theming support.
2012-07-09 12:20:47 +01:00
Alexander Ljungberg 1154a629a7 Code formatting. 2012-07-09 11:11:37 +01:00
Alexander Ljungberg 09e235eb60 Refs #1603. Optimise slightly. 2012-07-08 21:26:47 +01:00
Alexander Ljungberg 9dab0f083d Merge pull request #1603 from slevenbits/indexset-passingtest
Add *passingTest methods to CPIndexSet
2012-07-08 21:26:05 +01:00
Ilya Kulakov 6dd44687c5 Implement *passingTest methods of CPIndexSet. 2012-07-09 02:40:47 +07:00
Alexander Ljungberg 1a639afd99 Typos. 2012-07-08 14:13:21 +01:00
Antoine Mercadal 72cc494df4 fix bug showing the CPComboBox's list under popover 2012-07-06 16:02:40 -07:00
cacaodev f516078510 PR #1573
Support value transformers for CPContent and CPContentValues bindings.
Made _CPPopUpContentValuesBinder a subclass of CPPopUpContentBinder and reuse setContent:.
Fixed a bug in selectedIndex binding set and reverse set when insertsNull options is on.
_CPPopUPSelectionBinder : simplified the code for getting the unique selection binder in use.
ojunit and manual tests for contentvalues + value transformer.
2012-07-06 22:35:37 +02:00
cacaodev 6a1e5840b5 Merge remote-tracking branch 'mrcarlberg/binding_support_popup_button' into binding_support_popup_button
Conflicts:
	AppKit/CPPopUpButton.j
2012-07-06 22:30:12 +02:00
aparajita 98fbf3abc1 Merge pull request #1601 from slevenbits/CPComboBox
CPComboBox and CPTextField enhancements

- Full Cocoa-compliant implementation of CPComboBox and CPComboBoxDelegate.

- Better focus ring for CPTextField and all subclasses.

- CPTextField and its subclasses draw disabled contents differently, per Cocoa.
2012-07-06 13:24:01 -07:00
Martin Carlberg e265d09034 Fixed sortUsingDescriptors: so it can handle sort descriptors
with a key path instead of just a key.
Also added a test case for this.
2012-07-06 20:52:33 +02:00
Martin Carlberg dbb88b8a17 Included content and contentValue bindings improvments from cacaodev
Fixed a small typo error
2012-07-06 20:06:19 +02:00
Alexander Ljungberg 34e7d4abe5 Merge pull request #1600 from slevenbits/window-controller-container-view
Window controller container view
2012-07-06 16:36:26 +01:00
Ilya KulakovandAlexander Ljungberg f434717372 Fix style. 2012-07-06 16:03:29 +01:00
Ilya KulakovandAlexander Ljungberg 88f8581dcc Implement -[CPWindowController setViewControllerContainerView:], fix -[CPWindowController setViewControllerView:]
Container view is responsible for laying out its views.
Container view is a content view of the window.
If there is no container view, view controller's view is a content view of the window.
2012-07-06 16:03:29 +01:00
Alexander Ljungberg 552ba68187 Refs #1599. Fix teacher.car.year unit test message. 2012-07-06 15:53:19 +01:00
Alexander Ljungberg cff29904d7 Refs #1599. Format code. 2012-07-06 15:53:03 +01:00
Alexander Ljungberg b1774cdccf Merge pull request #1599 from slevenbits/kvo-fix
Wrong key path and change send to the observer
2012-07-06 15:38:50 +01:00
Aparajita Fishman 32737e0b72 CPComboBox and CPTextField enhancements
- Full Cocoa-compliant implementation of CPComboBox and CPComboBoxDelegate.

- Better focus ring for CPTextField and all subclasses.

- CPTextField and its subclasses draw disabled contents differently, per Cocoa.
2012-07-06 00:15:23 -07:00
aparajita b54ce4d782 Merge pull request #1597 from slevenbits/cptableview-grid
Make the default grid color in IB show correctly in CPTableView.

- Changed the default grid color from #dce0e2 to #ccc.
- Fixed NSColor to recognize the named color "gridColor" and set it to #ccc.
- NSTableView always saves the grid color from IB.
2012-07-05 16:16:30 -07:00
Aparajita Fishman b6adf26549 Make Alexander happy. ;-) 2012-07-05 12:26:55 -07:00
Aparajita Fishman d0bfde1887 Annotate indexOfObject methods, use "index" instead of "idx" 2012-07-05 11:34:01 -07:00
Ilya Kulakov 4094a1f826 Fix wrong change is sent to observer when top level object is changed.
When you change the top level object, observer MUST receive value
for the key path of the previous top level object as old and
value for the key path of the new top level object as new.
2012-07-05 17:59:29 +07:00
Alexander Ljungberg 8afb67521d Annotate indexesOfObjectsPassingTest: function signature. 2012-07-04 23:26:07 +01:00
Alexander Ljungberg 34be9cea3a Refs #1559. Fix split view autosave test. 2012-07-04 23:17:38 +01:00
Aparajita Fishman 618194996a Fixed CPString -hasSuffix docs 2012-07-04 17:29:28 -04:00
cacaodev 42f49795af Ignore Value Transformers, no error and log an info message. 2012-07-04 23:18:47 +02:00
aparajita e444a5d60a Merge pull request #1598 from slevenbits/array-filters-fix
Fixed the method names committed in 0f5a6b4e5e
2012-07-04 14:16:14 -07:00
Aparajita Fishman 593f3c2109 Fixed the method names 2012-07-04 17:03:53 -04:00
Aparajita Fishman e9fb821721 Make the default grid color in IB show correctly in CPTableView
Currently #888888 is being used as the default, mainly because NSColor.j doesn't recognize the "gridColor" named color, and the cached color in the .xib is #888888 for some reason. Actually the default grid color is #CCCCCC.
2012-07-04 16:39:47 -04:00
aparajita a4afe1bde9 Merge pull request #1596 from slevenbits/cptableview-typos
Added missing @
2012-07-04 13:29:45 -07:00
Aparajita Fishman 1d29fda5fd Added missing @ 2012-07-04 16:25:59 -04:00
aparajita 16b7093e19 Merge pull request #1595 from slevenbits/array-filters
Added CPArray -indexesOfObjectPassingTest methods
2012-07-04 12:46:51 -07:00
Aparajita Fishman 0f5a6b4e5e Added CPArray -indexesOfObjectPassingTest methods 2012-07-04 15:41:45 -04:00
cacaodev c7a8124be8 CPPopUpButtonTest test CPContentValuesBinding with value transformer. Currently failing. 2012-07-04 17:55:39 +02:00
Alexander Ljungberg c3c74a13c0 Merge pull request #1592 from slevenbits/splitview-autosave-improvement
Improve split view autosave.
2012-07-03 23:58:08 +01:00
Alexander Ljungberg cde50cc8b4 Refs #1558. Better ivar name and type. 2012-07-03 13:57:11 +01:00
Alexander Ljungberg fcc11b8969 Fixes #1559. Nested split view autosave and better override support.
Nested split views now correctly restore their divider positions by restoring "top down". E.g. a nesting split view is restored before the nested split view so that the nested split view has the correct frame size for the position it is restoring.

This commit also makes it easier to override autosave restores in a subclass or a controller's `viewDidLoad`. Now if `setPosition:ofDividerAtIndex:` is called after the split view's `initWithCoder:` has finished, but before the final autosave restore has occurred, the autosave restore is cancelled. This preserves whatever the modification the programmer intended to make instead of overwriting it with the autosaved position.

This commit also fixes a bug where an autosaved position would not be restored, or would be restored at an unexpected time, if `setFrameSize:` was not sent to the split view shortly after its `initWithCoder:`. (Such a `setFrameSize:` message is often sent due to a window `setFullPlatformWindow:` call in `AppController.j`'s `awakeFromCib`, but it's not necessarily sent.)
2012-07-03 13:53:52 +01:00
Alexander Ljungberg c9b7d1e842 Refs #1559. Autosave split view positions for frame size changes.
This covers the case where the whole split view is resized and the divider moves as a consequence. For example if the split view was made much smaller the fixed position of the divider previously autosaved might not even be inside of the split view frame anymore, and on restore from autosave that side of the split view might unexpectedly become collapsed.

The new behaviour also more closely matches Cocoa's, although there is still a slight difference in implementation.
2012-07-03 13:44:59 +01:00
Martin Carlberg e5f4a7c39a Added support for CPNullPlaceholderBindingOption and made some clean up of code 2012-07-03 12:36:19 +02:00
Alexander Ljungberg 814e72879e Manual test for split view autosave. 2012-07-03 11:09:39 +01:00
Alexander Ljungberg 5f9463a030 Refs #1558. Test all split view divider types. 2012-07-03 10:54:27 +01:00
Alexander Ljungberg 37d4a06aa4 Fixes #1558. Support "thick divider" split view style in nib2cib.
The thick divider style is converted to the pane splitter style in nib2cib since we only use two styles in Cappuccino.
2012-07-03 10:44:07 +01:00
aparajita fb590550cd Merge pull request #1589 from slevenbits/nib2cib-fixes
nib2cib fixes
2012-07-02 06:57:09 -07:00
Aparajita Fishman 2f27291c53 Tweaked debug output of custom image resources in nib2cib 2012-07-02 09:55:52 -04:00
Aparajita Fishman fc23863d85 Added support for alternate button title in nib2cib 2012-07-02 09:55:52 -04:00
aparajita 8651a59f43 Merge pull request #1587 from slevenbits/non-bordered-buttons
Non-bordered buttons should retain their size, not shrink to fit
2012-07-02 06:41:49 -07:00
Aparajita Fishman 2f1e9d76ec Non-bordered buttons should retain their size, not shrink to fit. 2012-07-02 09:40:00 -04:00
Mike Holman 2e1a72030e Fix CPPredicateEditor CPTextField action bug. 2012-07-02 16:17:35 +08:00
aparajita c9f32ac77b Merge pull request #1584 from slevenbits/splitview-autosave
CPSplitView autosave optimization
2012-06-30 13:34:50 -07:00
Aparajita Fishman 6efa30c52a autosave of position should not happen until divider tracking is completely done.
Also renamed a local variable that looked like an ivar.
2012-06-30 16:19:06 -04:00
Martin Carlberg ef30e21506 Missed to remove some line in manual merge 2012-06-30 09:20:50 +02:00
Martin Carlberg 70b5f9ee98 Merge branch 'popup_button_binder_subclass' of https://github.com/cacaodev/cappuccino into binding_support_popup_button
Conflicts:
	AppKit/CPPopUpButton.j
2012-06-30 08:41:14 +02:00
aparajita 3137839322 Merge pull request #1583 from slevenbits/splitview-userinfo
Splitview userinfo
2012-06-29 13:11:23 -07:00
Aparajita Fishman 345a865cc8 Post OS X 10.5, Cocoa adds a userInfo with the divider index when the user drags the divider 2012-06-29 13:09:47 -07:00
aparajita 2a4ef4394c Merge pull request #1582 from slevenbits/nib2cib-images
nib2cib image fixes
2012-06-29 11:33:13 -07:00
Aparajita Fishman 3ba5be1ec6 nib2cib image fixes
- nib2cib will now log the path and size of custom image resources in super verbose mode.

- Alternate images for buttons were not being set by nib2cib, that has been fixed.

- Fixed the name of the imagesize binary in the Xcode project.
2012-06-29 11:29:53 -07:00
Aparajita Fishman 606f3dfe6b Replaced Java-based image utility with Cocoa command line app, cleaned up some fontinfo stuff 2012-06-29 11:29:46 -07:00
cacaodev c865644e6c Test for CPPopUpButton bindings. 2012-06-29 19:42:20 +02:00
Martin Carlbergandcacaodev fec1586380 CPPopUpButton bindings support (set for all and reverse for selection related bindings) using a CPBinder subclass instead of dedicated selectors. 2012-06-29 19:40:23 +02:00
cacaodev 8e2afde3e4 CPKeyValueBinding -reverseSetValueFor: -> extract a method for getting the source value for a given binding. the goal is to facilitate subclassing. 2012-06-29 19:37:35 +02:00
Aparajita Fishman 5410884e03 Fixed the documentation for CPArray -indexOfObject methods 2012-06-29 09:02:35 -07:00
Aparajita Fishman e9ceb1d0c6 Documentation tweak 2012-06-28 15:25:39 -07:00
Alexander Ljungberg 8d14bdd819 CPToolbar autovalidate. 2012-06-28 22:41:41 +01:00
Alexander Ljungberg 23f3a01e3c Merge pull request #1579 from slevenbits/cptoolbar-delegate
CPToolbar delegate fix
2012-06-28 20:27:23 +01:00
aparajita 3540dd1c26 Merge pull request #1578 from slevenbits/initialize-fix
Implement missing +initialize checks and regularize checks
2012-06-28 12:09:42 -07:00
Aparajita Fishman cae5486ec6 Added missing class checks in +initialize, regularized checking code 2012-06-28 12:05:18 -07:00
Alexander Ljungberg a769618e3e Don't copy an array we'll copy again 2 lines later.
If the delegate returns nil we're just copying nil, and if it does return an array we only use it for a single read-only `arrayByAddingObjectsFromArray:`.
2012-06-28 19:15:20 +01:00
Alexander Ljungberg 80d537958e Fixed: CPToolbar delegate toolbarDefaultItemIdentifiers: is optional.
This fix makes it possible for a toolbar defined in a cib to have a delegate set without defining `toolbarDefaultItemIdentifiers:` like in Cocoa. You might be implementing other delegate methods.
2012-06-28 19:12:05 +01:00
aparajita d923fb56e2 Merge pull request #1577 from slevenbits/key-loop-fix
Key loop fix
2012-06-28 10:06:30 -07:00
Aparajita Fishman 7747bbffcf Fixed key loop calculation, might as well use _initialFirstResponder instance variable instead of accessor 2012-06-28 10:01:07 -07:00
ggsato db47d8fb85 fixed needsUntitled evaluation 2012-06-28 12:01:37 +09:00
Alexander Ljungberg c52315cd8d Refs #1572. Merge extra commit re highlights. 2012-06-25 21:58:02 +01:00
Alexander Ljungberg a2787f8783 Formatting. 2012-06-25 21:57:28 +01:00
Ilya Kulakov 913308d886 Refs #1572. Fix highlighted status is not preserved.
When higlightsBy == CPNoCellMask and showsStateBy == CPChangeBackgroundCellMask
higlighted status must be preserved when a user switch state from Off to On.
2012-06-26 03:54:59 +07:00
Alexander Ljungberg 21bb383193 Refs #1527. Fix button performClick: highlight.
Critically this is what enables button highlighting on key equivalents.
2012-06-25 18:13:16 +01:00
Alexander Ljungberg bd83885eca Refs #1527. Backwards compatibility.
If no highlight or state masks were encoded (button was encoded prior to them being added), make sure to let the default settings stand.
2012-06-25 17:42:31 +01:00
Alexander Ljungberg d34d139658 Refs #1572. Default CPButton type.
If a button is created in code it should act like a regular momentary push in button by default.
2012-06-25 17:21:56 +01:00
Alexander Ljungberg f5c201c0be Refs #1572. Fixed: CPPushInCellMask in showsStateBy.
Code didn't match comment.
2012-06-25 17:18:07 +01:00
Alexander Ljungberg 10fcc0c452 Refs #1572. Minor fixes. 2012-06-25 16:26:44 +01:00
Alexander Ljungberg 378822b777 Merge pull request #1572 from slevenbits/cpbutton-masks
CPButton and subclasses respect highlightsBy and showsStateBy masks now.

Conflicts:
	AppKit/CPButton.j
	Tests/Manual/CPButtonTest/AppController.j
	Tests/Manual/CPButtonTest/Info.plist
	Tests/Manual/CPButtonTest/Resources/MainMenu.cib
	Tests/Manual/CPButtonTest/Resources/MainMenu.xib
2012-06-25 16:05:03 +01:00
Alexander Ljungberg edebb81ed4 Merge pull request #1570 from aradabaugh/cpbutton-types
Enable additional button types for CPButton
2012-06-25 15:40:23 +01:00
Ilya Kulakov 7cf3ac3b40 CPButton and subclasses respect highlightsBy and showsStateBy now. 2012-06-25 18:57:10 +07:00
Ilya Kulakov c46c365823 Extenend CPButtonTest to test highlightsBy and showsStateBy. 2012-06-25 18:57:06 +07:00
Ilya Kulakov 66f5e1fb64 Take into account highlightsBy and showsStateBy when decoding cib.
nib2cib was modified to take into account these variables
during conversion nib->cib.
2012-06-25 18:57:01 +07:00
Ilya Kulakov c80417c433 Add highlightsBy method that returns current higlightsBy mask. 2012-06-25 18:56:56 +07:00
Martin Carlberg 32e3df1e80 Added key value binding support for CPPopupButton 2012-06-25 08:23:14 +02:00
Malte Tancred 3f65153d4f Corrected the format specifier for the flags variable. 2012-06-23 22:46:25 +02:00
Adam Radabaugh 5fbf0f83cb Make the check for CPOnOffButton tracking correctly use the highlights mask. 2012-06-23 14:26:46 -06:00
Adam Radabaugh 84c8427bb4 Merge branch master 2012-06-23 14:21:45 -06:00
cacaodev 539a8f0ca9 An OJTest for the table view's content binding 2012-06-22 21:59:41 +02:00
Alexander Ljungberg d39849b297 Improve token field keyboard navigation when tokens are selected.
If one or more token is selected and the left arrow key is pressed, collapse the selection to the left of the first selected token.

Similarly, on right arrow key collapse to the right of the last token.

Note that shift-left and shift-right have no effect if the first or last token respectively in the field are already selected.
2012-06-21 19:24:22 +01:00
Alexander Ljungberg 7764921c21 Select all support for CPTokenField.
Cmd-A (Mac) or Ctrl-A (other) finishes any ongoing editing and selects all tokens in a token field.

This commit also adds support for the `selectText:` and `selectAll:` methods.
2012-06-21 19:17:34 +01:00
Alexander Ljungberg 26ceb25e7b Merge pull request #1569 from slevenbits/rwelephant-token-field
Token field improved autocomplete, key bindings support, clean up
2012-06-21 10:32:33 -07:00
Aparajita Fishman 13423e43d5 Removed stray console.log 2012-06-20 11:05:22 -07:00
Aparajita Fishman 45da163230 text tweak 2012-06-18 09:31:34 -07:00
aparajita 281e3c925c Merge pull request #1566 from slevenbits/CPArrayController-tweaks
CPArrayController tweaks
2012-06-18 09:03:22 -07:00
Aparajita Fishman 6f50900b1b Added missing removeObjectAtArrangedObjectIndex, added missing return 2012-06-18 09:00:59 -07:00
Alexander Ljungberg 2200e40001 Fixed: browser shortcuts wouldn't work when a token field was active.
We now leave the default propagation policy of Cappuccino in place, which normally is NO for regular characters but YES for things which could be shortcuts.
2012-06-16 12:31:50 +01:00
Alexander Ljungberg 44b609f604 Don't make space for editing in token field if tokens are selected.
If the editor is placed while there is a token selection it can cause the token view to become scrollable to a white area at the bottom even that there is no editing cursor. And even if the editor is not at the bottom, the empty space made for the editor makes no sense when no editing cursor is visible.
2012-06-16 12:31:50 +01:00
Alexander Ljungberg d5918157ff Overwrite selected tokens by typing support.
If tokens are selected in `CPTokenField` and new text is entered, the selected tokens are overwritten by the newly entered text.
2012-06-16 12:31:50 +01:00
Alexander Ljungberg 19b53746cf Fix nil representedObjectForEditingString: response handling.
If `tokenField: representedObjectForEditingString:` returns nil, act the same as if the delegate method didn't exist. This matches Cocoa.
2012-06-16 12:31:50 +01:00
Alexander Ljungberg d0769ec360 Oops. Fix object value fix. 2012-06-16 12:31:49 +01:00
Alexander Ljungberg 3c20bf8ad6 Allow token field insertText: to be somewhat overridden.
If `insertText:` is overridden to do nothing, nothing in inserted.
2012-06-16 12:31:49 +01:00
Alexander Ljungberg 3eab2a528f Make token field object value more like Cocoa.
If a half typed token is in the field, Cocoa tries to convert it to a representedObject before responding to objectValue. Now CPTokenField does the same.
2012-06-16 12:31:49 +01:00
Alexander Ljungberg fb404a0671 Hide private token field API. Fix return type. 2012-06-16 12:31:49 +01:00
Alexander Ljungberg 6d6cf52180 Minor token field optimisation. 2012-06-16 12:31:49 +01:00
Alexander Ljungberg e9ba326610 Inlineable range functions. 2012-06-16 12:31:49 +01:00
Alexander Ljungberg 55ca956f50 Remove nonstandard CPCopyRange. 2012-06-16 12:31:49 +01:00
Alexander Ljungberg f43c643d5a Allow token field subclasses to override defaultCompletionDelay.
Also fixed incorrect return type.
2012-06-16 12:31:49 +01:00
Alexander Ljungberg 69f5fc536c Key bindings support for token field.
Also improve compatibility with `CPTextField` superclass and subclassing support by properly using `interpretKeyEvents:` like `CPTextField`.
2012-06-16 12:31:49 +01:00
Alexander Ljungberg 132ac7c03f Token field 'keyUp:' support. 2012-06-16 12:31:49 +01:00
Alexander Ljungberg 5683af9bc8 Improve token field subclassing support.
Token field now triggers autocompletion from textDidChange: which better meets the expectations of Cappuccino programmers, and is closer to how Cocoa does it.

Eliminated custom non-Cappuccino key press handler.
2012-06-16 12:31:48 +01:00
Alexander Ljungberg 429933f601 Fix token field keyDown: handling.
`CPTokenField` had custom key down handling making it function poorly with Cappuccino's event handling and subclasses.
2012-06-16 12:31:48 +01:00
Alexander Ljungberg 317364681a Fixed: make sure autocomplete menu fits within browser. 2012-06-16 12:31:48 +01:00
Alexander Ljungberg 9575fd7771 Autosize token field autocomplete menu.
The new menu is much more efficient for the user:

* Less tall items makes it much easier to select among many completions.
* Exactly wide enough for widest item.
* Tall enough to show all items (instead of just 3 as before).
* Uses a maximum width and height defined by the screen edges and some Cocoa-like constants.
2012-06-16 12:31:48 +01:00
Alexander Ljungberg 85cfb18906 Place token autocomplete underneath what's being completed.
This matches Cocoa.
2012-06-16 12:31:48 +01:00
Alexander Ljungberg 33fe1573ad Ensure autocomplete menu is on top.
The menu should appear above other normal windows and controls like a regular CPMenu. To do this, put the pop up in its own window with the `CPPopUpMenuWindowLevel` window level.
2012-06-16 12:31:48 +01:00
Alexander Ljungberg 2574fac44a Remove token field reference. 2012-06-16 12:31:48 +01:00
Alexander Ljungberg b166995327 Move autocomplete into reusable class. 2012-06-16 12:31:48 +01:00
Alexander Ljungberg feaf9c6f20 Improve CPTokenField autocomplete scrolling. 2012-06-16 12:31:48 +01:00
Alexander Ljungberg 0ef03d31b8 Refactor CPTokenField autocomplete.
The new code is simpler (single responsibility principle) and makes it easier to improve on autocomplete.
2012-06-16 12:31:48 +01:00
Alexander Ljungberg 80ee88d3a7 Hide another non-public API in CPTokenField. 2012-06-16 12:31:48 +01:00
Alexander Ljungberg bbc45dd947 Support tokenField:representedObjectForEditingString: delegate method.
This improves support for represented objects and is used both when an autocompletion suggestion is used or when the name of a token is typed in by hand.

The behaviour of taking an array of strings from `completionsForSubstring` and then asking for a represented object once a choice has been accepted matches the behaviour of Cocoa.
2012-06-16 12:31:47 +01:00
Alexander Ljungberg d07ee3ea23 Hide non-public API in CPTokenField.
Also improve documentation.
2012-06-16 12:31:47 +01:00
Alexander Ljungberg 7ffd65476b Fixed: token field auto completions.
Auto completions are strings, not represented objects. Revert "Fix CPTokenField autocompletion to deal with represented objects"

This reverts commit 8b9a0edeba.
2012-06-16 12:31:47 +01:00
Alexander Ljungberg ca0a07cab8 Formatting. 2012-06-16 12:31:47 +01:00
Antoine Mercadal 0d29f15b70 Merge pull request #1513 from BlairDuncan/MenuTimestampFix
Fix for menu selection that was broken with the change to CPEvent timestamp
2012-06-14 17:02:06 -07:00
Antoine Mercadal 714d36d8c8 Merge branch 'CPImageView-bindings' of https://github.com/cacaodev/cappuccino into pull1534 2012-06-14 13:05:04 -07:00
Antoine Mercadal cd94819099 Merge branch 'issue1435' of https://github.com/stewa/cappuccino into issue1435 2012-06-14 11:58:49 -07:00
Antoine Mercadal 52199776d5 Merge pull request #1537 from mrcarlberg/cptableview_selection_radius
Added a themed attribute for round rect selection of rows. [+1]
2012-06-14 10:29:58 -07:00
Antoine Mercadal f8df87edcf Merge pull request #1561 from tancred/xcodeapp_always_creates_support_sources
Create support sources folder if necessary.

Reviewed.
2012-06-14 10:27:43 -07:00
Antoine Mercadal dc68daa859 Merge pull request #1564 from tancred/xcodecapp_sync_last_event_id_more_frequently
Make XcodeCapp synchronize file system event status more frequently.

Reviewed.
2012-06-14 10:24:40 -07:00
Malte Tancred 1fd021770e Split -synchronizeLastEventId in two methods.
The first method (updateUserDefaultsWithLastEventId) just
sets the default while the other (synchronizeUserDefaultsWithDisk)
forces a synchronization with the disk.
2012-06-14 11:43:52 +02:00
Antoine Mercadal 6f32e598e9 Add manual tests for disabled button with image 2012-06-13 15:22:53 -07:00
Antoine Mercadal 19794b06ab nib2cib sets _imageDimsWhenDisabled to YES for buttons 2012-06-13 15:22:26 -07:00
Antoine Mercadal ecdb064a5b Makes CPButton to dim image when disabled by default 2012-06-13 15:21:45 -07:00
Antoine Mercadal d67a03bfb4 make disabled buttonbar buttons more visible 2012-06-13 14:30:26 -07:00
Antoine Mercadal c361d7a52a Merge branch 'new-cpbuttonbar-artwork' 2012-06-13 10:12:05 -07:00
Malte Tancred 0018be6fd8 Make XcodeCapp synchronize file system event status more frequently.
This is a small fix that makes XcodeCapp update the latestEventId value
in the defaults database at the end of each FSEvents callback.

Prior to this fix, the synchronization was performed only when the user
actively decided to stop listening to a project.
2012-06-13 10:37:08 +02:00
Antoine Mercadal 4a4aa5fc10 update artwork for CPButtonBar 2012-06-12 19:03:32 -07:00
Alexander Ljungberg 8791195673 Merge branch 'master' of github.com:cappuccino/cappuccino 2012-06-13 02:21:07 +01:00
Alexander Ljungberg 72374257ef Minor optimisation and clean up. 2012-06-13 02:20:58 +01:00
Alexander Ljungberg 1b9def2101 Allow asymmetric toolbar margins. Foundation for theming.
Toolbars cannot be themed yet but when theming becomes possible this code should adapt readily.
2012-06-13 02:17:13 +01:00
Alexander Ljungberg 7a467e249e Manual test for toolbars. 2012-06-13 01:40:59 +01:00
Alexander Ljungberg a66942b1b1 Fix and tweak toolbar margins. 2012-06-13 01:40:20 +01:00
Alexander Ljungberg acd3425c43 Dynamic CPToolbar height,
* Support for tall custom widgets. You can now finally have that CPTableView you always wanted in your toolbar.
* "Labels only" mode now makes sense, resulting in a narrow text only toolbar instead of a very tall toolbar with centred labels.
* Use any size toolbar icons such as 48x48 and the toolbar adapts automatically (unlike Cocoa).
2012-06-13 01:26:33 +01:00
Alexander Ljungberg 70bc45ba12 Toolbar CPToolbarDisplayModeIconOnly support. 2012-06-12 23:26:43 +01:00
Alexander Ljungberg 026c210e64 Toolbar CPToolbarDisplayModeIconOnly support. 2012-06-12 23:05:16 +01:00
Alexander Ljungberg 3bc1849041 Improve toolbar item layout.
The height of all items is determined by the tallest item, like in Cocoa. But unlike Cocoa our toolbar is presently fixed height so in order to make this look well for small or large items, the whole row of items is now vertically centred, making the allocation of margin above and below automatic.

Furthermore if a toolbar item has a small view or a small icon, it is now centred within the available space above the label. For example, for a tiny icon in one item next to a normal size icon the tiny icon would be centre aligned with the larger icon.
2012-06-12 23:04:33 +01:00
Antoine Mercadal 17668aca17 Merge remote-tracking branch 'upstream/master' 2012-06-12 11:59:26 -07:00
Antoine Mercadal 2a48b0ca54 make actualResizeEvent a private method 2012-06-12 11:57:19 -07:00
Antoine Mercadal 5acc15ea9e Merge https://github.com/jivadevoe/cappuccino into pr-1545 2012-06-12 11:45:34 -07:00
Malte Tancred 52fff2056b Fixed code standard issues. 2012-06-12 17:44:17 +02:00
Alexander Ljungberg 2a955884b8 Fix header. 2012-06-11 13:14:00 +01:00
Alexander Ljungberg ad5403b538 Setting the shadow style just once will do. 2012-06-11 13:13:36 +01:00
Alexander Ljungberg f538cbc51d Re #1560. Remove obsolete function. 2012-06-10 01:18:56 +01:00
Alexander Ljungberg e232b18b94 Merge pull request #1560 from mrcarlberg/cappuccino
---

I needed to sort a lot of objects and was not impressed by the speed.
Sharing my improvements...
2012-06-10 01:00:40 +01:00
Alexander Ljungberg fcf62080d6 Re #1562. Make native comparison more realistic.
This might have a small speed implication.
2012-06-10 00:59:08 +01:00
Alexander Ljungberg 58103ce0f3 Re #1562. Also performance test selector sort.
It looks like issue #1560 will cause a different sorting function to be used for selectors vs descriptors so performance of both should be monitored for regressions.
2012-06-10 00:58:27 +01:00
Alexander Ljungberg 0827f584be Re #1562. Simplify. 2012-06-10 00:39:37 +01:00
Alexander Ljungberg f042996e7f Re #1562. Only load sort text for tests which use it. 2012-06-09 23:16:52 +01:00
Alexander Ljungberg 7b307a6fb4 Re #1562. Format code. 2012-06-09 23:08:27 +01:00
Alexander Ljungberg bb8a7bacdc Merge pull request #1562 from cacaodev/cappuccino
---

for random numeric array and text array.
2012-06-09 16:49:23 +01:00
Martin Carlberg 0696b22971 Fixed formatting 2012-06-08 20:18:22 +02:00
Martin Carlberg d7ff93f7f2 SortUsingDescriptors: Using the selector in the descriptor instead of always using compare: 2012-06-08 19:48:39 +02:00
cacaodev 0483f9d714 CPArrayPerformanceTest: fixed native sort testing, added tests for random numeric array and text array 2012-06-08 18:19:37 +02:00
Malte Tancred 56c0f7f6f1 Create support sources folder if necessary.
Make sure the the xCodeSupport/Sources folder is always
present. The objj tool will fail if it's missing.

The Sources folder could be missing if it's not checked
into a repos for example.
2012-06-08 13:21:47 +02:00
Martin Carlberg dc30092b60 A very fast sortUsingDescriptors:
I needed to sort a lot of objects and was not impressed by the speed.
Sharing my improvements...
2012-06-07 23:25:58 +02:00
aparajita 7ccd6f842b Merge pull request #1557 from cacaodev/CPTableView-selectedColumn-typo
CPTableView -selectedColumn : missing return statement
2012-06-06 08:08:23 -07:00
cacaodev 299a664b9c CPTableView -selectedColumn : missing return statement 2012-06-06 14:24:28 +02:00
Alexander Ljungberg 0ed398310f Merge branch 'master' of github.com:cappuccino/cappuccino 2012-06-02 13:19:13 -07:00
Alexander Ljungberg 55709cb83a Test CPDate testInitWithString with a date prior to 1970.
This verifies that there are no problems with negative time intervals.
2012-06-02 13:18:58 -07:00
Alexander Ljungberg d0c7796e7c Match CPDate distantPast and distantFuture with Cocoa. 2012-06-02 13:17:34 -07:00
aparajita 544dff205d Merge pull request #1556 from cacaodev/CPDate-referenceDate
CPDateReferenceDate should be 'Jan 1 2001' instead of 'Feb 1 2001'
2012-06-02 12:41:46 -07:00
Alexander Ljungberg 25763962b2 Code formatting. 2012-06-02 11:53:04 -07:00
Alexander Ljungberg fc858933be Re #1556. Make CPDate testSince1970 agree with new reference date. 2012-06-02 11:32:19 -07:00
Alexander Ljungberg 6877aaaf61 Re #1556. Unit test CPDate dateWithTimeIntervalSinceReferenceDate:. 2012-06-02 11:27:19 -07:00
Alexander Ljungberg e4ab1256da Merge pull request #1556 from cacaodev/cappuccino
---

See <https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSDate_Class/Reference/Reference.html#//apple_ref/occ/clm/NSDate/dateWithTimeIntervalSinceReferenceDate:>
2012-06-02 11:23:22 -07:00
cacaodev f2dd6b5dce CPDateReferenceDate should be 'Jan 1 2001' instead of 'Feb 1 2001' 2012-06-02 19:38:34 +02:00
Blair Duncan eeceaa0c9b unlite if mouse is moved off and cursor up hilites last item if none 2012-06-01 20:17:09 -04:00
Alexander Ljungberg bc79d57712 Clean up. 2012-05-27 22:21:11 +01:00
aparajita 954ec26e80 Merge pull request #1551 from ggsato/subclassingDocController
fixed shared CPDocumentController instantiation and added its test
2012-05-26 12:44:18 -07:00
cacaodev 086c0e6ef0 Merge remote-tracking branch 'upstream/master' into CPTableView-content-binding 2012-05-26 08:03:56 +02:00
ggsato fabe1d8991 formatting and now subclassing is tested by Open a document 2012-05-26 11:08:57 +09:00
Antoine Mercadal 02b65e6dfb Fix a bug in Nib2Cib.j when configInfo is null 2012-05-25 18:06:05 -07:00
Alexander Ljungberg aa546374f3 Fixed: typo in aa4eff9. 2012-05-26 00:22:23 +01:00
Alexander Ljungberg 288ec78c3e Fixed: split view autosave.
The fix to prevent incorrect autosaving prevented correct autosaving as well.
2012-05-26 00:04:12 +01:00
Martin Carlberg 2f875615a2 Removed hardcoded width in disclosure button 2012-05-25 11:14:43 +02:00
Martin Carlberg 49adcd85fc Removed useless space after capp_lint warning 2012-05-25 10:54:10 +02:00
Martin Carlberg 8e785c2210 Removed set and get methods and blank line before if added. 2012-05-25 10:47:07 +02:00
ggsato 310422adb1 Added another way to subclass CPDocumentController 2012-05-25 17:09:31 +09:00
ggsato 0dbebf2f04 Added another way to subclass CPDocumentController 2012-05-25 16:54:10 +09:00
Alexander Ljungberg 46aabf0ea2 Code formatting. 2012-05-25 01:12:57 +01:00
Alexander Ljungberg 1a14ef2418 Fixed: capp_lint handling of string literals with escapes.
This could cause capp_lint to warn about what it perceived as code inside of string literals if the string literal ended with an escaped backslash.
2012-05-25 01:07:35 +01:00
Alexander Ljungberg aa4eff9f8d Format code, fix accidental global. 2012-05-25 00:04:46 +01:00
Alexander Ljungberg 9ffaf538e2 Remove unary + warning from capp_lint.
A statement like `x = +y;` actually does have an effect in JavaScript.
2012-05-24 23:58:01 +01:00
Alexander Ljungberg 2a21ce4a0c Support function argument types in capp_lint.
Syntax such as function(/*CPString*/anArgument) {} should not generate a warning, and in general inline /**/ comments should be ignored for linting purposes.
2012-05-24 23:52:30 +01:00
Alexander Ljungberg 09d5957c82 Code formatting. 2012-05-24 23:40:15 +01:00
Alexander Ljungberg 2b8b570dd4 Fixed: capp_lint exponential warnings.
capp_lint issued warnings over numerical literals like 2.1e+6 even that they were correctly formatted.
2012-05-24 23:22:24 +01:00
Alexander Ljungberg a7bee74fb0 Report the original line contents in capp_lint.
capp_lint does some preprocessing of lines to simplify the lint tests, but the user will expect the regular, non processed lines in the output.
2012-05-24 22:34:50 +01:00
Alexander Ljungberg 1f803f52d1 Add some illustrative capp_lint doctests. 2012-05-24 19:37:30 +01:00
Alexander Ljungberg 0d5b4d4958 Fixed: if linted text didn't end with a newline the last character would be ignored. 2012-05-24 19:26:05 +01:00
Alexander Ljungberg 24cce3ca8a Make LintChecker().lint_text('<code>') possible.
Made LintChecker()'s "view" and lint_text's "filename" arguments optional. Filename will default to <stdin> like Python does when you pipe to it. Also return found errors from lint_text as a convenience.
2012-05-24 19:24:50 +01:00
ggsato 2a0ee14130 wrapped window.status clear statement 2012-05-25 01:52:09 +09:00
Alexander Ljungberg e25394a322 Code formatting. 2012-05-24 17:10:46 +01:00
ggsato ab1dc15393 moved types declaration 2012-05-24 23:58:59 +09:00
ggsato 3a750591bb moved types declaration 2012-05-24 23:55:04 +09:00
ggsato 7da9877c5f fixed shared CPDocumentController instantiation and added its test 2012-05-24 23:12:07 +09:00
Alexander Ljungberg 66ff5dcb86 Merge pull request #1550 from ggsato/cappuccino
---

This is a tiny little minor fix of MainMenu.xib template. 

Before

https://www.dropbox.com/s/cqq8zhy8o2yof51/NibTemplate_Before.png

After

https://www.dropbox.com/s/78j95f1gl596vro/NibTemplate_After.png
2012-05-24 13:54:57 +01:00
ggsato f50a6ea7a3 fixed menu labels by removing numbers at Identity Label 2012-05-24 18:09:17 +09:00
Adam Radabaugh 253d7497ef Merge branch 'master' of git://github.com/cappuccino/cappuccino 2012-05-23 00:15:22 -06:00
Aparajita Fishman 1efc2e3c15 Fixed parsing in CGSizeFromString and CGPointFromString 2012-05-22 12:52:54 -07:00
Adam Radabaugh 909c6ed171 Fix style issue in CPControl 2012-05-19 16:56:57 -06:00
Aparajita Fishman b4f916351e Added capp_lint check for space inside parens and dependent statement on same line, cleaned up CPString.j 2012-05-19 14:20:07 -07:00
Adam Radabaugh a47a5b76eb Fix style issue in CPButton.j 2012-05-18 23:15:26 -06:00
Adam Radabaugh 919bfb7960 Fix style issue in CPControl 2012-05-18 17:11:04 -06:00
Antoine Mercadal bc09c99952 Merge branch 'master' of https://github.com/cappuccino/cappuccino 2012-05-18 12:51:34 -07:00
Antoine Mercadal 28ccb27d4f Merge branch 'cpstring_append_path_component_cocoa_way' of https://github.com/mrcarlberg/cappuccino into PR_mrcarlberg_cpstring_append_path_component_cocoa_way 2012-05-18 12:47:41 -07:00
Jiva DeVoe d205c4eac7 updating to remove a comment and to fix a formatting issue 2012-05-18 10:25:06 -07:00
Jiva DeVoe 18662deec6 removed the if statement before the invalidate 2012-05-17 23:52:41 -07:00
Jiva DeVoe d955eceafa fixed an errant semicolon 2012-05-17 23:34:26 -07:00
Jiva DeVoe 995d529fb7 Added a very hacky workaround for the jittery resize bug in webkit. Ref: https://github.com/cappuccino/cappuccino/issues/1325 2012-05-17 23:10:04 -07:00
Aparajita Fishman d4e460dac5 When popover closes implicitly, popoverShouldClose delegate method should be called.
Added extra button popover to test -close method, which does not consult popoverShouldClose.
2012-05-17 17:02:45 -07:00
cacaodev 0314005e0e Added CPImage -data. If needed, generates data for canvas compatible browsers. Added a test in CPImageViewTest where an image is created from the data of another image 2012-05-17 23:02:49 +02:00
cacaodev 7831085a97 Merge remote-tracking branch 'upstream/master' into CPImageView-bindings
Conflicts:
	Tests/Manual/CPImageViewbindingsTest/Resources/MainMenu.cib
2012-05-17 14:01:20 +02:00
cacaodev db8f2fdf75 Added support for CPTableView content binding, generally used with view-based tables.
Grouped the 3 ways to set objectValue on a dataview (content binding, column value binding or regular delegate method) under one main method: _setObjectValueFortableColumn:row:ForView:
    Also fixed a bug where the dragging rows didn't have their bindings applied. Columns and row dragging are now using the previous method for setting data view objectValue.

    Updated TableBindings example: table with content binding vs. columns with value binding.
2012-05-16 15:57:26 +02:00
aparajita d18e77329f Merge pull request #1542 from BlairDuncan/controlDidFailToFormatStringFix
controlDidFailToFormatString should send a string not an HTML element
2012-05-15 21:39:14 -07:00
Blair Duncan 8f4acc98d4 controlDidFailToFormatString should send a string not an HTML element 2012-05-16 00:03:00 -04:00
Adam Radabaugh 95f7ba29cc Update latest nib2cib with demo of button types 2012-05-15 14:38:54 -06:00
Adam Radabaugh 7ab20145d1 Merge branch 'master' of git://github.com/cappuccino/cappuccino
Conflicts:
	Tests/Manual/CPButtonTest/Resources/MainMenu.cib
2012-05-15 14:15:03 -06:00
Blair Duncan 5f7d1e8dc3 controlDidFailToFormatString should send a string not an HTML element 2012-05-15 16:07:56 -04:00
Antoine Mercadal 6010288124 Merge pull request #1541 from cacaodev/CPPopover-setBehavior
CPPopover typo: setBehaviour: -> setBehavior:

Reviewed.
2012-05-15 12:49:59 -07:00
cacaodev 8a10105f48 CPPopover typo: setBehaviour: -> setBehavior: 2012-05-15 21:42:14 +02:00
Antoine Mercadal 478fb43d2a Fix all Manual tests showing empty UI. (re-run nib2cib on all of them) 2012-05-15 12:08:19 -07:00
Alexander Ljungberg 4b7cef637b Refs #1538. Reapply formatting. 2012-05-14 21:21:45 +01:00
Alexander Ljungberg 69c72d366e (Fix commit attribution) Merge pull request #1538 from mrcarlberg/cappuccino
---

Dont you hate when your logs of arrays and dictionaries display [Object object] when you have JavaScript objects in them. Now with this patch all JavaScript objects will be display with all attributes in a nice good looking way. Log CGRect, CGPoint and other JavaScript objects withour any hassle anymore. For example: console.log([myRect]);

Conflicts:
	Foundation/CPObject.j
	Tests/Foundation/CPMutableArrayTest.j
2012-05-14 21:20:41 +01:00
Alexander Ljungberg 5e7125e310 Refs #1538. Clean up, accidental global. 2012-05-14 21:12:31 +01:00
Alexander Ljungberg bc370a2a5a Merge pull request #1538 from mrcarlberg/cappuccino
---

Dont you hate when your logs of arrays and dictionaries display [Object object] when you have JavaScript objects in them. Now with this patch all JavaScript objects will be display with all attributes in a nice good looking way. Log CGRect, CGPoint and other JavaScript objects withour any hassle anymore. For example: console.log([myRect]);
2012-05-14 21:12:17 +01:00
Martin Carlberg 0abd9855c2 Moved new description functionallity from CFDictionary to CPDictionary.
Added testcase for both CPDictionary and CPArray. Fixed failing testcase.
Checked all new code with capp_lint for correct formatting.
2012-05-14 10:14:05 +02:00
Alexander Ljungberg 3525bd0183 Code formatting. 2012-05-13 14:26:19 +01:00
Darrell Walisser 098f72651c -correct documentation 2012-05-12 15:05:48 -04:00
Darrell Walisser 8c1d147319 -remove next sheet context hack
-order of notifications/didEndSelect are correct now
2012-05-12 14:22:54 -04:00
Martin Carlberg 327debe3a8 Some more clean-up 2012-05-11 23:39:41 +02:00
Martin Carlberg 4af27541d0 Clean-up 2012-05-11 23:33:37 +02:00
Martin Carlberg 70182a0ea2 Description methods in CPArray and CPDictionary will display JavaScript object attributes instead of displaying [Object object]
Don't you hate when your logs of arrays and dictionaries display [Object object] when you have JavaScript objects in them.
Now with this patch all JavaScript objects will be display with all attributes in a nice good looking way. Log CGRect, CGPoint
and other JavaScript objects withour any hassle anymore. For example: console.log([myRect]);
2012-05-11 17:40:11 +02:00
Martin Carlberg 183260d9e3 Added a themed attribute for round rect selection of rows.
Selections in the tableview can now have round corners. The default is a regular
rect, but if the selecction radius is changed. Nice good looking round rect
selections will appear.
2012-05-11 16:14:14 +02:00
Martin Carlberg df2cf923e1 MainBundle path has no '/' at the end when running in CommonJS.
This will make relative paths fail. For example if OBJJ_INCLUDE_PATHS has the path "../../MyLibrary".
MyLibrary will not be found when the path is joined with mainBundlePath without an ending '/'.
This is working when running in Browser.
2012-05-11 15:52:44 +02:00
Martin Carlberg c35ccde682 Added stringByAppendingPathComponent: and stringByAppendingPathExtension: to CPString. Also, changed CPString path behaviour to correspond to Cocoa behaviour. 2012-05-11 15:32:18 +02:00
Alexander Ljungberg afbfde0909 Code formatting. 2012-05-10 16:01:22 +01:00
Alexander Ljungberg e72093c91e Merge pull request #1531 from BlairDuncan/cappuccino
---
2012-05-10 15:50:10 +01:00
Blair Duncan 1ffdaf0f8b typo, LOG should be log 2012-05-10 09:01:03 -04:00
Blair Duncan 74431972d8 added missing LOG math global and replaced any math. with correspoinding global 2012-05-10 08:55:19 -04:00
Stefan Wallström 19804720af CPTableView: Don't update selection etc unless becoming first responder succeeds.
Fix for issue #1435
2012-05-10 13:42:37 +02:00
Alexander Ljungberg 1f8555ffd2 Merge branch 'master' of github.com:cappuccino/cappuccino 2012-05-10 00:19:49 +01:00
Alexander Ljungberg 4218c49a7e Refs #1529. Verify that the actual issue error is gone. 2012-05-10 00:17:25 +01:00
Alexander Ljungberg 8aaf298466 Fixes #1529. Fixed: Incorrect CPDecimalNumber result for 220000/220.
And in general divisions where the quotient had fewer digits than the dividend when disregarding exponent would fail.

We want to stop dividing when we've gone over all the digits in the dividend and the remainder is 0.
2012-05-10 00:16:56 +01:00
Alexander Ljungberg 82e2c7a0e8 Refs #1529. Simpler test: 11/11. 2012-05-10 00:02:44 +01:00
Alexander Ljungberg 27fa01648f Code formatting, delete stray */. 2012-05-10 00:01:03 +01:00
Alexander Ljungberg ab25408429 Refs #1529. Unit test exposing division error. 2012-05-09 23:39:11 +01:00
Alexander Ljungberg d896baf38b Code formatting. 2012-05-09 19:09:35 +01:00
Darrell Walisser 53798c1545 -allow any window to become a sheet 2012-05-06 12:07:02 -04:00
Darrell Walisser 1e6f0090da -allow any window to become a sheet 2012-05-06 12:06:23 -04:00
aparajita 0dcca6d388 Merge pull request #1527 from BlairDuncan/reNib2cibTestFiles
ran nib2cib on all of current test files xib's
2012-05-04 18:04:55 -07:00
Blair Duncan 934691fffb nib2cib all of current test files xib's 2012-05-04 20:10:55 -04:00
Alexander Ljungberg 6bc26eb0cc Test app to verify CPProgressIndicator rendering, nib2cib and coding. 2012-05-03 20:42:41 +01:00
Alexander Ljungberg bdcc1539ac Use an ephemeral subview for the bar of a progress indicator.
This is clearer code and avoids encoding the 'pill view' automatically.
2012-05-03 20:40:50 +01:00
Alexander Ljungberg 6715fbbce2 nib2cib support for CPProgressIndicator size. Fixed: a regular size spinner in IB became twice as large in Cappuccino. 2012-05-03 20:27:05 +01:00
Alexander Ljungberg da055f83b3 Fixed: CPProgressIndicator encoder wasted space and caused errors.
The errors would cause exceptions such as "Not allowed to load local resource: file:///<some local path from the machine that ran nib2cib>" when loading cib driven app through a web server.
2012-05-03 19:45:12 +01:00
Alexander Ljungberg 1476efce90 Minor formatting. 2012-05-03 01:36:17 +01:00
Adam Radabaugh 2078d0e23b Restore copywrite info in headers. 2012-05-01 15:16:44 -06:00
Adam Radabaugh ea0107f67f Enable additional button types in CPButton with manual test. 2012-05-01 15:11:34 -06:00
Darrell Walisser c71f5baef2 -implement orderOut: to control sheet dismissal
-lots of comments and a few debug prints
2012-04-28 20:36:10 -04:00
Darrell Walisser 66f55df44a -use _endSheet to end sheets
-do not call orderFront: if the sheet is already visible
2012-04-28 20:32:13 -04:00
Darrell Walisser 8fd5f30b87 -call orderOut: to dismiss the alert sheet 2012-04-28 20:28:09 -04:00
Darrell Walisser 8bc4a287a6 -update docs for sheet notifications 2012-04-28 11:31:01 -04:00
cacaodev d1dd177bfd CPImageView: support for CPDataBinding. Test. 2012-04-28 17:12:22 +02:00
cacaodev 80b6788638 CPImage -initWithData: 2012-04-28 17:11:37 +02:00
Darrell Walisser ce6444c30e -implement CPWindow sheet notifications on delegate
-raise error when window already has a sheet, or attaching sheet to a sheet
2012-04-28 10:13:02 -04:00
Alexander Ljungberg c437537749 Merge branch 'master' of github.com:cappuccino/cappuccino 2012-04-27 01:19:56 +01:00
Alexander Ljungberg c16c0309c8 Fixed: CPOutlineView setMenu: was not effective.
A CPOutlineView without a delegate `outlineView:menuForTableColumn:item` method, would not display its context menu as specified by `setMenu:` or in IB.
2012-04-27 01:19:47 +01:00
aparajita 1dcd380bb2 Merge pull request #1283 from cacaodev/CPRulePredicateEditor
CPRuleEditor & CPPredicateEditor fixes and enhancements
2012-04-26 12:02:07 -07:00
cacaodev 6fe3d53a13 Merge remote-tracking branch 'upstream/master' into CPRulePredicateEditor 2012-04-26 20:34:18 +02:00
cacaodev 92cdda1d22 capplinted CPRuleEditor/*.j 2012-04-26 20:34:09 +02:00
Aparajita Fishman 3eb4155489 Switched to /usr/bin/env bash for better cross-platform compatibility 2012-04-26 19:11:05 +02:00
Aparajita Fishman e657e7a684 Make capp_lint use a single code base for command line and SublimeLinter 2012-04-26 18:14:06 +02:00
Alexander Ljungberg 5446bedfcc Fixes #1519. Fixed: capp_lint __init__ takes at least 2 arguments error.
Some SublimeLinter specific bits appear to have made it into the standalone capp_lint.
2012-04-26 16:02:41 +01:00
Alexander Ljungberg be36803570 Fixed: CPPredicateEditor "Display value must be…" exception in recent revisions. 2012-04-26 15:35:55 +01:00
Alexander Ljungberg 998bdb550b Merge branch 'master' of github.com:cappuccino/cappuccino 2012-04-26 15:25:59 +01:00
Alexander Ljungberg a0c7305334 Fixed: collection views cleared their selection whenever the content was changed.
This was unlike Cocoa and prevented CPArrayController's selectsInsertedObjects from working.
2012-04-26 15:19:18 +01:00
cacaodev edb86ebeeb CPPredicateEditorValueBinder cleaning, conforms to recent CPBinder updates 2012-04-26 16:09:32 +02:00
cacaodev bfe53a1d54 Merge branch 'CPPredicateEditorRowNode-formatting' into CPRulePredicateEditor 2012-04-26 15:39:16 +02:00
cacaodev 3ab2ebf71f Merge remote-tracking branch 'upstream/master' into CPRulePredicateEditor
Conflicts:
	AppKit/CPRuleEditor/CPRuleEditor.j
2012-04-26 15:38:30 +02:00
Darrell Walisser 0f43cdee00 -sheet attached to modal window runs in modal context
-events in modal run loop get passed to sheet's parent window, so it can move and resize
2012-04-25 21:04:38 -04:00
Antoine Mercadal b04dbb647b Typo in method name + make some methods private 2012-04-25 12:41:22 -07:00
aparajita 72092732f3 Merge pull request #1516 from zittix/Xcodecapp_mising_help_fix
Add missing help file in XcodeCapp to avoid startup crash
2012-04-25 08:10:26 -07:00
zittix 7f0ff5fd0a Add missing help file in XcodeCapp 2012-04-25 16:25:58 +02:00
Antoine Mercadal 0318d23ab6 Fix stupid error in tooltips management when initializing from a coder 2012-04-24 18:10:33 -07:00
Antoine Mercadal 8fdf78cf67 Move the tooltip code into the CPView code (remove category). Fix problem with tooltips not working when using deploy 2012-04-24 17:57:05 -07:00
Darrell Walisser 06348bbe0b -keep parent window behind sheet when orderFront: on sheet or left mouse down on parent window 2012-04-24 20:54:09 -04:00
Antoine Mercadal 3ec4d3e374 Encode/Decode tooltip in CPView 2012-04-24 16:27:36 -07:00
Antoine Mercadal 9866bf19a4 Support for setting ToolTips right from IB 2012-04-24 16:13:37 -07:00
Aparajita Fishman 1e3c668c9b Added instructions for using pre-commit hook 2012-04-24 10:37:40 +02:00
Aparajita Fishman 36bfc7c675 Fixed decode methods to return the correct defaults, removed unnecessary containsValueForKey and || with defaults 2012-04-24 10:15:19 +02:00
Blair Duncan d6429e532b typo fix 2012-04-24 00:02:12 -04:00
Blair Duncan 864db16e33 Fix for issue 1491, don't scroll if active menu container is menubar 2012-04-23 23:54:13 -04:00
Blair Duncan 02ebb6e4f7 highlite menu item only if the active item was found 2012-04-23 23:06:31 -04:00
Alexander Ljungberg 44521a3c22 Merge branch 'master' of github.com:cappuccino/cappuccino 2012-04-23 23:56:59 +01:00
Alexander Ljungberg c5afd3d39f Fixes #1512. Patch to improve rhino-narwhal platform support.
This rhino-narwhal patch can be applied to add JAVA_OPTS support when running Cappuccino utilities through rhino. This generally improves configurability for special cases, and specifically enables a work around for the "failed to map segment from shared object" error on some platforms.
2012-04-23 23:45:29 +01:00
Blair Duncan 5b5034da63 CPEvent - send a valid timestamp for periodic events 2012-04-23 18:19:37 -04:00
Aparajita Fishman 2fd67f6ba8 Merge branch 'master' of github.com:cappuccino/cappuccino 2012-04-23 23:24:27 +02:00
Blair Duncan 5b6779a3a9 Fix for menu selection that was broken with the change to CPEvent timestamp 2012-04-23 16:51:10 -04:00
Alexander Ljungberg 74820a5040 Merge branch 'master' of github.com:cappuccino/cappuccino 2012-04-23 19:16:05 +01:00
Alexander Ljungberg be76424513 Fixes #1460. Add an xcode-select warning to bootstrap.sh. 2012-04-23 19:15:37 +01:00
Alexander Ljungberg 2d4e544931 Don't mention a website which no longer exists. 2012-04-23 18:48:21 +01:00
Aparajita Fishman 1077294e9a Added missing -adjustSubviews method, code cleanup. 2012-04-23 12:08:12 +02:00
Aparajita Fishman bd691d5307 Hopefully finally fixed the problem with CPScrollView/CPScroller initialization. Fixes #1485. 2012-04-23 01:12:24 +02:00
Aparajita Fishman 48ef639408 Merge branch 'master' of github.com:cappuccino/cappuccino 2012-04-22 23:14:18 +02:00
Aparajita Fishman 9830b2b115 Subviews may not be accessed during initWithCoder. Fixes #1485. 2012-04-22 23:13:58 +02:00
Alexander Ljungberg 40e07bbb45 Missing semicolons. 2012-04-22 15:22:00 +01:00
Alexander Ljungberg 7efc8230a2 Fixed: a collection view wouldn't become the first responder when its items were clicked. 2012-04-20 17:30:17 +01:00
Alexander Ljungberg 38dd03652a Merge branch 'master' of github.com:cappuccino/cappuccino 2012-04-20 15:14:37 +01:00
Alexander Ljungberg 21a34f88b2 Fixed: don't crash when removing objects from an array controller which has its arrangedObjects.@count observed. 2012-04-20 15:12:59 +01:00
Aparajita Fishman 092cb01bb3 Added capp_lint to Tools 2012-04-20 11:57:18 +02:00
Alexander Ljungberg d9640aa205 Merge branch 'master' of github.com:cappuccino/cappuccino 2012-04-19 22:44:06 +01:00
Alexander Ljungberg 469414cb35 Fixed: a CPURLRequest created without using the designated initialiser wouldn't work.
Now `init` calls the designated initialiser like in Cocoa.
2012-04-19 22:43:45 +01:00
aparajita f96c113065 Merge pull request #1509 from cacaodev/CPData-bytes-base64
CFData: completed bytes(), base64() and adds CPData +dataWithBytes and +dataWithBase64:
2012-04-17 10:44:53 -07:00
cacaodev 7fe576163d CFData: Adds lazy getters bytes(), base64().
CPData: Adds +dataWithBytes and +dataWithBase64:
Tests.
2012-04-17 19:08:29 +02:00
Alexander Ljungberg 314be1ec11 Merge branch 'master' of github.com:cappuccino/cappuccino 2012-04-17 15:28:11 +01:00
Alexander Ljungberg 0d810e64b7 Stub out CPDateFormatter and nib2cib support. 2012-04-17 15:27:47 +01:00
Aparajita Fishman 5763ebdf2b Fixed CPEvent -timestamp to return seconds since startup, as documented in Cocoa.
Miscellaneous cleanup of timestamp usage as well.
2012-04-15 11:30:27 -04:00
aparajita 3f58c4ea6f Merge pull request #1494 from cacaodev/CPImageView-bindings
CPImageView: support CPValueURLBinding and CPValuePathBinding.
2012-04-15 05:52:22 -07:00
cacaodev 22f75fa9cd Very minor UI changes 2012-04-15 09:52:57 +02:00
Randall Luecke 340b86e97f CPAlert shouldn't use 'alert' as a variable name 2012-04-13 10:59:30 -04:00
Aparajita Fishman 4fff92f3ee Ignore NS_*.j userland NS classes in XcodeCapp 2012-04-13 08:25:19 -04:00
cacaodev 0c8715dd8d Merge remote-tracking branch 'upstream/master' into CPImageView-bindings 2012-04-12 23:26:11 +02:00
cacaodev 487d38fd21 Merge remote-tracking branch 'upstream/master' into CPImageView-bindings 2012-04-12 23:12:09 +02:00
Aparajita Fishman c028c0ad26 Fixed infinite loop when finished editing a tableview cell. 2012-04-12 17:09:20 -04:00
cacaodev 925a922d90 Remove first row in the plist 2012-04-12 21:41:26 +02:00
Aparajita Fishman aeb2671fc0 CPImageView enhancements
- Changed from deprecated image scaling constants to new ones.
- Added support for CPImageScaleProportionallyUpOrDown (thanks BlairDuncan).
- Cleaned up image layout code.
2012-04-12 14:55:46 -04:00
Aparajita Fishman 502edbd152 nib2cib enhancements
- Added support for User Defined Runtime Attributes in IB.
- Added support for userland NS classes in IB.
- Added support for file-based nib2cib configuration.
- Converted nib2cib to Objective-J from straight Javascript.
- Updated man page for new features.
- Test app.
2012-04-12 12:09:24 -04:00
Aparajita Fishman 5fed81e1dc CFURL/CPURL fixes/enhancements
- Fixed bizarre bug where local variable path was being set as attribute of object in CPURL -pathComponents.
- Added CPURL -URLByDeletingLastPathComponent.
- Linted CFURL.js.
- CFURL constructor should copy when passed a CFURL.
- Added CFURL.createCopyDeletingLastPathComponent.
- Added test for URLByDeletingLastPathComponent.
2012-04-12 10:45:01 -04:00
Aparajita Fishman 6293380406 Let jake proceed if a man page cannot be copied 2012-04-10 22:42:46 -04:00
Antoine Mercadal 73641cb726 Merge remote-tracking branch 'upstream/master' 2012-04-10 16:10:14 -07:00
Antoine Mercadal 71cfeae5f1 fix typo preventing the highlighting color to be draw. 2012-04-10 16:08:17 -07:00
Aparajita Fishman c40aaa04f6 Merge branch 'master' of github.com:cappuccino/cappuccino into cappuccino 2012-04-10 18:42:43 -04:00
Aparajita Fishman f4f4554cde Fixed test of result of sudo() 2012-04-10 18:42:26 -04:00
aparajita 1b0fa21f28 Merge pull request #1498 from BlairDuncan/unnecessaryGlobals
Unnecessary globals
2012-04-10 14:57:40 -07:00
Aparajita Fishman 5c0e079873 CPBinder: In reverseSetValueFor:, suspend observation to avoid unwanted setValueFor:
isssue #1463
Manual test and ojtest.
2012-04-10 17:28:20 -04:00
Blair Duncan 6ede1ccb04 Unnecessary globals 2012-04-10 17:25:46 -04:00
aparajita 7173d3c866 Merge pull request #1496 from BlairDuncan/testBranch
Fix for issue 1425 CPOutlineView expand all items
2012-04-10 14:15:10 -07:00
cacaodev c989c30e00 Use new CPBinder methods from #1495 2012-04-10 22:57:20 +02:00
cacaodev d649fc2413 Merge remote-tracking branch 'upstream/master' into CPImageView-bindings 2012-04-10 22:26:23 +02:00
aparajita 8015106976 Merge pull request #1495 from cacaodev/CPBinder
CPBinder: consolidate setValueFor: with placeholders management
2012-04-10 13:22:23 -07:00
Blair Duncan 6b6c44c4d5 Fix for issue 1425 CPOutlineView expand all items when option key is pressed while clicking the disclosure triangle 2012-04-10 16:11:31 -04:00
cacaodev 742bfcb0e7 Fix non-applicable syntax 2012-04-10 22:06:50 +02:00
cacaodev f222d7bfe7 CPBinder: move placeholder handling to superclass, add 2 subclassable methods for appying the regular value or a placeholder value.
Update binder subclasses for CPTextField, CPCheckBox, CPColorWeel.
2012-04-10 21:48:09 +02:00
Aparajita Fishman f6bdf06e45 Fix _CPFormatLogMessage to do something intelligent if aLevel and/or aTitle is empty or not passed 2012-04-10 15:07:39 -04:00
Aparajita Fishman c04f188adc Fix for dump_theme failing without admin rights, common.jake linting 2012-04-10 14:26:00 -04:00
Antoine Mercadal 1e2964ad8f Fix a crash do to calling non-existing selector
That said, the popover is not moving correctly with the
attached view as it did. Patch in a following commit
2012-04-09 19:20:47 -07:00
Aparajita Fishman dd63174493 Merge branch 'master' of github.com:cappuccino/cappuccino into cappuccino 2012-04-09 15:53:53 -04:00
Aparajita Fishman 91642080d6 Eliminate flashing of insertion point when becoming first responder due to double setTimeout 2012-04-09 15:53:31 -04:00
cacaodev ccf18bb9cb CPPredicateEditorRowNode formatting 2012-04-09 19:54:00 +02:00
Antoine Mercadal 64a74d9ac6 Merge branch 'master' of https://github.com/cappuccino/cappuccino 2012-04-09 10:28:02 -07:00
Aparajita Fishman bc8dc10ac3 Fix for #1433 2012-04-09 13:25:38 -04:00
Antoine Mercadal 324e75650d code style cleaning 2012-04-09 10:24:39 -07:00
Antoine Mercadal 8c205faf2d Merge https://github.com/rvanzon/cappuccino into rvanzon-xcc 2012-04-09 10:23:59 -07:00
Richard van Zon d56a15db83 Using fm instance and ignore errors 2012-04-09 08:06:53 +02:00
Aparajita Fishman 342bde7767 Started linting CPRuleEditor classes 2012-04-09 01:56:59 -04:00
Aparajita Fishman ec80a4c9e6 Add some missing imports 2012-04-09 00:59:57 -04:00
aparajita 2a1af53d79 Merge pull request #1456 from cacaodev/CPTabView
CPTabView: Do not track the segment when the delegate disallows item selection
2012-04-08 21:38:53 -07:00
Alexander Ljungberg c528563421 Merge branch 'master' of github.com:cappuccino/cappuccino 2012-04-08 18:51:15 +02:00
Alexander Ljungberg a3a01c2419 Missing semicolons, whitespace. 2012-04-08 18:50:54 +02:00
Alexander Ljungberg 40d30459b8 Missing semicolons. 2012-04-08 18:10:54 +02:00
Alexander Ljungberg b746824933 Formatting. 2012-04-08 18:10:41 +02:00
cacaodev 1e9958c4c7 Handle CPValueBinding in the custom binder. Added a CPImageView with CPValueBinding to the test app.
Removed setBackgroundColor:gray for placeholders because it's a bad idea (non cocoa and need to restore bg when the value != placeholder).
2012-04-08 10:01:04 +02:00
aparajita 3230ea2519 Merge pull request #1492 from daboe01/master
fix for issue 1451
2012-04-07 13:25:39 -07:00
aparajita 22fc8337a3 Merge pull request #1257 from aparajita/_CPImageAndTextView-API
Add textFrame method to locate the text within the view
2012-04-07 10:51:10 -07:00
Aparajita Fishman 86d5818c0f Revert "Use /var/tmp, in Lion /tmp is not world writable"
This reverts commit e9d076adcd.
2012-04-07 10:42:27 -07:00
cacaodev b6a173cc0c CPImageView: support CPValueURLBinding and CPValuePathBinding. Readonly. With test. 2012-04-07 13:16:16 +02:00
daboe01 ec9c682052 Small progress indicator images fixed (http://www.preloaders.net/en/terms_of_use) 2012-04-06 13:56:06 +02:00
Aparajita Fishman e9d076adcd Use /var/tmp, in Lion /tmp is not world writable 2012-04-05 20:28:14 -07:00
Aparajita Fishman d59bc012b6 Added dump_theme tool 2012-04-05 20:25:14 -07:00
Aparajita Fishman eb292e6d87 Factored image creation code so -description can be added 2012-04-05 19:57:30 -07:00
Aparajita Fishman 129a8cb411 Added ability to specify bundle, which makes this usable with non-main bundle images. 2012-04-05 19:42:23 -07:00
Aparajita Fishman d76706b865 Cocoa always sends NSControlTextDidEndEditingNotification and the action when resigning, whether or not editing had begun. 2012-04-05 18:04:10 -07:00
aparajita 159c5c7342 Merge pull request #1253 from aparajita/better-theme-template
Improvements to the ThemeDescriptor capp template
2012-04-05 17:07:40 -07:00
Aparajita Fishman 4d50eea29b capp templates
- Small comment tweaks
2012-04-05 17:06:15 -07:00
daboe01 0ec10515cd Small progress indicator images 2012-04-05 20:45:19 +02:00
Aparajita Fishman c2f20c21e6 Added CGInsetUnion and CGInsetDifference 2012-04-04 23:17:24 -07:00
Aparajita Fishman e2ead56256 Collection KVC fixes, nextObject correctness
- Moved common CPArray/CPSet collection KVC operators to _CPCollectionKVCOperators.
- Implemented KVC operator dispatch using Objective-J.
- Fixed infinite loop with empty  collection in @min, @max and @sum operators.
- Correctly return valueForUndefinedKey when necessary.
- valueForUndefinedKey reason uses raw description for consistency, class' overridden description may not helpful at all.
- Don't create a forwarder for @ operators with property paths.
- Fixed CPSet -valueForKeyPath to correctly deal with nil/undefined/empty values.
- Added tests for collection  KVC operators.
- enumerator -nextObject should always compare against nil for clarity, correctness, and consistency.
2012-04-03 22:16:55 -07:00
Aparajita Fishman 029e45d027 Use === when possible, made it clearer where the ternary operator ends 2012-04-03 17:17:26 -07:00
Aparajita Fishman 93cc97002a Cocoa conformance and bug fixes
- showRelativeToRect:ofView:preferredEdge: must take provide a view, and if the rect is empty it defaults to the view's bounds.
- If If showRelativeToRect is called while a popover is closing, it is ignored.
- If showRelativeToRect is called when the popover is already open, it should just reposition the existing popover.
- close should NOT consult the delegate's popoverShouldClose. Only performClose should do that.
- If a window is closed, all of its popovers immediately order out.
- Updated demo app to cover more cases.
- Note that child popovers are currently not supported, as this requires support for child windows in CPWindow.
2012-03-31 18:40:47 -07:00
Aparajita Fishman 8fed89164f Add the appkit_tag_dom_elements flag to the NibApplication index-debug.html template 2012-03-30 11:19:40 -07:00
Aparajita Fishman 48b9f3198f Methods that return CGPoint should always copy! 2012-03-30 10:53:00 -07:00
Aparajita Fishman 5893b33962 Merge branch 'master' of github.com:cappuccino/cappuccino into cappuccino 2012-03-27 16:29:51 -07:00
Alexander Ljungberg d2f3ceaf67 Documentation. 2012-03-27 23:45:18 +01:00
Alexander Ljungberg 271b935ba2 + (BOOL)automaticallyNotifiesObserversOf<Key> support. 2012-03-27 23:42:17 +01:00
Aparajita Fishman 3ddab9e26a Added configurable list of source directories for framework Jakefile 2012-03-27 11:20:31 -07:00
Aparajita Fishman d68278e41f Use isMenuBar instead of testing class 2012-03-27 11:19:41 -07:00
Alexander Ljungberg 25676b4460 Fixed: reverse value transformations were not applied for table view bindings. 2012-03-27 13:56:25 +01:00
Alexander Ljungberg 56c7e1991e Fixed: check box binding value transformers were ignored. 2012-03-27 13:53:32 +01:00
Alexander Ljungberg ff68ccdeab Fix CPPopUpButtonTest. 2012-03-27 13:51:52 +01:00
Alexander Ljungberg 4acbfd5587 Formatters are a part of Foundation. 2012-03-27 10:37:15 +01:00
Alexander Ljungberg 8df2e608ab Merge branch 'master' of github.com:cappuccino/cappuccino 2012-03-27 10:02:52 +01:00
Alexander Ljungberg 38f8b1a931 Raise an exception if a view is added to itself as a subview.
This is better than a DOM node exception.
2012-03-27 10:02:27 +01:00
Alexander Ljungberg 099ee1e249 RC1 bootstrap. 2012-03-26 21:09:37 +01:00
Aparajita Fishman 9e8f659faf Stop generating useless XML from doxygen. 2012-03-26 12:47:05 -07:00
Aparajita Fishman cd148c36c9 Menu tracking fixes:
- Finally fixed #1457.
- Fixed case where mouse is dragged and then released over a submenu, which should release the menu.
- Fixed case where clicking without dragging, then clicking again on a menu title would not close the menu.
2012-03-26 12:38:50 -07:00
Alexander Ljungberg aba7fd5527 Make CPPopUpButton selectedTag private API to match Cocoa. 2012-03-26 19:55:50 +01:00
Alexander Ljungberg 68c794bf9d This will be Cappuccino 0.9.6. 2012-03-26 19:55:17 +01:00
Alexander Ljungberg ca9b3a7dbf Demonstrate that pop up button test is using tags. 2012-03-25 22:01:16 +01:00
Alexander Ljungberg 4eba585286 Fix manual pop up button test. 2012-03-25 21:40:52 +01:00
Alexander Ljungberg 4172ecfdf2 Merge branch 'master' of github.com:cappuccino/cappuccino 2012-03-25 14:15:39 +01:00
Alexander Ljungberg da80176935 Minor optimisation. 2012-03-25 14:15:18 +01:00
Alexander Ljungberg f50802b85b Fixes #1164. Support CPOutlineView selectionShouldChangeInOutlineView: delegate method. 2012-03-25 13:58:41 +01:00
Alexander Ljungberg 5351bf7e12 Select outline view item parent with left key.
If there's a single item selected and it's not expanded, pressing the left arrow key on the keyboard now selects the item's parent unless the delegate vetoes.
2012-03-25 13:47:32 +01:00
Aparajita Fishman 96a038559e CPPopover fixes
- Removed animationStyle for now.
- Made sure that popoverDidClose is not called until animation is finished.
- Don't create a new attached window unless: there isn't one; the popover behavior has changed; the current attached window is still visible.
- Don't call popoverWillShow if there is not content view controller.
-  Removed unused _shown instance variable.
- Removed redundant !_attachedWindow checks followed by _attachedWindow message that returns a BOOL.
- Documentation tweaks.
- Fixed up some demo issues.
2012-03-24 20:56:31 -07:00
Aparajita Fishman c321084990 Whitespace 2012-03-24 17:57:13 -07:00
aparajita e13d070439 Merge pull request #1483 from cacaodev/CFPropertyList-XML-date-deserialization
CPDate deserialization from XML Property List, with test.
2012-03-24 17:49:37 -07:00
Aparajita Fishman 1a8fc7f07f CPPopover fixes/enhancements
- Lion-style popovers now zoom open just like their Lion counterparts (except for opacity, the browser couldn't handle that at the same time).
- Fixed a number of subtle drawing issues caused by not aligning path points correctly.
- The anchor arrow deals correctly with corner cases where the middle of the reference rect is not within the corners of the popover.
- Code cleanup: factored redundant code, removed unused code.
- Added corner cases to the demo app, changed demo app to reuse a single popover.
2012-03-23 19:53:46 -07:00
cacaodev 9ef95e1f68 Support for decoding date type in XML 1.0, with test. 2012-03-23 22:28:42 +01:00
aparajita 28ed2f9bd0 Merge pull request #1482 from cacaodev/CPViewController-bundle-fix
CPViewController The cib should be initialized with bundle information.
2012-03-23 09:30:23 -07:00
cacaodev 93f51eaa42 CPViewController The cib should be initialized with bundle information. 2012-03-23 10:09:48 +01:00
Aparajita Fishman 7c807dd887 Moved animationStyle to dedicated methods so they can be documented 2012-03-23 01:57:24 -07:00
Aparajita Fishman 429b42d3e0 Implement what is documented, that loadView without a cib name will create an empty view 2012-03-23 01:49:44 -07:00
Aparajita Fishman 08f013171e CPPopover tweaks:
- Added animationStyle (Lion/iOS) to CPPopover. iOS style does not zoom open, it just appears.
- Tweaked the Lion animation a bit to be a bit less rushed and match Mac OS X timing better.
- Fixed some typos.
2012-03-23 01:49:01 -07:00
Aparajita Fishman d620032d0d Switch from CPRect/Point to CGRect/Point functions 2012-03-22 18:58:41 -07:00
Alexander Ljungberg 3bc5605633 Merge branch 'master' of github.com:cappuccino/cappuccino 2012-03-23 00:35:00 +00:00
Alexander Ljungberg 3a0068186a Implement stopping support for CPArray enumerateObjectsUsingBlock:. 2012-03-23 00:34:09 +00:00
Alexander Ljungberg e19a782954 Test CPArray enumerateObjectsUsingBlock:. 2012-03-23 00:26:05 +00:00
Aparajita Fishman 88783efa7b Needed an _isLazy flag to get correct behavior 2012-03-22 15:43:18 -07:00
Aparajita Fishman a249588f52 UIKit does NOT call viewDidLoad from setView, made this explicit in the docs
viewDidLoad is meant to deal with asynchronous *lazy* instantiation of a view via a cib or loadView. setView is neither asynchronous nor lazy.
2012-03-22 14:22:20 -07:00
Alexander Ljungberg 2951a83e73 CPArray enumerateObjectsWithOptions:usingBlock:. 2012-03-22 17:05:59 +00:00
Aparajita Fishman b99ece088d Prevent doxygen from parsing @implementation within comments 2012-03-21 12:48:12 -07:00
Aparajita Fishman ebd797d6d7 Documented need to use CPColorWithImages() instead of PatternColor() 2012-03-20 13:48:50 -07:00
aparajita fa7a68f3f8 Merge pull request #1479 from aparajita/DOM-class
Put view class in the DOM
2012-03-20 13:02:55 -07:00
Aparajita Fishman 8167c46cfc Added documentation for registerThemeValues methods 2012-03-20 12:51:30 -07:00
Aparajita Fishman 9456810c7e Add registerThemeValues methods in CPView, allows runtime registration of theme values using same format used in ThemeDescriptors.j 2012-03-20 12:21:05 -07:00
Alexander Ljungberg 79f2ec5d17 Refs #1480. Change NSSortDescriptors to CPSortDescriptors in docs. 2012-03-19 21:03:04 +00:00
Alexander Ljungberg 38a0a261c0 Merge pull request #1480 from Kentzo/cappuccino
---
2012-03-19 20:57:52 +00:00
Ilya Kulakov 91eb23ba87 Implement -sortedArrayUsingDescriptors: for CPSet. 2012-03-20 03:43:49 +07:00
Aparajita Fishman 706129bcbd Implement a mechanism to display a DOM element's CPView class 2012-03-18 16:19:01 -07:00
Aparajita Fishman 97b77e9b7b Changed to using data-cappuccino-view attribute 2012-03-18 15:33:19 -07:00
Alexander Ljungberg 3b85a67faf Fixed: table column divider lines were drawn on top of the header bottom line. 2012-03-18 18:01:24 +00:00
Alexander Ljungberg f2571e6536 Don't draw a table corner view if there is no vertical scrollbar.
This could either be due to autohiding or they usage of overlay scrollbars. Not showing it matches Cocoa and makes sense because it takes up space for no reason without the scrollbar.
2012-03-18 17:56:20 +00:00
Alexander Ljungberg bec8a4b1c6 Fixed: scroll views with a bezel border had two strange dots in the upper corners instead of a Lion-like bezel. 2012-03-18 16:56:04 +00:00
Alexander Ljungberg 028fb03ef1 Slightly optimise scroll view border drawing code. 2012-03-18 16:41:39 +00:00
Alexander Ljungberg 65aa08a9d9 Format code. 2012-03-18 16:38:51 +00:00
Alexander Ljungberg 22058a7a93 New corner view test which tests more cases and demonstrates the actual code rather than a category. 2012-03-18 16:30:46 +00:00
Alexander Ljungberg 90514bd3cb Test table view notifications for deselectAll. Verify absence of CPTableViewSelectionIsChangingNotification when changing programmatically. 2012-03-18 15:21:09 +00:00
Alexander Ljungberg bd7d258fcd Slightly less shiny outline view disclosure triangle. Subtle is more Cocoa like. 2012-03-18 14:15:40 +00:00
Alexander Ljungberg c21e40e819 Simplify. 2012-03-18 14:13:15 +00:00
Alexander Ljungberg e0c8ae6335 Minor outline view optimisation: don't apply a context rotation of 0 degrees. 2012-03-18 14:02:14 +00:00
Alexander Ljungberg e9d5d33cb2 Fixed: blurry outline view disclosure triangle.
The triangle centring was such that for a regular size disclosure control the right pointing triangle (collapsed state) was not drawn on integral coordinates.
2012-03-18 14:00:38 +00:00
Alexander Ljungberg 0d9b49df85 Optimise CPIndexSet. 2012-03-18 00:44:02 +00:00
Alexander Ljungberg db5e5d7da6 Test stopping CPIndexSet enumeration. 2012-03-18 00:39:07 +00:00
Alexander Ljungberg 44236795b5 CPIndexSet enumerateIndexesInRange:options:usingBlock:. 2012-03-17 18:18:08 +00:00
Alexander Ljungberg a26bca5dbe CPIndexSet enumerateIndexesWithOptions:usingBlock:. 2012-03-17 18:03:21 +00:00
Alexander Ljungberg 872b446695 CPIndexSet enumerateIndexesUsingBlock:. 2012-03-17 17:36:31 +00:00
Alexander Ljungberg 2b0ed8234c Format code. 2012-03-17 17:19:37 +00:00
Aparajita Fishman 39ec1cfd27 Put the view's class in the DOM for easier debugging 2012-03-16 13:25:13 -07:00
Alexander Ljungberg b7dcd24e11 Adjust size of spinner progress indicators properly in nib2cib. 2012-03-16 18:36:09 +00:00
Alexander Ljungberg 5097030143 Fixed: spinner style progress indicators were nib2cibbed to progress bars. 2012-03-16 18:23:47 +00:00
Alexander Ljungberg 516fac037f Merge branch 'master' of github.com:cappuccino/cappuccino 2012-03-15 00:14:39 +00:00
Alexander Ljungberg 1bf632a575 Rename shouldShowOutlineViewForItem to shouldShowOutlineDisclosureControlForItem.
ShouldShowOutlineView is not a great delegate method name for a control called an outline view. The original Cocoa name refers to an 'OutlineCell' which we don't have so that's not appropriate either.
2012-03-15 00:14:25 +00:00
Alexander Ljungberg 6137aa8637 Optimise shouldShowOutlineView. 2012-03-14 23:23:12 +00:00
Alexander Ljungberg 4be4506ffc Implement outline view outlineView:shouldShowOutlineViewForItem: delegate method (corresponding to shouldShowOutlineCellForItem in Cocoa). 2012-03-14 23:08:01 +00:00
aparajita d3c368ba92 Merge pull request #1477 from cacaodev/CFBundle-loadStatus-fix
CFBundle: isLoaded() should return a bool
2012-03-14 14:27:04 -07:00
cacaodev 9b0d03b024 CFBundle: isLoaded() should return a bool 2012-03-14 21:10:35 +01:00
Alexander Ljungberg c21d2fd017 Fixed: toolbar search fields created in IB were cut in half height-wise due to a too small max size. 2012-03-14 16:02:25 +00:00
Alexander Ljungberg 2940b5e787 Fixed: nib2cibbed search fields had the bottom pixel cut off. 2012-03-14 15:58:35 +00:00
Alexander Ljungberg cf18bcaaf9 Clean up. 2012-03-14 15:50:07 +00:00
Alexander Ljungberg c4eaf083b4 Code formatting. Don't shadow compressor function name. 2012-03-13 20:29:38 +00:00
Alexander Ljungberg df6b592d11 Refs #1474. Allow -T argument before -- in objjc and document it in help.
Seems like all options should be before -- really.
2012-03-13 20:27:20 +00:00
Alexander Ljungberg 109e8b1e33 Merge pull request #1474 from ternarylabs/cappuccino
---
2012-03-13 20:06:33 +00:00
Alexander Ljungberg 85c88d7c93 Whitespace. 2012-03-13 20:03:11 +00:00
Alexander Ljungberg d8e5fa3087 Merge pull request #1441 from cacaodev/cappuccino
---

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

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

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

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

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

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

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

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

Added isEqual:
Renamed CPExpression classes
Fixed -filteredArrayUsingPredicate: for proxy arrays.
2011-12-29 20:04:35 +01:00
cacaodev fe1bd1a978 Cleanup: removed log statements, some comments, css transition hack for fading the drop line separator. 2011-12-29 18:44:06 +01:00
cacaodev b39f509263 CPArray (CPPredicate): -filteredArrayUsingPredicate: and -filterUsingPredicate:
Use CPArray methods (not js array) because the receiver can be a CPArray subclass. With tests.

Fixes the bug reported here: https://groups.google.com/forum/?pli=1#!topic/objectivej/8q9hqbZZUv0
2011-12-29 17:16:53 +01:00
cacaodev 7a8173bf6f CPRuleEditor : Fixes a bug where a rule editor embedded in a scroll view was not updating its frameSize when rows where added/removed.
Reported here: https://groups.google.com/d/msg/objectivej/G2MFGGSHaOY/ojcQaoNSpcAJ
I also adjusted the plus button right padding to give enough space for the scroller.
Edited CPRuleEditorCibTest xib to unhide the vertical scroller.
2011-12-25 22:16:01 +01:00
cacaodev 1ea95bf6e0 CPExpression: renamed private classes to follow naming rules. 2011-12-17 16:10:06 +01:00
cacaodev 08d690b65d Completed isEqual: support for CPExpression & CPPredicate subclasses 2011-12-17 15:37:43 +01:00
cacaodev edf07a8fbc CPRuleEditor: In -initWithFrame: the _CPRuleEditorLocalizer was not initialized by default. 2011-12-17 15:28:41 +01:00
cacaodev fab7d41446 CPRuleEditor: renamed private class RowObject -> _CPRuleEditorRowObject 2011-12-13 10:32:34 +01:00
cacaodev f33a55f1d0 CPPredicateEditor: bindings compatibility. Send control action only after a UI interaction to prevent sending unwanted notifications to the binder.
Send action through the responder chain even if target or action is nil. CPControl relies on this to send updates to the binder.
2011-12-13 10:32:34 +01:00
cacaodev 96a3eef4e1 CPRuleEditor IE7/8/9 compatibility, closes #1279 2011-12-13 10:32:22 +01:00
cacaodev 93dc4d1bc9 CPRuleEditor: -bind:toObject:withKeyPath:options: removed a useless check that was causing an exception when keyPath was a compound key path.
CPPredicateEditor test app: bind textfield and editor to a CPObjectController.
2011-12-13 09:54:24 +01:00
cacaodev d973670026 CPPredicateEditor: - Templates merging. Means that from the same left item you can have different views on the right:
* date is (today, yesterday)
                      * date is less than [text field]

                    - CPPredicateEditorCibTest example: templates merging in the 'mixed' criterion.
                    - ojtest AppKit/CPPredicateEditorTest testing the merging feature.

                    - Cleaned and rearranged code related to the right control action method.
                    - re-enable tooltips.
2011-12-13 09:50:26 +01:00
cacaodev c327956537 CPRuleEditor: Since commit 2b52f7d, CPRuleEditor's delegate method -ruleEditor:displayValueForCriterion:inRow: is more restricive: you must return the same view object for a specific criterion in a given row.
In CPRuleEditorCibTest, the delegate has been updated to follow this rule, it also fixes a bug where the predicate was not correctly handling custom control values.
2011-12-13 09:49:35 +01:00
Randy Luecke 80f5ab09f3 Merge pull request #1410 from vhbit/master
Fixed a bug when changing selection in CPPopUpButton wasn't propagated back to bound object
2011-12-10 20:22:02 -08:00
Randy Luecke 5c8f201a92 Merge pull request #1406 from james-dessart-hb/master
Issue #1297 - fixing CPBrowser selection when using up/down arrow keys
2011-12-10 20:21:06 -08:00
Randy Luecke cf777d7f41 Merge pull request #1417 from BlairDuncan/master
Unnecessary globals
2011-12-10 20:20:22 -08:00
Blair Duncan bb7876759a unnecessary globals 2011-12-10 23:10:22 -05:00
Aparajita Fishman 800d6498d6 Added some missing semicolons 2011-12-10 10:48:54 -08:00
Aparajita Fishman 0648b4279f Added usage documentation for Framework.j 2011-12-10 09:48:08 -08:00
Antoine Mercadal 1a73abe7c3 Merge pull request #1267 from primalmotion/nib2cib-do-not-truncate-bold-labels
Do not truncate bold labels.

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

Now the code agrees with its comments.
2011-12-01 18:18:15 +00:00
Antoine Mercadal ddc5994869 tooltips are now themable. 2011-11-28 12:05:43 +01:00
Darrell Walisser a2eb9e728c Various fixes for sheet bugs
-handle attempt to close sheet while it is animating in
-fixes Safari 5.1 animate out bug by using a timer to
initiate the in/out process
-allow window shadow to become 0 width/height for smoother animation
2011-11-24 19:28:04 -05:00
lowell 2169ba35ad [XcodeCapp] Silenced build warning: -[id<NSTableViewDelegate> tableView:heightOfRow:] expects an NSInteger for the second argument. 2011-11-24 13:59:39 -08:00
lowell 50b447b05d [XcodeCapp] App controller should conform to NSTableView data source and delegate protocols. Protocol methods don't need to be declared in the adopting class' interface because they will have already been declared in the protocol declaration. 2011-11-24 13:58:03 -08:00
Antoine Mercadal bc14ad6b9d small improvments in XcodeCapp, including handling quick remove/create existing files 2011-11-24 17:59:09 +01:00
Neer Friedman ffa33788c4 enquote ENVIRONMENTS environment variable 2011-11-24 18:04:26 +02:00
Neer Friedman 23c9c6bf44 concat command parts in Objective-j/Jakefile 2011-11-24 18:03:20 +02:00
dwalisser 604a49634d Merge remote-tracking branch 'upstream/master' 2011-11-24 09:43:10 -05:00
Alexander Ljungberg 476c02976b Code formatting. 2011-11-23 00:28:27 +00:00
Aparajita Fishman 6ac28e1a77 A few text tweaks to make the prompts more friendly. 2011-11-18 01:02:32 -08:00
Antoine Mercadal 4ec7cea6c4 update doxygen displayed Cappuccini version to 0.9.5 2011-11-16 15:12:22 +01:00
Alexander Ljungberg 0036f329f5 Fixed: in recent builds, WithBindingsTest failed with a "CPScroller does not contain theme attribute 'scroller-width'" error. 2011-11-16 12:57:01 +00:00
Alexander Ljungberg 15af54efda Fixed with CPTokenField: quickly entered tokens would be ignored.
If the autocomplete state had not been set yet, tokens could not be finished using the token separator, return or tab. Instead the user typed text remained in its 'non token' state.
2011-11-16 12:52:27 +00:00
Alexander Ljungberg 07966bb7fe Fixed with CPTokenField: crash if added to a window in a unit test. 2011-11-16 12:50:05 +00:00
Alexander Ljungberg e7d9b0503b Fixes #1398. Fixed with CPTokenField: deleting tokens in front of selected tokens would shift the selection to the right. 2011-11-16 12:04:03 +00:00
Alexander Ljungberg 072b43d178 Fixes #1397. Fixed with CPTokenField: make sure selection is initialised when loading from cib. 2011-11-16 11:55:38 +00:00
Alexander Ljungberg 281d2295ae Code formatting. 2011-11-15 23:47:56 +00:00
Darrell Walisser 3c7783f97c Revert "-fix uninitialized _selectedRange member when loading from cib",
putting in another branch

This reverts commit 2a82703e46.
2011-11-15 10:31:44 -05:00
Darrell Walisser 2a82703e46 -fix uninitialized _selectedRange member when loading from cib 2011-11-15 10:14:07 -05:00
Alexander Ljungberg 79cf4370b4 Update bootstrap to 0.9.5 as well. 2011-11-14 18:49:30 +00:00
Alexander Ljungberg 6217fc8459 Given the large number of changes, this will be Cappuccino 0.9.5 instead. 2011-11-14 18:37:00 +00:00
Alexander Ljungberg f1fd3d170a Merge branch '0.9.2b' of github.com:cappuccino/cappuccino into 0.9.2b 2011-11-14 18:27:08 +00:00
Antoine Mercadal 4e410f8a81 Merge remote-tracking branch 'upstream/0.9.2b' into 0.9.2b 2011-11-14 16:46:36 +01:00
Antoine Mercadal 7a1b273d8d simplify the ignored path matching 2011-11-13 23:34:49 +01:00
Antoine Mercadal 820531342d fix during tidying shadow files 2011-11-13 21:58:45 +01:00
Antoine Mercadal 353db3277a fix file level mode deactivated, fix auto ignore not working 2011-11-13 21:36:52 +01:00
Antoine Mercadal 82f37549ae reactivate 10.7 file level API 2011-11-13 20:28:11 +01:00
Alexander Ljungberg 09e1bd6bf1 The 0.9.2 GM will be tagged v0.9.2 simply. 2011-11-11 16:52:48 +00:00
Alexander Ljungberg 44f3abf262 Don't mention "steam" in TOOLS-README. 2011-11-11 16:45:43 +00:00
Antoine Mercadal 8c09af5013 Merge remote-tracking branch 'upstream/master' 2011-11-10 14:11:12 +01:00
Antoine Mercadal 0781e932c6 Merge branch 'xcc-improvments' 2011-11-10 14:10:45 +01:00
Alexander Ljungberg 3cee00323c Don't separate statements by commas. 2011-11-10 12:31:16 +00:00
Alexander Ljungberg b1f6f3ddfa Missing semicolons. 2011-11-10 12:30:05 +00:00
Alexander Ljungberg 7147266ddf objjc option to compile to plain JavaScript (suitable for linting). 2011-11-10 11:59:26 +00:00
Alexander Ljungberg 357212bff7 Missing semicolons. 2011-11-10 11:34:26 +00:00
Alexander Ljungberg ed4fc3b20f objjc compile to stdout, argument parsing, --help. 2011-11-10 10:37:46 +00:00
Alexander Ljungberg 7e8b71dd52 Semicolons. 2011-11-10 10:36:47 +00:00
Alexander Ljungberg 267f00bfe1 Put spaces around = in [name] = function... generated JS to reduce lint warnings. 2011-11-10 09:41:21 +00:00
Alexander Ljungberg 8f90dbce99 Allow almost anything as a key equivalent unless a text field is the first responder.
After testing in Cocoa, even unexpected keys such as tab can be used when a text field isn't selected. Some keys such as the arrow keys and escape act like key equivalents even with a text field active.
2011-11-10 00:52:38 +00:00
Alexander Ljungberg 00485dba89 Refs #1019. Clean up. 2011-11-10 00:12:48 +00:00
Alexander Ljungberg 8fd4f5e4b6 Merge branch 'master' of github.com:cappuccino/cappuccino 2011-11-09 23:36:47 +00:00
Scott RiceandAlexander Ljungberg e7e69b3fd4 Fixed issue #1019 in IE 2011-11-10 07:35:50 +08:00
Alexander Ljungberg 2463c1dc05 IE compatibility. 2011-11-09 23:02:31 +00:00
Alexander Ljungberg bc590286f2 Missing semicolons. 2011-11-09 22:55:11 +00:00
Aparajita Fishman 8c83816ec8 Made [CPMenu -removeAllItems] KVO compliant
Fixes https://github.com/cappuccino/cappuccino/issues/1395
2011-11-09 14:50:52 -08:00
Alexander Ljungberg 699069ce8f Typo fix. 2011-11-09 20:48:01 +00:00
Alexander Ljungberg ec0cd22c1d Merge pull request #1382 from kjamieson/cappuccino
---

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

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

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

adding autoreconf to fix issues reported at [1]

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

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

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

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

This patch makes CPScrollView acts like Lions NSScrollView.

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

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

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

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

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

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

Cocoa compliance.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

This commit fix this.
2011-05-17 01:02:53 +02:00
Aparajita Fishman 329baa1719 Added license to header, SYS var 2011-05-11 11:39:18 -04:00
Aparajita Fishman 85080f5c58 Made colorPrint function local 2011-05-11 09:02:05 -04:00
Aparajita Fishman 910f02ea50 Removed duplicate productName 2011-05-10 12:20:26 -04:00
Aparajita Fishman bfd8eefa0e Added textFrame method to locate the text within the view 2011-05-09 21:15:12 -04:00
Aparajita Fishman 2d96fcf87f Improvements to the ThemeDescriptor capp template:
- New/improved jake tasks: debug, release, all, clean, clobber, test, test-release, help.
- help task shows comprehensive, formatted documentation for the available tasks.
- BlendKit is automatically symlinked into the Frameworks directory if necessary as part of the build process, so that the showcase will always work.
- User can easily change the build directory by changing one line.
- Fixed incorrect placeholders in main.j.
2011-05-07 13:12:12 -04:00
2513 changed files with 130885 additions and 33537 deletions
+2
View File
@@ -9,3 +9,5 @@ WebSite
*.xcodeproj/*.perspectivev3
xcuserdata/
!*.xcodeproj/project.pbxproj
*.xCodeSupport/
*.XcodeSupport/
+8
View File
@@ -0,0 +1,8 @@
language: node_js
node_js:
- 0.8
before_install:
- jdk_switcher use openjdk6
install: ./bootstrap.sh --quiet --noprompt --directory ./narwhal
script: jake test
env: PATH=$HOME/build/$TRAVIS_REPO_SLUG/narwhal/bin:$PATH CAPP_BUILD=$HOME/build/$TRAVIS_REPO_SLUG/Build NARWHAL_ENGINE=rhino
+10 -2
View File
@@ -20,7 +20,10 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "_CPToolTip.j"
@import "CALayer.j"
@import "CGGeometry.j"
@import "CPAccordionView.j"
@import "CPAlert.j"
@import "CPAnimation.j"
@import "CPApplication.j"
@@ -35,16 +38,21 @@
@import "CPCibBindingConnector.j"
@import "CPCibConnector.j"
@import "CPCibControlConnector.j"
@import "CPCibHelpConnector.j"
@import "CPCibLoading.j"
@import "CPCibOutletConnector.j"
@import "CPCibRuntimeAttributesConnector.j"
@import "CPClipView.j"
@import "CPCollectionView.j"
@import "CPCollectionViewItem.j"
@import "CPColor.j"
@import "CPColorPanel.j"
@import "CPColorSpace.j"
@import "CPColorWell.j"
@import "CPComboBox.j"
@import "CPCompatibility.j"
@import "CPControl.j"
@import "CPController.j"
@import "CPCookie.j"
@import "CPCursor.j"
@import "CPDocument.j"
@@ -54,7 +62,7 @@
@import "CPFlashView.j"
@import "CPFont.j"
@import "CPFontManager.j"
@import "CPGeometry.j"
@import "CPGradient.j"
@import "CPGraphics.j"
@import "CPImage.j"
@import "CPImageView.j"
@@ -92,7 +100,6 @@
@import "CPTokenField.j"
@import "CPToolbar.j"
@import "CPToolbarItem.j"
@import "_CPToolTip.j"
@import "CPTreeNode.j"
@import "CPUserDefaultsController.j"
@import "CPView.j"
@@ -101,3 +108,4 @@
@import "CPWebView.j"
@import "CPWindow.j"
@import "CPWindowController.j"
@import "CPWorkspace.j"
+1 -1
View File
@@ -227,7 +227,7 @@ var secondItem = [[CPAccordionViewItem alloc] initWithIdentifier:@"secondSection
{
var indexSet = [CPIndexSet indexSetWithIndexesInRange:CPMakeRange(0, _items.length)];
[indexSet removeIndexes:_expandedIndexes];
[indexSet removeIndexes:_expandedItemIndexes];
return indexSet;
}
+142 -78
View File
@@ -28,15 +28,19 @@
@import <Foundation/CPObject.j>
@import <Foundation/CPString.j>
@import "CPApplication.j"
@import "CPButton.j"
@import "CPColor.j"
@import "CPFont.j"
@import "CPImage.j"
@import "CPImageView.j"
@import "CPPanel.j"
@import "CPText.j"
@import "CPTextField.j"
@class CPCheckBox
@global CPApp
/*
@global
@group CPAlertStyle
@@ -53,6 +57,8 @@ CPInformationalAlertStyle = 1;
*/
CPCriticalAlertStyle = 2;
var bottomHeight = 71;
/*!
@ingroup appkit
@@ -75,32 +81,33 @@ CPCriticalAlertStyle = 2;
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 : CPView
@implementation CPAlert : CPObject
{
BOOL _showHelp @accessors(property=showsHelp);
BOOL _showSuppressionButton @accessors(property=showsSuppressionButton);
BOOL _showHelp @accessors(property=showsHelp);
BOOL _showSuppressionButton @accessors(property=showsSuppressionButton);
CPAlertStyle _alertStyle @accessors(property=alertStyle);
CPString _title @accessors(property=title);
CPView _accessoryView @accessors(property=accessoryView);
CPImage _icon @accessors(property=icon);
CPAlertStyle _alertStyle @accessors(property=alertStyle);
CPString _title @accessors(property=title);
CPView _accessoryView @accessors(property=accessoryView);
CPImage _icon @accessors(property=icon);
CPArray _buttons @accessors(property=buttons,readonly);
CPCheckBox _suppressionButton @accessors(property=suppressionButton,readonly);
CPArray _buttons @accessors(property=buttons,readonly);
CPCheckBox _suppressionButton @accessors(property=suppressionButton,readonly);
id _delegate @accessors(property=delegate);
id _modalDelegate;
SEL _didEndSelector;
id _delegate @accessors(property=delegate);
id _modalDelegate;
SEL _didEndSelector;
CPWindow _window @accessors(property=window,readonly);
int _defaultWindowStyle;
_CPAlertThemeView _themeView @accessors(property=themeView, readonly);
CPWindow _window @accessors(property=window,readonly);
int _defaultWindowStyle;
CPImageView _alertImageView;
CPTextField _informativeLabel;
CPTextField _messageLabel;
CPButton _alertHelpButton;
CPImageView _alertImageView;
CPTextField _informativeLabel;
CPTextField _messageLabel;
CPButton _alertHelpButton;
BOOL _needsLayout;
BOOL _needsLayout;
}
#pragma mark Creating Alerts
@@ -117,21 +124,21 @@ CPCriticalAlertStyle = 2;
*/
+ (CPAlert)alertWithMessageText:(CPString)aMessage defaultButton:(CPString)defaultButtonTitle alternateButton:(CPString)alternateButtonTitle otherButton:(CPString)otherButtonTitle informativeTextWithFormat:(CPString)informativeText
{
var alert = [[self alloc] init];
var newAlert = [[self alloc] init];
[alert setMessageText:aMessage];
[alert addButtonWithTitle:defaultButtonTitle];
[newAlert setMessageText:aMessage];
[newAlert addButtonWithTitle:defaultButtonTitle];
if (alternateButtonTitle)
[alert addButtonWithTitle:alternateButtonTitle];
[newAlert addButtonWithTitle:alternateButtonTitle];
if (otherButtonTitle)
[alert addButtonWithTitle:otherButtonTitle];
[newAlert addButtonWithTitle:otherButtonTitle];
if (informativeText)
[alert setInformativeText:informativeText];
[newAlert setInformativeText:informativeText];
return alert;
return newAlert;
}
/*!
@@ -142,12 +149,12 @@ CPCriticalAlertStyle = 2;
*/
+ (CPAlert)alertWithError:(CPString)anErrorMessage
{
var alert = [[self alloc] init];
var newAlert = [[self alloc] init];
[alert setMessageText:anErrorMessage];
[alert setAlertStyle:CPCriticalAlertStyle];
[newAlert setMessageText:anErrorMessage];
[newAlert setAlertStyle:CPCriticalAlertStyle];
return alert;
return newAlert;
}
/*!
@@ -163,7 +170,8 @@ CPCriticalAlertStyle = 2;
_alertStyle = CPWarningAlertStyle;
_showHelp = NO;
_needsLayout = YES;
_defaultWindowStyle = CPTitledWindowMask;
_defaultWindowStyle = _CPModalWindowMask;
_themeView = [_CPAlertThemeView new];
_messageLabel = [CPTextField labelWithTitle:@"Alert"];
_alertImageView = [[CPImageView alloc] init];
@@ -180,6 +188,11 @@ CPCriticalAlertStyle = 2;
#pragma mark Accessors
- (CPTheme)theme
{
return [_themeView theme];
}
/*!
set the theme to use
@@ -197,9 +210,20 @@ CPCriticalAlertStyle = 2;
_window = nil; // will be regenerated at next layout
_needsLayout = YES;
[super setTheme:aTheme];
[_themeView setTheme:aTheme];
}
- (void)setValue:(id)aValue forThemeAttribute:(CPString)aName
{
[_themeView setValue:aValue forThemeAttribute:aName];
}
- (void)setValue:(id)aValue forThemeAttribute:(CPString)aName inState:(CPThemeState)aState
{
[_themeView setValue:aValue forThemeAttribute:aName inState:aState];
}
/*! @deprecated
*/
- (void)setWindowStyle:(int)aStyle
@@ -334,16 +358,16 @@ CPCriticalAlertStyle = 2;
*/
- (void)_layoutMessageView
{
var inset = [self currentValueForThemeAttribute:@"content-inset"],
var inset = [_themeView currentValueForThemeAttribute:@"content-inset"],
sizeWithFontCorrection = 6.0,
messageLabelWidth,
messageLabelTextSize;
[_messageLabel setTextColor:[self currentValueForThemeAttribute:@"message-text-color"]];
[_messageLabel setFont:[self currentValueForThemeAttribute:@"message-text-font"]];
[_messageLabel setTextShadowColor:[self currentValueForThemeAttribute:@"message-text-shadow-color"]];
[_messageLabel setTextShadowOffset:[self currentValueForThemeAttribute:@"message-text-shadow-offset"]];
[_messageLabel setAlignment:[self currentValueForThemeAttribute:@"message-text-alignment"]];
[_messageLabel setTextColor:[_themeView currentValueForThemeAttribute:@"message-text-color"]];
[_messageLabel setFont:[_themeView currentValueForThemeAttribute:@"message-text-font"]];
[_messageLabel setTextShadowColor:[_themeView currentValueForThemeAttribute:@"message-text-shadow-color"]];
[_messageLabel setTextShadowOffset:[_themeView currentValueForThemeAttribute:@"message-text-shadow-offset"]];
[_messageLabel setAlignment:[_themeView currentValueForThemeAttribute:@"message-text-alignment"]];
[_messageLabel setLineBreakMode:CPLineBreakByWordWrapping];
messageLabelWidth = CGRectGetWidth([[_window contentView] frame]) - inset.left - inset.right;
@@ -357,22 +381,22 @@ CPCriticalAlertStyle = 2;
*/
- (void)_layoutInformativeView
{
var inset = [self currentValueForThemeAttribute:@"content-inset"],
defaultElementsMargin = [self currentValueForThemeAttribute:@"default-elements-margin"],
var inset = [_themeView currentValueForThemeAttribute:@"content-inset"],
defaultElementsMargin = [_themeView currentValueForThemeAttribute:@"default-elements-margin"],
sizeWithFontCorrection = 6.0,
informativeLabelWidth,
informativeLabelOriginY,
informativeLabelTextSize;
[_informativeLabel setTextColor:[self currentValueForThemeAttribute:@"informative-text-color"]];
[_informativeLabel setFont:[self currentValueForThemeAttribute:@"informative-text-font"]];
[_informativeLabel setTextShadowColor:[self currentValueForThemeAttribute:@"informative-text-shadow-color"]];
[_informativeLabel setTextShadowOffset:[self currentValueForThemeAttribute:@"informative-text-shadow-offset"]];
[_informativeLabel setAlignment:[self currentValueForThemeAttribute:@"informative-text-alignment"]];
[_informativeLabel setTextColor:[_themeView currentValueForThemeAttribute:@"informative-text-color"]];
[_informativeLabel setFont:[_themeView currentValueForThemeAttribute:@"informative-text-font"]];
[_informativeLabel setTextShadowColor:[_themeView currentValueForThemeAttribute:@"informative-text-shadow-color"]];
[_informativeLabel setTextShadowOffset:[_themeView currentValueForThemeAttribute:@"informative-text-shadow-offset"]];
[_informativeLabel setAlignment:[_themeView currentValueForThemeAttribute:@"informative-text-alignment"]];
[_informativeLabel setLineBreakMode:CPLineBreakByWordWrapping];
informativeLabelWidth = CGRectGetWidth([[_window contentView] frame]) - inset.left - inset.right,
informativeLabelOriginY = [_messageLabel frameOrigin].y + [_messageLabel frameSize].height + defaultElementsMargin,
informativeLabelWidth = CGRectGetWidth([[_window contentView] frame]) - inset.left - inset.right;
informativeLabelOriginY = [_messageLabel frameOrigin].y + [_messageLabel frameSize].height + defaultElementsMargin;
informativeLabelTextSize = [[_informativeLabel stringValue] sizeWithFont:[_informativeLabel font] inWidth:informativeLabelWidth];
[_informativeLabel setFrame:CGRectMake(inset.left, informativeLabelOriginY, informativeLabelTextSize.width, informativeLabelTextSize.height + sizeWithFontCorrection)];
@@ -386,8 +410,8 @@ CPCriticalAlertStyle = 2;
if (!_accessoryView)
return;
var inset = [self currentValueForThemeAttribute:@"content-inset"],
defaultElementsMargin = [self currentValueForThemeAttribute:@"default-elements-margin"],
var inset = [_themeView currentValueForThemeAttribute:@"content-inset"],
defaultElementsMargin = [_themeView currentValueForThemeAttribute:@"default-elements-margin"],
accessoryViewWidth = CGRectGetWidth([[_window contentView] frame]) - inset.left - inset.right,
accessoryViewOriginY = CGRectGetMaxY([_informativeLabel frame]) + defaultElementsMargin;
@@ -403,16 +427,16 @@ CPCriticalAlertStyle = 2;
if (!_showSuppressionButton)
return;
var inset = [self currentValueForThemeAttribute:@"content-inset"],
suppressionViewXOffset = [self currentValueForThemeAttribute:@"suppression-button-x-offset"],
suppressionViewYOffset = [self currentValueForThemeAttribute:@"suppression-button-y-offset"],
defaultElementsMargin = [self currentValueForThemeAttribute:@"default-elements-margin"],
var inset = [_themeView currentValueForThemeAttribute:@"content-inset"],
suppressionViewXOffset = [_themeView currentValueForThemeAttribute:@"suppression-button-x-offset"],
suppressionViewYOffset = [_themeView currentValueForThemeAttribute:@"suppression-button-y-offset"],
defaultElementsMargin = [_themeView currentValueForThemeAttribute:@"default-elements-margin"],
suppressionButtonViewOriginY = CGRectGetMaxY([(_accessoryView || _informativeLabel) frame]) + defaultElementsMargin + suppressionViewYOffset;
[_suppressionButton setTextColor:[self currentValueForThemeAttribute:@"suppression-button-text-color"]];
[_suppressionButton setFont:[self currentValueForThemeAttribute:@"suppression-button-text-font"]];
[_suppressionButton setTextShadowColor:[self currentValueForThemeAttribute:@"suppression-button-text-shadow-color"]];
[_suppressionButton setTextShadowOffset:[self currentValueForThemeAttribute:@"suppression-button-text-shadow-offset"]];
[_suppressionButton setTextColor:[_themeView currentValueForThemeAttribute:@"suppression-button-text-color"]];
[_suppressionButton setFont:[_themeView currentValueForThemeAttribute:@"suppression-button-text-font"]];
[_suppressionButton setTextShadowColor:[_themeView currentValueForThemeAttribute:@"suppression-button-text-shadow-color"]];
[_suppressionButton setTextShadowOffset:[_themeView currentValueForThemeAttribute:@"suppression-button-text-shadow-offset"]];
[_suppressionButton sizeToFit];
[_suppressionButton setFrameOrigin:CGPointMake(inset.left + suppressionViewXOffset, suppressionButtonViewOriginY)];
@@ -424,14 +448,17 @@ CPCriticalAlertStyle = 2;
*/
- (CGSize)_layoutButtonsFromView:(CPView)lastView
{
var inset = [self currentValueForThemeAttribute:@"content-inset"],
minimumSize = [self currentValueForThemeAttribute:@"size"],
buttonOffset = [self currentValueForThemeAttribute:@"button-offset"],
helpLeftOffset = [self currentValueForThemeAttribute:@"help-image-left-offset"],
var inset = [_themeView currentValueForThemeAttribute:@"content-inset"],
minimumSize = [_themeView currentValueForThemeAttribute:@"size"],
buttonOffset = [_themeView currentValueForThemeAttribute:@"button-offset"],
helpLeftOffset = [_themeView currentValueForThemeAttribute:@"help-image-left-offset"],
aRepresentativeButton = [_buttons objectAtIndex:0],
defaultElementsMargin = [self currentValueForThemeAttribute:@"default-elements-margin"],
defaultElementsMargin = [_themeView currentValueForThemeAttribute:@"default-elements-margin"],
panelSize = [[_window contentView] frame].size,
buttonsOriginY,
buttonMarginY,
buttonMarginX,
theme = [self theme],
offsetX;
[aRepresentativeButton setTheme:[self theme]];
@@ -442,8 +469,25 @@ CPCriticalAlertStyle = 2;
panelSize.height = minimumSize.height;
buttonsOriginY = panelSize.height - [aRepresentativeButton frameSize].height + buttonOffset;
if ([_window styleMask] & _CPModalWindowMask)
buttonsOriginY = panelSize.height - [aRepresentativeButton frameSize].height / 2 + buttonOffset;
offsetX = panelSize.width - inset.right;
switch ([_window styleMask])
{
case _CPModalWindowMask:
buttonMarginY = [_themeView currentValueForThemeAttribute:@"modal-window-button-margin-y"];
buttonMarginX = [_themeView currentValueForThemeAttribute:@"modal-window-button-margin-x"];
break;
default:
buttonMarginY = [_themeView currentValueForThemeAttribute:@"standard-window-button-margin-y"];
buttonMarginX = [_themeView currentValueForThemeAttribute:@"standard-window-button-margin-x"];
break;
}
for (var i = [_buttons count] - 1; i >= 0 ; i--)
{
var button = _buttons[i];
@@ -455,14 +499,14 @@ CPCriticalAlertStyle = 2;
height = CGRectGetHeight(buttonFrame);
offsetX -= width;
[button setFrame:CGRectMake(offsetX, buttonsOriginY, width, height)];
[button setFrame:CGRectMake(offsetX + buttonMarginX, buttonsOriginY + buttonMarginY, width, height)];
offsetX -= 10;
}
if (_showHelp)
{
var helpImage = [self currentValueForThemeAttribute:@"help-image"],
helpImagePressed = [self currentValueForThemeAttribute:@"help-image-pressed"],
var helpImage = [_themeView currentValueForThemeAttribute:@"help-image"],
helpImagePressed = [_themeView currentValueForThemeAttribute:@"help-image-pressed"],
helpImageSize = helpImage ? [helpImage size] : CGSizeMakeZero(),
helpFrame = CGRectMake(helpLeftOffset, buttonsOriginY, helpImageSize.width, helpImageSize.height);
@@ -487,7 +531,7 @@ CPCriticalAlertStyle = 2;
if (!_window)
[self _createWindowWithStyle:nil];
var iconOffset = [self currentValueForThemeAttribute:@"image-offset"],
var iconOffset = [_themeView currentValueForThemeAttribute:@"image-offset"],
theImage = _icon,
finalSize;
@@ -495,13 +539,13 @@ CPCriticalAlertStyle = 2;
switch (_alertStyle)
{
case CPWarningAlertStyle:
theImage = [self currentValueForThemeAttribute:@"warning-image"];
theImage = [_themeView currentValueForThemeAttribute:@"warning-image"];
break;
case CPInformationalAlertStyle:
theImage = [self currentValueForThemeAttribute:@"information-image"];
theImage = [_themeView currentValueForThemeAttribute:@"information-image"];
break;
case CPCriticalAlertStyle:
theImage = [self currentValueForThemeAttribute:@"error-image"];
theImage = [_themeView currentValueForThemeAttribute:@"error-image"];
break;
}
@@ -519,7 +563,7 @@ CPCriticalAlertStyle = 2;
if (_showSuppressionButton)
lastView = _suppressionButton;
else if (_accessoryView)
lastView = _accessoryView
lastView = _accessoryView;
finalSize = [self _layoutButtonsFromView:lastView];
if ([_window styleMask] & CPDocModalWindowMask)
@@ -528,6 +572,12 @@ CPCriticalAlertStyle = 2;
[_window setFrameSize:finalSize];
[_window center];
if ([_window styleMask] & _CPModalWindowMask || [_window styleMask] & CPHUDBackgroundWindowMask)
{
[_window setMovable:YES];
[_window setMovableByWindowBackground:YES];
}
_needsLayout = NO;
}
@@ -592,9 +642,10 @@ CPCriticalAlertStyle = 2;
- (void)_createWindowWithStyle:(int)forceStyle
{
var frame = CGRectMakeZero();
frame.size = [self currentValueForThemeAttribute:@"size"];
frame.size = [_themeView currentValueForThemeAttribute:@"size"];
_window = [[CPWindow alloc] initWithContentRect:frame styleMask:forceStyle || _defaultWindowStyle];
[_window setLevel:CPStatusWindowLevel];
if (_title)
[_window setTitle:_title];
@@ -631,7 +682,10 @@ CPCriticalAlertStyle = 2;
- (@action)_takeReturnCodeFrom:(id)aSender
{
if ([_window isSheet])
{
[_window orderOut:nil];
[CPApp endSheet:_window returnCode:[aSender tag]];
}
else
{
[CPApp abortModal];
@@ -646,17 +700,19 @@ CPCriticalAlertStyle = 2;
*/
- (void)_alertDidEnd:(CPWindow)aWindow returnCode:(int)returnCode contextInfo:(id)contextInfo
{
if ([_delegate respondsToSelector:@selector(alertDidEnd:returnCode:)])
[_delegate alertDidEnd:self returnCode:returnCode];
if (_didEndSelector)
objj_msgSend(_modalDelegate, _didEndSelector, self, returnCode, contextInfo);
_modalDelegate = nil;
_didEndSelector = nil;
if ([_delegate respondsToSelector:@selector(alertDidEnd:returnCode:)])
[_delegate alertDidEnd:self returnCode:returnCode];
}
#pragma mark Theme Attributes
@end
@implementation _CPAlertThemeView : CPView
+ (CPString)defaultThemeClass
{
@@ -681,7 +737,11 @@ CPCriticalAlertStyle = 2;
[CPColor blackColor],
[CPFont systemFontOfSize:12.0],
[CPNull null],
0.0
0.0,
0.0,
0.0,
0.0,
0.0,
]
forKeys:[@"size", @"content-inset", @"informative-offset", @"button-offset",
@"message-text-alignment", @"message-text-color", @"message-text-font", @"message-text-shadow-color", @"message-text-shadow-offset",
@@ -699,7 +759,11 @@ CPCriticalAlertStyle = 2;
@"suppression-button-text-color",
@"suppression-button-text-font",
@"suppression-button-text-shadow-color",
@"suppression-button-text-shadow-offset"
@"suppression-button-text-shadow-offset",
@"modal-window-button-margin-y",
@"modal-window-button-margin-x",
@"standard-window-button-margin-y",
@"standard-window-button-margin-x"
]];
}
+20 -13
View File
@@ -122,23 +122,30 @@ ACTUAL_FRAME_RATE = 0;
*/
- (void)setAnimationCurve:(CPAnimationCurve)anAnimationCurve
{
var timingFunctionName;
switch (anAnimationCurve)
{
case CPAnimationEaseInOut: timingFunctionName = kCAMediaTimingFunctionEaseInEaseOut;
break;
case CPAnimationEaseInOut:
timingFunctionName = kCAMediaTimingFunctionEaseInEaseOut;
break;
case CPAnimationEaseIn: timingFunctionName = kCAMediaTimingFunctionEaseIn;
break;
case CPAnimationEaseIn:
timingFunctionName = kCAMediaTimingFunctionEaseIn;
break;
case CPAnimationEaseOut: timingFunctionName = kCAMediaTimingFunctionEaseOut;
break;
case CPAnimationEaseOut:
timingFunctionName = kCAMediaTimingFunctionEaseOut;
break;
case CPAnimationLinear: timingFunctionName = kCAMediaTimingFunctionLinear;
break;
case CPAnimationLinear:
timingFunctionName = kCAMediaTimingFunctionLinear;
break;
default: [CPException raise:CPInvalidArgumentException
reason:"Invalid value provided for animation curve"];
break;
default:
[CPException raise:CPInvalidArgumentException
reason:@"Invalid value provided for animation curve"];
break;
}
_animationCurve = anAnimationCurve;
@@ -306,7 +313,7 @@ ACTUAL_FRAME_RATE = 0;
if ([_delegate respondsToSelector:@selector(animation:valueForProgress:)])
return [_delegate animation:self valueForProgress:t];
if (_animationCurve == CPAnimationLinear)
return t;
@@ -324,7 +331,7 @@ ACTUAL_FRAME_RATE = 0;
// currently used function to determine time
// 1:1 conversion to js from webkit source files
// UnitBezier.h, WebCore_animation_AnimationBase.cpp
var CubicBezierAtTime = function CubicBezierAtTime(t, p1x, p1y, p2x, p2y, duration)
var CubicBezierAtTime = function(t, p1x, p1y, p2x, p2y, duration)
{
var ax = 0,
bx = 0,
+153 -73
View File
@@ -20,20 +20,26 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#import "../Foundation/CPRange.h"
@import <Foundation/CPBundle.j>
@import "CPCompatibility.j"
@import "CPColorPanel.j"
@import "CPCursor.j"
@import "CPDocumentController.j"
@import "CPEvent.j"
@import "CPMenu.j"
@import "CPResponder.j"
@import "CPDocumentController.j"
@import "CPThemeBlend.j"
@import "CPCibLoading.j"
@import "CPPanel.j"
@import "CPPlatform.j"
@import "CPWindowController.j"
var CPMainCibFile = @"CPMainCibFile",
CPMainCibFileHumanFriendly = @"Main cib file base name";
CPMainCibFileHumanFriendly = @"Main cib file base name",
CPEventModifierFlags = 0;
CPApp = nil;
@@ -83,6 +89,7 @@ CPRunContinuesResponse = -1002;
CPArray _eventListeners;
CPEvent _currentEvent;
CPWindow _lastMouseMoveWindow;
CPArray _windows;
CPWindow _keyWindow;
@@ -138,9 +145,7 @@ CPRunContinuesResponse = -1002;
{
_eventListeners = [];
_windows = [];
[_windows addObject:nil];
_windows = [[CPNull null]];
}
return self;
@@ -219,28 +224,22 @@ CPRunContinuesResponse = -1002;
// At this point we clear the window.status to eliminate Safari's "Cancelled" error message
// The message shouldn't be displayed, because only an XHR is cancelled, but it is a usability issue.
// We do it here so that applications can change it in willFinish or didFinishLaunching
#if PLATFORM(DOM)
window.status = " ";
#endif
// We also want to set the default cursor on the body, so that buttons and things don't have an iBeam
[[CPCursor arrowCursor] set];
var bundle = [CPBundle mainBundle],
types = [bundle objectForInfoDictionaryKey:@"CPBundleDocumentTypes"];
if ([types count] > 0)
_documentController = [CPDocumentController sharedDocumentController];
var delegateClassName = [bundle objectForInfoDictionaryKey:@"CPApplicationDelegateClass"];
delegateClassName = [bundle objectForInfoDictionaryKey:@"CPApplicationDelegateClass"];
if (delegateClassName)
{
var delegateClass = objj_getClass(delegateClassName);
if (delegateClass)
if ([_documentController class] == delegateClass)
[self setDelegate:_documentController];
else
[self setDelegate:[[delegateClass alloc] init]];
[self setDelegate:[[delegateClass alloc] init]];
}
var defaultCenter = [CPNotificationCenter defaultCenter];
@@ -249,13 +248,23 @@ CPRunContinuesResponse = -1002;
postNotificationName:CPApplicationWillFinishLaunchingNotification
object:self];
var types = [bundle objectForInfoDictionaryKey:@"CPBundleDocumentTypes"];
if ([types count] > 0)
_documentController = [CPDocumentController sharedDocumentController];
var needsUntitled = !!_documentController,
URLStrings = window.cpOpeningURLStrings && window.cpOpeningURLStrings(),
index = 0,
URLStrings = nil;
#if PLATFORM(DOM)
URLStrings = window.cpOpeningURLStrings && window.cpOpeningURLStrings();
#endif
var index = 0,
count = [URLStrings count];
for (; index < count; ++index)
needsUntitled = ![self _openURL:[CPURL URLWithString:URLStrings[index]]] || needsUntitled;
needsUntitled = ![self _openURL:[CPURL URLWithString:URLStrings[index]]] && needsUntitled;
if (needsUntitled && [_delegate respondsToSelector:@selector(applicationShouldOpenUntitledFile:)])
needsUntitled = [_delegate applicationShouldOpenUntitledFile:self];
@@ -338,7 +347,7 @@ CPRunContinuesResponse = -1002;
Copyright - Human readable copyright information.
</pre>
If you choose not the include any of the above keys, they will default
If you choose not the include any of the above keys, they will default
to the following respective keys in your info.plist file.
<pre>
@@ -374,7 +383,7 @@ CPRunContinuesResponse = -1002;
standardPath = [[CPBundle bundleForClass:[self class]] pathForResource:@"standardApplicationIcon.png"];
// FIXME move this into the CIB eventually
[applicationLabel setFont:[CPFont boldSystemFontOfSize:14.0]];
[applicationLabel setFont:[CPFont boldSystemFontOfSize:[CPFont systemFontSize] + 2]];
[applicationLabel setAlignment:CPCenterTextAlignment];
[versionLabel setAlignment:CPCenterTextAlignment];
[copyrightLabel setAlignment:CPCenterTextAlignment];
@@ -401,7 +410,7 @@ CPRunContinuesResponse = -1002;
}
- (void)_documentController:(NSDocumentController *)docController didCloseAll:(BOOL)didCloseAll context:(Object)info
- (void)_documentController:(CPDocumentController)docController didCloseAll:(BOOL)didCloseAll context:(Object)info
{
// callback method for terminate:
if (didCloseAll)
@@ -576,38 +585,60 @@ CPRunContinuesResponse = -1002;
- (void)sendEvent:(CPEvent)anEvent
{
_currentEvent = anEvent;
CPEventModifierFlags = [anEvent modifierFlags];
var willPropagate = [[[anEvent window] platformWindow] _willPropagateCurrentDOMEvent];
var theWindow = [anEvent window];
#if PLATFORM(DOM)
var willPropagate = [[theWindow platformWindow] _willPropagateCurrentDOMEvent];
// temporarily pretend we won't propagate the event. we'll restore the saved value later
// we do this outside the if so that changes user code might make in _handleKeyEquiv. are preserved
[[[anEvent window] platformWindow] _propagateCurrentDOMEvent:NO];
[[theWindow platformWindow] _propagateCurrentDOMEvent:NO];
#endif
// Check if this is a candidate for key equivalent...
if ([anEvent _couldBeKeyEquivalent] && [self _handleKeyEquivalent:anEvent])
{
#if PLATFORM(DOM)
var characters = [anEvent characters],
modifierFlags = [anEvent modifierFlags];
// Unconditionally propagate on these keys to solve browser copy paste bugs
if ((characters == "c" || characters == "x" || characters == "v") && (modifierFlags & CPPlatformActionKeyMask))
[[[anEvent window] platformWindow] _propagateCurrentDOMEvent:YES];
[[theWindow platformWindow] _propagateCurrentDOMEvent:YES];
#endif
return;
}
#if PLATFORM(DOM)
// if we make it this far, then restore the original willPropagate value
[[[anEvent window] platformWindow] _propagateCurrentDOMEvent:willPropagate];
[[theWindow platformWindow] _propagateCurrentDOMEvent:willPropagate];
#endif
if (_eventListeners.length)
{
if (_eventListeners[_eventListeners.length - 1]._mask & (1 << [anEvent type]))
_eventListeners.pop()._callback(anEvent);
{
var listener = _eventListeners.pop();
listener._callback(anEvent);
return;
if (listener._dequeue)
return;
}
}
[[anEvent window] sendEvent:anEvent];
if ([anEvent type] == CPMouseMoved)
{
if (theWindow !== _lastMouseMoveWindow)
[_lastMouseMoveWindow _mouseExitedResizeRect];
_lastMouseMoveWindow = theWindow;
}
if (theWindow)
[theWindow sendEvent:anEvent];
}
/*!
@@ -643,6 +674,10 @@ CPRunContinuesResponse = -1002;
*/
- (CPWindow)windowWithWindowNumber:(int)aWindowNumber
{
// Never allow _windows[0] to be returned - it's an internal CPNull placeholder.
if (!aWindowNumber)
return nil;
return _windows[aWindowNumber];
}
@@ -651,7 +686,8 @@ CPRunContinuesResponse = -1002;
*/
- (CPArray)windows
{
return _windows;
// Return all windows, but not the CPNull placeholder in _windows[0].
return [_windows subarrayWithRange:_CPMakeRange(1, [_windows count] - 1)];
}
/*!
@@ -879,31 +915,33 @@ CPRunContinuesResponse = -1002;
/*!
Fires a callback function when an event matching a given mask occurs.
@param aCallback - A js function to be fired.
@prarm aMask - An event mask for the next event.
@param anExpiration - The date for which this callback expires (not implemented).
@param aCallback A js function to be fired.
@prarm aMask An event mask for the next event.
@param anExpiration The date for which this callback expires (not implemented).
@param inMode (not implemented).
@param shouldDequeue (not implemented).
@param shouldDequeue YES to remove the event from the queue after calling the callback,
NO to deliver it normally.
*/
- (void)setCallback:(Function)aCallback forNextEventMatchingMask:(unsigned int)aMask untilDate:(CPDate)anExpiration inMode:(CPString)aMode dequeue:(BOOL)shouldDequeue
{
_eventListeners.push(_CPEventListenerMake(aMask, aCallback));
_eventListeners.push(_CPEventListenerMake(aMask, aCallback, shouldDequeue));
}
/*!
Assigns a target and action for the next event matching a given event mask.
The callback method called will be passed the CPEvent when it fires.
@param aTarget - The target object for the callback.
@param aSelector - The selector which should be called on the target object.
@param aMask - The mask for a given event which should trigger the callback.
@param anExpiration - The date for which the callback expires (not implemented).
@param aTarget The target object for the callback.
@param aSelector The selector which should be called on the target object.
@param aMask The mask for a given event which should trigger the callback.
@param anExpiration The date for which the callback expires (not implemented).
@param aMode (not implemented).
@param shouldDequeue (not implemented).
@param shouldDequeue YES to remove the event from the queue after calling the callback,
NO to deliver it normally.
*/
- (void)setTarget:(id)aTarget selector:(SEL)aSelector forNextEventMatchingMask:(unsigned int)aMask untilDate:(CPDate)anExpiration inMode:(CPString)aMode dequeue:(BOOL)shouldDequeue
{
_eventListeners.push(_CPEventListenerMake(aMask, function (anEvent) { objj_msgSend(aTarget, aSelector, anEvent); }));
_eventListeners.push(_CPEventListenerMake(aMask, function (anEvent) { objj_msgSend(aTarget, aSelector, anEvent); }, shouldDequeue));
}
/*!
@@ -926,15 +964,22 @@ CPRunContinuesResponse = -1002;
*/
- (void)beginSheet:(CPWindow)aSheet modalForWindow:(CPWindow)aWindow modalDelegate:(id)aModalDelegate didEndSelector:(SEL)aDidEndSelector contextInfo:(id)aContextInfo
{
var styleMask = [aSheet styleMask];
if (!(styleMask & CPDocModalWindowMask))
if ([aWindow isSheet])
{
[CPException raise:CPInternalInconsistencyException reason:@"Currently only CPDocModalWindowMask style mask is supported for attached sheets"];
[CPException raise:CPInternalInconsistencyException reason:@"The target window of beginSheet: cannot be a sheet"];
return;
}
[aWindow orderFront:self];
[aSheet setPlatformWindow:[aWindow platformWindow]];
[aSheet._windowView _enableSheet:YES];
// -dw- if a sheet is already visible, we skip this since it serves no purpose and causes
// orderOut: to be called on the sheet, which is not what we want.
if (![aWindow isVisible])
{
[aWindow orderFront:self];
[aSheet setPlatformWindow:[aWindow platformWindow]];
}
[aWindow _attachSheet:aSheet modalDelegate:aModalDelegate didEndSelector:aDidEndSelector contextInfo:aContextInfo];
}
@@ -963,7 +1008,7 @@ CPRunContinuesResponse = -1002;
if (context != nil && context["sheet"] === sheet)
{
context["returnCode"] = returnCode;
[aWindow _detachSheetWindow];
[aWindow _endSheet];
return;
}
}
@@ -996,14 +1041,15 @@ CPRunContinuesResponse = -1002;
*/
- (CPArray)arguments
{
if (_fullArgsString !== window.location.hash)
// FIXME This should probably not access the window object #if !PLATFORM(DOM), but the unit tests rely on it.
if (window && window.location && _fullArgsString !== window.location.hash)
[self _reloadArguments];
return _args;
}
/*!
Sets the arguments of your application.
Sets the arguments of your application.
That is, set the slash seperated values of an array as the window location hash.
For example if you pass an array:
@@ -1023,8 +1069,9 @@ CPRunContinuesResponse = -1002;
if (!args || args.length == 0)
{
_args = [];
window.location.hash = @"#";
// Don't use if PLATFORM(DOM) here - the unit test fakes window.location so we should play along.
if (window && window.location)
window.location.hash = @"#";
return;
}
@@ -1039,12 +1086,15 @@ CPRunContinuesResponse = -1002;
var hash = [toEncode componentsJoinedByString:@"/"];
window.location.hash = @"#" + hash;
// Don't use if PLATFORM(DOM) here - the unit test fakes window.location so we should play along.
if (window && window.location)
window.location.hash = @"#" + hash;
}
- (void)_reloadArguments
{
_fullArgsString = window.location.hash;
// FIXME This should probably not access the window object #if !PLATFORM(DOM), but the unit tests rely on it.
_fullArgsString = (window && window.location) ? window.location.hash : "";
if (_fullArgsString.length)
{
@@ -1158,7 +1208,7 @@ CPRunContinuesResponse = -1002;
+ (CPString)defaultThemeName
{
return ([[CPBundle mainBundle] objectForInfoDictionaryKey:"CPDefaultTheme"] || @"Aristo");
return ([[CPBundle mainBundle] objectForInfoDictionaryKey:"CPDefaultTheme"] || @"Aristo2");
}
@end
@@ -1166,24 +1216,32 @@ CPRunContinuesResponse = -1002;
var _CPModalSessionMake = function(aWindow, aStopCode)
{
return { _window:aWindow, _state:CPRunContinuesResponse , _previous:nil };
}
};
var _CPEventListenerMake = function(anEventMask, aCallback)
var _CPEventListenerMake = function(anEventMask, aCallback, shouldDequeue)
{
return { _mask:anEventMask, _callback:aCallback };
}
return { _mask:anEventMask, _callback:aCallback, _dequeue:shouldDequeue };
};
// Make this a global for use in CPPlatformWindow+DOM.j.
_CPRunModalLoop = function(anEvent)
{
[CPApp setCallback:_CPRunModalLoop forNextEventMatchingMask:CPAnyEventMask untilDate:nil inMode:0 dequeue:NO];
[CPApp setCallback:_CPRunModalLoop forNextEventMatchingMask:CPAnyEventMask untilDate:nil inMode:0 dequeue:YES];
var theWindow = [anEvent window],
modalSession = CPApp._currentSession;
if (theWindow == modalSession._window || [theWindow worksWhenModal])
/*
The special case for popovers here is not clear. In Cocoa the popover window does not respond YES to worksWhenModal, yet it works when there is a modal window. Maybe it starts its own modal session, but interaction with the original modal window seems to continue working as well. Regardless of correctness, this solution beats popovers not working at all from sheets.
*/
if (theWindow == modalSession._window ||
[theWindow worksWhenModal] ||
[theWindow attachedSheet] == modalSession._window || // -dw- allow modal parent of sheet to be repositioned
([theWindow isKindOfClass:_CPPopoverWindow] && [[theWindow targetView] window] === modalSession._window))
{
[theWindow sendEvent:anEvent];
}
}
};
/*!
Starts the GUI and Cappuccino frameworks. This function should be
@@ -1198,7 +1256,17 @@ function CPApplicationMain(args, namedArgs)
#if PLATFORM(DOM)
// hook to allow recorder, etc to manipulate things before starting AppKit
if (window.parent !== window && typeof window.parent._childAppIsStarting === "function")
window.parent._childAppIsStarting(window);
{
try
{
window.parent._childAppIsStarting(window);
}
catch(err)
{
// This could happen if we're in an iframe without access to the parent frame.
CPLog.warn("Failed to call parent frame's _childAppIsStarting().");
}
}
#endif
var mainBundle = [CPBundle mainBundle],
@@ -1255,7 +1323,7 @@ var _CPAppBootstrapperActions = nil;
var defaultThemeName = [CPApplication defaultThemeName],
themeURL = nil;
if (defaultThemeName === @"Aristo")
if (defaultThemeName === @"Aristo" || defaultThemeName === @"Aristo2")
themeURL = [[CPBundle bundleForClass:[CPApplication class]] pathForResource:defaultThemeName + @".blend"];
else
themeURL = [[CPBundle mainBundle] pathForResource:defaultThemeName + @".blend"];
@@ -1300,26 +1368,25 @@ var _CPAppBootstrapperActions = nil;
// FIXME: We should implement autoenabling.
[mainMenu setAutoenablesItems:NO];
var bundle = [CPBundle bundleForClass:[CPApplication class]],
newMenuItem = [[CPMenuItem alloc] initWithTitle:@"New" action:@selector(newDocument:) keyEquivalent:@"n"];
var newMenuItem = [[CPMenuItem alloc] initWithTitle:@"New" action:@selector(newDocument:) keyEquivalent:@"n"];
[newMenuItem setImage:[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPApplication/New.png"] size:CGSizeMake(16.0, 16.0)]];
[newMenuItem setAlternateImage:[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPApplication/NewHighlighted.png"] size:CGSizeMake(16.0, 16.0)]];
[newMenuItem setImage:[[CPTheme defaultTheme] valueForAttributeWithName:@"menu-general-icon-new" forClass:_CPMenuView]];
[newMenuItem setAlternateImage:[[CPTheme defaultTheme] valueForAttributeWithName:@"menu-general-icon-new" inState:CPThemeStateHighlighted forClass:_CPMenuView]];
[mainMenu addItem:newMenuItem];
var openMenuItem = [[CPMenuItem alloc] initWithTitle:@"Open" action:@selector(openDocument:) keyEquivalent:@"o"];
[openMenuItem setImage:[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPApplication/Open.png"] size:CGSizeMake(16.0, 16.0)]];
[openMenuItem setAlternateImage:[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPApplication/OpenHighlighted.png"] size:CGSizeMake(16.0, 16.0)]];
[openMenuItem setImage:[[CPTheme defaultTheme] valueForAttributeWithName:@"menu-general-icon-open" forClass:_CPMenuView]];
[openMenuItem setAlternateImage:[[CPTheme defaultTheme] valueForAttributeWithName:@"menu-general-icon-open" inState:CPThemeStateHighlighted forClass:_CPMenuView]];
[mainMenu addItem:openMenuItem];
var saveMenu = [[CPMenu alloc] initWithTitle:@"Save"],
saveMenuItem = [[CPMenuItem alloc] initWithTitle:@"Save" action:@selector(saveDocument:) keyEquivalent:nil];
[saveMenuItem setImage:[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPApplication/Save.png"] size:CGSizeMake(16.0, 16.0)]];
[saveMenuItem setAlternateImage:[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPApplication/SaveHighlighted.png"] size:CGSizeMake(16.0, 16.0)]];
[saveMenuItem setImage:[[CPTheme defaultTheme] valueForAttributeWithName:@"menu-general-icon-save" forClass:_CPMenuView]];
[saveMenuItem setAlternateImage:[[CPTheme defaultTheme] valueForAttributeWithName:@"menu-general-icon-save" inState:CPThemeStateHighlighted forClass:_CPMenuView]];
[saveMenu addItem:[[CPMenuItem alloc] initWithTitle:@"Save" action:@selector(saveDocument:) keyEquivalent:@"s"]];
[saveMenu addItem:[[CPMenuItem alloc] initWithTitle:@"Save As" action:@selector(saveDocumentAs:) keyEquivalent:nil]];
@@ -1340,8 +1407,8 @@ var _CPAppBootstrapperActions = nil;
[editMenu addItem:undoMenuItem];
[editMenu addItem:redoMenuItem];
[editMenu addItem:[[CPMenuItem alloc] initWithTitle:@"Cut" action:@selector(cut:) keyEquivalent:@"x"]],
[editMenu addItem:[[CPMenuItem alloc] initWithTitle:@"Copy" action:@selector(copy:) keyEquivalent:@"c"]],
[editMenu addItem:[[CPMenuItem alloc] initWithTitle:@"Cut" action:@selector(cut:) keyEquivalent:@"x"]];
[editMenu addItem:[[CPMenuItem alloc] initWithTitle:@"Copy" action:@selector(copy:) keyEquivalent:@"c"]];
[editMenu addItem:[[CPMenuItem alloc] initWithTitle:@"Paste" action:@selector(paste:) keyEquivalent:@"v"]];
[editMenuItem setSubmenu:editMenu];
@@ -1370,3 +1437,16 @@ var _CPAppBootstrapperActions = nil;
}
@end
@implementation CPEvent (CPApplicationModifierFlags)
/*!
Returns the currently pressed modifier flags.
*/
+ (unsigned)modifierFlags
{
return CPEventModifierFlags;
}
@end
+102 -42
View File
@@ -564,8 +564,9 @@
- (BOOL)setSelectionIndexes:(CPIndexSet)indexes
{
[self _selectionWillChange]
[self __setSelectionIndexes:indexes];
var r = [self __setSelectionIndexes:indexes avoidEmpty:NO];
[self _selectionDidChange];
return r;
}
/*
@@ -574,7 +575,7 @@
*/
- (BOOL)__setSelectionIndex:(int)theIndex
{
[self __setSelectionIndexes:[CPIndexSet indexSetWithIndex:theIndex]];
return [self __setSelectionIndexes:[CPIndexSet indexSetWithIndex:theIndex]];
}
/*
@@ -583,28 +584,43 @@
*/
- (BOOL)__setSelectionIndexes:(CPIndexSet)indexes
{
if (!indexes)
indexes = [CPIndexSet indexSet];
return [self __setSelectionIndexes:indexes avoidEmpty:_avoidsEmptySelection];
}
if (![indexes count])
- (BOOL)__setSelectionIndexes:(CPIndexSet)indexes avoidEmpty:(BOOL)avoidEmpty
{
var newIndexes = indexes;
if (!newIndexes)
newIndexes = [CPIndexSet indexSet];
if (![newIndexes count])
{
if (_avoidsEmptySelection && [[self arrangedObjects] count])
indexes = [CPIndexSet indexSetWithIndex:0];
if (avoidEmpty && [[self arrangedObjects] count])
newIndexes = [CPIndexSet indexSetWithIndex:0];
}
else
{
var objectsCount = [[self arrangedObjects] count];
// Don't trash the input - the caller might depend on it or we might have been
// given _selectionIndexes as the input in which case the equality test below
// would always succeed despite our change below.
newIndexes = [newIndexes copy];
// Remove out of bounds indexes.
[indexes removeIndexesInRange:CPMakeRange(objectsCount, [indexes lastIndex] + 1)];
[newIndexes removeIndexesInRange:CPMakeRange(objectsCount, [newIndexes lastIndex] + 1)];
// When avoiding empty selection and the deleted selection was at the bottom, select the last item.
if (![indexes count] && _avoidsEmptySelection && objectsCount)
indexes = [CPIndexSet indexSetWithIndex:objectsCount - 1];
if (![newIndexes count] && avoidEmpty && objectsCount)
newIndexes = [CPIndexSet indexSetWithIndex:objectsCount - 1];
}
if ([_selectionIndexes isEqualToIndexSet:indexes])
if ([_selectionIndexes isEqualToIndexSet:newIndexes])
return NO;
_selectionIndexes = [indexes copy];
// If we haven't already created our own index instance, make sure to copy it here so that
// the copy the user sent in is decoupled from our internal copy.
_selectionIndexes = indexes === newIndexes ? [indexes copy] : newIndexes;
// Push back the new selection to the model for selectionIndexes if we have one.
// There won't be an infinite loop because of the equality check above.
@@ -636,10 +652,11 @@
[self willChangeValueForKey:@"selectionIndexes"];
[self _selectionWillChange];
[self __setSelectedObjects:objects];
var r = [self __setSelectedObjects:objects avoidEmpty:NO];
[self didChangeValueForKey:@"selectionIndexes"];
[self _selectionDidChange];
return r;
}
/*
@@ -647,6 +664,11 @@
@ignore
*/
- (BOOL)__setSelectedObjects:(CPArray)objects
{
[self __setSelectedObjects:objects avoidEmpty:_avoidsEmptySelection];
}
- (BOOL)__setSelectedObjects:(CPArray)objects avoidEmpty:(BOOL)avoidEmpty
{
var set = [CPIndexSet indexSet],
count = [objects count],
@@ -660,7 +682,7 @@
[set addIndex:index];
}
[self __setSelectionIndexes:set];
[self __setSelectionIndexes:set avoidEmpty:avoidEmpty];
return YES;
}
@@ -857,6 +879,9 @@
[_arrangedObjects removeObjectAtIndex:pos];
[_selectionIndexes shiftIndexesStartingAtIndex:pos by:-1];
// This will automatically handle the avoidsEmptySelection case.
[self __setSelectionIndexes:_selectionIndexes];
}
[self didChangeValueForKey:@"content"];
@@ -898,6 +923,15 @@
[self removeObjectsAtArrangedObjectIndexes:_selectionIndexes];
}
/*!
Removes the object at the specified index in the controller's arranged objects from the content array.
@param int index - index of the object to remove.
*/
- (void)removeObjectAtArrangedObjectIndex:(int)index
{
[self removeObjectsAtArrangedObjectIndexes:[CPIndexSet indexSetWithIndex:index]];
}
/*!
Removes the objects at the specified indexes in the controller's arranged objects from the content array.
@param CPIndexSet indexes - indexes of the objects to remove.
@@ -912,36 +946,38 @@
_disableSetContent = YES;
var arrangedObjects = [self arrangedObjects],
index = [anIndexSet lastIndex],
position = CPNotFound,
newSelectionIndexes = [_selectionIndexes copy];
while (index !== CPNotFound)
{
var object = [arrangedObjects objectAtIndex:index];
// First try the simple case which should work if there are no sort descriptors.
if ([_contentObject objectAtIndex:index] === object)
[_contentObject removeObjectAtIndex:index];
else
[anIndexSet enumerateIndexesWithOptions:CPEnumerationReverse
usingBlock:function(anIndex)
{
// Since we don't have a reverse mapping between the sorted order and the
// unsorted one, we'll just simply have to remove an arbitrary pointer. It might
// be the 'wrong' one - as in not the one the user selected - but the wrong
// one is still just another pointer to the same object, so the user will not
// be able to see any difference.
contentIndex = [_contentObject indexOfObjectIdenticalTo:object];
[_contentObject removeObjectAtIndex:contentIndex];
}
[arrangedObjects removeObjectAtIndex:index];
var object = [arrangedObjects objectAtIndex:anIndex];
// Deselect this row if it was selected, and either way shift all selection indexes
// following it up by 1.
[newSelectionIndexes removeIndex:index];
[newSelectionIndexes shiftIndexesStartingAtIndex:index by:-1];
// First try the simple case which should work if there are no sort descriptors.
if ([_contentObject objectAtIndex:anIndex] === object)
[_contentObject removeObjectAtIndex:anIndex];
else
{
// Since we don't have a reverse mapping between the sorted order and the
// unsorted one, we'll just simply have to remove an arbitrary pointer. It might
// be the 'wrong' one - as in not the one the user selected - but the wrong
// one is still just another pointer to the same object, so the user will not
// be able to see any difference.
var contentIndex = [_contentObject indexOfObjectIdenticalTo:object];
[_contentObject removeObjectAtIndex:contentIndex];
}
[arrangedObjects removeObjectAtIndex:anIndex];
if (!_avoidsEmptySelection || [newSelectionIndexes count] > 1)
{
[newSelectionIndexes removeIndex:anIndex];
[newSelectionIndexes shiftIndexesStartingAtIndex:anIndex by:-1];
}
else if ([newSelectionIndexes lastIndex] !== anIndex)
[newSelectionIndexes shiftIndexesStartingAtIndex:anIndex by:-1];
}];
index = [anIndexSet indexLessThanIndex:index];
}
// Allow handlesContentAsCompoundValue reverse sets to trigger.
[[CPBinder getBinding:@"contentArray" forObject:self] _contentArrayDidChange];
_disableSetContent = NO;
@@ -1054,22 +1090,46 @@
var destination = [_info objectForKey:CPObservedObjectKey],
keyPath = [_info objectForKey:CPObservedKeyPathKey],
options = [_info objectForKey:CPOptionsKey],
isCompound = [self handlesContentAsCompoundValue];
isCompound = [self handlesContentAsCompoundValue],
dotIndex = keyPath.lastIndexOf("."),
firstPart = dotIndex !== CPNotFound ? keyPath.substring(0, dotIndex) : nil,
isSelectionProxy = firstPart && [[destination valueForKeyPath:firstPart] isKindOfClass:CPControllerSelectionProxy],
newValue;
if (!isCompound)
if (!isCompound && !isSelectionProxy)
{
newValue = [destination mutableArrayValueForKeyPath:keyPath];
}
else
{
// handlesContentAsCompoundValue == YES so we cannot just set up a proxy.
// 1. If handlesContentAsCompoundValue we cannot just set up a proxy.
// Every read and every write must go through transformValue and
// reverseTransformValue, and the resulting object cannot be described by
// a key path.
// 2. If isSelectionProxy, we don't want to proxy a proxy - that's bad
// for performance and won't work with markers.
newValue = [destination valueForKeyPath:keyPath];
}
newValue = [self transformValue:newValue withOptions:options];
var isPlaceholder = CPIsControllerMarker(newValue);
if (isPlaceholder)
{
if (newValue === CPNotApplicableMarker && [options objectForKey:CPRaisesForNotApplicableKeysBindingOption])
{
[CPException raise:CPGenericException
reason:@"can't transform non applicable key on: " + _source + " value: " + newValue];
}
newValue = [self _placeholderForMarker:newValue];
// This seems to be what Cocoa does.
if (!newValue)
newValue = [CPMutableArray array];
}
else
newValue = [self transformValue:newValue withOptions:options];
if (isCompound)
{
+36 -2
View File
@@ -20,7 +20,6 @@
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
* Copyright 2009 280 North, Inc.
*/
@import <Foundation/CPObject.j>
@@ -166,6 +165,19 @@ var DefaultLineWidth = 1.0;
CGPathAddCurveToPoint(_path, nil, controlPoint1.x, controlPoint1.y, controlPoint2.x, controlPoint2.y, endPoint.x, endPoint.y);
}
- (CGRect)bounds
{
// TODO: this should return this. The controlPointBounds is not a tight fit.
// return CGPathGetPathBoundingBox(_path);
return [self controlPointBounds];
}
- (CGRect)controlPointBounds
{
return CGPathGetBoundingBox(_path);
}
/*!
Create a line segment between the first and last points in the subpath, closing it.
*/
@@ -273,10 +285,15 @@ var DefaultLineWidth = 1.0;
CGPathAddPath(_path, nil, CGPathWithRoundedRectangleInRect(rect, xRadius, yRadius, YES, YES, YES, YES));
}
- (void)appendBezierPathWithArcFromPoint:(CGPoint)fromPoint toPoint:(CGPoint)toPoint radius:(float)radius
{
CGPathAddArcToPoint(_path, null, fromPoint.x, fromPoint.y, toPoint.x, toPoint.y, radius);
}
/*!
Append the contents of a CPBezierPath object.
*/
- (void)appendBezierPath:(NSBezierPath *)other
- (void)appendBezierPath:(CPBezierPath)other
{
CGPathAddPath(_path, nil, other._path);
}
@@ -289,4 +306,21 @@ var DefaultLineWidth = 1.0;
_path = CGPathCreateMutable();
}
- (void)addClip
{
var ctx = [[CPGraphicsContext currentContext] graphicsPort];
CGContextAddPath(ctx, _path);
CGContextClip(ctx);
}
- (void)setClip
{
var ctx = [[CPGraphicsContext currentContext] graphicsPort];
CGContextBeginPath(ctx);
CGContextAddPath(ctx, _path);
CGContextClip(ctx);
}
@end
+237 -92
View File
@@ -20,6 +20,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "CPTextField.j"
@import "CPView.j"
// CPBoxType
@@ -35,6 +36,16 @@ CPLineBorder = 1;
CPBezelBorder = 2;
CPGrooveBorder = 3;
// CPTitlePosition
CPNoTitle = 0;
CPAboveTop = 1;
CPAtTop = 2;
CPBelowTop = 3;
CPAboveBottom = 4;
CPAtBottom = 5;
CPBelowBottom = 6;
/*!
@ingroup appkit
@class CPBox
@@ -45,15 +56,11 @@ CPGrooveBorder = 3;
{
CPBoxType _boxType;
CPBorderType _borderType;
CPColor _borderColor;
CPColor _fillColor;
float _cornerRadius;
float _borderWidth;
CPSize _contentMargin;
CPView _contentView;
CPString _title @accessors(getter=title);
int _titlePosition @accessors(getter=titlePosition);
CPTextField _titleView;
}
+ (id)boxEnclosingView:(CPView)aView
@@ -61,7 +68,7 @@ CPGrooveBorder = 3;
var box = [[self alloc] initWithFrame:CGRectMakeZero()],
enclosingView = [aView superview];
[box setAutoresizingMask:[aView autoresizingMask]];
[box setAutoresizingMask:[aView autoresizingMask]];
[box setFrameFromContentFrame:[aView frame]];
[enclosingView replaceSubview:aView with:box];
@@ -71,18 +78,34 @@ CPGrooveBorder = 3;
return box;
}
- (id)initWithFrame:(CPRect)frameRect
+ (CPString)defaultThemeClass
{
return @"box";
}
+ (id)themeAttributes
{
return [CPDictionary dictionaryWithObjects:[[CPNull null], [CPNull null], 1.0, 3.0, CGSizeMakeZero(), 6.0, [CPNull null], CGSizeMakeZero()]
forKeys:[ @"background-color",
@"border-color",
@"border-width",
@"corner-radius",
@"inner-shadow-offset",
@"inner-shadow-size",
@"inner-shadow-color",
@"content-margin"]];
}
- (id)initWithFrame:(CGRect)frameRect
{
self = [super initWithFrame:frameRect];
if (self)
{
_borderType = CPBezelBorder;
_fillColor = [CPColor clearColor];
_borderColor = [CPColor blackColor];
_borderWidth = 1.0;
_contentMargin = CGSizeMake(0.0, 0.0);
_titlePosition = CPNoTitle;
_titleView = [CPTextField labelWithTitle:@""];
_contentView = [[CPView alloc] initWithFrame:[self bounds]];
[_contentView setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
@@ -101,7 +124,7 @@ CPGrooveBorder = 3;
@return the border rectangle of the box
*/
- (CPRect)borderRect
- (CGRect)borderRect
{
return [self bounds];
}
@@ -191,58 +214,54 @@ CPGrooveBorder = 3;
- (CPColor)borderColor
{
return _borderColor;
return [self valueForThemeAttribute:@"border-color"];
}
- (void)setBorderColor:(CPColor)color
{
if ([color isEqual:_borderColor])
if ([color isEqual:[self borderColor]])
return;
_borderColor = color;
[self setNeedsDisplay:YES];
[self setValue:color forThemeAttribute:@"border-color"];
}
- (float)borderWidth
{
return _borderWidth;
return [self valueForThemeAttribute:@"border-width"];
}
- (void)setBorderWidth:(float)width
{
if (width === _borderWidth)
if (width === [self borderWidth])
return;
_borderWidth = width;
[self setNeedsDisplay:YES];
[self setValue:width forThemeAttribute:@"border-width"];
}
- (float)cornerRadius
{
return _cornerRadius;
return [self valueForThemeAttribute:@"corner-radius"];
}
- (void)setCornerRadius:(float)radius
{
if (radius === _cornerRadius)
if (radius === [self cornerRadius])
return;
_cornerRadius = radius;
[self setNeedsDisplay:YES];
[self setValue:radius forThemeAttribute:@"corner-radius"];
}
- (CPColor)fillColor
{
return _fillColor;
return [self valueForThemeAttribute:@"background-color"];
}
- (void)setFillColor:(CPColor)color
{
if ([color isEqual:_fillColor])
if ([color isEqual:[self fillColor]])
return;
_fillColor = color;
[self setNeedsDisplay:YES];
[self setValue:color forThemeAttribute:@"background-color"];
}
- (CPView)contentView
@@ -255,49 +274,146 @@ CPGrooveBorder = 3;
if (aView === _contentView)
return;
[aView setFrame:CGRectInset([self bounds], _contentMargin.width + _borderWidth, _contentMargin.height + _borderWidth)];
var borderWidth = [self borderWidth],
contentMargin = [self valueForThemeAttribute:@"content-margin"];
[aView setFrame:CGRectInset([self bounds], contentMargin.width + borderWidth, contentMargin.height + borderWidth)];
[aView setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
[self replaceSubview:_contentView with:aView];
_contentView = aView;
}
- (CPSize)contentViewMargins
- (CGSize)contentViewMargins
{
return _contentMargin;
return [self valueForThemeAttribute:@"content-margin"];
}
- (void)setContentViewMargins:(CPSize)size
- (void)setContentViewMargins:(CGSize)size
{
if (size.width < 0 || size.height < 0)
[CPException raise:CPGenericException reason:@"Margins must be positive"];
_contentMargin = CGSizeMakeCopy(size);
[self setNeedsDisplay:YES];
[self setValue:CGSizeMakeCopy(size) forThemeAttribute:@"content-margin"];
}
- (void)setFrameFromContentFrame:(CPRect)aRect
- (void)setFrameFromContentFrame:(CGRect)aRect
{
[self setFrame:CGRectInset(aRect, -(_contentMargin.width + _borderWidth), -(_contentMargin.height + _borderWidth))];
var offset = [self _titleHeightOffset],
borderWidth = [self borderWidth],
contentMargin = [self valueForThemeAttribute:@"content-margin"];
[self setFrame:CGRectInset(aRect, -(contentMargin.width + borderWidth), -(contentMargin.height + offset[0] + borderWidth))];
}
- (void)setTitle:(CPString)aTitle
{
if (aTitle == _title)
return;
_title = aTitle;
[self _manageTitlePositioning];
}
- (void)setTitlePosition:(int)aTitlePotisition
{
if (aTitlePotisition == _titlePosition)
return;
_titlePosition = aTitlePotisition;
[self _manageTitlePositioning];
}
- (CPFont)titleFont
{
return [_titleView font];
}
- (void)setTitleFont:(CPFont)aFont
{
[_titleView setFont:aFont];
}
/*!
Return the text field used to display the receiver's title.
This is the Cappuccino equivalent to the `titleCell` method.
*/
- (CPTextField)titleView
{
return _titleView;
}
- (void)_manageTitlePositioning
{
if (_titlePosition == CPNoTitle)
{
[_titleView removeFromSuperview];
[self setNeedsDisplay:YES];
return;
}
[_titleView setStringValue:_title];
[_titleView sizeToFit];
[self addSubview:_titleView];
switch (_titlePosition)
{
case CPAtTop:
case CPAboveTop:
case CPBelowTop:
[_titleView setFrameOrigin:CGPointMake(5.0, 0.0)];
[_titleView setAutoresizingMask:CPViewNotSizable];
break;
case CPAboveBottom:
case CPAtBottom:
case CPBelowBottom:
var h = [_titleView frameSize].height;
[_titleView setFrameOrigin:CGPointMake(5.0, [self frameSize].height - h)];
[_titleView setAutoresizingMask:CPViewMinYMargin];
break;
}
[self sizeToFit];
[self setNeedsDisplay:YES];
}
- (void)sizeToFit
{
var contentFrame = [_contentView frame];
var contentFrame = [_contentView frame],
offset = [self _titleHeightOffset],
contentMargin = [self valueForThemeAttribute:@"content-margin"];
[self setFrameSize:CGSizeMake(contentFrame.size.width + _contentMargin.width * 2,
contentFrame.size.height + _contentMargin.height * 2)];
[_contentView setFrameOrigin:CGPointMake(_contentMargin.width, _contentMargin.height)];
}
- (void)drawRect:(CPRect)rect
{
if (_borderType === CPNoBorder)
if (!contentFrame)
return;
var bounds = [self bounds];
[_contentView setFrameOrigin:CGPointMake(contentMargin.width, contentMargin.height + offset[1])];
}
- (float)_titleHeightOffset
{
if (_titlePosition == CPNoTitle)
return [0.0, 0.0];
switch (_titlePosition)
{
case CPAtTop:
return [[_titleView frameSize].height, [_titleView frameSize].height];
case CPAtBottom:
return [[_titleView frameSize].height, 0.0];
default:
return [0.0, 0.0];
}
}
- (void)drawRect:(CGRect)rect
{
var bounds = CGRectMakeCopy([self bounds]);
switch (_boxType)
{
@@ -312,16 +428,30 @@ CPGrooveBorder = 3;
break;
}
if (_titlePosition == CPAtTop)
{
bounds.origin.y += [_titleView frameSize].height;
bounds.size.height -= [_titleView frameSize].height;
}
if (_titlePosition == CPAtBottom)
{
bounds.size.height -= [_titleView frameSize].height;
}
switch (_borderType)
{
case CPBezelBorder:
[self _drawBezelBorderInRect:bounds];
break;
default:
case CPGrooveBorder:
case CPLineBorder:
[self _drawLineBorderInRect:bounds];
break;
case CPNoBorder:
[self _drawNoBorderInRect:bounds];
break;
}
}
@@ -332,8 +462,8 @@ CPGrooveBorder = 3;
CGContextSetStrokeColor(context, [self borderColor]);
CGContextSetLineWidth(context, 1.0);
CGContextMoveToPoint(context, CGRectGetMinX(aRect), CGRectGetMinY(aRect) + 0.5);
CGContextAddLineToPoint(context, CGRectGetWidth(aRect), CGRectGetMinY(aRect) + 0.5);
CGContextMoveToPoint(context, CGRectGetMinX(aRect), CGRectGetMidY(aRect));
CGContextAddLineToPoint(context, CGRectGetWidth(aRect), CGRectGetMidY(aRect));
CGContextStrokePath(context);
}
@@ -344,49 +474,71 @@ CPGrooveBorder = 3;
CGContextSetStrokeColor(context, [self borderColor]);
CGContextSetLineWidth(context, 1.0);
CGContextMoveToPoint(context, CGRectGetMinX(aRect) + 0.5, CGRectGetMinY(aRect));
CGContextAddLineToPoint(context, CGRectGetMinX(aRect) + 0.5, CGRectGetHeight(aRect));
CGContextMoveToPoint(context, CGRectGetMidX(aRect), CGRectGetMinY(aRect));
CGContextAddLineToPoint(context, CGRectGetMidX(aRect), CGRectGetHeight(aRect));
CGContextStrokePath(context);
}
- (void)_drawLineBorderInRect:(CGRect)aRect
{
var context = [[CPGraphicsContext currentContext] graphicsPort],
cornerRadius = [self cornerRadius],
borderWidth = [self borderWidth];
aRect = CGRectInset(aRect, borderWidth / 2.0, borderWidth / 2.0);
CGContextSetFillColor(context, [self fillColor]);
CGContextSetStrokeColor(context, [self borderColor]);
CGContextSetLineWidth(context, borderWidth);
CGContextFillRoundedRectangleInRect(context, aRect, cornerRadius, YES, YES, YES, YES);
CGContextStrokeRoundedRectangleInRect(context, aRect, cornerRadius, YES, YES, YES, YES);
}
- (void)_drawBezelBorderInRect:(CGRect)aRect
{
var context = [[CPGraphicsContext currentContext] graphicsPort],
sides = [CPMinYEdge, CPMaxXEdge, CPMaxYEdge, CPMinXEdge],
sideGray = 190.0 / 255.0,
grays = [142.0 / 255.0, sideGray, sideGray, sideGray],
borderWidth = _borderWidth;
cornerRadius = [self cornerRadius],
borderWidth = [self borderWidth],
shadowOffset = [self valueForThemeAttribute:@"inner-shadow-offset"],
shadowSize = [self valueForThemeAttribute:@"inner-shadow-size"],
shadowColor = [self valueForThemeAttribute:@"inner-shadow-color"];
while (borderWidth--)
aRect = CPDrawTiledRects(aRect, aRect, sides, grays);
aRect = CGRectInset(aRect, borderWidth / 2.0, borderWidth / 2.0);
// clip the canvas to the actual content view in order to only display inner shadow
CGContextBeginPath(context);
CGContextAddPath(context, CGPathWithRoundedRectangleInRect(aRect, cornerRadius, cornerRadius, YES, YES, YES, YES));
CGContextClip(context);
CGContextSetFillColor(context, [self fillColor]);
CGContextSetStrokeColor(context, [self borderColor]);
CGContextSetShadowWithColor(context, shadowOffset, shadowSize, shadowColor);
CGContextSetLineWidth(context, borderWidth);
CGContextFillRoundedRectangleInRect(context, aRect, cornerRadius, YES, YES, YES, YES);
CGContextStrokeRoundedRectangleInRect(context, aRect, cornerRadius, YES, YES, YES, YES);
}
- (void)_drawNoBorderInRect:(CGRect)aRect
{
var context = [[CPGraphicsContext currentContext] graphicsPort];
CGContextSetFillColor(context, [self fillColor]);
CGContextFillRect(context, aRect);
}
- (void)_drawLineBorderInRect:(CGRect)aRect
{
var context = [[CPGraphicsContext currentContext] graphicsPort];
aRect = CGRectInset(aRect, _borderWidth / 2.0, _borderWidth / 2.0);
CGContextSetFillColor(context, [self fillColor]);
CGContextSetStrokeColor(context, [self borderColor]);
CGContextSetLineWidth(context, _borderWidth);
CGContextFillRoundedRectangleInRect(context, aRect, _cornerRadius, YES, YES, YES, YES);
CGContextStrokeRoundedRectangleInRect(context, aRect, _cornerRadius, YES, YES, YES, YES);
}
@end
var CPBoxTypeKey = @"CPBoxTypeKey",
CPBoxBorderTypeKey = @"CPBoxBorderTypeKey",
CPBoxBorderColorKey = @"CPBoxBorderColorKey",
CPBoxFillColorKey = @"CPBoxFillColorKey",
CPBoxCornerRadiusKey = @"CPBoxCornerRadiusKey",
CPBoxBorderWidthKey = @"CPBoxBorderWidthKey",
CPBoxContentMarginKey = @"CPBoxContentMarginKey";
CPBoxTitle = @"CPBoxTitle",
CPBoxTitlePosition = @"CPBoxTitlePosition",
CPBoxTitleView = @"CPBoxTitleView";
@implementation CPBox (CPCoding)
@@ -399,18 +551,16 @@ var CPBoxTypeKey = @"CPBoxTypeKey",
_boxType = [aCoder decodeIntForKey:CPBoxTypeKey];
_borderType = [aCoder decodeIntForKey:CPBoxBorderTypeKey];
_borderColor = [aCoder decodeObjectForKey:CPBoxBorderColorKey];
_fillColor = [aCoder decodeObjectForKey:CPBoxFillColorKey];
_cornerRadius = [aCoder decodeFloatForKey:CPBoxCornerRadiusKey];
_borderWidth = [aCoder decodeFloatForKey:CPBoxBorderWidthKey];
_contentMargin = [aCoder decodeSizeForKey:CPBoxContentMarginKey];
_title = [aCoder decodeObjectForKey:CPBoxTitle];
_titlePosition = [aCoder decodeIntForKey:CPBoxTitlePosition];
_titleView = [aCoder decodeObjectForKey:CPBoxTitleView] || [CPTextField labelWithTitle:_title];
_contentView = [self subviews][0];
[self setAutoresizesSubviews:YES];
[_contentView setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
[self _manageTitlePositioning];
}
return self;
@@ -422,14 +572,9 @@ var CPBoxTypeKey = @"CPBoxTypeKey",
[aCoder encodeInt:_boxType forKey:CPBoxTypeKey];
[aCoder encodeInt:_borderType forKey:CPBoxBorderTypeKey];
[aCoder encodeObject:_borderColor forKey:CPBoxBorderColorKey];
[aCoder encodeObject:_fillColor forKey:CPBoxFillColorKey];
[aCoder encodeFloat:_cornerRadius forKey:CPBoxCornerRadiusKey];
[aCoder encodeFloat:_borderWidth forKey:CPBoxBorderWidthKey];
[aCoder encodeSize:_contentMargin forKey:CPBoxContentMarginKey];
[aCoder encodeObject:_title forKey:CPBoxTitle];
[aCoder encodeInt:_titlePosition forKey:CPBoxTitlePosition];
[aCoder encodeObject:_titleView forKey:CPBoxTitleView];
}
@end
+28 -31
View File
@@ -24,15 +24,16 @@
@import "CPControl.j"
@import "CPImage.j"
@import "CPScrollView.j"
@import "CPTableView.j"
@import "CPTextField.j"
@import "CPScrollView.j"
@global CPApp
/*!
@ingroup appkit
@class CPBrowser
*/
@implementation CPBrowser : CPControl
{
id _delegate;
@@ -65,18 +66,18 @@
CPArray _columnWidths;
}
+ (CPImage)branchImage
+ (CPString)defaultThemeClass
{
return [[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:[CPBrowser class]]
pathForResource:"browser-leaf.png"]
size:CGSizeMake(9,9)];
return "browser";
}
+ (CPImage)highlightedBranchImage
+ (id)themeAttributes
{
return [[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:[CPBrowser class]]
pathForResource:"browser-leaf-highlighted.png"]
size:CGSizeMake(9,9)];
return [CPDictionary dictionaryWithJSObject:{
@"image-control-resize": [CPNull null],
@"image-control-leaf": [CPNull null],
@"image-control-leaf-pressed": [CPNull null]
}];
}
- (id)initWithFrame:(CGRect)aFrame
@@ -258,7 +259,7 @@
var column = [[CPTableColumn alloc] initWithIdentifier:@"Image"],
view = [[CPImageView alloc] initWithFrame:CGRectMakeZero()];
[view setImageScaling:CPScaleProportionally];
[view setImageScaling:CPImageScaleProportionallyDown];
[column setDataView:view];
[column setResizingMask:CPTableColumnNoResizing];
@@ -276,8 +277,8 @@
var column = [[CPTableColumn alloc] initWithIdentifier:@"Leaf"],
view = [[_CPBrowserLeafView alloc] initWithFrame:CGRectMakeZero()];
[view setBranchImage:[[self class] branchImage]];
[view setHighlightedBranchImage:[[self class] highlightedBranchImage]];
[view setBranchImage:[self valueForThemeAttribute:@"image-control-leaf"]];
[view setHighlightedBranchImage:[self valueForThemeAttribute:@"image-control-leaf-pressed"]];
[column setDataView:view];
[column setResizingMask:CPTableColumnNoResizing];
@@ -704,8 +705,6 @@
@end
var _CPBrowserResizeControlBackgroundImage = nil;
@implementation _CPBrowserResizeControl : CPView
{
CGPoint _mouseDownX;
@@ -714,22 +713,14 @@ var _CPBrowserResizeControlBackgroundImage = nil;
unsigned _width;
}
+ (CPImage)backgroundImage
{
if (!_CPBrowserResizeControlBackgroundImage)
{
var path = [[CPBundle bundleForClass:[self class]] pathForResource:"browser-resize-control.png"];
_CPBrowserResizeControlBackgroundImage = [[CPImage alloc] initWithContentsOfFile:path
size:CGSizeMake(15, 14)];
}
return _CPBrowserResizeControlBackgroundImage;
}
- (id)initWithFrame:(CGRect)aFrame
{
if (self = [super initWithFrame:aFrame])
[self setBackgroundColor:[CPColor colorWithPatternImage:[[self class] backgroundImage]]];
{
var browser = [[CPBrowser alloc] init];
[self setBackgroundColor:[CPColor colorWithPatternImage:[browser valueForThemeAttribute:@"image-control-resize"]]];
}
return self;
}
@@ -819,13 +810,13 @@ var _CPBrowserResizeControlBackgroundImage = nil;
return [_browser canDragRowsWithIndexes:rowIndexes inColumn:[_browser columnOfTableView:self] withEvent:[CPApp currentEvent]];
}
- (CPImage)dragImageForRowsWithIndexes:(CPIndexSet)dragRows tableColumns:(CPArray)theTableColumns event:(CPEvent)dragEvent offset:(CPPointPointer)dragImageOffset
- (CPImage)dragImageForRowsWithIndexes:(CPIndexSet)dragRows tableColumns:(CPArray)theTableColumns event:(CPEvent)dragEvent offset:(CGPoint)dragImageOffset
{
return [_browser draggingImageForRowsWithIndexes:dragRows inColumn:[_browser columnOfTableView:self] withEvent:dragEvent offset:dragImageOffset] ||
[super dragImageForRowsWithIndexes:dragRows tableColumns:theTableColumns event:dragEvent offset:dragImageOffset];
}
- (CPView)dragViewForRowsWithIndexes:(CPIndexSet)dragRows tableColumns:(CPArray)theTableColumns event:(CPEvent)dragEvent offset:(CPPoint)dragViewOffset
- (CPView)dragViewForRowsWithIndexes:(CPIndexSet)dragRows tableColumns:(CPArray)theTableColumns event:(CPEvent)dragEvent offset:(CGPoint)dragViewOffset
{
var count = theTableColumns.length;
while (count--)
@@ -901,6 +892,12 @@ var _CPBrowserResizeControlBackgroundImage = nil;
[_browser _column:_index clickedRow:[selectedIndexes count] === 1 ? [selectedIndexes firstIndex] : -1];
}
- (void)tableViewSelectionDidChange:(CPNotification)aNotification
{
var selectedIndexes = [[aNotification object] selectedRowIndexes];
[_browser selectRowIndexes:selectedIndexes inColumn:_index];
}
- (id)childAtIndex:(unsigned)index
{
return [_delegate browser:_browser child:index ofItem:_item];
@@ -982,7 +979,7 @@ var _CPBrowserResizeControlBackgroundImage = nil;
isHighlighted = [self themeState] & CPThemeStateSelectedDataView;
[imageView setImage: _isLeaf ? (isHighlighted ? _highlightedBranchImage : _branchImage) : nil];
[imageView setImageScaling:CPScaleNone];
[imageView setImageScaling:CPImageScaleNone];
}
- (void)encodeWithCoder:(CPCoder)aCoder
+216 -83
View File
@@ -25,24 +25,26 @@
@import "CPControl.j"
@import "CPStringDrawing.j"
@import "CPText.j"
@import "CPWindow_Constants.j"
/* @group CPBezelStyle */
CPRoundedBezelStyle = 1;
CPRegularSquareBezelStyle = 2;
// IB style
CPRoundedBezelStyle = 1; // Push
CPRegularSquareBezelStyle = 2; // Bevel
CPThickSquareBezelStyle = 3;
CPThickerSquareBezelStyle = 4;
CPDisclosureBezelStyle = 5;
CPShadowlessSquareBezelStyle = 6;
CPCircularBezelStyle = 7;
CPTexturedSquareBezelStyle = 8;
CPHelpButtonBezelStyle = 9;
CPSmallSquareBezelStyle = 10;
CPTexturedRoundedBezelStyle = 11;
CPRoundRectBezelStyle = 12;
CPRecessedBezelStyle = 13;
CPRoundedDisclosureBezelStyle = 14;
CPDisclosureBezelStyle = 5; // Disclosure triangle
CPShadowlessSquareBezelStyle = 6; // Square
CPCircularBezelStyle = 7; // Round
CPTexturedSquareBezelStyle = 8; // Textured
CPHelpButtonBezelStyle = 9; // Help
CPSmallSquareBezelStyle = 10; // Gradient
CPTexturedRoundedBezelStyle = 11; // Round Textured
CPRoundRectBezelStyle = 12; // Round Rect
CPRecessedBezelStyle = 13; // Recessed
CPRoundedDisclosureBezelStyle = 14; // Disclosure
CPHUDBezelStyle = -1;
@@ -78,7 +80,7 @@ var CPButtonBezelStyleStateMap = [CPDictionary dictionaryWithObjects:[CPButtonSt
forKeys:[CPRoundedBezelStyle, CPRoundRectBezelStyle]];
CPButtonDefaultHeight = 24.0;
CPButtonDefaultHeight = 25.0;
CPButtonImageOffset = 3.0;
/*!
@@ -111,6 +113,8 @@ CPButtonImageOffset = 3.0;
CPTimer _continuousTimer;
float _periodicDelay;
float _periodicInterval;
BOOL _isTracking;
}
+ (id)buttonWithTitle:(CPString)aTitle
@@ -141,9 +145,9 @@ CPButtonImageOffset = 3.0;
}
/*!
Initializes and returns a newly allocated CPButton object with a specified frame rectangle.
@param aFrame The frame rectangle for the created button object.
@return An initialized CPView object or nil if the object couldn't be created.
Initializes and returns a newly allocated CPButton object with a specified frame rectangle.
@param aFrame The frame rectangle for the created button object.
@return An initialized CPView object or nil if the object couldn't be created.
*/
- (id)initWithFrame:(CGRect)aFrame
{
@@ -155,7 +159,7 @@ CPButtonImageOffset = 3.0;
[self setValue:CPCenterTextAlignment forThemeAttribute:@"alignment"];
[self setValue:CPCenterVerticalTextAlignment forThemeAttribute:@"vertical-alignment"];
[self setValue:CPImageLeft forThemeAttribute:@"image-position"];
[self setValue:CPScaleNone forThemeAttribute:@"image-scaling"];
[self setValue:CPImageScaleNone forThemeAttribute:@"image-scaling"];
[self setBezelStyle:CPRoundRectBezelStyle];
[self setBordered:YES];
@@ -176,11 +180,13 @@ CPButtonImageOffset = 3.0;
// Continuous button defaults.
_periodicInterval = 0.05;
_periodicDelay = 0.5;
[self setButtonType:CPMomentaryPushInButton];
}
// Setting the state
/*!
Returns a Boolean value indicating whether the button allows a mixed state.
Returns a Boolean value indicating whether the button allows a mixed state.
@return \c YES if the button has a 'mixed' state in addition to on and off.
*/
- (BOOL)allowsMixedState
@@ -206,24 +212,20 @@ CPButtonImageOffset = 3.0;
}
/*!
Sets the value of the button using an Objective-J object.
@param anObjectValue The value of the button interpreted as an Objective-J object.
Sets the value of the button using an Objective-J object.
@param anObjectValue The value of the button interpreted as an Objective-J object.
*/
- (void)setObjectValue:(id)anObjectValue
{
if (!anObjectValue || anObjectValue === @"" || ([anObjectValue intValue] === 0))
anObjectValue = CPOffState;
else if (![anObjectValue isKindOfClass:[CPNumber class]])
anObjectValue = CPOnState;
else if (anObjectValue >= CPOnState)
anObjectValue = CPOnState
else if (anObjectValue < CPOffState)
if ([self allowsMixedState])
anObjectValue = CPMixedState;
else
anObjectValue = CPOnState;
@@ -231,24 +233,35 @@ CPButtonImageOffset = 3.0;
switch ([self objectValue])
{
case CPMixedState: [self unsetThemeState:CPThemeStateSelected];
[self setThemeState:CPButtonStateMixed];
break;
case CPMixedState:
[self unsetThemeState:CPThemeStateSelected];
[self setThemeState:CPButtonStateMixed];
if (_showsStateBy & (CPChangeGrayCellMask | CPChangeBackgroundCellMask))
[self setThemeState:CPThemeStateHighlighted];
else
[self unsetThemeState:CPThemeStateHighlighted];
break;
case CPOnState: [self unsetThemeState:CPButtonStateMixed];
[self setThemeState:CPThemeStateSelected];
break;
case CPOnState:
[self unsetThemeState:CPButtonStateMixed];
[self setThemeState:CPThemeStateSelected];
if (_showsStateBy & (CPChangeGrayCellMask | CPChangeBackgroundCellMask))
[self setThemeState:CPThemeStateHighlighted];
else
[self unsetThemeState:CPThemeStateHighlighted];
break;
case CPOffState: [self unsetThemeState:CPThemeStateSelected | CPButtonStateMixed];
case CPOffState:
[self unsetThemeState:CPThemeStateSelected | CPButtonStateMixed | CPThemeStateHighlighted];
}
}
/*!
Returns the button's next state.
@return The button's state. A button can have two or three states.
If it has two, this value is either \c CPOffState (the normal or unpressed state)
or \c CPOnState (the alternate or pressed state).
If it has three, this value can be \c CPOnState (the feature is in effect everywhere), \c CPOffState (the feature is in effect nowhere), or \c CPMixedState (the feature is in effect somewhere).
Returns the button's next state.
@return The button's state. A button can have two or three states.
If it has two, this value is either \c CPOffState (the normal or unpressed state)
or \c CPOnState (the alternate or pressed state).
If it has three, this value can be \c CPOnState (the feature is in effect everywhere), \c CPOffState (the feature is in effect nowhere), or \c CPMixedState (the feature is in effect somewhere).
*/
- (CPInteger)nextState
{
@@ -294,9 +307,9 @@ CPButtonImageOffset = 3.0;
}
/*!
Sets the title displayed by the button when in its normal state.
@param aTitle The string to set as the button's title. This title is always shown on buttons
that dont use their alternate contents when highlighting or displaying their alternate state.
Sets the title displayed by the button when in its normal state.
@param aTitle The string to set as the button's title. This title is always shown on buttons
that dont use their alternate contents when highlighting or displaying their alternate state.
*/
- (void)setTitle:(CPString)aTitle
{
@@ -310,9 +323,9 @@ CPButtonImageOffset = 3.0;
}
/*!
Returns the title displayed on the button when its in its normal state.
@return The title displayed on the receiver when its in its normal state
or the empty string if the button doesnt display a title.
Returns the title displayed on the button when its in its normal state.
@return The title displayed on the receiver when its in its normal state
or the empty string if the button doesnt display a title.
*/
- (CPString)title
{
@@ -374,11 +387,19 @@ CPButtonImageOffset = 3.0;
- (void)setShowsStateBy:(CPInteger)aMask
{
// CPPushInCellMask cannot be set for showsStateBy.
aMask &= ~CPPushInCellMask;
if (_showsStateBy === aMask)
return;
_showsStateBy = aMask;
if (_showsStateBy & (CPChangeGrayCellMask | CPChangeBackgroundCellMask) && [self state] != CPOffState)
[self setThemeState:CPThemeStateHighlighted];
else
[self unsetThemeState:CPThemeStateHighlighted];
[self setNeedsDisplay:YES];
[self setNeedsLayout];
}
@@ -402,15 +423,20 @@ CPButtonImageOffset = 3.0;
}
}
- (CPInteger)highlightsBy
{
return _highlightsBy;
}
- (void)setButtonType:(CPButtonType)aButtonType
{
switch (aButtonType)
{
case CPMomentaryLightButton: [self setHighlightsBy:CPChangeBackgroundCellMask];
case CPMomentaryLightButton: [self setHighlightsBy:CPChangeGrayCellMask | CPChangeBackgroundCellMask];
[self setShowsStateBy:CPNoCellMask];
break;
case CPMomentaryPushInButton: [self setHighlightsBy:CPPushInCellMask | CPChangeGrayCellMask];
case CPMomentaryPushInButton: [self setHighlightsBy:CPPushInCellMask | CPChangeGrayCellMask | CPChangeBackgroundCellMask];
[self setShowsStateBy:CPNoCellMask];
break;
@@ -418,12 +444,12 @@ CPButtonImageOffset = 3.0;
[self setShowsStateBy:CPNoCellMask];
break;
case CPPushOnPushOffButton: [self setHighlightsBy:CPPushInCellMask | CPChangeGrayCellMask];
[self setShowsStateBy:CPChangeBackgroundCellMask];
case CPPushOnPushOffButton: [self setHighlightsBy:CPPushInCellMask | CPChangeGrayCellMask | CPChangeBackgroundCellMask];
[self setShowsStateBy:CPChangeBackgroundCellMask | CPChangeGrayCellMask];
break;
case CPOnOffButton: [self setHighlightsBy:CPChangeBackgroundCellMask];
[self setShowsStateBy:CPChangeBackgroundCellMask];
case CPOnOffButton: [self setHighlightsBy:CPChangeGrayCellMask | CPChangeBackgroundCellMask];
[self setShowsStateBy:CPChangeGrayCellMask | CPChangeBackgroundCellMask];
break;
case CPToggleButton: [self setHighlightsBy:CPPushInCellMask | CPContentsCellMask];
@@ -494,20 +520,43 @@ CPButtonImageOffset = 3.0;
- (BOOL)startTrackingAt:(CGPoint)aPoint
{
[self highlight:YES];
_isTracking = YES;
return [super startTrackingAt:aPoint];
var startedTracking = [super startTrackingAt:aPoint];
if (_highlightsBy & (CPPushInCellMask | CPChangeGrayCellMask))
{
if (_showsStateBy & (CPChangeGrayCellMask | CPChangeBackgroundCellMask))
[self highlight:[self state] == CPOffState];
else
[self highlight:YES];
}
else
{
if (_showsStateBy & (CPChangeGrayCellMask | CPChangeBackgroundCellMask))
[self highlight:[self state] != CPOffState];
else
[self highlight:NO];
}
return startedTracking;
}
- (void)stopTracking:(CGPoint)lastPoint at:(CGPoint)aPoint mouseIsUp:(BOOL)mouseIsUp
{
[self highlight:NO];
[self invalidateTimers];
[super stopTracking:lastPoint at:aPoint mouseIsUp:mouseIsUp];
_isTracking = NO;
if (mouseIsUp && CGRectContainsPoint([self bounds], aPoint))
[self setNextState];
else
{
if (_showsStateBy & (CPChangeGrayCellMask | CPChangeBackgroundCellMask))
[self highlight:[self state] != CPOffState];
else
[self highlight:NO];
}
[self setNeedsLayout];
[self setNeedsDisplay:YES];
[self invalidateTimers];
}
- (void)invalidateTimers
@@ -529,35 +578,18 @@ CPButtonImageOffset = 3.0;
{
var contentInset = [self currentValueForThemeAttribute:@"content-inset"];
if (_CGInsetIsEmpty(contentInset))
return bounds;
bounds = _CGRectMakeCopy(bounds);
bounds.origin.x += contentInset.left;
bounds.origin.y += contentInset.top;
bounds.size.width -= contentInset.left + contentInset.right;
bounds.size.height -= contentInset.top + contentInset.bottom;
return bounds;
return _CGRectInsetByInset(bounds, contentInset);
}
- (CGRect)bezelRectForBounds:(CGRect)bounds
{
// Is this necessary? The theme itself can just change its inset to a zero inset when !CPThemeStateBordered.
if (![self isBordered])
return _CGRectMakeZero();
return bounds;
var bezelInset = [self currentValueForThemeAttribute:@"bezel-inset"];
if (_CGInsetIsEmpty(bezelInset))
return bounds;
bounds = _CGRectMakeCopy(bounds);
bounds.origin.x += bezelInset.left;
bounds.origin.y += bezelInset.top;
bounds.size.width -= bezelInset.left + bezelInset.right;
bounds.size.height -= bezelInset.top + bezelInset.bottom;
return bounds;
return _CGRectInsetByInset(bounds, bezelInset);
}
- (CGSize)_minimumFrameSize
@@ -641,8 +673,51 @@ CPButtonImageOffset = 3.0;
if (contentView)
{
[contentView setText:([self hasThemeState:CPThemeStateHighlighted] && _alternateTitle) ? _alternateTitle : _title];
[contentView setImage:[self currentValueForThemeAttribute:@"image"]];
var title = nil,
image = nil;
if (_isTracking)
{
if (_highlightsBy & CPContentsCellMask)
{
if (_showsStateBy & CPContentsCellMask)
{
title = ([self state] == CPOffState && _alternateTitle) ? _alternateTitle : _title;
image = ([self state] == CPOffState && [self alternateImage]) ? [self alternateImage] : [self image];
}
else
{
title = [self alternateTitle];
image = [self alternateImage];
}
}
else if (_showsStateBy & CPContentsCellMask)
{
title = ([self state] != CPOffState && _alternateTitle) ? _alternateTitle : _title;
image = ([self state] != CPOffState && [self alternateImage]) ? [self alternateImage] : [self image];
}
else
{
title = _title;
image = [self image];
}
}
else
{
if (_showsStateBy & CPContentsCellMask)
{
title = ([self state] != CPOffState && _alternateTitle) ? _alternateTitle : _title;
image = ([self state] != CPOffState && [self alternateImage]) ? [self alternateImage] : [self image];
}
else
{
title = _title;
image = [self image];
}
}
[contentView setText:title];
[contentView setImage:image];
[contentView setImageOffset:[self currentValueForThemeAttribute:@"image-offset"]];
[contentView setFont:[self currentValueForThemeAttribute:@"font"]];
@@ -741,9 +816,51 @@ CPButtonImageOffset = 3.0;
return NO;
[self performClick:nil];
return YES;
}
/*!
Perform a click on the receiver.
@param sender - The sender object
*/
- (void)performClick:(id)sender
{
// This is slightly different from [super performClick:] in that the highlight behaviour is dependent on
// highlightsBy and showsStateBy.
if (![self isEnabled])
return;
[self setState:[self nextState]];
var shouldHighlight = NO;
if (_highlightsBy & (CPPushInCellMask | CPChangeGrayCellMask))
{
if (_showsStateBy & (CPChangeGrayCellMask | CPChangeBackgroundCellMask))
shouldHighlight = [self state] == CPOffState;
else
shouldHighlight = YES;
}
[self highlight:shouldHighlight];
try
{
[self sendAction:[self action] to:[self target]];
}
catch (e)
{
throw e;
}
finally
{
if (shouldHighlight)
[CPTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(unhighlightButtonTimerDidFinish:) userInfo:nil repeats:NO];
}
}
@end
@implementation CPButton (NS)
@@ -784,7 +901,9 @@ var CPButtonImageKey = @"CPButtonImageKey",
CPButtonKeyEquivalentKey = @"CPButtonKeyEquivalentKey",
CPButtonKeyEquivalentMaskKey = @"CPButtonKeyEquivalentMaskKey",
CPButtonPeriodicDelayKey = @"CPButtonPeriodicDelayKey",
CPButtonPeriodicIntervalKey = @"CPButtonPeriodicIntervalKey";
CPButtonPeriodicIntervalKey = @"CPButtonPeriodicIntervalKey",
CPButtonHighlightsByKey = @"CPButtonHighlightsByKey",
CPButtonShowsStateByKey = @"CPButtonShowsStateByKey";
@implementation CPButton (CPCoding)
@@ -802,9 +921,20 @@ var CPButtonImageKey = @"CPButtonImageKey",
_title = [aCoder decodeObjectForKey:CPButtonTitleKey];
_alternateTitle = [aCoder decodeObjectForKey:CPButtonAlternateTitleKey];
_allowsMixedState = [aCoder decodeBoolForKey:CPButtonAllowsMixedStateKey];
if ([aCoder containsValueForKey:CPButtonAllowsMixedStateKey])
_allowsMixedState = [aCoder decodeBoolForKey:CPButtonAllowsMixedStateKey];
if ([aCoder containsValueForKey:CPButtonHighlightsByKey])
{
// If one exists, assume both do.
_highlightsBy = [aCoder decodeIntForKey:CPButtonHighlightsByKey];
_showsStateBy = [aCoder decodeIntForKey:CPButtonShowsStateByKey];
}
else
{
// Backwards compatibility: if this CPButton was encoded before coding of
// highlightsBy and showsStateBy were added, we should just use the
// default values from _init rather than overwriting with 0, 0.
}
[self setImageDimsWhenDisabled:[aCoder decodeObjectForKey:CPButtonImageDimsWhenDisabledKey]];
@@ -843,6 +973,9 @@ var CPButtonImageKey = @"CPButtonImageKey",
[aCoder encodeBool:_allowsMixedState forKey:CPButtonAllowsMixedStateKey];
[aCoder encodeInt:_highlightsBy forKey:CPButtonHighlightsByKey];
[aCoder encodeInt:_showsStateBy forKey:CPButtonShowsStateByKey];
[aCoder encodeBool:[self imageDimsWhenDisabled] forKey:CPButtonImageDimsWhenDisabledKey];
[aCoder encodeInt:[self imagePosition] forKey:CPButtonImagePositionKey];
@@ -857,5 +990,5 @@ var CPButtonImageKey = @"CPButtonImageKey",
@end
@import "CPCheckBox.j"
@import "CPRadio.j"
//@import "CPCheckBox.j"
//@import "CPRadio.j"
+47 -5
View File
@@ -1,5 +1,31 @@
/*
* CPButtonBar.j
* AppKit
*
* Created by Francisco Tolmasky.
* Copyright 2009, 280 North, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "CPView.j"
@import "CPWindow_Constants.j"
@class CPSplitView
@global CPPopUpButtonStatePullsDown
@implementation CPButtonBar : CPView
@@ -12,7 +38,7 @@
+ (id)plusButton
{
var button = [[CPButton alloc] initWithFrame:CGRectMake(0, 0, 35, 25)],
image = [[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:[CPButtonBar class]] pathForResource:@"plus_button.png"] size:CGSizeMake(11, 12)];
image = [[CPTheme defaultTheme] valueForAttributeWithName:@"button-image-plus" forClass:[CPButtonBar class]];
[button setBordered:NO];
[button setImage:image];
@@ -24,7 +50,7 @@
+ (id)minusButton
{
var button = [[CPButton alloc] initWithFrame:CGRectMake(0, 0, 35, 25)],
image = [[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:[CPButtonBar class]] pathForResource:@"minus_button.png"] size:CGSizeMake(11, 4)];
image = [[CPTheme defaultTheme] valueForAttributeWithName:@"button-image-minus" forClass:[CPButtonBar class]];
[button setBordered:NO];
[button setImage:image];
@@ -36,7 +62,7 @@
+ (id)actionPopupButton
{
var button = [[CPPopUpButton alloc] initWithFrame:CGRectMake(0, 0, 35, 25)],
image = [[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:[CPButtonBar class]] pathForResource:@"action_button.png"] size:CGSizeMake(22, 14)];
image = [[CPTheme defaultTheme] valueForAttributeWithName:@"button-image-action" forClass:[CPButtonBar class]];
[button addItemWithTitle:nil];
[[button lastItem] setImage:image];
@@ -55,8 +81,24 @@
+ (id)themeAttributes
{
return [CPDictionary dictionaryWithObjects:[CGInsetMake(0.0, 0.0, 0.0, 0.0), CGSizeMakeZero(), [CPNull null], [CPNull null], [CPNull null], [CPNull null]]
forKeys:[@"resize-control-inset", @"resize-control-size", @"resize-control-color", @"bezel-color", @"button-bezel-color", @"button-text-color"]];
return [CPDictionary dictionaryWithObjects:[ CGInsetMake(0.0, 0.0, 0.0, 0.0),
CGSizeMakeZero(),
[CPNull null],
[CPNull null],
[CPNull null],
[CPNull null],
[CPNull null],
[CPNull null],
[CPNull null]]
forKeys:[ @"resize-control-inset",
@"resize-control-size",
@"resize-control-color",
@"bezel-color",
@"button-bezel-color",
@"button-text-color",
@"button-image-plus",
@"button-image-minus",
@"button-image-action"]];
}
- (id)initWithFrame:(CGRect)aFrame
+32 -38
View File
@@ -94,54 +94,48 @@ CPCheckBoxImageOffset = 4.0;
[self takeStateFromKeyPath:aKeyPath ofObjects:objects];
}
- (CPImage)image
{
return [self currentValueForThemeAttribute:@"image"];
}
- (CPImage)alternateImage
{
return [self currentValueForThemeAttribute:@"image"];
}
- (BOOL)startTrackingAt:(CGPoint)aPoint
{
var startedTracking = [super startTrackingAt:aPoint];
[self highlight:YES];
return startedTracking;
}
@end
@implementation _CPCheckBoxValueBinder : CPBinder
{
}
- (void)setValueFor:(CPString)theBinding
- (void)_updatePlaceholdersWithOptions:(CPDictionary)options
{
var destination = [_info objectForKey:CPObservedObjectKey],
keyPath = [_info objectForKey:CPObservedKeyPathKey],
options = [_info objectForKey:CPOptionsKey],
newValue = [destination valueForKeyPath:keyPath],
isPlaceholder = CPIsControllerMarker(newValue);
[super _updatePlaceholdersWithOptions:options];
if (isPlaceholder)
{
switch (newValue)
{
case CPMultipleValuesMarker:
newValue = CPMixedState;
break;
[self _setPlaceholder:CPMixedState forMarker:CPMultipleValuesMarker isDefault:YES];
[self _setPlaceholder:CPOffState forMarker:CPNoSelectionMarker isDefault:YES];
[self _setPlaceholder:CPOffState forMarker:CPNotApplicableMarker isDefault:YES];
[self _setPlaceholder:CPOffState forMarker:CPNullMarker isDefault:YES];
}
case CPNoSelectionMarker:
newValue = CPOffState;
break;
- (void)setPlaceholderValue:(id)aValue withMarker:(CPString)aMarker forBinding:(CPString)aBinding
{
[_source setAllowsMixedState:(aValue === CPMixedState)];
[_source setState:aValue];
}
case CPNotApplicableMarker:
if ([options objectForKey:CPRaisesForNotApplicableKeysBindingOption])
[CPException raise:CPGenericException reason:@"can't transform non applicable key on: "+_source+" value: "+newValue];
newValue = CPOffState;
break;
}
if (newValue === CPMixedState)
{
[_source setAllowsMixedState:YES];
}
else
{
// Cocoa will always set allowsMixedState to NO
// This behavior will be fine for Cappuccino as well if we (like Cocoa)
// default the CPConditionallySetsEnabledBindingOption to YES
[_source setAllowsMixedState:NO];
}
}
[_source setState:newValue];
- (void)setValue:(id)aValue forBinding:(CPString)aBinding
{
[_source setState:aValue];
}
@end
+1
View File
@@ -22,6 +22,7 @@
@import "CPView.j"
@class CPScrollView
/*!
@ingroup appkit
+53 -26
View File
@@ -26,8 +26,12 @@
@import <Foundation/CPKeyedArchiver.j>
@import <Foundation/CPKeyedUnarchiver.j>
@import "CPView.j"
@import "CPCollectionViewItem.j"
@import "CPCompatibility.j"
@import "CPPasteboard.j"
@import "CPView.j"
@class CPClipView
/*!
@@ -40,23 +44,23 @@
@par Delegate Methods
@delegate -(void)collectionViewDidChangeSelection:(CPCollectionView)collectionView;
@delegate - (void)collectionViewDidChangeSelection:(CPCollectionView)collectionView;
Called when the selection in the collection view has changed.
@param collectionView the collection view who's selection changed
@delegate -(void)collectionView:(CPCollectionView)collectionView didDoubleClickOnItemAtIndex:(int)index;
@delegate - (void)collectionView:(CPCollectionView)collectionView didDoubleClickOnItemAtIndex:(int)index;
Called when the user double-clicks on an item in the collection view.
@param collectionView the collection view that received the double-click
@param index the index of the item that received the double-click
@delegate -(CPData)collectionView:(CPCollectionView)collectionView dataForItemsAtIndexes:(CPIndexSet)indices forType:(CPString)aType;
@delegate - (CPData)collectionView:(CPCollectionView)collectionView dataForItemsAtIndexes:(CPIndexSet)indices forType:(CPString)aType;
Invoked to obtain data for a set of indices.
@param collectionView the collection view to obtain data for
@param indices the indices to return data for
@param aType the data type
@return a data object containing the index items
@delegate -(CPArray)collectionView:(CPCollectionView)collectionView dragTypesForItemsAtIndexes:(CPIndexSet)indices;
@delegate - (CPArray)collectionView:(CPCollectionView)collectionView dragTypesForItemsAtIndexes:(CPIndexSet)indices;
Invoked to obtain the data types supported by the specified indices for placement on the pasteboard.
@param collectionView the collection view the items reside in
@param indices the indices to obtain drag types
@@ -242,13 +246,15 @@
Sets the content of the collection view to the content in \c anArray.
This array can be of any type, and each element will be passed to the \c -setRepresentedObject: method.
It's the responsibility of your custom collection view item to interpret the object.
@param anArray the content array
If the new content array is smaller than the previous one, note that [receiver selectionIndexes] may
refer to out of range indices. \c selectionIndexes is not changed as a result of calling the
\c setContent: method.
@param anArray a content array
*/
- (void)setContent:(CPArray)anArray
{
// reset the _selectionIndexes
[self setSelectionIndexes:[CPIndexSet indexSet]];
_content = anArray;
[self reloadContent];
@@ -284,9 +290,11 @@
if (!_isSelectable)
{
var index = CPNotFound;
var index = CPNotFound,
itemCount = [_items count];
while ((index = [_selectionIndexes indexGreaterThanIndex:index]) != CPNotFound)
// Be wary of invalid selection ranges since setContent: does not clear selection indexes.
while ((index = [_selectionIndexes indexGreaterThanIndex:index]) != CPNotFound && index < itemCount)
[_items[index] setSelected:NO];
}
}
@@ -340,19 +348,23 @@
*/
- (void)setSelectionIndexes:(CPIndexSet)anIndexSet
{
if ([_selectionIndexes isEqual:anIndexSet] || !_isSelectable)
if (!anIndexSet)
anIndexSet = [CPIndexSet indexSet];
if (!_isSelectable || [_selectionIndexes isEqual:anIndexSet])
return;
var index = CPNotFound;
var index = CPNotFound,
itemCount = [_items count];
while ((index = [_selectionIndexes indexGreaterThanIndex:index]) != CPNotFound)
// Be wary of invalid selection ranges since setContent: does not clear selection indexes.
while ((index = [_selectionIndexes indexGreaterThanIndex:index]) !== CPNotFound && index < itemCount)
[_items[index] setSelected:NO];
_selectionIndexes = anIndexSet;
var index = CPNotFound;
while ((index = [_selectionIndexes indexGreaterThanIndex:index]) != CPNotFound)
while ((index = [_selectionIndexes indexGreaterThanIndex:index]) !== CPNotFound)
[_items[index] setSelected:YES];
var binderClass = [[self class] _binderClassForBinding:@"selectionIndexes"];
@@ -401,7 +413,8 @@
}
index = CPNotFound;
while ((index = [_selectionIndexes indexGreaterThanIndex:index]) != CPNotFound)
// Be wary of invalid selection ranges since setContent: does not clear selection indexes.
while ((index = [_selectionIndexes indexGreaterThanIndex:index]) != CPNotFound && index < count)
[_items[index] setSelected:YES];
[self tile];
@@ -473,7 +486,7 @@
}
var superview = [self superview],
proposedHeight = y + itemSize.height + _verticalMargin;
proposedHeight = y + itemSize.height + _verticalMargin;
if ([superview isKindOfClass:[CPClipView class]])
{
@@ -559,6 +572,8 @@
*/
- (void)setMinItemSize:(CGSize)aSize
{
if (aSize === nil || aSize === undefined)
[CPException raise:CPInvalidArgumentException reason:"Invalid value provided for minimum size"];
if (CGSizeEqualToSize(_minItemSize, aSize))
return;
@@ -636,9 +651,9 @@
if (index >= 0 && index < _items.length)
{
if (_allowsMultipleSelection && ([anEvent modifierFlags] & CPCommandKeyMask || [anEvent modifierFlags] & CPShiftKeyMask))
if (_allowsMultipleSelection && ([anEvent modifierFlags] & CPPlatformActionKeyMask || [anEvent modifierFlags] & CPShiftKeyMask))
{
if ([anEvent modifierFlags] & CPCommandKeyMask)
if ([anEvent modifierFlags] & CPPlatformActionKeyMask)
{
var indexes = [_selectionIndexes copy];
@@ -665,6 +680,13 @@
indexes = [CPIndexSet indexSetWithIndex:index];
[self setSelectionIndexes:indexes];
// TODO Is it allowable for collection view items to become the first responder? In that case they
// may have become that at this point by virtue of CPWindow's sendEvent: mouse down handling, and
// the following line will rudely snatch it away from them. For most cases though, clicking on an
// item should naturally make the collection view the first responder so that keyboard navigation
// is enabled.
[[self window] makeFirstResponder:self];
}
else if (_allowsEmptySelection)
[self setSelectionIndexes:[CPIndexSet indexSet]];
@@ -672,6 +694,10 @@
- (void)mouseDragged:(CPEvent)anEvent
{
// Don't crash if we never registered the intial click.
if (!_mouseDownEvent)
return;
var locationInWindow = [anEvent locationInWindow],
mouseDownLocationInWindow = [_mouseDownEvent locationInWindow];
@@ -965,14 +991,15 @@ var CPCollectionViewMinItemSizeKey = @"CPCollectionViewMinItemSizeK
{
[super awakeFromCib];
if (CGSizeEqualToSize(_minItemSize, CGSizeMakeZero()) || CGSizeEqualToSize(_maxItemSize, CGSizeMakeZero()))
var prototypeView = [_itemPrototype view];
if (prototypeView && (CGSizeEqualToSize(_minItemSize, CGSizeMakeZero()) || CGSizeEqualToSize(_maxItemSize, CGSizeMakeZero())))
{
var item = _itemPrototype;
if (CGSizeEqualToSize(_minItemSize, CGSizeMakeZero()))
_minItemSize = [[item view] frameSize];
_minItemSize = [prototypeView frameSize];
else if (CGSizeEqualToSize(_maxItemSize, CGSizeMakeZero()))
_maxItemSize = [[item view] frameSize];
_maxItemSize = [prototypeView frameSize];
}
}
@@ -989,11 +1016,11 @@ var CPCollectionViewMinItemSizeKey = @"CPCollectionViewMinItemSizeK
_itemSize = CGSizeMakeZero();
_minItemSize = [aCoder decodeSizeForKey:CPCollectionViewMinItemSizeKey] || CGSizeMakeZero();
_maxItemSize = [aCoder decodeSizeForKey:CPCollectionViewMaxItemSizeKey] || CGSizeMakeZero();
_minItemSize = [aCoder decodeSizeForKey:CPCollectionViewMinItemSizeKey];
_maxItemSize = [aCoder decodeSizeForKey:CPCollectionViewMaxItemSizeKey];
_maxNumberOfRows = [aCoder decodeIntForKey:CPCollectionViewMaxNumberOfRowsKey] || 0;
_maxNumberOfColumns = [aCoder decodeIntForKey:CPCollectionViewMaxNumberOfColumnsKey] || 0;
_maxNumberOfRows = [aCoder decodeIntForKey:CPCollectionViewMaxNumberOfRowsKey];
_maxNumberOfColumns = [aCoder decodeIntForKey:CPCollectionViewMaxNumberOfColumnsKey];
_verticalMargin = [aCoder decodeFloatForKey:CPCollectionViewVerticalMarginKey];
+642 -23
View File
@@ -21,6 +21,7 @@
*/
@import <Foundation/CPObject.j>
@import "CPGraphicsContext.j"
@import "CGColor.j"
@@ -28,6 +29,18 @@
@import "CPImage.j"
/*!
Orientation to use with \c CPColorPattern for vertical patterns.
*/
CPColorPatternIsVertical = YES;
/*!
Orientation to use with \c CPColorPattern for horizontal patterns.
*/
CPColorPatternIsHorizontal = NO;
/// @cond IGNORE
var _redComponent = 0,
_greenComponent = 1,
_blueComponent = 2,
@@ -54,6 +67,8 @@ var cachedBlackColor,
cachedShadowColor,
cachedClearColor;
/// @endcond
/*!
@ingroup appkit
@@ -72,7 +87,7 @@ var cachedBlackColor,
}
/*!
Creates a color in the RGB color space, with an alpha value.
Creates a color in the RGB colorspace, with an alpha value.
Each component should be between the range of 0.0 to 1.0. For
the alpha component, a value of 1.0 is opaque, and 0.0 means
completely transparent.
@@ -86,13 +101,13 @@ var cachedBlackColor,
*/
+ (CPColor)colorWithRed:(float)red green:(float)green blue:(float)blue alpha:(float)alpha
{
return [[CPColor alloc] _initWithRGBA:[red, green, blue, alpha]];
return [[CPColor alloc] _initWithRGBA:[MAX(0.0, MIN(1.0, red)), MAX(0.0, MIN(1.0, green)), MAX(0.0, MIN(1.0, blue)), MAX(0.0, MIN(1.0, alpha))]];
}
/*!
@deprecated in favor of colorWithRed:green:blue:alpha:
Creates a color in the RGB color space, with an alpha value.
Creates a color in the RGB colorspace, with an alpha value.
Each component should be between the range of 0.0 to 1.0. For
the alpha component, a value of 1.0 is opaque, and 0.0 means
completely transparent.
@@ -167,12 +182,12 @@ var cachedBlackColor,
switch (FLOOR(hue / 60))
{
case 0: return [CPColor colorWithCalibratedRed: b green: t blue: p alpha: alpha];
case 1: return [CPColor colorWithCalibratedRed: q green: b blue: p alpha: alpha];
case 2: return [CPColor colorWithCalibratedRed: p green: b blue: t alpha: alpha];
case 3: return [CPColor colorWithCalibratedRed: p green: q blue: b alpha: alpha];
case 4: return [CPColor colorWithCalibratedRed: t green: p blue: b alpha: alpha];
case 5: return [CPColor colorWithCalibratedRed: b green: p blue: q alpha: alpha];
case 0: return [CPColor colorWithCalibratedRed:b green:t blue:p alpha:alpha];
case 1: return [CPColor colorWithCalibratedRed:q green:b blue:p alpha:alpha];
case 2: return [CPColor colorWithCalibratedRed:p green:b blue:t alpha:alpha];
case 3: return [CPColor colorWithCalibratedRed:p green:q blue:b alpha:alpha];
case 4: return [CPColor colorWithCalibratedRed:t green:p blue:b alpha:alpha];
case 5: return [CPColor colorWithCalibratedRed:b green:p blue:q alpha:alpha];
}
}
@@ -192,6 +207,17 @@ var cachedBlackColor,
return rgba ? [[CPColor alloc] _initWithRGBA: rgba] : null;
}
/*!
Creates a color in the sRGB colorspace with the given components and alpha values.
Values below 0.0 are treated as 0.0 and values above 1.0 are treated as 1.0.
*/
+ (CPColor)colorWithSRGBRed:(float)red green:(float)green blue:(float)blue alpha:(float)alpha
{
// TODO If Cappuccino is ported to a colorspace aware platform, this color should be in
// sRGBColorSpace.
return [self colorWithRed:red green:green blue:blue alpha:alpha];
}
/*!
Returns a black color object. (RGBA=[0.0, 0.0, 0.0, 1.0])
*/
@@ -419,7 +445,9 @@ var cachedBlackColor,
parts[3] ? parseFloat(parts[3], 10) : 1.0
];
_cssString = aString;
// We can't reuse aString as _cssString because the browser might not support the `rgba` syntax, and aString might
// use it (issue #1413.)
[self _initCSSStringFromComponents];
return self;
}
@@ -433,18 +461,23 @@ var cachedBlackColor,
{
_components = components;
var hasAlpha = CPFeatureIsCompatible(CPCSSRGBAFeature) && _components[3] != 1.0;
_cssString = (hasAlpha ? "rgba(" : "rgb(") +
parseInt(_components[0] * 255.0) + ", " +
parseInt(_components[1] * 255.0) + ", " +
parseInt(_components[2] * 255.0) +
(hasAlpha ? (", " + _components[3]) : "") + ")";
[self _initCSSStringFromComponents];
}
return self;
}
- (void)_initCSSStringFromComponents
{
var hasAlpha = CPFeatureIsCompatible(CPCSSRGBAFeature) && _components[3] != 1.0;
_cssString = (hasAlpha ? "rgba(" : "rgb(") +
parseInt(_components[0] * 255.0) + ", " +
parseInt(_components[1] * 255.0) + ", " +
parseInt(_components[2] * 255.0) +
(hasAlpha ? (", " + _components[3]) : "") + ")";
}
/* @ignore */
- (id)_initWithPatternImage:(CPImage)anImage
{
@@ -532,6 +565,14 @@ var cachedBlackColor,
return [[[self class] alloc] _initWithRGBA:components];
}
/*!
Returns the receiver. This method is a placeholder that does nothing but may be implemented in the future.
*/
- (CPColor)colorUsingColorSpaceName:(id)aColorSpaceName
{
return self;
}
/*!
Returns an array with the HSB values for this color.
The index values are ordered as:
@@ -633,7 +674,36 @@ url("data:image/png;base64,BASE64ENCODEDDATA") // if there is a pattern image
- (CPString)description
{
return [super description]+" "+[self cssString];
var description = [super description],
patternImage = [self patternImage];
if (!patternImage)
return description + " " + [self cssString];
description += " {\n";
if ([patternImage isThreePartImage] || [patternImage isNinePartImage])
{
var slices = [patternImage imageSlices];
if ([patternImage isThreePartImage])
description += " orientation: " + ([patternImage isVertical] ? "vertical" : "horizontal") + ",\n";
description += " patternImage (" + slices.length + " part): [\n";
for (var i = 0; i < slices.length; ++i)
{
var imgDescription = [slices[i] description] || "nil";
description += imgDescription.replace(/^/mg, " ") + ",\n";
}
description = description.substr(0, description.length - 2) + "\n ]\n}";
}
else
description += ([patternImage description] || "nil").replace(/^/mg, " ") + "\n}";
return description;
}
@end
@@ -678,8 +748,10 @@ url("data:image/png;base64,BASE64ENCODEDDATA") // if there is a pattern image
@end
/// @cond IGNORE
var CPColorComponentsKey = @"CPColorComponentsKey",
CPColorPatternImageKey = @"CPColorPatternImageKey";
/// @endcond
@implementation CPColor (CPCoding)
@@ -710,13 +782,12 @@ var CPColorComponentsKey = @"CPColorComponentsKey",
@end
/// @cond IGNORE
var hexCharacters = "0123456789ABCDEF";
/*!
Used for the CPColor \c +colorWithHexString: implementation
@ignore
@class CPColor
@return an array of rgb components
/*
Used for the CPColor +colorWithHexString: implementation.
Returns an array of rgb components.
*/
var hexToRGB = function(hex)
{
@@ -754,3 +825,551 @@ var byteToHex = function(n)
return hexCharacters.charAt((n - n % 16) / 16) +
hexCharacters.charAt(n % 16);
};
/*!
To create a simple color with a pattern image:
CPColorWithImages(name, width, height{, bundle})
To create a color with a three-part/nine-part image using a pattern string:
CPColorWithImages(pattern, attributes{, bundle})
<pattern> must have one or more placeholders. There are there possible
placeholders available that together can be used to build a filename:
style A top-level style, for example normal (empty) and "default".
state The state of a view, for example "highlighted" and "disabled".
position The position of an image within a 3-part or 9-part image.
This must be provided.
Each placeholder is filled with the values you pass in a the attributes object.
Neither style nor state are necessary, if you omit them the next level of the
hierarchy is the top level.
Attributes
----------
styles: [...]
An array of style names. For example, if you want to generate the filenames
"button-bezel" and "default-button-bezel", you would use ["", "default"]
for the styles.
states: [...]
An array of state names.
positions: <spec>
Specifies the naming convention for the slices of the image. For 3-part images,
<spec> may be one of:
"@" Equivalent to ["left", "center", "right"] for horizontal
images, ["top", "center", "bottom"] for vertical images
"#" Equivalent to ["0", "1", "2"]
[...] An array of any three literal strings
For 9-part images, <spec> may be one of:
"@" | "abbrev" Equivalent to ["top-left", "top", "top-right",
"left", "center", "right",
"bottom-left", "bottom", "bottom-right"]
"full" Equivalent to ["top-left", "top-center", "top-right",
"center-left", "center-center", "center-right",
"bottom-left", "bottom-center", "bottom-right"]
"#" Equivalent to ["0", "1", "2", "3", "4", "5", "6", "7", "8"]
[...] An array of any nine literal strings
width: <number>
The width of the left image for horizontal 3-part images, the top image for
vertical 3-part images, or the top left corner for 9-part images.
height: <number>
The height of the left image for horizontal 3-part images, the top image for
vertical 3-part images, or the top left corner for 9-part images.
centerWidth: <number>
For a horizontal 3-part image that has a center slice width that is not 1.0,
set this for the width of the center slice. If omitted, it defaults
to 1.0. Not used for 9-part images.
rightWidth: <number>
For a horizontal 3-part image that has different left/right slice widths,
or a 9-part image that has different left/right corner slice widths,
set this for the width of the right slice. If omitted, the "width"
value is used for left and right widths.
centerHeight: <number>
For a vertical 3-part image that has a center slice height that is not 1.0,
set this for the height of the center slice. If omitted, it defaults
to 1.0. Not used for 9-part images.
bottomHeight: <number>
For a vertical image that has different top/bottom slice heights,
or a 9-part image that has different top/bottom corner slice heights,
set this for the height of the bottom slice. If omitted, the "height"
value is used for top and bottom heights.
centerIsNil: <BOOL>
For 9-part images, if the center image is nil, set this to YES.
If omitted or set to NO, a center image must be provided.
separator: <string>
The separator to use between components of the pattern.
If it is omitted, it defaults to "-".
orientation: PatternIsHorizontal | PatternIsVertical
The orientation of the image. This must be specified for 3-part images,
it should NOT be specified for 9-part images.
Using a pattern, all of this:
bezelColor = PatternColor(
[
["button-bezel-left.png", 4.0, 24.0],
["button-bezel-center.png", 1.0, 24.0],
["button-bezel-right.png", 4.0, 24.0]
],
PatternIsHorizontal),
highlightedBezelColor = PatternColor(
[
["button-bezel-highlighted-left.png", 4.0, 24.0],
["button-bezel-highlighted-center.png", 1.0, 24.0],
["button-bezel-highlighted-right.png", 4.0, 24.0]
],
PatternIsHorizontal),
disabledBezelColor = PatternColor(
[
["button-bezel-disabled-left.png", 4.0, 24.0],
["button-bezel-disabled-center.png", 1.0, 24.0],
["button-bezel-disabled-right.png", 4.0, 24.0]
],
PatternIsHorizontal),
defaultBezelColor = PatternColor(
[
["default-button-bezel-left.png", 4.0, 24.0],
["default-button-bezel-center.png", 1.0, 24.0],
["default-button-bezel-right.png", 4.0, 24.0]
],
PatternIsHorizontal),
defaultHighlightedBezelColor = PatternColor(
[
["default-button-bezel-highlighted-left.png", 4.0, 24.0],
["default-button-bezel-highlighted-center.png", 1.0, 24.0],
["default-button-bezel-highlighted-right.png", 4.0, 24.0]
],
PatternIsHorizontal),
defaultDisabledBezelColor = PatternColor(
[
["default-button-bezel-disabled-left.png", 4.0, 24.0],
["default-button-bezel-disabled-center.png", 1.0, 24.0],
["default-button-bezel-disabled-right.png", 4.0, 24.0]
],
PatternIsHorizontal)
can be replaced with this:
bezelColors = PatternColor(
"{style}button-bezel{state}{position}.png",
{
styles: ["", "default"],
states: ["", "highlighted", "disabled"],
positions: "@",
width: 4.0,
height: 24.0,
orientation: PatternIsHorizontal
})
Which would effectively create the following object:
{
"@":
{
"@": <ThreePartImage>:
[
["button-bezel-left.png", 4.0, 24.0],
["button-bezel-center.png", 1.0, 24.0],
["button-bezel-right.png", 4.0, 24.0]
],
"highlighted": <ThreePartImage>:
[
["button-bezel-highlighted-left.png", 4.0, 24.0],
["button-bezel-highlighted-center.png", 1.0, 24.0],
["button-bezel-highlighted-right.png", 4.0, 24.0]
],
"disabled": <ThreePartImage>:
[
["button-bezel-disabled-left.png", 4.0, 24.0],
["button-bezel-disabled-center.png", 1.0, 24.0],
["button-bezel-disabled-right.png", 4.0, 24.0]
]
},
"default":
{
"@": <ThreePartImage>:
[
["default-button-bezel-left.png", 4.0, 24.0],
["default-button-bezel-center.png", 1.0, 24.0],
["default-button-bezel-right.png", 4.0, 24.0]
],
"highlighted": <ThreePartImage>:
[
["default-button-bezel-highlighted-left.png", 4.0, 24.0],
["default-button-bezel-highlighted-center.png", 1.0, 24.0],
["default-button-bezel-highlighted-right.png", 4.0, 24.0]
],
"disabled": <ThreePartImage>:
[
["default-button-bezel-disabled-left.png", 4.0, 24.0],
["button-bezel-disabled-center.png", 1.0, 24.0],
["default-button-bezel-disabled-right.png", 4.0, 24.0]
]
}
}
To reference empty names in the pattern color, use the key "@".
So, for example, to reference the "default" style, "disabled" state,
you would use the following expression:
bezelColors["@"]["disabled"]
To create a color with a three-part pattern image explicitly:
CPColorWithImages(slices, orientation)
where slices is an array of three [name, width, height{, bundle}] arrays,
and orientation is CPColorPatternIsVertical or CPColorPatternIsHorizontal.
To create a color with a nine-part pattern image explicitly:
CPColorWithImages(slices);
where slices is an array of nine [name, width, height{, bundle}] arrays.
*/
function CPColorWithImages()
{
var slices = nil,
numParts = 0,
isVertical = false,
imageFactory = CPImageInBundle,
args = Array.prototype.slice.apply(arguments);
if (typeof(args[args.length - 1]) === "function")
imageFactory = args.pop();
switch (args.length)
{
case 1:
return imageFromSlices(args[0], isVertical, imageFactory);
case 2:
// New-style 3-part and 9-part images
if (typeof(args[0]) === "string")
return patternColorsFromPattern.call(this, args[0], args[1], imageFactory);
return imageFromSlices(args[0], args[1], imageFactory);
case 3:
return [CPColor colorWithPatternImage:imageFactory(args[0], args[1], args[2])];
default:
throw("ERROR: Invalid argument count: " + args.length);
}
}
var imageFromSlices = function(slices, isVertical, imageFactory)
{
var imageSlices = [];
for (var i = 0; i < slices.length; ++i)
{
var slice = slices[i];
imageSlices.push(slice ? imageFactory(slice[0], slice[1], slice[2]) : nil);
}
switch (slices.length)
{
case 3:
return [CPColor colorWithPatternImage:[[CPThreePartImage alloc] initWithImageSlices:imageSlices isVertical:isVertical]];
case 9:
return [CPColor colorWithPatternImage:[[CPNinePartImage alloc] initWithImageSlices:imageSlices]];
default:
throw("ERROR: Invalid number of image slices: " + slices.length);
}
};
var patternColorsFromPattern = function(pattern, attributes, imageFactory)
{
if (pattern.match(/^.*\{[^}]+\}/))
{
var width = attributes["width"],
height = attributes["height"],
separator = attributes["separator"] || "-",
orientation = attributes["orientation"],
rightWidth,
bottomHeight,
centerWidthHeight,
centerIsNil,
numParts;
// positions are mandatory
if (pattern.indexOf("{position}") < 0)
throw("ERROR: Pattern strings must have a {position} placeholder (\"" + pattern + "\")");
if (orientation === undefined)
{
numParts = 9;
if (attributes["centerIsNil"] !== undefined)
centerIsNil = attributes["centerIsNil"];
}
else
{
numParts = 3;
isVertical = orientation === PatternIsVertical;
if (isVertical)
{
if (attributes["centerHeight"])
centerWidthHeight = attributes["centerHeight"];
}
else
{
if (attributes["centerWidth"])
centerWidthHeight = attributes["centerWidth"];
}
}
if (attributes["rightWidth"])
rightWidth = attributes["rightWidth"];
if (attributes["bottomHeight"])
bottomHeight = attributes["bottomHeight"];
var positions = attributes["positions"] || "@",
states = nil,
styles = nil;
if (numParts === 3)
{
if (positions === "@")
{
if (isVertical)
positions = ["top", "center", "bottom"];
else
positions = ["left", "center", "right"];
}
else if (positions === "#")
positions = ["0", "1", "2"];
else
throw("ERROR: Invalid positions: " + positions)
}
else // numParts === 9
{
if (positions === "@" || positions === "abbrev")
positions = ["top-left", "top", "top-right", "left", "center", "right", "bottom-left", "bottom", "bottom-right"];
else if (positions === "full")
positions = ["top-left", "top-center", "top-right", "center-left", "center-center", "center-right", "bottom-left", "bottom-center", "bottom-right"];
else if (positions === "#")
positions = ["0", "1", "2", "3", "4", "5", "6", "7", "8"];
else
throw("ERROR: Invalid positions: " + positions)
}
// states
if (pattern.indexOf("{state}") >= 0)
{
states = attributes["states"];
if (!states)
throw("ERROR: {state} placeholder in the pattern (\"" + pattern + "\") but no states item in the attributes");
}
// styles
if (pattern.indexOf("{style}") >= 0)
{
styles = attributes["styles"];
if (!styles)
throw("ERROR: {style} placeholder in the pattern (\"" + pattern + "\") but no styles item in the attributes");
}
// Now assemble the hierarchy
var placeholder = "{position}",
pos = pattern.indexOf(placeholder),
i;
for (i = 0; i < positions.length; ++i)
positions[i] = pattern.replace(placeholder, pos === 0 ? positions[i] + separator : separator + positions[i]);
var slices = positions,
object = slices,
key,
sep;
if (states)
{
placeholder = "{state}";
pos = pattern.indexOf(placeholder);
object = {};
for (i = 0; i < states.length; ++i)
{
var state = states[i];
key = state || "@";
sep = state ? separator : "";
object[key] = slices.slice(0);
replacePlaceholderInArray(object[key], placeholder, pos === 0 ? state + sep : sep + state);
}
}
if (styles)
{
placeholder = "{style}";
pos = pattern.indexOf(placeholder);
var styleObject = {};
for (i = 0; i < styles.length; ++i)
{
var style = styles[i];
key = style || "@";
sep = style ? separator : "";
if (states)
{
styleObject[key] = cloneObject(object);
replacePlaceholderInObject(styleObject[key], placeholder, pos === 0 ? style + sep : sep + style);
}
else
{
styleObject[key] = slices.slice(0);
replacePlaceholderInArray(styleObject[key], placeholder, pos === 0 ? style + sep : sep + style);
}
}
object = styleObject;
}
if (styles || states)
{
if (numParts === 3)
makeThreePartSlicesFromObject(object, width, height, centerWidthHeight, rightWidth, bottomHeight, isVertical);
else
makeNinePartSlicesFromObject(object, width, height, rightWidth, bottomHeight, centerIsNil);
makeImagesFromObject(object, isVertical, imageFactory);
return object;
}
else
{
if (numParts === 3)
makeThreePartSlicesFromArray(object, width, height, centerWidthHeight, rightWidth, bottomHeight, isVertical);
else
makeNinePartSlicesFromArray(object, width, height, rightWidth, bottomHeight, centerIsNil);
return imageFromSlices(object, isVertical, imageFactory);
}
}
else
throw("ERROR: No placeholders in slice pattern (\"" + pattern + "\")");
};
var replacePlaceholderInArray = function(array, find, replacement)
{
for (var i = 0; i < array.length; ++i)
array[i] = array[i].replace(find, replacement);
};
var replacePlaceholderInObject = function(object, find, replacement)
{
for (var key in object)
if (object.hasOwnProperty(key))
if (object[key].constructor === Array)
replacePlaceholderInArray(object[key], find, replacement);
else
replacePlaceholderInObject(object[key], find, replacement);
};
var cloneObject = function(object)
{
var clone = {};
for (var key in object)
if (object.hasOwnProperty(key))
if (object[key].constructor === Array)
clone[key] = object[key].slice(0);
else if (typeof(object) === "object")
clone[key] = cloneObject(object[key]);
else
clone[key] = object[key];
return clone;
};
var makeThreePartSlicesFromObject = function(object, width, height, centerWidthHeight, rightWidth, bottomHeight, isVertical)
{
for (var key in object)
if (object.hasOwnProperty(key))
if (object[key].constructor === Array)
makeThreePartSlicesFromArray(object[key], width, height, centerWidthHeight, rightWidth, bottomHeight, isVertical);
else // object
makeThreePartSlicesFromObject(object[key], width, height, centerWidthHeight, rightWidth, bottomHeight, isVertical);
};
var makeThreePartSlicesFromArray = function(array, width, height, centerWidthHeight, rightWidth, bottomHeight, isVertical)
{
array[0] = [array[0], width, height];
if (isVertical)
{
array[1] = [array[1], width, centerWidthHeight ? centerWidthHeight : 1.0];
array[2] = [array[2], width, bottomHeight ? bottomHeight : height];
}
else
{
array[1] = [array[1], centerWidthHeight ? centerWidthHeight : 1.0, height];
array[2] = [array[2], rightWidth ? rightWidth : width, height];
}
};
var makeNinePartSlicesFromObject = function(object, width, height, rightWidth, bottomHeight, centerIsNil)
{
for (var key in object)
if (object.hasOwnProperty(key))
if (object[key].constructor === Array)
makeNinePartSlicesFromArray(object[key], width, height, rightWidth, bottomHeight, centerIsNil);
else // object
makeNinePartSlicesFromObject(object[key], width, height, rightWidth, bottomHeight, centerIsNil);
};
var makeNinePartSlicesFromArray = function(array, width, height, rightWidth, bottomHeight, centerIsNil)
{
rightWidth = rightWidth ? rightWidth : width;
bottomHeight = bottomHeight ? bottomHeight : height;
array[0] = [array[0], width, height]; // top-left
array[1] = [array[1], 1.0, height]; // top
array[2] = [array[2], rightWidth, height]; // top-right
array[3] = [array[3], width, 1.0]; // left
array[4] = centerIsNil ? nil : [array[4], 1.0, 1.0]; // center
array[5] = [array[5], rightWidth, 1.0]; // right
array[6] = [array[6], width, bottomHeight]; // bottom-left
array[7] = [array[7], 1.0, bottomHeight]; // bottom
array[8] = [array[8], rightWidth, bottomHeight]; // bottom-right
};
var makeImagesFromObject = function(object, isVertical, imageFactory)
{
for (var key in object)
if (object.hasOwnProperty(key))
if (object[key].constructor === Array)
object[key] = imageFromSlices(object[key], isVertical, imageFactory);
else // object
makeImagesFromObject(object[key], isVertical, imageFactory);
};
/// @endcond
+63 -59
View File
@@ -20,12 +20,31 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "CPApplication.j"
@import "CPButton.j"
@import "CPCookie.j"
@import "CPPanel.j"
@import "CPView.j"
@class CPSlider
@global CPApp
/*
A color wheel
@global
@group CPColorPanelMode
*/
CPWheelColorPickerMode = 1;
/*
Slider based picker
@global
@group CPColorPanelMode
*/
CPSliderColorPickerMode = 2;
CPColorPickerViewWidth = 265;
CPColorPickerViewHeight = 370;
CPColorPanelColorDidChangeNotification = @"CPColorPanelColorDidChangeNotification";
@@ -38,22 +57,6 @@ var PREVIEW_HEIGHT = 20.0,
var SharedColorPanel = nil,
ColorPickerClasses = [];
/*
A color wheel
@global
@group CPColorPanelMode
*/
CPWheelColorPickerMode = 1;
/*
Slider based picker
@global
@group CPColorPanelMode
*/
CPSliderColorPickerMode = 2;
CPColorPickerViewWidth = 265,
CPColorPickerViewHeight = 370;
/*!
@ingroup appkit
@class CPColorPanel
@@ -123,7 +126,7 @@ CPColorPickerViewHeight = 370;
if (self)
{
[[self contentView] setBackgroundColor:[CPColor colorWithWhite:0.95 alpha:1.0]];
//[[self contentView] setBackgroundColor:[CPColor colorWithWhite:0.95 alpha:1.0]];
[self setTitle:@"Color Panel"];
[self setLevel:CPFloatingWindowLevel];
@@ -144,7 +147,7 @@ CPColorPickerViewHeight = 370;
- (void)setColor:(CPColor)aColor
{
_color = aColor;
[_previewView setBackgroundColor: _color];
[_previewView setBackgroundColor:_color];
[CPApp sendAction:@selector(changeColor:) to:nil from:self];
@@ -248,8 +251,8 @@ CPColorPickerViewHeight = 370;
var height = (TOOLBAR_HEIGHT + 10 + PREVIEW_HEIGHT + 5 + SWATCH_HEIGHT + 32),
bounds = [[self contentView] bounds];
[view setFrameSize:CPSizeMake(bounds.size.width - 10, bounds.size.height - height)];
[view setFrameOrigin:CPPointMake(5, height)];
[view setFrameSize:CGSizeMake(bounds.size.width - 10, bounds.size.height - height)];
[view setFrameOrigin:CGPointMake(5, height)];
}
[_currentView removeFromSuperview];
@@ -299,7 +302,7 @@ CPColorPickerViewHeight = 370;
bounds = [contentView bounds];
_toolbar = [[CPView alloc] initWithFrame:CGRectMake(0, 6, CGRectGetWidth(bounds), TOOLBAR_HEIGHT)];
[_toolbar setAutoresizingMask: CPViewWidthSizable];
[_toolbar setAutoresizingMask:CPViewWidthSizable];
var totalToolbarWidth = count * ICON_WIDTH + (count - 1) * ICON_PADDING,
leftOffset = (CGRectGetWidth(bounds) - totalToolbarWidth) / 2.0,
@@ -339,7 +342,7 @@ CPColorPickerViewHeight = 370;
[previewBox addSubview:_previewView];
var _previewLabel = [[CPTextField alloc] initWithFrame: CPRectMake(10, TOOLBAR_HEIGHT + 10, 60, 15)];
var _previewLabel = [[CPTextField alloc] initWithFrame:CGRectMake(10, TOOLBAR_HEIGHT + 10, 60, 15)];
[_previewLabel setStringValue:"Preview:"];
[_previewLabel setTextColor:[CPColor blackColor]];
[_previewLabel setAlignment:CPRightTextAlignment];
@@ -357,14 +360,14 @@ CPColorPickerViewHeight = 370;
[swatchBox addSubview:_swatchView];
var _swatchLabel = [[CPTextField alloc] initWithFrame: CPRectMake(10, TOOLBAR_HEIGHT + 8 + PREVIEW_HEIGHT + 6, 60, 15)];
[_swatchLabel setStringValue: "Swatches:"];
var _swatchLabel = [[CPTextField alloc] initWithFrame:CGRectMake(10, TOOLBAR_HEIGHT + 8 + PREVIEW_HEIGHT + 6, 60, 15)];
[_swatchLabel setStringValue:"Swatches:"];
[_swatchLabel setTextColor:[CPColor blackColor]];
[_swatchLabel setAlignment:CPRightTextAlignment];
var opacityLabel = [[CPTextField alloc] initWithFrame: CPRectMake(10, TOOLBAR_HEIGHT + PREVIEW_HEIGHT + 35, 60, 20)];
[opacityLabel setStringValue: "Opacity:"];
var opacityLabel = [[CPTextField alloc] initWithFrame:CGRectMake(10, TOOLBAR_HEIGHT + PREVIEW_HEIGHT + 35, 60, 20)];
[opacityLabel setStringValue:"Opacity:"];
[opacityLabel setTextColor:[CPColor blackColor]];
[opacityLabel setAlignment:CPRightTextAlignment];
@@ -389,7 +392,7 @@ CPColorPickerViewHeight = 370;
_action = nil;
_activePicker = nil;
[_previewView setBackgroundColor: _color];
[_previewView setBackgroundColor:_color];
if (buttonForLater)
[self _setPicker:buttonForLater];
@@ -407,28 +410,29 @@ CPColorPickerViewHeight = 370;
CPColorDragType = "CPColorDragType";
var CPColorPanelSwatchesCookie = "CPColorPanelSwatchesCookie";
/* @ignore */
@implementation _CPColorPanelSwatches : CPView
{
CPView[] _swatches;
CPArray _swatches;
CPColor _dragColor;
CPColorPanel _colorPanel;
CPCookie _swatchCookie;
}
- (id)initWithFrame:(CPRect)aFrame
- (id)initWithFrame:(CGRect)aFrame
{
self = [super initWithFrame:aFrame];
[self setBackgroundColor: [CPColor grayColor]];
[self setBackgroundColor:[CPColor grayColor]];
[self registerForDraggedTypes:[CPArray arrayWithObjects:CPColorDragType]];
var whiteColor = [CPColor whiteColor];
_swatchCookie = [[CPCookie alloc] initWithName: CPColorPanelSwatchesCookie];
_swatchCookie = [[CPCookie alloc] initWithName:CPColorPanelSwatchesCookie];
var colorList = [self startingColorList];
_swatches = [];
@@ -436,15 +440,15 @@ var CPColorPanelSwatchesCookie = "CPColorPanelSwatchesCookie";
for (var i = 0; i < 50; i++)
{
// FIXME: http://280north.lighthouseapp.com/projects/13294-cappuccino/tickets/25-implement-cpbox
var view = [[CPView alloc] initWithFrame: CPRectMake(13 * i + 1, 1, 12, 12)],
var view = [[CPView alloc] initWithFrame:CGRectMake(13 * i + 1, 1, 12, 12)],
fillView = [[CPView alloc] initWithFrame:CGRectInset([view bounds], 1.0, 1.0)];
[view setBackgroundColor:whiteColor];
[fillView setBackgroundColor: (i < colorList.length) ? colorList[i] : whiteColor];
[fillView setBackgroundColor:(i < colorList.length) ? colorList[i] : whiteColor];
[view addSubview:fillView];
[self addSubview: view];
[self addSubview:view];
_swatches.push(view);
}
@@ -461,7 +465,7 @@ var CPColorPanelSwatchesCookie = "CPColorPanelSwatchesCookie";
{
var cookieValue = [_swatchCookie value];
if (cookieValue == "")
if (!cookieValue)
{
return [
[CPColor blackColor],
@@ -480,7 +484,7 @@ var CPColorPanelSwatchesCookie = "CPColorPanelSwatchesCookie";
result = [];
for (var i = 0; i < cookieValue.length; i++)
result.push([CPColor colorWithHexString: cookieValue[i]]);
result.push([CPColor colorWithHexString:cookieValue[i]]);
return result;
}
@@ -495,7 +499,7 @@ var CPColorPanelSwatchesCookie = "CPColorPanelSwatchesCookie";
var future = new Date();
future.setYear(2019);
[_swatchCookie setValue: JSON.stringify(result) expires:future domain: nil];
[_swatchCookie setValue:JSON.stringify(result) expires:future domain:nil];
}
- (void)setColorPanel:(CPColorPanel)panel
@@ -528,7 +532,7 @@ var CPColorPanelSwatchesCookie = "CPColorPanelSwatchesCookie";
if (!CGRectContainsPoint(bounds, point) || point.x > [self bounds].size.width - 1 || point.x < 1)
return NO;
[_colorPanel setColor: [self colorAtIndex:FLOOR(point.x / 13)] updatePicker: YES];
[_colorPanel setColor:[self colorAtIndex:FLOOR(point.x / 13)] updatePicker:YES];
}
- (void)mouseDragged:(CPEvent)anEvent
@@ -545,10 +549,10 @@ var CPColorPanelSwatchesCookie = "CPColorPanelSwatchesCookie";
// FIXME: http://280north.lighthouseapp.com/projects/13294-cappuccino/tickets/25-implement-cpbox
_dragColor = [[swatch subviews][0] backgroundColor];
var bounds = CPRectCreateCopy([swatch bounds]);
var bounds = CGRectMakeCopy([swatch bounds]);
// FIXME: http://280north.lighthouseapp.com/projects/13294-cappuccino/tickets/25-implement-cpbox
var dragView = [[CPView alloc] initWithFrame: bounds],
var dragView = [[CPView alloc] initWithFrame:bounds],
dragFillView = [[CPView alloc] initWithFrame:CGRectInset(bounds, 1.0, 1.0)];
[dragView setBackgroundColor:[CPColor blackColor]];
@@ -556,13 +560,13 @@ var CPColorPanelSwatchesCookie = "CPColorPanelSwatchesCookie";
[dragView addSubview:dragFillView];
[self dragView: dragView
at: CPPointMake(point.x - bounds.size.width / 2.0, point.y - bounds.size.height / 2.0)
offset: CPPointMake(0.0, 0.0)
event: anEvent
pasteboard: nil
source: self
slideBack: YES];
[self dragView:dragView
at:CGPointMake(point.x - bounds.size.width / 2.0, point.y - bounds.size.height / 2.0)
offset:CGPointMake(0.0, 0.0)
event:anEvent
pasteboard:nil
source:self
slideBack:YES];
}
- (void)pasteboard:(CPPasteboard)aPasteboard provideDataForType:(CPString)aType
@@ -580,7 +584,7 @@ var CPColorPanelSwatchesCookie = "CPColorPanelSwatchesCookie";
if (![pasteboard availableTypeFromArray:[CPColorDragType]] || location.x > [self bounds].size.width - 1 || location.x < 1)
return NO;
[self setColor:[CPKeyedUnarchiver unarchiveObjectWithData:[pasteboard dataForType:CPColorDragType]] atIndex: FLOOR(location.x / 13)];
[self setColor:[CPKeyedUnarchiver unarchiveObjectWithData:[pasteboard dataForType:CPColorDragType]] atIndex:FLOOR(location.x / 13)];
}
@end
@@ -591,7 +595,7 @@ var CPColorPanelSwatchesCookie = "CPColorPanelSwatchesCookie";
CPColorPanel _colorPanel;
}
- (id)initWithFrame:(CPRect)aFrame
- (id)initWithFrame:(CGRect)aFrame
{
self = [super initWithFrame:aFrame];
@@ -632,10 +636,10 @@ var CPColorPanelSwatchesCookie = "CPColorPanelSwatchesCookie";
[[CPPasteboard pasteboardWithName:CPDragPboard] declareTypes:[CPColorDragType] owner:self];
var bounds = CPRectMake(0, 0, 15, 15);
var bounds = CGRectMake(0, 0, 15, 15);
// FIXME: http://280north.lighthouseapp.com/projects/13294-cappuccino/tickets/25-implement-cpbox
var dragView = [[CPView alloc] initWithFrame: bounds],
var dragView = [[CPView alloc] initWithFrame:bounds],
dragFillView = [[CPView alloc] initWithFrame:CGRectInset(bounds, 1.0, 1.0)];
[dragView setBackgroundColor:[CPColor blackColor]];
@@ -643,13 +647,13 @@ var CPColorPanelSwatchesCookie = "CPColorPanelSwatchesCookie";
[dragView addSubview:dragFillView];
[self dragView: dragView
at: CPPointMake(point.x - bounds.size.width / 2.0, point.y - bounds.size.height / 2.0)
offset: CPPointMake(0.0, 0.0)
event: anEvent
pasteboard: nil
source: self
slideBack: YES];
[self dragView:dragView
at:CGPointMake(point.x - bounds.size.width / 2.0, point.y - bounds.size.height / 2.0)
offset:CGPointMake(0.0, 0.0)
event:anEvent
pasteboard:nil
source:self
slideBack:YES];
}
- (void)pasteboard:(CPPasteboard)aPasteboard provideDataForType:(CPString)aType
+50 -40
View File
@@ -24,6 +24,12 @@
@import "CPView.j"
@class CPSlider
@global CPColorPickerViewWidth
@global CPColorPickerViewHeight
@global CPWheelColorPickerMode
/*!
@ingroup appkit
@@ -44,10 +50,11 @@
*/
- (id)initWithPickerMask:(int)aMask colorPanel:(CPColorPanel)aPanel
{
self = [super init];
_panel = aPanel;
_mask = aMask;
if (self = [super init])
{
_panel = aPanel;
_mask = aMask;
}
return self;
}
@@ -76,7 +83,6 @@
*/
- (void)setMode:(CPColorPanelMode)mode
{
return;
}
/*!
@@ -85,7 +91,6 @@
*/
- (void)setColor:(CPColor)aColor
{
return;
}
@end
@@ -110,12 +115,12 @@
- (id)initView
{
aFrame = CPRectMake(0, 0, CPColorPickerViewWidth, CPColorPickerViewHeight);
var aFrame = _CGRectMake(0, 0, CPColorPickerViewWidth, CPColorPickerViewHeight);
_pickerView = [[CPView alloc] initWithFrame:aFrame];
[_pickerView setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
_brightnessSlider = [[CPSlider alloc] initWithFrame:CGRectMake(0, (aFrame.size.height - 34), aFrame.size.width, 15)];
_brightnessSlider = [[CPSlider alloc] initWithFrame:_CGRectMake(0, (aFrame.size.height - 34), aFrame.size.width, 15)];
[_brightnessSlider setValue:15.0 forThemeAttribute:@"track-width"];
[_brightnessSlider setValue:[CPColor colorWithPatternImage:[[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:[CPColorPicker class]] pathForResource:@"brightness_bar.png"]]] forThemeAttribute:@"track-color"];
@@ -128,9 +133,9 @@
[_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)];
_hueSaturationView = [[__CPColorWheel alloc] initWithFrame:_CGRectMake(0, 0, aFrame.size.width, aFrame.size.height - 38)];
[_hueSaturationView setDelegate:self];
[_hueSaturationView setAutoresizingMask:(CPViewWidthSizable | CPViewHeightSizable)];
[_pickerView addSubview:_hueSaturationView];
[_pickerView addSubview:_brightnessSlider];
@@ -223,60 +228,64 @@
float _radius;
}
- (id)initWithFrame:(CPRect)aFrame
- (id)initWithFrame:(CGRect)aFrame
{
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"];
_blackWheelImage = new Image();
_blackWheelImage.src = path;
_blackWheelImage.style.opacity = "0";
_blackWheelImage.style.filter = "alpha(opacity=0)"
_blackWheelImage.style.position = "absolute";
if (self = [super initWithFrame:aFrame])
{
#if PLATFORM(DOM)
_DOMElement.appendChild(_wheelImage);
_DOMElement.appendChild(_blackWheelImage);
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"];
_blackWheelImage = new Image();
_blackWheelImage.src = path;
_blackWheelImage.style.opacity = "0";
_blackWheelImage.style.filter = "alpha(opacity=0)"
_blackWheelImage.style.position = "absolute";
_DOMElement.appendChild(_wheelImage);
_DOMElement.appendChild(_blackWheelImage);
#endif
[self setWheelSize:aFrame.size];
[self setWheelSize:aFrame.size];
_crosshair = [[CPView alloc] initWithFrame:CPRectMake(_radius - 2, _radius - 2, 4, 4)];
[_crosshair setBackgroundColor:[CPColor blackColor]];
_crosshair = [[CPView alloc] initWithFrame:CGRectMake(_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]];
var view = [[CPView alloc] initWithFrame:CGRectInset([_crosshair bounds], 1.0, 1.0)];
[view setBackgroundColor:[CPColor whiteColor]];
[_crosshair addSubview:view];
[_crosshair addSubview:view];
[self addSubview:_crosshair];
[self addSubview:_crosshair];
}
return self;
}
- (void)setWheelBrightness:(float)brightness
{
#if PLATFORM(DOM)
_blackWheelImage.style.opacity = 1.0 - brightness;
_blackWheelImage.style.filter = "alpha(opacity=" + (1.0 - brightness) * 100 + ")"
#endif
}
- (void)setFrameSize:(CPSize)aSize
- (void)setFrameSize:(CGSize)aSize
{
[super setFrameSize:aSize];
[self setWheelSize:aSize];
}
- (void)setWheelSize:(CPSize)aSize
- (void)setWheelSize:(CGSize)aSize
{
var min = MIN(aSize.width, aSize.height);
#if PLATFORM(DOM)
_blackWheelImage.style.width = min;
_blackWheelImage.style.height = min;
_blackWheelImage.width = min;
@@ -290,6 +299,7 @@
_wheelImage.height = min;
_wheelImage.style.top = (aSize.height - min) / 2.0 + "px";
_wheelImage.style.left = (aSize.width - min) / 2.0 + "px";
#endif
_radius = min / 2.0;
@@ -349,7 +359,7 @@
_angle = [self radiansToDegrees:angle];
_distance = (distance / _radius) * 100.0;
[_crosshair setFrameOrigin:CPPointMake(COS(angle) * distance + midX - 2.0, SIN(angle) * distance + midY - 2.0)];
[_crosshair setFrameOrigin:CGPointMake(COS(angle) * distance + midX - 2.0, SIN(angle) * distance + midY - 2.0)];
}
- (void)setPositionToColor:(CPColor)aColor
+64
View File
@@ -0,0 +1,64 @@
/*
* CPColorSpace.j
* AppKit
*
* Created by Alexander Ljungberg.
* Copyright 2012, SlevenBits Ltd.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import <Foundation/CPObject.j>
var sRGBColorSpace = nil;
/*!
Represent color spaces.
*/
@implementation CPColorSpace : CPObject
{
CGColorSpace _cgColorSpace;
}
/*!
Return an object representing the standard sRGB color space.
*/
+ (CPColorSpace)sRGBColorSpace
{
if (!sRGBColorSpace)
sRGBColorSpace = [[self alloc] initWithCGColorSpace:CGColorSpaceCreateDeviceRGB()];
return sRGBColorSpace;
}
- (id)initWithCGColorSpace:(CGColorSpace)cgColorSpace
{
if (self = [super init])
{
_cgColorSpace = cgColorSpace;
}
return self;
}
/*!
Return a Core Graphics color space representing the receiver.
*/
- (CGColorSpace)CGColorSpace
{
return _cgColorSpace;
}
@end
+155 -78
View File
@@ -43,7 +43,33 @@ var _CPColorWellDidBecomeExclusiveNotification = @"_CPColorWellDidBecomeExclusiv
BOOL _bordered;
CPColor _color;
CPView _wellView;
}
+ (Class)_binderClassForBinding:(CPString)theBinding
{
if (theBinding == CPValueBinding)
return [CPColorWellValueBinder class];
return [super _binderClassForBinding:theBinding];
}
+ (CPString)defaultThemeClass
{
return @"colorwell";
}
+ (id)themeAttributes
{
return [CPDictionary dictionaryWithObjects:[_CGInsetMakeZero(), [CPNull null], _CGInsetMake(3.0, 3.0, 3.0, 3.0), _CGInsetMakeZero(), [CPNull null]]
forKeys:[@"bezel-inset", @"bezel-color", @"content-inset", @"content-border-inset", @"content-border-color"]];
}
- (void)_reverseSetBinding
{
var binderClass = [[self class] _binderClassForBinding:CPValueBinding],
theBinding = [binderClass getBinding:CPValueBinding forObject:self];
[theBinding reverseSetValueFor:@"color"];
}
- (id)initWithFrame:(CGRect)aFrame
@@ -53,11 +79,8 @@ var _CPColorWellDidBecomeExclusiveNotification = @"_CPColorWellDidBecomeExclusiv
if (self)
{
_active = NO;
_bordered = YES;
_color = [CPColor whiteColor];
[self drawBezelWithHighlight:NO];
[self drawWellInside:CGRectInset([self bounds], 3.0, 3.0)];
[self setBordered:YES];
[self _registerForNotifications];
}
@@ -82,25 +105,23 @@ var _CPColorWellDidBecomeExclusiveNotification = @"_CPColorWellDidBecomeExclusiv
object:[CPColorPanel sharedColorPanel]];
}
/*!
Sets whether the color well is bordered.
*/
- (void)setBordered:(BOOL)shouldBeBordered
{
if (shouldBeBordered)
[self setThemeState:CPThemeStateBordered];
else
[self unsetThemeState:CPThemeStateBordered];
}
/*!
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)];
return [self hasThemeState:CPThemeStateBordered];
}
// Managing Color From Color Wells
@@ -123,7 +144,7 @@ var _CPColorWellDidBecomeExclusiveNotification = @"_CPColorWellDidBecomeExclusiv
_color = aColor;
[self drawWellInside:CGRectInset([self bounds], 3.0, 3.0)];
[self setNeedsLayout];
}
/*!
@@ -186,31 +207,6 @@ var _CPColorWellDidBecomeExclusiveNotification = @"_CPColorWellDidBecomeExclusiv
return _active;
}
// Drawing a Color Well
- (void)drawBezelWithHighlight:(BOOL)shouldHighlight
{
}
/*!
Draws the colored area inside the color well without borders.
@param aRect the location at which to draw
*/
- (void)drawWellInside:(CGRect)aRect
{
if (!_wellView)
{
_wellView = [[CPView alloc] initWithFrame:aRect];
[_wellView setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
[self addSubview:_wellView];
}
else
[_wellView setFrame:aRect];
[_wellView setBackgroundColor:_color];
}
- (void)colorPanelDidChangeColor:(CPNotification)aNotification
{
[self takeColorFrom:[aNotification object]];
@@ -229,27 +225,11 @@ var _CPColorWellDidBecomeExclusiveNotification = @"_CPColorWellDidBecomeExclusiv
[self deactivate];
}
- (void)mouseDown:(CPEvent)anEvent
- (void)stopTracking:(CGPoint)lastPoint at:(CGPoint)aPoint mouseIsUp:(BOOL)mouseIsUp
{
if (![self isEnabled])
return;
[self highlight:NO];
[self drawBezelWithHighlight:YES];
}
- (void)mouseDragged:(CPEvent)anEvent
{
if (![self isEnabled])
return;
[self drawBezelWithHighlight:CGRectContainsPoint([self bounds], [self convertPoint:[anEvent locationInWindow] fromView:nil])];
}
- (void)mouseUp:(CPEvent)anEvent
{
[self drawBezelWithHighlight:NO];
if (!CGRectContainsPoint([self bounds], [self convertPoint:[anEvent locationInWindow] fromView:nil]) || ![self isEnabled])
if (!mouseIsUp || !CGRectContainsPoint([self bounds], aPoint) || ![self isEnabled])
return;
[self activate:YES];
@@ -260,6 +240,115 @@ var _CPColorWellDidBecomeExclusiveNotification = @"_CPColorWellDidBecomeExclusiv
[colorPanel orderFront:self];
}
- (CGRect)contentRectForBounds:(CGRect)bounds
{
var contentInset = [self currentValueForThemeAttribute:@"content-inset"];
return _CGRectInsetByInset(bounds, contentInset);
}
- (CGRect)bezelRectForBounds:(CGRect)bounds
{
var bezelInset = [self currentValueForThemeAttribute:@"bezel-inset"];
return _CGRectInsetByInset(bounds, bezelInset);
}
- (CGRect)contentBorderRectForBounds:(CGRect)bounds
{
var contentBorderInset = [self currentValueForThemeAttribute:@"content-border-inset"];
return _CGRectInsetByInset(bounds, contentBorderInset);
}
- (CGRect)rectForEphemeralSubviewNamed:(CPString)aName
{
switch (aName)
{
case "bezel-view":
return [self bezelRectForBounds:[self bounds]];
case "content-view":
return [self contentRectForBounds:[self bounds]];
case "content-border-view":
return [self contentBorderRectForBounds:[self bounds]];
}
return [super rectForEphemeralSubviewNamed:aName];
}
- (CPView)createEphemeralSubviewNamed:(CPString)aName
{
var view = [[CPView alloc] initWithFrame:_CGRectMakeZero()];
[view setHitTests:NO];
return view;
}
- (void)layoutSubviews
{
var bezelView = [self layoutEphemeralSubviewNamed:@"bezel-view"
positioned:CPWindowBelow
relativeToEphemeralSubviewNamed:@"content-view"];
[bezelView setBackgroundColor:[self currentValueForThemeAttribute:@"bezel-color"]];
var contentView = [self layoutEphemeralSubviewNamed:@"content-view"
positioned:CPWindowAbove
relativeToEphemeralSubviewNamed:@"bezel-view"];
[contentView setBackgroundColor:_color];
var contentBorderView = [self layoutEphemeralSubviewNamed:@"content-border-view"
positioned:CPWindowAbove
relativeToEphemeralSubviewNamed:@"content-view"];
[contentBorderView setBackgroundColor:[self currentValueForThemeAttribute:@"content-border-color"]];
}
@end
@implementation CPColorWellValueBinder : CPBinder
{
}
- (void)_updatePlaceholdersWithOptions:(CPDictionary)options
{
var placeholderColor = [CPColor blueColor];
[self _setPlaceholder:placeholderColor forMarker:CPMultipleValuesMarker isDefault:YES];
[self _setPlaceholder:placeholderColor forMarker:CPNoSelectionMarker isDefault:YES];
[self _setPlaceholder:placeholderColor forMarker:CPNotApplicableMarker isDefault:YES];
[self _setPlaceholder:placeholderColor forMarker:CPNullMarker isDefault:YES];
}
- (void)setValueFor:(CPString)theBinding
{
var destination = [_info objectForKey:CPObservedObjectKey],
keyPath = [_info objectForKey:CPObservedKeyPathKey],
options = [_info objectForKey:CPOptionsKey],
newValue = [destination valueForKeyPath:keyPath],
isPlaceholder = CPIsControllerMarker(newValue);
if (isPlaceholder)
{
if (newValue === CPNotApplicableMarker && [options objectForKey:CPRaisesForNotApplicableKeysBindingOption])
{
[CPException raise:CPGenericException
reason:@"can't transform non applicable key on: " + _source + " value: " + newValue];
}
newValue = [self _placeholderForMarker:newValue];
}
else
{
newValue = [self transformValue:newValue withOptions:options];
}
[_source setColor:newValue];
}
@end
var CPColorWellColorKey = "CPColorWellColorKey",
@@ -278,11 +367,8 @@ var CPColorWellColorKey = "CPColorWellColorKey",
if (self)
{
_active = NO;
_bordered = [aCoder decodeBoolForKey:CPColorWellBorderedKey];
_color = [aCoder decodeObjectForKey:CPColorWellColorKey];
[self drawBezelWithHighlight:NO];
[self drawWellInside:CGRectInset([self bounds], 3.0, 3.0)];
[self setBordered:[aCoder decodeBoolForKey:CPColorWellBorderedKey]];
[self _registerForNotifications];
}
@@ -296,19 +382,10 @@ var CPColorWellColorKey = "CPColorWellColorKey",
*/
- (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];
[aCoder encodeObject:[self isBordered] forKey:CPColorWellBorderedKey];
}
@end
+1193
View File
File diff suppressed because it is too large Load Diff
+150 -2
View File
@@ -20,7 +20,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "CPEvent.j"
@import "CPEvent_Constants.j"
@import "CPPlatform.j"
@@ -67,13 +67,29 @@ CPHTML5DragAndDropSourceYOffBy1 = 1 << 26;
CPSOPDisabledFromFileURLs = 1 << 27;
// element.style.font can be set for an element not in the DOM.
CPInputSetFontOutsideOfDOM = 1 << 28;
// Input elements have 1 px of extra padding on the left regardless of padding setting.
CPInput1PxLeftPadding = 1 << 29;
CPInputOnInputEventFeature = 1 << 30;
// When an absolutely positioned div (CPView) with an absolutely positioned canvas in it (CPView with drawRect:) moves things on top of the canvas
// (subviews) don't redraw correctly. E.g. if you have a bunch of text fields in a CPBox in a sheet which animates in, some of the text fields might
// not be visible because the CPBox has a canvas at the bottom and the box moved form offscreen to onscreen.
// This bug is probably very related: https://bugs.webkit.org/show_bug.cgi?id=67203
CPCanvasParentDrawErrorsOnMovementBug = 1 << 0;
var USER_AGENT = "",
PLATFORM_ENGINE = CPUnknownBrowserEngine,
PLATFORM_FEATURES = 0;
PLATFORM_FEATURES = 0,
PLATFORM_BUGS = 0,
PLATFORM_STYLE_JS_PROPERTIES = {};
// default these features to true
PLATFORM_FEATURES |= CPInputTypeCanBeChangedFeature;
PLATFORM_FEATURES |= CPInputSetFontOutsideOfDOM;
if (typeof window !== "undefined" && typeof window.navigator !== "undefined")
USER_AGENT = window.navigator.userAgent;
@@ -99,6 +115,9 @@ else if (typeof window !== "undefined" && window.attachEvent) // Must follow Ope
PLATFORM_FEATURES |= CPOpacityRequiresFilterFeature;
PLATFORM_FEATURES &= ~CPInputTypeCanBeChangedFeature;
// Tested in Internet Explore 8 and 9.
PLATFORM_FEATURES &= ~CPInputSetFontOutsideOfDOM;
}
// WebKit
@@ -135,8 +154,16 @@ else if (USER_AGENT.indexOf("AppleWebKit/") != -1)
if (majorVersion < 532 || (majorVersion === 532 && minorVersion < 6))
PLATFORM_FEATURES |= CPHTML5DragAndDropSourceYOffBy1;
// This is supposedly fixed in webkit r123603. Seems to work in Chrome 21 but not Safari 6.0.
if (majorVersion < 537)
PLATFORM_FEATURES |= CPInput1PxLeftPadding;
if (USER_AGENT.indexOf("Chrome") === CPNotFound)
PLATFORM_FEATURES |= CPSOPDisabledFromFileURLs;
// Assume this bug was introduced around Safari 5.1/Chrome 16. This could probably be tighter.
if (majorVersion > 533)
PLATFORM_BUGS |= CPCanvasParentDrawErrorsOnMovementBug;
}
// KHTML
@@ -160,6 +187,9 @@ else if (USER_AGENT.indexOf("Gecko") !== -1) // Must follow KHTML check.
if (version < 3.0)
PLATFORM_FEATURES |= CPJavaScriptMouseWheelValues_8_15;
// Some day this might be fixed and should be version prefixed. No known fixed version yet.
PLATFORM_FEATURES |= CPInput1PxLeftPadding;
}
// Feature Specific Checks
@@ -185,6 +215,16 @@ if (typeof document != "undefined")
PLATFORM_FEATURES |= CPJavaScriptInnerTextFeature;
else if (DOMElement.textContent != undefined)
PLATFORM_FEATURES |= CPJavaScriptTextContentFeature;
var DOMInputElement = document.createElement("input");
if ("oninput" in DOMInputElement)
PLATFORM_FEATURES |= CPInputOnInputEventFeature;
else if (typeof DOMInputElement.setAttribute === "function")
{
DOMInputElement.setAttribute("oninput", "return;");
if (typeof DOMInputElement.oninput === "function")
PLATFORM_FEATURES |= CPInputOnInputEventFeature;
}
}
function CPFeatureIsCompatible(aFeature)
@@ -192,6 +232,11 @@ function CPFeatureIsCompatible(aFeature)
return PLATFORM_FEATURES & aFeature;
}
function CPPlatformHasBug(aBug)
{
return PLATFORM_BUGS & aBug;
}
function CPBrowserIsEngine(anEngine)
{
return PLATFORM_ENGINE === anEngine;
@@ -229,3 +274,106 @@ else
CPUndoKeyEquivalentModifierMask = CPControlKeyMask;
CPRedoKeyEquivalentModifierMask = CPControlKeyMask;
}
/*!
Return the properly prefixed JS property for the given name. E.g. in a webkit browser,
CPBrowserStyleProperty('transition') -> WebkitTransition
While technically not a style property, style related event handler names are also supported.
CPBrowserStyleProperty('transitionend') -> 'webkitTransitionEnd'
CSS is only available in platform(dom), so don't rely too heavily on it.
*/
function CPBrowserStyleProperty(aProperty)
{
var lowerProperty = aProperty.toLowerCase();
if (PLATFORM_STYLE_JS_PROPERTIES[lowerProperty] === undefined)
{
var r = nil;
#if PLATFORM(DOM)
var testElement = document.createElement('div');
switch (lowerProperty)
{
case 'transitionend':
var candidates = {
'WebkitTransition' : 'webkitTransitionEnd',
'MozTransition' : 'transitionend',
'OTransition' : 'oTransitionEnd',
'msTransition' : 'MSTransitionEnd',
'transition' : 'transitionend'
};
r = candidates[PLATFORM_STYLE_JS_PROPERTIES['transition']] || nil;
break;
default:
var prefixes = ["Webkit", "Moz", "O", "ms"],
strippedProperty = aProperty.split('-').join(' '),
capProperty = [strippedProperty capitalizedString].split(' ').join('');
for (var i = 0; i < prefixes.length; i++)
{
// First check if the property is already valid without being formatted, otherwise try the capitalized property
if (prefixes[i] + aProperty in testElement.style)
{
r = prefixes[i] + aProperty;
break;
}
else if (prefixes[i] + capProperty in testElement.style)
{
r = prefixes[i] + capProperty;
break;
}
}
if (!r && lowerProperty in testElement.style)
r = lowerProperty;
break;
}
#endif
PLATFORM_STYLE_JS_PROPERTIES[lowerProperty] = r;
}
return PLATFORM_STYLE_JS_PROPERTIES[lowerProperty];
}
function CPBrowserCSSProperty(aProperty)
{
var browserProperty = CPBrowserStyleProperty(aProperty);
if (!browserProperty)
return nil;
var prefixes = {
'Webkit': '-webkit-',
'Moz': '-moz-',
'O': '-o-',
'ms': '-ms-'
};
for (var prefix in prefixes)
{
if (browserProperty.substring(0, prefix.length) == prefix)
{
var browserPropertyWithoutPrefix = browserProperty.substring(prefix.length),
parts = browserPropertyWithoutPrefix.match(/[A-Z][a-z]+/g);
// If there were any capitalized words in the browserProperty, insert a "-" between each one
if (parts && parts.length > 0)
browserPropertyWithoutPrefix = parts.join("-");
return prefixes[prefix] + browserPropertyWithoutPrefix.toLowerCase();
}
}
var parts = browserProperty.match(/[A-Z][a-z]+/g);
if (parts && parts.length > 0)
browserProperty = parts.join("-");
return browserProperty.toLowerCase();
}
+85 -59
View File
@@ -22,48 +22,58 @@
#import "../Foundation/Ref.h"
@import "../Foundation/CPFormatter.j"
@import <Foundation/CPFormatter.j>
@import <Foundation/CPTimer.j>
@import "CPFont.j"
@import "CPShadow.j"
@import "CPView.j"
@import "CPKeyValueBinding.j"
CPLeftTextAlignment = 0;
CPRightTextAlignment = 1;
CPCenterTextAlignment = 2;
CPJustifiedTextAlignment = 3;
CPNaturalTextAlignment = 4;
@global CPApp
CPRegularControlSize = 0;
CPSmallControlSize = 1;
CPMiniControlSize = 2;
CPLeftTextAlignment = 0;
CPRightTextAlignment = 1;
CPCenterTextAlignment = 2;
CPJustifiedTextAlignment = 3;
CPNaturalTextAlignment = 4;
CPLineBreakByWordWrapping = 0;
CPLineBreakByCharWrapping = 1;
CPLineBreakByClipping = 2;
CPLineBreakByTruncatingHead = 3;
CPLineBreakByTruncatingTail = 4;
CPLineBreakByTruncatingMiddle = 5;
CPRegularControlSize = 0;
CPSmallControlSize = 1;
CPMiniControlSize = 2;
CPTopVerticalTextAlignment = 1;
CPCenterVerticalTextAlignment = 2;
CPBottomVerticalTextAlignment = 3;
CPLineBreakByWordWrapping = 0;
CPLineBreakByCharWrapping = 1;
CPLineBreakByClipping = 2;
CPLineBreakByTruncatingHead = 3;
CPLineBreakByTruncatingTail = 4;
CPLineBreakByTruncatingMiddle = 5;
CPScaleProportionally = 0;
CPScaleToFit = 1;
CPScaleNone = 2;
CPTopVerticalTextAlignment = 1;
CPCenterVerticalTextAlignment = 2;
CPBottomVerticalTextAlignment = 3;
CPNoImage = 0;
CPImageOnly = 1;
CPImageLeft = 2;
CPImageRight = 3;
CPImageBelow = 4;
CPImageAbove = 5;
CPImageOverlaps = 6;
// Deprecated for use with images, use the CPImageScale constants
CPScaleProportionally = 0;
CPScaleToFit = 1;
CPScaleNone = 2;
CPOnState = 1;
CPOffState = 0;
CPMixedState = -1;
CPImageScaleProportionallyDown = 0;
CPImageScaleAxesIndependently = 1;
CPImageScaleNone = 2;
CPImageScaleProportionallyUpOrDown = 3;
CPNoImage = 0;
CPImageOnly = 1;
CPImageLeft = 2;
CPImageRight = 3;
CPImageBelow = 4;
CPImageAbove = 5;
CPImageOverlaps = 6;
CPOnState = 1;
CPOffState = 0;
CPMixedState = -1;
CPControlNormalBackgroundColor = "CPControlNormalBackgroundColor";
CPControlSelectedBackgroundColor = "CPControlSelectedBackgroundColor";
@@ -106,7 +116,7 @@ var CPControlBlackColor = [CPColor blackColor];
CPTopVerticalTextAlignment,
CPLineBreakByClipping,
[CPColor blackColor],
[CPFont systemFontOfSize:12.0],
[CPFont systemFontOfSize:CPFontCurrentSystemSize],
[CPNull null],
_CGSizeMakeZero(),
CPImageLeft,
@@ -128,18 +138,18 @@ var CPControlBlackColor = [CPColor blackColor];
+ (void)initialize
{
if (self === [CPControl class])
{
[self exposeBinding:@"value"];
[self exposeBinding:@"objectValue"];
[self exposeBinding:@"stringValue"];
[self exposeBinding:@"integerValue"];
[self exposeBinding:@"intValue"];
[self exposeBinding:@"doubleValue"];
[self exposeBinding:@"floatValue"];
if (self !== [CPControl class])
return;
[self exposeBinding:@"enabled"];
}
[self exposeBinding:@"value"];
[self exposeBinding:@"objectValue"];
[self exposeBinding:@"stringValue"];
[self exposeBinding:@"integerValue"];
[self exposeBinding:@"intValue"];
[self exposeBinding:@"doubleValue"];
[self exposeBinding:@"floatValue"];
[self exposeBinding:@"enabled"];
}
+ (Class)_binderClassForBinding:(CPString)theBinding
@@ -385,7 +395,18 @@ var CPControlBlackColor = [CPColor blackColor];
- (void)stopTracking:(CGPoint)lastPoint at:(CGPoint)aPoint mouseIsUp:(BOOL)mouseIsUp
{
[self highlight:NO];
if (mouseIsUp)
[self highlight:NO];
else
[self highlight:YES];
}
/*!
Enabled controls accept first mouse by default.
*/
- (BOOL)acceptsFirstMouse:(CPEvent)anEvent
{
return [self isEnabled];
}
- (void)mouseDown:(CPEvent)anEvent
@@ -507,7 +528,7 @@ var CPControlBlackColor = [CPColor blackColor];
*/
- (CPString)stringValue
{
if (_formatter && _value !== undefined && _value !== nil)
if (_formatter && _value !== undefined)
{
var formattedValue = [self hasThemeState:CPThemeStateEditing] ? [_formatter editingStringForObjectValue:_value] : [_formatter stringForObjectValue:_value];
@@ -526,7 +547,7 @@ var CPControlBlackColor = [CPColor blackColor];
// Cocoa raises an invalid parameter assertion and returns if you pass nil.
if (aString === nil || aString === undefined)
{
CPLog.warn("nil sent to CPControl -setStringValue");
CPLog.warn("nil or undefined sent to CPControl -setStringValue");
return;
}
@@ -784,9 +805,10 @@ var CPControlBlackColor = [CPColor blackColor];
Sets the image scaling of the control.
<pre>
CPScaleProportionally
CPScaleToFit
CPScaleNone
CPImageScaleProportionallyDown
CPImageScaleAxesIndependently
CPImageScaleNone
CPImageScaleProportionallyUpOrDown
</pre>
*/
- (void)setImageScaling:(CPImageScaling)scaling
@@ -857,17 +879,16 @@ var CPControlBlackColor = [CPColor blackColor];
@end
var CPControlValueKey = "CPControlValueKey",
CPControlControlStateKey = @"CPControlControlStateKey",
CPControlIsEnabledKey = "CPControlIsEnabledKey",
var CPControlValueKey = @"CPControlValueKey",
CPControlControlStateKey = @"CPControlControlStateKey",
CPControlIsEnabledKey = @"CPControlIsEnabledKey",
CPControlTargetKey = @"CPControlTargetKey",
CPControlActionKey = @"CPControlActionKey",
CPControlSendActionOnKey = @"CPControlSendActionOnKey",
CPControlFormatterKey = @"CPControlFormatterKey",
CPControlSendsActionOnEndEditingKey = @"CPControlSendsActionOnEndEditingKey",
CPControlTargetKey = "CPControlTargetKey",
CPControlActionKey = "CPControlActionKey",
CPControlSendActionOnKey = "CPControlSendActionOnKey",
CPControlSendsActionOnEndEditingKey = "CPControlSendsActionOnEndEditingKey";
var __Deprecated__CPImageViewImageKey = @"CPImageViewImageKey";
__Deprecated__CPImageViewImageKey = @"CPImageViewImageKey";
@implementation CPControl (CPCoding)
@@ -890,6 +911,8 @@ var __Deprecated__CPImageViewImageKey = @"CPImageViewImageKey";
[self sendActionOn:[aCoder decodeIntForKey:CPControlSendActionOnKey]];
[self setSendsActionOnEndEditing:[aCoder decodeBoolForKey:CPControlSendsActionOnEndEditingKey]];
[self setFormatter:[aCoder decodeObjectForKey:CPControlFormatterKey]];
}
return self;
@@ -919,6 +942,9 @@ var __Deprecated__CPImageViewImageKey = @"CPImageViewImageKey";
[aCoder encodeObject:_action forKey:CPControlActionKey];
[aCoder encodeInt:_sendActionOn forKey:CPControlSendActionOnKey];
if (_formatter !== nil)
[aCoder encodeObject:_formatter forKey:CPControlFormatterKey];
}
@end
+1 -1
View File
@@ -64,7 +64,7 @@ var CPControllerDeclaredKeysKey = @"CPControllerDeclaredKeysKey";
count = _editors.length;
for (; index < count; ++index)
if (![[_editors objectAtIndex:i] commitEditing])
if (![[_editors objectAtIndex:index] commitEditing])
return NO;
return YES;
+7 -3
View File
@@ -94,7 +94,7 @@
domain = "";
#if PLATFORM(DOM)
document.cookie = _cookieName+"="+value+expires+"; path=/"+domain;
document.cookie = _cookieName + "=" + value + expires + "; path=/" + domain;
#else
_cookieValue = value;
_expires = expires;
@@ -111,8 +111,12 @@
for (var i = 0; i < ca.length; i++)
{
var c = ca[i];
while (c.charAt(0) == ' ') c = c.substring(1, c.length);
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
while (c.charAt(0) == ' ')
c = c.substring(1, c.length);
if (c.indexOf(nameEQ) == 0)
return c.substring(nameEQ.length, c.length);
}
#endif
return "";
+92 -11
View File
@@ -23,9 +23,12 @@ Cursor support by browser:
@import <Foundation/CPObject.j>
@global CPApp
var currentCursor = nil,
cursorStack = [],
cursors = {};
cursors = {},
ieCursorMap = {};
@implementation CPCursor : CPObject
{
@@ -36,6 +39,20 @@ var currentCursor = nil,
BOOL _isSetOnMouseExited @accessors(readwrite, getter=isSetOnMouseExited, setter=setOnMouseExited:);
}
+ (void)initialize
{
if (self !== CPCursor)
return;
// IE < 9 does not support some CSS cursors, we map them to supported ones
ieCursorMap = {
"ew-resize": "e-resize",
"ns-resize": "n-resize",
"nesw-resize": "ne-resize",
"nwse-resize": "nw-resize"
};
}
- (id)initWithCSSString:(CPString)aString
{
if (self = [super init])
@@ -44,23 +61,30 @@ var currentCursor = nil,
return self;
}
// hotspot is supported in CSS3 (but not IE).
- (id)initWithImage:(CPImage)image hotSpot:(CPPoint)hotSpot
/*!
Init a cursor with the given image and hotspot.
hotspot is supported in CSS3 (but not IE).
*/
- (id)initWithImage:(CPImage)image hotSpot:(CGPoint)hotSpot
{
_hotSpot = hotSpot;
_image = image;
return [self initWithCSSString:"url(" + [_image filename] + ")" + hotSpot.x + " " + hotSpot.y + ", auto"];
}
// foregroundColor and backgroundColor are ignored in Cocoa as well. See http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/ApplicationKit/Classes/NSCursor_Class/Reference/Reference.html
- (id)initWithImage:(CPImage)image foregroundColorHint:(CPColor)foregroundColor backgroundColorHint:(CPColor)backgroundColor hotSpot:(CPPoint)aHotSpot
/*!
Init a cursor with the given image and hotspot. This is provided
for compliance with Cocoa. Note that foregroundColor and backgroundColor are ignored
(as they are in Cocoa). See http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/ApplicationKit/Classes/NSCursor_Class/Reference/Reference.html
*/
- (id)initWithImage:(CPImage)image foregroundColorHint:(CPColor)foregroundColor backgroundColorHint:(CPColor)backgroundColor hotSpot:(CGPoint)aHotSpot
{
return [self initWithImage:image hotSpot:hotSpot];
return [self initWithImage:image hotSpot:aHotSpot];
}
+ (void)hide
{
[self _setCursorCSS:"none"]; // Not supported in IE
[self _setCursorCSS:@"none"]; // Not supported in IE < 9
}
+ (void)unhide
@@ -121,6 +145,7 @@ var currentCursor = nil,
{
#if PLATFORM(DOM)
var platformWindows = [[CPPlatformWindow visiblePlatformWindows] allObjects];
for (var i = 0, count = [platformWindows count]; i < count; i++)
platformWindows[i]._DOMBodyElement.style.cursor = aString;
#endif
@@ -130,22 +155,38 @@ var currentCursor = nil,
+ (CPCursor)_systemCursorWithName:(CPString)cursorName cssString:(CPString)aString hasImage:(BOOL)doesHaveImage
{
var cursor = cursors[cursorName];
if (typeof cursor === 'undefined')
if (typeof cursor === "undefined")
{
var cssString;
if (doesHaveImage)
cssString = @"url(" + [[CPBundle bundleForClass:self] resourcePath] + @"/CPCursor/" + cursorName + ".cur), " + aString;
{
var themeResourcePath = [[[CPApp themeBlend] bundle] resourcePath];
cssString = [CPString stringWithFormat:@"url(%@cursors/%@.cur), %@", themeResourcePath, cursorName, aString];
}
else
cssString = aString
{
// IE <= 8 does not support some cursors, map them to supported cursors
var ieLessThan9 = CPBrowserIsEngine(CPInternetExplorerBrowserEngine) && !CPFeatureIsCompatible(CPHTMLCanvasFeature);
if (ieLessThan9)
cssString = ieCursorMap[aString] || aString;
else
cssString = aString;
}
cursor = [[CPCursor alloc] initWithCSSString:cssString];
cursors[cursorName] = cursor;
}
return cursor;
}
+ (CPCursor)arrowCursor
{
return [CPCursor _systemCursorWithName:CPStringFromSelector(_cmd) cssString:"default" hasImage:NO];
return [CPCursor _systemCursorWithName:CPStringFromSelector(_cmd) cssString:@"default" hasImage:NO];
}
+ (CPCursor)crosshairCursor
@@ -163,6 +204,36 @@ var currentCursor = nil,
return [CPCursor _systemCursorWithName:CPStringFromSelector(_cmd) cssString:@"pointer" hasImage:NO];
}
+ (CPCursor)resizeNorthwestCursor
{
return [CPCursor _systemCursorWithName:CPStringFromSelector(_cmd) cssString:@"nw-resize" hasImage:NO];
}
+ (CPCursor)resizeNorthwestSoutheastCursor
{
return [CPCursor _systemCursorWithName:CPStringFromSelector(_cmd) cssString:@"nwse-resize" hasImage:NO];
}
+ (CPCursor)resizeNortheastCursor
{
return [CPCursor _systemCursorWithName:CPStringFromSelector(_cmd) cssString:@"ne-resize" hasImage:NO];
}
+ (CPCursor)resizeNortheastSouthwestCursor
{
return [CPCursor _systemCursorWithName:CPStringFromSelector(_cmd) cssString:@"nesw-resize" hasImage:NO];
}
+ (CPCursor)resizeSouthwestCursor
{
return [CPCursor _systemCursorWithName:CPStringFromSelector(_cmd) cssString:@"sw-resize" hasImage:NO];
}
+ (CPCursor)resizeSoutheastCursor
{
return [CPCursor _systemCursorWithName:CPStringFromSelector(_cmd) cssString:@"se-resize" hasImage:NO];
}
+ (CPCursor)resizeDownCursor
{
return [CPCursor _systemCursorWithName:CPStringFromSelector(_cmd) cssString:@"s-resize" hasImage:NO];
@@ -188,11 +259,21 @@ var currentCursor = nil,
return [CPCursor _systemCursorWithName:CPStringFromSelector(_cmd) cssString:@"col-resize" hasImage:NO];
}
+ (CPCursor)resizeEastWestCursor
{
return [CPCursor _systemCursorWithName:CPStringFromSelector(_cmd) cssString:@"ew-resize" hasImage:NO];
}
+ (CPCursor)resizeUpDownCursor
{
return [CPCursor _systemCursorWithName:CPStringFromSelector(_cmd) cssString:@"row-resize" hasImage:NO];
}
+ (CPCursor)resizeNorthSouthCursor
{
return [CPCursor _systemCursorWithName:CPStringFromSelector(_cmd) cssString:@"ns-resize" hasImage:NO];
}
+ (CPCursor)operationNotAllowedCursor
{
return [CPCursor _systemCursorWithName:CPStringFromSelector(_cmd) cssString:@"not-allowed" hasImage:NO];
+9 -5
View File
@@ -23,12 +23,16 @@
@import <Foundation/CPString.j>
@import <Foundation/CPArray.j>
@import "CPApplication.j"
@import "CPAlert.j"
@import "CPResponder.j"
@import "CPSavePanel.j"
@import "CPViewController.j"
@import "CPWindowController.j"
@class CPDocumentController
@global CPApp
/*
@global
@@ -142,7 +146,7 @@ var CPDocumentUntitledCount = 0;
@param anError not used
@return the initialized document
*/
- (id)initWithType:(CPString)aType error:({CPError})anError
- (id)initWithType:(CPString)aType error:(/*{*/CPError/*}*/)anError
{
self = [self init];
@@ -211,7 +215,7 @@ var CPDocumentUntitledCount = 0;
@throws CPUnsupportedMethodException if this method hasn't been overridden by the subclass
@return the document data
*/
- (CPData)dataOfType:(CPString)aType error:({CPError})anError
- (CPData)dataOfType:(CPString)aType error:(/*{*/CPError/*}*/)anError
{
[CPException raise:CPUnsupportedMethodException
reason:"dataOfType:error: must be overridden by the document subclass."];
@@ -922,9 +926,9 @@ var CPDocumentUntitledCount = 0;
var _CPReadSessionMake = function(aType, aDelegate, aDidReadSelector, aContextInfo)
{
return { fileType:aType, delegate:aDelegate, didReadSelector:aDidReadSelector, contextInfo:aContextInfo };
}
};
var _CPSaveSessionMake = function(anAbsoluteURL, aSaveOperation, aChangeCount, aDelegate, aDidSaveSelector, aContextInfo, aConnection)
{
return { absoluteURL:anAbsoluteURL, saveOperation:aSaveOperation, changeCount:aChangeCount, delegate:aDelegate, didSaveSelector:aDidSaveSelector, contextInfo:aContextInfo, connection:aConnection };
}
};
+9 -5
View File
@@ -25,6 +25,10 @@
@import "CPDocument.j"
@import "CPOpenPanel.j"
@import "CPMenuItem.j"
@import "CPWindowController.j"
@global CPApp
var CPSharedDocumentController = nil;
@@ -124,7 +128,7 @@ var CPSharedDocumentController = nil;
@param anError not used
@return the created document
*/
- (CPDocument)makeUntitledDocumentOfType:(CPString)aType error:({CPError})anError
- (CPDocument)makeUntitledDocumentOfType:(CPString)aType error:(/*{*/CPError/*}*/)anError
{
return [[[self documentClassForType:aType] alloc] initWithType:aType error:anError];
}
@@ -339,10 +343,10 @@ var CPSharedDocumentController = nil;
- (void)closeAllDocumentsWithDelegate:(id)aDelegate didCloseAllSelector:(SEL)didCloseSelector contextInfo:(Object)info
{
var context = {
delegate: aDelegate,
selector: didCloseSelector,
context: info
};
delegate: aDelegate,
selector: didCloseSelector,
context: info
};
[self _closeDocumentsStartingWith:nil shouldClose:YES context:context];
}
+6 -11
View File
@@ -20,22 +20,16 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "CPApplication.j"
@import "CPDragServer_Constants.j"
@import "CPEvent.j"
@import "CPImageView.j"
@import "CPPasteboard.j"
@import "CPView.j"
@import "CPWindow.j"
@class _CPDOMDataTransferPasteboard
CPDragOperationNone = 0;
CPDragOperationCopy = 1 << 1;
CPDragOperationLink = 1 << 1;
CPDragOperationGeneric = 1 << 2;
CPDragOperationPrivate = 1 << 3;
CPDragOperationMove = 1 << 4;
CPDragOperationDelete = 1 << 5;
CPDragOperationEvery = -1;
@global CPApp
#define DRAGGING_WINDOW(anObject) ([anObject isKindOfClass:[CPWindow class]] ? anObject : [anObject window])
@@ -72,7 +66,7 @@ var CPDragServerSource = nil,
- (unsigned)draggingSourceOperationMask
*/
- (CPPoint)draggingLocation
- (CGPoint)draggingLocation
{
return [[CPDragServer sharedDragServer] draggingLocation];
}
@@ -461,6 +455,7 @@ var CPDraggingSource_draggedImage_movedTo_ = 1 << 0,
else if (type === CPKeyDown)
{
var characters = [anEvent characters];
if (characters === CPEscapeFunctionKey)
{
_dragOperation = CPDragOperationNone;
@@ -477,7 +472,7 @@ var CPDraggingSource_draggedImage_movedTo_ = 1 << 0,
// If we're not a mouse up, then we're going to want to grab the next event.
[CPApp setTarget:self selector:@selector(trackDragging:)
forNextEventMatchingMask:CPMouseMovedMask | CPLeftMouseDraggedMask | CPLeftMouseUpMask | CPKeyDownMask
untilDate:nil inMode:0 dequeue:NO];
untilDate:nil inMode:0 dequeue:YES];
}
@end
+30
View File
@@ -0,0 +1,30 @@
/*
* CPDragServer_Constants.j
* AppKit
*
* Created by Francisco Tolmasky.
* Copyright 2008, 280 North, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
CPDragOperationNone = 0;
CPDragOperationCopy = 1 << 1;
CPDragOperationLink = 1 << 1;
CPDragOperationGeneric = 1 << 2;
CPDragOperationPrivate = 1 << 3;
CPDragOperationMove = 1 << 4;
CPDragOperationDelete = 1 << 5;
CPDragOperationEvery = -1;
+69 -170
View File
@@ -20,166 +20,24 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "CPEvent_Constants.j"
@import <Foundation/CPObject.j>
@import <Foundation/CPObjJRuntime.j>
@import <Foundation/CPString.j>
@import "CPCompatibility.j"
@import "CGGeometry.j"
@import "CPText.j"
@class CPTextField
CPLeftMouseDown = 1;
CPLeftMouseUp = 2;
CPRightMouseDown = 3;
CPRightMouseUp = 4;
CPMouseMoved = 5;
CPLeftMouseDragged = 6;
CPRightMouseDragged = 7;
CPMouseEntered = 8;
CPMouseExited = 9;
CPKeyDown = 10;
CPKeyUp = 11;
CPFlagsChanged = 12;
CPAppKitDefined = 13;
CPSystemDefined = 14;
CPApplicationDefined = 15;
CPPeriodic = 16;
CPCursorUpdate = 17;
CPScrollWheel = 22;
CPOtherMouseDown = 25;
CPOtherMouseUp = 26;
CPOtherMouseDragged = 27;
// iPhone Event Types
CPTouchStart = 28;
CPTouchMove = 29;
CPTouchEnd = 30;
CPTouchCancel = 31;
CPAlphaShiftKeyMask = 1 << 16;
CPShiftKeyMask = 1 << 17;
CPControlKeyMask = 1 << 18;
CPAlternateKeyMask = 1 << 19;
CPCommandKeyMask = 1 << 20;
CPNumericPadKeyMask = 1 << 21;
CPHelpKeyMask = 1 << 22;
CPFunctionKeyMask = 1 << 23;
CPDeviceIndependentModifierFlagsMask = 0xffff0000;
CPLeftMouseDownMask = 1 << CPLeftMouseDown;
CPLeftMouseUpMask = 1 << CPLeftMouseUp;
CPRightMouseDownMask = 1 << CPRightMouseDown;
CPRightMouseUpMask = 1 << CPRightMouseUp;
CPOtherMouseDownMask = 1 << CPOtherMouseDown;
CPOtherMouseUpMask = 1 << CPOtherMouseUp;
CPMouseMovedMask = 1 << CPMouseMoved;
CPLeftMouseDraggedMask = 1 << CPLeftMouseDragged;
CPRightMouseDraggedMask = 1 << CPRightMouseDragged;
CPOtherMouseDragged = 1 << CPOtherMouseDragged;
CPMouseEnteredMask = 1 << CPMouseEntered;
CPMouseExitedMask = 1 << CPMouseExited;
CPCursorUpdateMask = 1 << CPCursorUpdate;
CPKeyDownMask = 1 << CPKeyDown;
CPKeyUpMask = 1 << CPKeyUp;
CPFlagsChangedMask = 1 << CPFlagsChanged;
CPAppKitDefinedMask = 1 << CPAppKitDefined;
CPSystemDefinedMask = 1 << CPSystemDefined;
CPApplicationDefinedMask = 1 << CPApplicationDefined;
CPPeriodicMask = 1 << CPPeriodic;
CPScrollWheelMask = 1 << CPScrollWheel;
CPAnyEventMask = 0xffffffff;
CPUpArrowFunctionKey = "\uF700";
CPDownArrowFunctionKey = "\uF701";
CPLeftArrowFunctionKey = "\uF702";
CPRightArrowFunctionKey = "\uF703";
CPF1FunctionKey = "\uF704";
CPF2FunctionKey = "\uF705";
CPF3FunctionKey = "\uF706";
CPF4FunctionKey = "\uF707";
CPF5FunctionKey = "\uF708";
CPF6FunctionKey = "\uF709";
CPF7FunctionKey = "\uF70A";
CPF8FunctionKey = "\uF70B";
CPF9FunctionKey = "\uF70C";
CPF10FunctionKey = "\uF70D";
CPF11FunctionKey = "\uF70E";
CPF12FunctionKey = "\uF70F";
CPF13FunctionKey = "\uF710";
CPF14FunctionKey = "\uF711";
CPF15FunctionKey = "\uF712";
CPF16FunctionKey = "\uF713";
CPF17FunctionKey = "\uF714";
CPF18FunctionKey = "\uF715";
CPF19FunctionKey = "\uF716";
CPF20FunctionKey = "\uF717";
CPF21FunctionKey = "\uF718";
CPF22FunctionKey = "\uF719";
CPF23FunctionKey = "\uF71A";
CPF24FunctionKey = "\uF71B";
CPF25FunctionKey = "\uF71C";
CPF26FunctionKey = "\uF71D";
CPF27FunctionKey = "\uF71E";
CPF28FunctionKey = "\uF71F";
CPF29FunctionKey = "\uF720";
CPF30FunctionKey = "\uF721";
CPF31FunctionKey = "\uF722";
CPF32FunctionKey = "\uF723";
CPF33FunctionKey = "\uF724";
CPF34FunctionKey = "\uF725";
CPF35FunctionKey = "\uF726";
CPInsertFunctionKey = "\uF727";
CPDeleteFunctionKey = "\uF728";
CPHomeFunctionKey = "\uF729";
CPBeginFunctionKey = "\uF72A";
CPEndFunctionKey = "\uF72B";
CPPageUpFunctionKey = "\uF72C";
CPPageDownFunctionKey = "\uF72D";
CPPrintScreenFunctionKey = "\uF72E";
CPScrollLockFunctionKey = "\uF72F";
CPPauseFunctionKey = "\uF730";
CPSysReqFunctionKey = "\uF731";
CPBreakFunctionKey = "\uF732";
CPResetFunctionKey = "\uF733";
CPStopFunctionKey = "\uF734";
CPMenuFunctionKey = "\uF735";
CPUserFunctionKey = "\uF736";
CPSystemFunctionKey = "\uF737";
CPPrintFunctionKey = "\uF738";
CPClearLineFunctionKey = "\uF739";
CPClearDisplayFunctionKey = "\uF73A";
CPInsertLineFunctionKey = "\uF73B";
CPDeleteLineFunctionKey = "\uF73C";
CPInsertCharFunctionKey = "\uF73D";
CPDeleteCharFunctionKey = "\uF73E";
CPPrevFunctionKey = "\uF73F";
CPNextFunctionKey = "\uF740";
CPSelectFunctionKey = "\uF741";
CPExecuteFunctionKey = "\uF742";
CPUndoFunctionKey = "\uF743";
CPRedoFunctionKey = "\uF744";
CPFindFunctionKey = "\uF745";
CPHelpFunctionKey = "\uF746";
CPModeSwitchFunctionKey = "\uF747";
CPEscapeFunctionKey = "\u001B";
CPSpaceFunctionKey = "\u0020";
CPDOMEventDoubleClick = "dblclick";
CPDOMEventMouseDown = "mousedown";
CPDOMEventMouseUp = "mouseup";
CPDOMEventMouseMoved = "mousemove";
CPDOMEventMouseDragged = "mousedrag";
CPDOMEventKeyUp = "keyup";
CPDOMEventKeyDown = "keydown";
CPDOMEventKeyPress = "keypress";
CPDOMEventCopy = "copy";
CPDOMEventPaste = "paste";
CPDOMEventScrollWheel = "mousewheel";
CPDOMEventTouchStart = "touchstart";
CPDOMEventTouchMove = "touchmove";
CPDOMEventTouchEnd = "touchend";
CPDOMEventTouchCancel = "touchcancel";
@global CPApp
var _CPEventPeriodicEventPeriod = 0,
_CPEventPeriodicEventTimer = nil,
_CPEventUpperCaseRegex = new RegExp("[A-Z]");
_CPEventUpperCaseRegex = new RegExp("[A-Z]"),
_CPEventStartupMilliseconds = new Date().getTime();
/*!
@ingroup appkit
@@ -189,7 +47,7 @@ var _CPEventPeriodicEventPeriod = 0,
@implementation CPEvent : CPObject
{
CPEventType _type;
CPPoint _location;
CGPoint _location;
unsigned _modifierFlags;
CPTimeInterval _timestamp;
CPGraphicsContext _context;
@@ -203,12 +61,23 @@ var _CPEventPeriodicEventPeriod = 0,
BOOL _isARepeat;
unsigned _keyCode;
DOMEvent _DOMEvent;
int _data1;
int _data2;
short _subtype;
float _deltaX;
float _deltaY;
float _deltaZ;
}
/*!
Returns the current time in fractional seconds since startup.
*/
+ (CPTimeInterval)currentTimestamp
{
return (new Date().getTime() - _CPEventStartupMilliseconds) / 1000;
}
/*!
Creates a new keyboard event.
@@ -297,13 +166,13 @@ var _CPEventPeriodicEventPeriod = 0,
}
/* @ignore */
- (id)_initMouseEventWithType:(CPEventType)anEventType location:(CPPoint)aPoint modifierFlags:(unsigned)modifierFlags
- (id)_initMouseEventWithType:(CPEventType)anEventType location:(CGPoint)aPoint modifierFlags:(unsigned)modifierFlags
timestamp:(CPTimeInterval)aTimestamp windowNumber:(int)aWindowNumber context:(CPGraphicsContext)aGraphicsContext
eventNumber:(int)anEventNumber clickCount:(int)aClickCount pressure:(float)aPressure
{
if (self = [self _initWithType:anEventType])
{
_location = CPPointCreateCopy(aPoint);
_location = CGPointCreateCopy(aPoint);
_modifierFlags = modifierFlags;
_timestamp = aTimestamp;
_context = aGraphicsContext;
@@ -317,13 +186,13 @@ var _CPEventPeriodicEventPeriod = 0,
}
/* @ignore */
- (id)_initKeyEventWithType:(CPEventType)anEventType location:(CPPoint)aPoint modifierFlags:(unsigned int)modifierFlags
- (id)_initKeyEventWithType:(CPEventType)anEventType location:(CGPoint)aPoint modifierFlags:(unsigned int)modifierFlags
timestamp:(CPTimeInterval)aTimestamp windowNumber:(int)aWindowNumber context:(CPGraphicsContext)aGraphicsContext
characters:(CPString)characters charactersIgnoringModifiers:(CPString)unmodCharacters isARepeat:(BOOL)isARepeat keyCode:(unsigned short)code
{
if (self = [self _initWithType:anEventType])
{
_location = CPPointCreateCopy(aPoint);
_location = CGPointCreateCopy(aPoint);
_modifierFlags = modifierFlags;
_timestamp = aTimestamp;
_context = aGraphicsContext;
@@ -344,7 +213,7 @@ var _CPEventPeriodicEventPeriod = 0,
{
if (self = [self _initWithType:anEventType])
{
_location = CPPointCreateCopy(aPoint);
_location = CGPointCreateCopy(aPoint);
_modifierFlags = modifierFlags;
_timestamp = aTimestamp;
_context = aGraphicsContext;
@@ -389,7 +258,7 @@ var _CPEventPeriodicEventPeriod = 0,
}
/*!
Returns the time the event occurred.
Returns the time the event occurred in seconds since startup.
*/
- (CPTimeInterval)timestamp
{
@@ -508,6 +377,16 @@ var _CPEventPeriodicEventPeriod = 0,
return _DOMEvent;
}
- (int)data1
{
return _data1;
}
- (int)data2
{
return _data2;
}
// Getting Scroll Wheel Event Information
/*!
Returns the change in the x-axis for a mouse event.
@@ -571,10 +450,12 @@ var _CPEventPeriodicEventPeriod = 0,
if (_modifierFlags & (CPCommandKeyMask | CPControlKeyMask))
return YES;
// Cocoa does not consider space, backspace, or escape a key equivalent
// if the first responder is a text field (presumably a subclass of NSText).
// Cocoa allows almost any key as a key equivalent unless the first responder is a
// text field (presumably a subclass of NSText.)
var firstResponderIsText = [[_window firstResponder] isKindOfClass:[CPTextField class]];
// Some keys are accepted as key equivalents even if the first responder is a text
// field.
for (var i = 0; i < characterCount; i++)
{
var c = _characters.charAt(i);
@@ -583,18 +464,13 @@ var _CPEventPeriodicEventPeriod = 0,
c === CPEnterCharacter ||
c === CPNewlineCharacter ||
c === CPCarriageReturnCharacter ||
c === CPEscapeFunctionKey ||
(!firstResponderIsText &&
(c === CPSpaceFunctionKey ||
c === CPDeleteCharacter ||
c === CPBackspaceCharacter)))
c === CPEscapeFunctionKey)
{
return YES;
}
}
// FIXME: More cases?
return NO;
return !firstResponderIsText;
}
/*!
@@ -624,11 +500,34 @@ var _CPEventPeriodicEventPeriod = 0,
_CPEventPeriodicEventTimer = nil;
}
- (CPString)description
{
switch (_type)
{
case CPKeyDown:
case CPKeyUp:
case CPFlagsChanged:
return [CPString stringWithFormat:@"CPEvent: type=%d loc=%@ time=%.1f flags=0x%X win=%@ winNum=%d ctxt=%@ chars=\"%@\" unmodchars=\"%@\" repeat=%d keyCode=%d", _type, CGStringFromPoint(_location), _timestamp, _modifierFlags, _window, _windowNumber, _context, _characters, _charactersIgnoringModifiers, _isARepeat, _keyCode];
case CPLeftMouseDown:
case CPLeftMouseUp:
case CPRightMouseDown:
case CPRightMouseUp:
case CPMouseMoved:
case CPLeftMouseDragged:
case CPRightMouseDragged:
case CPMouseEntered:
case CPMouseExited:
return [CPString stringWithFormat:@"CPEvent: type=%d loc=%@ time=%.1f flags=0x%X win=%@ winNum=%d ctxt=%@ evNum=%d click=%d buttonNumber=%d pressure=%f", _type, CGStringFromPoint(_location), _timestamp, _modifierFlags, _window, _windowNumber, _context, _eventNumber, _clickCount, [self buttonNumber], _pressure];
default:
return [CPString stringWithFormat:@"CPEvent: type=%d loc=%@ time=%.1f flags=0x%X win=%@ winNum=%d ctxt=%@ subtype=%d data1=%d data2=%d", _type, CGStringFromPoint(_location), _timestamp, _modifierFlags, _window, _windowNumber, _context, _subtype, _data1, _data2];
}
}
@end
function _CPEventFirePeriodEvent()
{
[CPApp sendEvent:[CPEvent otherEventWithType:CPPeriodic location:_CGPointMakeZero() modifierFlags:0 timestamp:0 windowNumber:0 context:nil subtype:0 data1:0 data2:0]];
[CPApp sendEvent:[CPEvent otherEventWithType:CPPeriodic location:_CGPointMakeZero() modifierFlags:0 timestamp:[CPEvent currentTimestamp] windowNumber:0 context:nil subtype:0 data1:0 data2:0]];
}
var CPEventClass = [CPEvent class];
+174
View File
@@ -0,0 +1,174 @@
/*
* CPEvent_Constants.j
* AppKit
*
* Created by Francisco Tolmasky.
* Copyright 2008, 280 North, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
CPLeftMouseDown = 1;
CPLeftMouseUp = 2;
CPRightMouseDown = 3;
CPRightMouseUp = 4;
CPMouseMoved = 5;
CPLeftMouseDragged = 6;
CPRightMouseDragged = 7;
CPMouseEntered = 8;
CPMouseExited = 9;
CPKeyDown = 10;
CPKeyUp = 11;
CPFlagsChanged = 12;
CPAppKitDefined = 13;
CPSystemDefined = 14;
CPApplicationDefined = 15;
CPPeriodic = 16;
CPCursorUpdate = 17;
CPScrollWheel = 22;
CPOtherMouseDown = 25;
CPOtherMouseUp = 26;
CPOtherMouseDragged = 27;
// iPhone Event Types
CPTouchStart = 28;
CPTouchMove = 29;
CPTouchEnd = 30;
CPTouchCancel = 31;
CPAlphaShiftKeyMask = 1 << 16;
CPShiftKeyMask = 1 << 17;
CPControlKeyMask = 1 << 18;
CPAlternateKeyMask = 1 << 19;
CPCommandKeyMask = 1 << 20;
CPNumericPadKeyMask = 1 << 21;
CPHelpKeyMask = 1 << 22;
CPFunctionKeyMask = 1 << 23;
CPDeviceIndependentModifierFlagsMask = 0xffff0000;
CPLeftMouseDownMask = 1 << CPLeftMouseDown;
CPLeftMouseUpMask = 1 << CPLeftMouseUp;
CPRightMouseDownMask = 1 << CPRightMouseDown;
CPRightMouseUpMask = 1 << CPRightMouseUp;
CPOtherMouseDownMask = 1 << CPOtherMouseDown;
CPOtherMouseUpMask = 1 << CPOtherMouseUp;
CPMouseMovedMask = 1 << CPMouseMoved;
CPLeftMouseDraggedMask = 1 << CPLeftMouseDragged;
CPRightMouseDraggedMask = 1 << CPRightMouseDragged;
CPOtherMouseDragged = 1 << CPOtherMouseDragged;
CPMouseEnteredMask = 1 << CPMouseEntered;
CPMouseExitedMask = 1 << CPMouseExited;
CPCursorUpdateMask = 1 << CPCursorUpdate;
CPKeyDownMask = 1 << CPKeyDown;
CPKeyUpMask = 1 << CPKeyUp;
CPFlagsChangedMask = 1 << CPFlagsChanged;
CPAppKitDefinedMask = 1 << CPAppKitDefined;
CPSystemDefinedMask = 1 << CPSystemDefined;
CPApplicationDefinedMask = 1 << CPApplicationDefined;
CPPeriodicMask = 1 << CPPeriodic;
CPScrollWheelMask = 1 << CPScrollWheel;
CPAnyEventMask = 0xffffffff;
CPUpArrowFunctionKey = "\uF700";
CPDownArrowFunctionKey = "\uF701";
CPLeftArrowFunctionKey = "\uF702";
CPRightArrowFunctionKey = "\uF703";
CPF1FunctionKey = "\uF704";
CPF2FunctionKey = "\uF705";
CPF3FunctionKey = "\uF706";
CPF4FunctionKey = "\uF707";
CPF5FunctionKey = "\uF708";
CPF6FunctionKey = "\uF709";
CPF7FunctionKey = "\uF70A";
CPF8FunctionKey = "\uF70B";
CPF9FunctionKey = "\uF70C";
CPF10FunctionKey = "\uF70D";
CPF11FunctionKey = "\uF70E";
CPF12FunctionKey = "\uF70F";
CPF13FunctionKey = "\uF710";
CPF14FunctionKey = "\uF711";
CPF15FunctionKey = "\uF712";
CPF16FunctionKey = "\uF713";
CPF17FunctionKey = "\uF714";
CPF18FunctionKey = "\uF715";
CPF19FunctionKey = "\uF716";
CPF20FunctionKey = "\uF717";
CPF21FunctionKey = "\uF718";
CPF22FunctionKey = "\uF719";
CPF23FunctionKey = "\uF71A";
CPF24FunctionKey = "\uF71B";
CPF25FunctionKey = "\uF71C";
CPF26FunctionKey = "\uF71D";
CPF27FunctionKey = "\uF71E";
CPF28FunctionKey = "\uF71F";
CPF29FunctionKey = "\uF720";
CPF30FunctionKey = "\uF721";
CPF31FunctionKey = "\uF722";
CPF32FunctionKey = "\uF723";
CPF33FunctionKey = "\uF724";
CPF34FunctionKey = "\uF725";
CPF35FunctionKey = "\uF726";
CPInsertFunctionKey = "\uF727";
CPDeleteFunctionKey = "\uF728";
CPHomeFunctionKey = "\uF729";
CPBeginFunctionKey = "\uF72A";
CPEndFunctionKey = "\uF72B";
CPPageUpFunctionKey = "\uF72C";
CPPageDownFunctionKey = "\uF72D";
CPPrintScreenFunctionKey = "\uF72E";
CPScrollLockFunctionKey = "\uF72F";
CPPauseFunctionKey = "\uF730";
CPSysReqFunctionKey = "\uF731";
CPBreakFunctionKey = "\uF732";
CPResetFunctionKey = "\uF733";
CPStopFunctionKey = "\uF734";
CPMenuFunctionKey = "\uF735";
CPUserFunctionKey = "\uF736";
CPSystemFunctionKey = "\uF737";
CPPrintFunctionKey = "\uF738";
CPClearLineFunctionKey = "\uF739";
CPClearDisplayFunctionKey = "\uF73A";
CPInsertLineFunctionKey = "\uF73B";
CPDeleteLineFunctionKey = "\uF73C";
CPInsertCharFunctionKey = "\uF73D";
CPDeleteCharFunctionKey = "\uF73E";
CPPrevFunctionKey = "\uF73F";
CPNextFunctionKey = "\uF740";
CPSelectFunctionKey = "\uF741";
CPExecuteFunctionKey = "\uF742";
CPUndoFunctionKey = "\uF743";
CPRedoFunctionKey = "\uF744";
CPFindFunctionKey = "\uF745";
CPHelpFunctionKey = "\uF746";
CPModeSwitchFunctionKey = "\uF747";
CPEscapeFunctionKey = "\u001B";
CPSpaceFunctionKey = "\u0020";
CPDOMEventDoubleClick = "dblclick";
CPDOMEventMouseDown = "mousedown";
CPDOMEventMouseUp = "mouseup";
CPDOMEventMouseMoved = "mousemove";
CPDOMEventMouseDragged = "mousedrag";
CPDOMEventKeyUp = "keyup";
CPDOMEventKeyDown = "keydown";
CPDOMEventKeyPress = "keypress";
CPDOMEventCopy = "copy";
CPDOMEventPaste = "paste";
CPDOMEventScrollWheel = "mousewheel";
CPDOMEventTouchStart = "touchstart";
CPDOMEventTouchMove = "touchmove";
CPDOMEventTouchEnd = "touchend";
CPDOMEventTouchCancel = "touchcancel";
+5 -5
View File
@@ -104,10 +104,10 @@ var IEFlashCLSID = "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000";
- (void)setFlashVars:(CPDictionary)aDictionary
{
var varString = @"",
enumerator = [aDictionary keyEnumerator];
enumerator = [aDictionary keyEnumerator],
key;
var key;
while (key = [enumerator nextObject])
while ((key = [enumerator nextObject]) !== nil)
varString = [varString stringByAppendingFormat:@"&%@=%@", key, [aDictionary objectForKey:key]];
if (!_params)
@@ -146,7 +146,7 @@ var IEFlashCLSID = "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000";
var enumerator = [_params keyEnumerator],
key;
while (_DOMObjectElement && (key = [enumerator nextObject]))
while (_DOMObjectElement && (key = [enumerator nextObject]) !== nil)
{
var param = document.createElement(@"param");
param.name = key;
@@ -178,7 +178,7 @@ var IEFlashCLSID = "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000";
paramEnumerator = [_params keyEnumerator],
key;
while (key = [paramEnumerator nextObject])
while ((key = [paramEnumerator nextObject]) !== nil)
paramString = [paramString stringByAppendingFormat:@"<param name='%@' value='%@' />", key, [_params objectForKey:key]];
_DOMObjectElement = document.createElement(@"object");
+192 -74
View File
@@ -28,46 +28,85 @@
CPFontDefaultSystemFontFace = @"Arial, sans-serif";
CPFontDefaultSystemFontSize = 12;
var _CPFonts = {},
_CPFontSystemFontFace = CPFontDefaultSystemFontFace,
_CPFontSystemFontSize = 12,
_CPFontFallbackFaces = CPFontDefaultSystemFontFace.split(", "),
_CPFontStripRegExp = new RegExp("(^\\s*[\"']?|[\"']?\\s*$)", "g");
/*!
To create a font of a size that will dynamically reflect the current
system font size, use this for the size argument.
*/
CPFontCurrentSystemSize = -1;
// For internal use only by this class and subclasses
_CPFontSystemFacePlaceholder = "_CPFontSystemFacePlaceholder";
var _CPFontCache = {},
_CPSystemFontCache = {},
_CPFontSystemFontFace = CPFontDefaultSystemFontFace,
_CPFontSystemFontSize = 12,
_CPFontFallbackFaces = CPFontDefaultSystemFontFace.split(", "),
_CPFontStripRegExp = new RegExp("(^\\s*[\"']?|[\"']?\\s*$)", "g");
#define _CPRealFontSize(aSize) (aSize <= 0 ? _CPFontSystemFontSize : aSize)
#define _CPFontNormalizedNames(aName) _CPFontNormalizedNameArray(aName).join(", ")
#define _CPCachedFont(aName, aSize, isBold, isItalic) _CPFonts[_CPFontCreateCSSString(_CPFontNormalizedNames(aName), aSize, isBold, isItalic)]
#define _CPCachedFont(aName, aSize, isBold, isItalic) _CPFontCache[_CPFontCreateCSSString(_CPFontNormalizedNames(aName), aSize, isBold, isItalic)]
#define _CPUserFont(aName, aSize, isBold, isItalic) _CPCachedFont(aName, aSize, isBold, isItalic) || [[CPFont alloc] _initWithName:aName size:aSize bold:isBold italic:isItalic system:NO]
#define _CPSystemFontCacheKey(aSize, isBold) (String(aSize) + (isBold ? "b" : ""))
#define _CPCachedSystemFont(aSize, isBold) _CPSystemFontCache[_CPSystemFontCacheKey(aSize, isBold)]
#define _CPSystemFont(aSize, isBold) (_CPCachedSystemFont(aSize, isBold) || [[CPFont alloc] _initWithName:_CPFontSystemFacePlaceholder size:aSize bold:isBold italic:NO system:YES])
/*!
@ingroup appkit
@class CPFont
@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.
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.
By default the system font face/size is Arial 12px, with a fallback to sans-serif. You may
configure this at runtime in two ways:
### System fonts
When you create a font using \c -systemFontOfSize: or \c -boldSystemFontOfSize:, a proxy font is
created that always refers to the current system font face and size. By default the system
font face/size is Arial 12px, with a fallback to sans-serif 12px. You may configure this at
runtime in two ways:
- By sending [CPFont @link CPFont::setSystemFontFace: setSystemFontFace:@endlink] and/or [CPFont @link CPFont::setSystemFontSize: setSystemFontSize:@endlink].
- By configuring Info.plist for your application or for AppKit. You can set the font face
by adding a CPSystemFontFace string item to the Info.plist, and you can set the font size
by adding a CPSystemFontSize integer item to the Info.plist.
- By sending [CPFont setSystemFontFace:<face>] and/or [CPFont setSystemFontSize:<size>].
Note that if you change the system font face or size during runtime, the next time
any view using a system font is redrawn, it will show the new font.
- By configuring Info.plist for your application or for AppKit. You can set the font face
by adding a CPSystemFontFace string item to the Info.plist, and you can set the font size
by adding a CPSystemFontSize integer item to the Info.plist.
Note that in either case, you can specify a comma-delimited list of fonts as the font face.
The browser will use the first available font in the list. CPFont always ensures that Arial
and sans-serif are in the generated CSS string, so there is no need to add them to the end
of your font list.
Note that in either case, you can specify a comma-delimited list of fonts as the font face.
Do not quote enclose font faces that contain spaces, that is done automatically when a CSS
representation of a font is requested.
If you are using nib2cib, you should use the second method (using Info.plist),
and be sure to run nib2cib again any time you modify the CPSystemFontFace or CPSystemFontSize items.
For example, you might add this to your application's Info.plist to set the system font to Lucida Grande,
with an automatic fallback to Arial or sans-serif:
The browser will use the first available font in the list you supply. CPFont always ensures
that Arial and sans-serif are in the CSS representation of a font as a fallback, so there is
no need to add them to the end of your font list.
@code
### nib2cib conversion
Fonts are converted by nib2cib according to the following algorithm:
- If the font family is Lucida Grande, then a system font will be created.
- If the font is Lucida Grande 13 (plain), the "default" font will be used at runtime.
The default font is taken from the "font" theme attribute if one exists,
otherwise from the current system font face and size.
- Lucida Grande of any size other than 13 will retain its size.
- Fonts using any family other than Lucida Grande will be used as is, including the size.
### Using custom web fonts
The configurability of CPFont makes it easy to use a custom web font as the system font.
For example, if you want to use the google font Asap as the system font, you would do the
following:
- Add a <link> to the <head> of index-debug.html and index.html:
@code
<link href='http://fonts.googleapis.com/css?family=Asap:400,700' rel='stylesheet' type='text/css'>
@endcode
- Specify Asap as the system font in Info.plist by adding the following item:
@code
<key>CPSystemFontFace</key>
<string>Lucida Grande</string>
@endcode
<string>Asap</string>
@endcode
*/
@implementation CPFont : CPObject
{
@@ -78,19 +117,23 @@ var _CPFonts = {},
float _lineHeight;
BOOL _isBold @accessors(readonly, getter=isBold);
BOOL _isItalic @accessors(readonly, getter=isItalic);
BOOL _isSystem @accessors(readonly, getter=isSystem);
CPString _cssString;
}
+ (void)initialize
{
if (self !== [CPFont class])
return;
var systemFontFace = [[CPBundle mainBundle] objectForInfoDictionaryKey:@"CPSystemFontFace"];
if (!systemFontFace)
systemFontFace = [[CPBundle bundleForClass:[CPView class]] objectForInfoDictionaryKey:@"CPSystemFontFace"];
if (systemFontFace)
[self setSystemFontFace:systemFontFace];
_CPFontSystemFontFace = _CPFontNormalizedNames(systemFontFace);
var systemFontSize = [[CPBundle mainBundle] objectForInfoDictionaryKey:@"CPSystemFontSize"];
@@ -114,7 +157,13 @@ var _CPFonts = {},
*/
+ (CPString)setSystemFontFace:(CPString)aFace
{
_CPFontSystemFontFace = _CPFontNormalizedNames(aFace);
var normalizedFaces = _CPFontNormalizedNames(aFace);
if (normalizedFaces === _CPFontSystemFontFace)
return;
[self _invalidateSystemFontCache]
_CPFontSystemFontFace = aFace;
}
/*!
@@ -125,106 +174,156 @@ var _CPFonts = {},
return _CPFontSystemFontSize;
}
+ (float)systemFontSizeForControlSize:(CPControlSize)aSize
{
// TODO These sizes should be themable or made less arbitrary in some other way.
switch (aSize)
{
case CPSmallControlSize:
return _CPFontSystemFontSize - 1;
case CPMiniControlSize:
return _CPFontSystemFontSize - 2;
case CPRegularControlSize:
default:
return _CPFontSystemFontSize;
}
}
/*!
Sets the default system font size.
*/
+ (float)setSystemFontSize:(float)size
{
if (size > 0)
if (size > 0 && size !== _CPFontSystemFontSize)
{
[self _invalidateSystemFontCache];
_CPFontSystemFontSize = size;
}
}
+ (void)_invalidateSystemFontCache
{
var systemSize = String(_CPFontSystemFontSize),
currentSize = String(CPFontCurrentSystemSize);
for (key in _CPSystemFontCache)
{
if (_CPSystemFontCache.hasOwnProperty(key) &&
(key.indexOf(systemSize) === 0 || key.indexOf(currentSize) === 0))
{
delete _CPSystemFontCache[key];
}
}
}
/*!
Returns a font with the specified name and size.
@param aName the name of the font
@param aSize the size of the font (in px)
@param aSize the size of the font (in px). 0 or negative will create a font
in the current system font size.
@return the requested font
*/
+ (CPFont)fontWithName:(CPString)aName size:(float)aSize
{
return _CPCachedFont(aName, aSize, NO, NO) || [[CPFont alloc] _initWithName:aName size:aSize bold:NO italic:NO];
return _CPUserFont(aName, aSize <= 0 ? _CPFontSystemFontSize : aSize, NO, NO);
}
/*!
Returns a font with the specified name, size and style.
@param aName the name of the font
@param aSize the size of the font (in px)
@param aSize the size of the font (in px). 0 or negative will create a font
in the current system font size.
@param italic whether the font should be italicized
@return the requested font
*/
+ (CPFont)fontWithName:(CPString)aName size:(float)aSize italic:(BOOL)italic
{
return _CPCachedFont(aName, aSize, NO, NO) || [[CPFont alloc] _initWithName:aName size:aSize bold:NO italic:italic];
return _CPUserFont(aName, aSize <= 0 ? _CPFontSystemFontSize : aSize, NO, italic);
}
/*!
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 px)
@param aSize the size of the font (in px). 0 or negative will create a font
in the current system font size.
@return the requested bold font
*/
+ (CPFont)boldFontWithName:(CPString)aName size:(float)aSize
{
return _CPCachedFont(aName, aSize, YES, NO) || [[CPFont alloc] _initWithName:aName size:aSize bold:YES italic:NO];
return _CPUserFont(aName, aSize <= 0 ? _CPFontSystemFontSize : aSize, YES, NO);
}
/*!
Returns a bold font with the specified name, size and style.
@param aName the name of the font
@param aSize the size of the font (in px)
@param aSize the size of the font (in px). 0 or negative will create a font
in the current system font size.
@param italic whether the font should be italicized
@return the requested font
*/
+ (CPFont)boldFontWithName:(CPString)aName size:(float)aSize italic:(BOOL)italic
{
return _CPCachedFont(aName, aSize, NO, NO) || [[CPFont alloc] _initWithName:aName size:aSize bold:YES italic:italic];
return _CPUserFont(aName, aSize <= 0 ? _CPFontSystemFontSize : aSize, YES, italic);
}
/*!
Internal font getter like fontWithName:size:italic: with a bold selector.
*/
+ (CPFont)_fontWithName:(CPString)aName size:(float)aSize bold:(BOOL)bold italic:(BOOL)italic
{
return _CPUserFont(aName, aSize <= 0 ? _CPFontSystemFontSize : aSize, bold, italic);
}
/*!
Returns the system font scaled to the specified size
@param aSize the size of the font (in px)
@param aSize the size of the font (in px). 0 creates a static font
in the current system font size. Negative creates a font
that dynamically tracks the current system font size.
@return the requested system font
*/
+ (CPFont)systemFontOfSize:(CPSize)aSize
+ (CPFont)systemFontOfSize:(CGSize)aSize
{
return _CPCachedFont(_CPFontSystemFontFace, aSize, NO, NO) || [[CPFont alloc] _initWithName:_CPFontSystemFontFace size:aSize bold:NO italic:NO];
return _CPSystemFont(aSize === 0 ? _CPFontSystemFontSize : aSize, NO);
}
/*!
Returns the bold system font scaled to the specified size
@param aSize the size of the font (in px)
@param aSize the size of the font (in px). 0 creates a static font
in the current system font size. Negative creates a font
that dynamically tracks the current system font size.
@return the requested bold system font
*/
+ (CPFont)boldSystemFontOfSize:(CPSize)aSize
+ (CPFont)boldSystemFontOfSize:(CGSize)aSize
{
return _CPCachedFont(_CPFontSystemFontFace, aSize, YES, NO) || [[CPFont alloc] _initWithName:_CPFontSystemFontFace size:aSize bold:YES italic:NO];
return _CPSystemFont(aSize === 0 ? _CPFontSystemFontSize : aSize, YES);
}
/* FIXME Font Descriptor
@ignore
*/
- (id)_initWithName:(CPString)aName size:(float)aSize bold:(BOOL)isBold
{
return [self _initWithName:aName size:aSize bold:isBold italic:NO];
}
- (id)_initWithName:(CPString)aName size:(float)aSize bold:(BOOL)isBold italic:(BOOL)isItalic
- (id)_initWithName:(CPString)aName size:(float)aSize bold:(BOOL)isBold italic:(BOOL)isItalic system:(BOOL)isSystem
{
self = [super init];
if (self)
{
_name = _CPFontNormalizedNames(aName);
_size = aSize;
_ascender = 0;
_descender = 0;
_lineHeight = 0;
_isBold = isBold;
_isItalic = isItalic;
_isSystem = isSystem;
_cssString = _CPFontCreateCSSString(_name, _size, _isBold, _isItalic);
_CPFonts[_cssString] = self;
if (isSystem)
{
_name = aName;
_cssString = _CPFontCreateCSSString(_CPFontSystemFontFace, _size, _isBold, _isItalic);
_CPSystemFontCache[_CPSystemFontCacheKey(_size, _isBold)] = self;
}
else
{
_name = _CPFontNormalizedNames(aName);
_cssString = _CPFontCreateCSSString(_name, _size, _isBold, _isItalic);
_CPFontCache[_cssString] = self;
}
}
return self;
@@ -235,10 +334,12 @@ var _CPFonts = {},
*/
- (float)ascender
{
if (!_ascender)
[self _getMetrics];
var font = _isSystem ? _CPSystemFont(_size, _isBold) : self;
return _ascender;
if (!font._ascender)
[font _getMetrics];
return font._ascender;
}
/*!
@@ -247,10 +348,12 @@ var _CPFonts = {},
*/
- (float)descender
{
if (!_descender)
[self _getMetrics];
var font = _isSystem ? _CPSystemFont(_size, _isBold) : self;
return _descender;
if (!font._descender)
[font _getMetrics];
return font._descender;
}
/*!
@@ -260,10 +363,12 @@ var _CPFonts = {},
*/
- (float)defaultLineHeightForFont
{
if (!_lineHeight)
[self _getMetrics];
var font = _isSystem ? _CPSystemFont(_size, _isBold) : self;
return _lineHeight;
if (!font._lineHeight)
[font _getMetrics];
return font._lineHeight;
}
/*!
@@ -271,7 +376,7 @@ var _CPFonts = {},
*/
- (float)size
{
return _size;
return _CPRealFontSize(_size);
}
/*!
@@ -279,7 +384,9 @@ var _CPFonts = {},
*/
- (CPString)cssString
{
return _cssString;
var font = _isSystem ? _CPSystemFont(_size, _isBold) : self;
return font._cssString;
}
/*!
@@ -287,9 +394,17 @@ var _CPFonts = {},
*/
- (CPString)familyName
{
if (_isSystem)
return _CPFontSystemFontFace;
return _name;
}
- (BOOL)isSystemSize
{
return _size <= 0;
}
- (BOOL)isEqual:(id)anObject
{
return [anObject isKindOfClass:[CPFont class]] && [anObject cssString] === _cssString;
@@ -302,7 +417,7 @@ var _CPFonts = {},
- (id)copy
{
return [[CPFont alloc] _initWithName:_name size:_size bold:_isBold italic:_isItalic];
return [[CPFont alloc] _initWithName:_name size:_size bold:_isBold italic:_isItalic system:_isSystem];
}
- (void)_getMetrics
@@ -319,7 +434,8 @@ var _CPFonts = {},
var CPFontNameKey = @"CPFontNameKey",
CPFontSizeKey = @"CPFontSizeKey",
CPFontIsBoldKey = @"CPFontIsBoldKey",
CPFontIsItalicKey = @"CPFontIsItalicKey";
CPFontIsItalicKey = @"CPFontIsItalicKey",
CPFontIsSystemKey = @"CPFontIsSystemKey";
@implementation CPFont (CPCoding)
@@ -333,9 +449,10 @@ var CPFontNameKey = @"CPFontNameKey",
var fontName = [aCoder decodeObjectForKey:CPFontNameKey],
size = [aCoder decodeFloatForKey:CPFontSizeKey],
isBold = [aCoder decodeBoolForKey:CPFontIsBoldKey],
isItalic = [aCoder decodeBoolForKey:CPFontIsItalicKey];
isItalic = [aCoder decodeBoolForKey:CPFontIsItalicKey],
isSystem = [aCoder decodeBoolForKey:CPFontIsSystemKey];
return [self _initWithName:fontName size:size bold:isBold italic:isItalic];
return [self _initWithName:fontName size:size bold:isBold italic:isItalic system:isSystem];
}
/*!
@@ -348,6 +465,7 @@ var CPFontNameKey = @"CPFontNameKey",
[aCoder encodeFloat:_size forKey:CPFontSizeKey];
[aCoder encodeBool:_isBold forKey:CPFontIsBoldKey];
[aCoder encodeBool:_isItalic forKey:CPFontIsItalicKey];
[aCoder encodeBool:_isSystem forKey:CPFontIsSystemKey];
}
@end
@@ -356,7 +474,7 @@ var CPFontNameKey = @"CPFontNameKey",
// aName must be normalized
var _CPFontCreateCSSString = function(aName, aSize, isBold, isItalic)
{
var properties = (isItalic ? "italic " : "") + (isBold ? "bold " : "") + aSize + "px ";
var properties = (isItalic ? "italic " : "") + (isBold ? "bold " : "") + _CPRealFontSize(aSize) + "px ";
return properties + _CPFontConcatNameWithFallback(aName);
};
+152 -31
View File
@@ -24,6 +24,21 @@
@import "CPFont.j"
@global CPApp
CPItalicFontMask = 1 << 0;
CPBoldFontMask = 1 << 1;
CPUnboldFontMask = 1 << 2;
CPNonStandardCharacterSetFontMask = 1 << 3;
CPNarrowFontMask = 1 << 4;
CPExpandedFontMask = 1 << 5;
CPCondensedFontMask = 1 << 6;
CPSmallCapsFontMask = 1 << 7;
CPPosterFontMask = 1 << 8;
CPCompressedFontMask = 1 << 9;
CPFixedPitchFontMask = 1 << 10;
CPUnitalicFontMask = 1 << 24;
var CPSharedFontManager = nil,
CPFontManagerFactory = Nil;
@@ -33,7 +48,17 @@ var CPSharedFontManager = nil,
*/
@implementation CPFontManager : CPObject
{
CPArray _availableFonts;
CPArray _availableFonts;
id _target @accessors(property=target);
SEL _action @accessors(property=action);
id _delegate @accessors(property=delegate);
CPFont _selectedFont;
BOOL _multiple @accessors(getter=isMultiple, setter=setMultiple:);
CPDictionary _activeChange;
}
// Getting the Shared Font Manager
@@ -59,6 +84,16 @@ var CPSharedFontManager = nil,
CPFontManagerFactory = aClass;
}
- (id)init
{
if (self = [super init])
{
_action = @selector(changeFont:);
}
return self;
}
/*!
Returns an array of the available fonts
*/
@@ -66,6 +101,9 @@ var CPSharedFontManager = nil,
{
if (!_availableFonts)
{
_availableFonts = [];
#if PLATFORM(DOM)
_CPFontDetectSpan = document.createElement("span");
_CPFontDetectSpan.fontSize = "24px";
_CPFontDetectSpan.appendChild(document.createTextNode("mmmmmmmmmml"));
@@ -77,13 +115,16 @@ var CPSharedFontManager = nil,
_CPFontDetectReferenceFonts = _CPFontDetectPickTwoDifferentFonts(["monospace", "serif", "sans-serif", "cursive"]);
_availableFonts = [];
for (var i = 0; i < _CPFontDetectAllFonts.length; i++)
{
var available = _CPFontDetectFontAvailable(_CPFontDetectAllFonts[i]);
if (available)
_availableFonts.push(_CPFontDetectAllFonts[i]);
}
#else
// If there's no font detection, just assume all fonts are available.
_availableFonts = _CPFontDetectAllFonts;
#endif
}
return _availableFonts;
}
@@ -97,43 +138,123 @@ var CPSharedFontManager = nil,
return _CPFontDetectFontAvailable(aFontName);
}
- (void)setSelectedFont:(CPFont)aFont isMultiple:(BOOL)aFlag
{
_selectedFont = aFont;
_multiple = aFlag;
// TODO Notify CPFontPanel when it exists.
}
- (CPFont)selectedFont
{
return _selectedFont;
}
- (int)weightOfFont:(CPFont)aFont
{
// TODO Weight 5 is a normal of book weight and 9 and above is bold, but it would be nice to be more
// precise than that.
return [aFont isBold] ? 9 : 5;
}
- (CPFontTraitMask)traitsOfFont:(CPFont)aFont
{
return ([aFont isBold] ? CPBoldFontMask : 0) | ([aFont isItalic] ? CPItalicFontMask : 0);
}
- (CPFont)convertFont:(CPFont)aFont
{
if (!_activeChange)
return aFont;
var addTraits = [_activeChange valueForKey:@"addTraits"];
if (addTraits)
aFont = [self convertFont:aFont toHaveTrait:addTraits];
return aFont;
}
- (CPFont)convertFont:(CPFont)aFont toHaveTrait:(CPFontTraitMask)addTraits
{
if (!aFont)
return nil;
var shouldBeBold = ([aFont isBold] || (addTraits & CPBoldFontMask)) && !(addTraits & CPUnboldFontMask),
shouldBeItalic = ([aFont isItalic] || (addTraits & CPItalicFontMask)) && !(addTraits & CPUnitalicFontMask),
shouldBeSize = [aFont size];
// XXX On the current platform there will always be a bold/italic version of each font, but still leave
// || aFont in here for future platforms.
aFont = [CPFont _fontWithName:[aFont familyName] size:shouldBeSize bold:shouldBeBold italic:shouldBeItalic] || aFont;
return aFont;
}
- (CPFont)convertFont:(CPFont)aFont toFace:(CPString)aTypeface
{
if (!aFont)
return nil;
var shouldBeBold = [aFont isBold],
shouldBeItalic = [aFont isItalic],
shouldBeSize = [aFont size];
aFont = [CPFont _fontWithName:aTypeface size:shouldBeSize bold:shouldBeBold italic:shouldBeItalic] || aFont;
return aFont;
}
- (@action)addFontTrait:(id)sender
{
_activeChange = [CPDictionary dictionaryWithObject:[sender tag] forKey:@"addTraits"];
[self sendAction];
}
- (BOOL)sendAction
{
return [CPApp sendAction:_action to:_target from:self];
}
@end
var _CPFontDetectSpan,
_CPFontDetectReferenceFonts,
_CPFontDetectAllFonts = [
/* "04b_21","A Charming Font","Abadi MT Condensed","Abadi MT Condensed Extra Bold","Abadi MT Condensed Light","Academy Engraved LET","Agency FB","Alba","Alba Matter","Alba Super","Algerian",*/
/* "04b_21", "A Charming Font", "Abadi MT Condensed", "Abadi MT Condensed Extra Bold", "Abadi MT Condensed Light", "Academy Engraved LET", "Agency FB", "Alba", "Alba Matter", "Alba Super", "Algerian",*/
"American Typewriter",
/* "Andale Mono","Andale Mono IPA","Andy", */
"Apple Chancery","Arial","Arial Black","Arial Narrow","Arial Rounded MT Bold","Arial Unicode MS",
/* "Avant Garde","Avantgarde","Baby Kruffy","Base 02","Baskerville","Baskerville Old Face","Bauhaus 93","Beesknees ITC","Bell MT","Berlin Sans FB","Berlin Sans FB Demi","Bernard MT Condensed","Bickley Script",*/
"Big Caslon","Bitstream Vera Sans","Bitstream Vera Sans Mono","Bitstream Vera Serif",
/* "Blackadder ITC","Blackletter686 BT","Bodoni MT","Bodoni MT Black","Bodoni MT Condensed","Bodoni MT Poster Compressed","Book Antiqua","Bookman","Bookman Old Style","Bradley Hand ITC","Braggadocio","Britannic Bold","Broadway","Broadway BT",*/
/* "Andale Mono", "Andale Mono IPA", "Andy", */
"Apple Chancery", "Arial", "Arial Black", "Arial Narrow", "Arial Rounded MT Bold", "Arial Unicode MS",
/* "Avant Garde", "Avantgarde", "Baby Kruffy", "Base 02", "Baskerville", "Baskerville Old Face", "Bauhaus 93", "Beesknees ITC", "Bell MT", "Berlin Sans FB", "Berlin Sans FB Demi", "Bernard MT Condensed", "Bickley Script",*/
"Big Caslon", "Bitstream Vera Sans", "Bitstream Vera Sans Mono", "Bitstream Vera Serif",
/* "Blackadder ITC", "Blackletter686 BT", "Bodoni MT", "Bodoni MT Black", "Bodoni MT Condensed", "Bodoni MT Poster Compressed", "Book Antiqua", "Bookman", "Bookman Old Style", "Bradley Hand ITC", "Braggadocio", "Britannic Bold", "Broadway", "Broadway BT",*/
"Brush Script MT",
/* "BudHand","CAMPBELL","Calibri","Californian FB","Calisto MT","Calligraph421 BT",*/
/* "BudHand", "CAMPBELL", "Calibri", "Californian FB", "Calisto MT", "Calligraph421 BT",*/
"Cambria",
/* "Candara","Capitals",*/
"Caslon","Castellar","Cataneo BT","Centaur","Century Gothic","Century Schoolbook","Century Schoolbook L",
/* "Champignon","Charcoal","Charter","Charter BT","Chicago","Chick","Chiller","ClearlyU","Colonna MT",*/
"Comic Sans", "Comic Sans MS","Consolas","Constantia","Cooper Black","Copperplate","Copperplate Gothic Bold","Copperplate Gothic Light","Corbel","Courier","Courier New",
/* "Croobie","Curlz MT","Desdemona","Didot","DomBold BT","Edwardian Script ITC","Engravers MT","Eras Bold ITC","Eras Demi ITC","Eras Light ITC","Eras Medium ITC","Eurostile","FIRSTHOME","Fat","Felix Titling","Fine Hand","Fixed","Footlight MT Light","Forte","Franklin Gothic Book","Franklin Gothic Demi","Franklin Gothic Demi Cond","Franklin Gothic Heavy","Franklin Gothic Medium","Franklin Gothic Medium Cond","Freestyle Script","French Script MT","Freshbot","Frosty",*/
/* "Candara", "Capitals",*/
"Caslon", "Castellar", "Cataneo BT", "Centaur", "Century Gothic", "Century Schoolbook", "Century Schoolbook L",
/* "Champignon", "Charcoal", "Charter", "Charter BT", "Chicago", "Chick", "Chiller", "ClearlyU", "Colonna MT",*/
"Comic Sans", "Comic Sans MS", "Consolas", "Constantia", "Cooper Black", "Copperplate", "Copperplate Gothic Bold", "Copperplate Gothic Light", "Corbel", "Courier", "Courier New",
/* "Croobie", "Curlz MT", "Desdemona", "Didot", "DomBold BT", "Edwardian Script ITC", "Engravers MT", "Eras Bold ITC", "Eras Demi ITC", "Eras Light ITC", "Eras Medium ITC", "Eurostile", "FIRSTHOME", "Fat", "Felix Titling", "Fine Hand", "Fixed", "Footlight MT Light", "Forte", "Franklin Gothic Book", "Franklin Gothic Demi", "Franklin Gothic Demi Cond", "Franklin Gothic Heavy", "Franklin Gothic Medium", "Franklin Gothic Medium Cond", "Freestyle Script", "French Script MT", "Freshbot", "Frosty",*/
"Futura",
/* "GENUINE","Gadget","Garamond",*/
"Geneva","Georgia","Georgia Ref", "Geeza Pro", "Gigi","Gill Sans","Gill Sans MT","Gill Sans MT Condensed","Gill Sans MT Ext Condensed Bold","Gill Sans Ultra Bold","Gill Sans Ultra Bold Condensed",
/* "GlooGun","Gloucester MT Extra Condensed","Goudy Old Style","Goudy Stout","Haettenschweiler","Harlow Solid Italic","Harrington",*/
"Helvetica","Helvetica Narrow","Helvetica Neue","Herculanum","High Tower Text","Highlight LET","Hoefler Text","Impact","Imprint MT Shadow",
/* "Informal Roman","Jenkins v2.0","John Handy LET","Jokerman","Jokerman LET","Jokewood","Juice ITC","Kabel Ult BT","Kartika","Kino MT","Kristen ITC","Kunstler Script","La Bamba LET", */
"Lucida","Lucida Bright","Lucida Calligraphy","Lucida Console","Lucida Fax","Lucida Grande","Lucida Handwriting","Lucida Sans","Lucida Sans Typewriter","Lucida Sans Unicode",
/* "Luxi Mono","Luxi Sans","Luxi Serif","MARKETPRO","MS Reference Sans Serif","MS Reference Serif","Magneto","Maiandra GD", */
/* "GENUINE", "Gadget", "Garamond",*/
"Geneva", "Georgia", "Georgia Ref", "Geeza Pro", "Gigi", "Gill Sans", "Gill Sans MT", "Gill Sans MT Condensed", "Gill Sans MT Ext Condensed Bold", "Gill Sans Ultra Bold", "Gill Sans Ultra Bold Condensed",
/* "GlooGun", "Gloucester MT Extra Condensed", "Goudy Old Style", "Goudy Stout", "Haettenschweiler", "Harlow Solid Italic", "Harrington",*/
"Helvetica", "Helvetica Narrow", "Helvetica Neue", "Herculanum", "High Tower Text", "Highlight LET", "Hoefler Text", "Impact", "Imprint MT Shadow",
/* "Informal Roman", "Jenkins v2.0", "John Handy LET", "Jokerman", "Jokerman LET", "Jokewood", "Juice ITC", "Kabel Ult BT", "Kartika", "Kino MT", "Kristen ITC", "Kunstler Script", "La Bamba LET", */
"Lucida", "Lucida Bright", "Lucida Calligraphy", "Lucida Console", "Lucida Fax", "Lucida Grande", "Lucida Handwriting", "Lucida Sans", "Lucida Sans Typewriter", "Lucida Sans Unicode",
/* "Luxi Mono", "Luxi Sans", "Luxi Serif", "MARKETPRO", "MS Reference Sans Serif", "MS Reference Serif", "Magneto", "Maiandra GD", */
"Marker Felt",
/* "Matisse ITC","Matura MT Script Capitals","Mead Bold","Mekanik LET","Mercurius Script MT Bold", */
"Microsoft Sans Serif","Milano LET","Minion Web","MisterEarl BT","Mistral","Monaco","Monotype Corsiva","Monotype.com","New Century Schoolbook","New York","News Gothic MT",
/* "Niagara Engraved","Niagara Solid","Nimbus Mono L","Nimbus Roman No9 L","OCR A Extended","OCRB","Odessa LET","Old English Text MT","OldDreadfulNo7 BT","One Stroke Script LET","Onyx","Optima","Orange LET","Palace Script MT","Palatino","Palatino Linotype", */
/* "Matisse ITC", "Matura MT Script Capitals", "Mead Bold", "Mekanik LET", "Mercurius Script MT Bold", */
"Microsoft Sans Serif", "Milano LET", "Minion Web", "MisterEarl BT", "Mistral", "Monaco", "Monotype Corsiva", "Monotype.com", "New Century Schoolbook", "New York", "News Gothic MT",
/* "Niagara Engraved", "Niagara Solid", "Nimbus Mono L", "Nimbus Roman No9 L", "OCR A Extended", "OCRB", "Odessa LET", "Old English Text MT", "OldDreadfulNo7 BT", "One Stroke Script LET", "Onyx", "Optima", "Orange LET", "Palace Script MT", "Palatino", "Palatino Linotype", */
"Papyrus",
/* "ParkAvenue BT","Pepita MT","Perpetua","Perpetua Titling MT","Placard Condensed","Playbill","Poornut","Pristina","Pump Demi Bold LET","Pussycat","Quixley LET","Rage Italic","Rage Italic LET","Ravie","Rockwell","Rockwell Condensed","Rockwell Extra Bold","Ruach LET","Runic MT Condensed","Sand","Script MT Bold","Scruff LET","Segoe UI","Showcard Gothic","Skia","Smudger LET","Snap ITC","Square721 BT","Staccato222 BT","Stencil","Sylfaen", */
"Tahoma","Techno","Tempus Sans ITC","Terminal","Textile","Times","Times New Roman","Tiranti Solid LET","Trebuchet MS",
/* "Tw Cen MT","Tw Cen MT Condensed","Tw Cen MT Condensed Extra Bold","URW Antiqua T","URW Bookman L","URW Chancery L","URW Gothic L","URW Palladio L","Univers","University Roman LET","Utopia", */
"Verdana","Verdana Ref", /* "Victorian LET","Viner Hand ITC","Vivaldi","Vladimir Script","Vrinda","Weltron Urban","Westwood LET","Wide Latin","Zapf Chancery", */
/* "ParkAvenue BT", "Pepita MT", "Perpetua", "Perpetua Titling MT", "Placard Condensed", "Playbill", "Poornut", "Pristina", "Pump Demi Bold LET", "Pussycat", "Quixley LET", "Rage Italic", "Rage Italic LET", "Ravie", "Rockwell", "Rockwell Condensed", "Rockwell Extra Bold", "Ruach LET", "Runic MT Condensed", "Sand", "Script MT Bold", "Scruff LET", "Segoe UI", "Showcard Gothic", "Skia", "Smudger LET", "Snap ITC", "Square721 BT", "Staccato222 BT", "Stencil", "Sylfaen", */
"Tahoma", "Techno", "Tempus Sans ITC", "Terminal", "Textile", "Times", "Times New Roman", "Tiranti Solid LET", "Trebuchet MS",
/* "Tw Cen MT", "Tw Cen MT Condensed", "Tw Cen MT Condensed Extra Bold", "URW Antiqua T", "URW Bookman L", "URW Chancery L", "URW Gothic L", "URW Palladio L", "Univers", "University Roman LET", "Utopia", */
"Verdana", "Verdana Ref", /* "Victorian LET", "Viner Hand ITC", "Vivaldi", "Vladimir Script", "Vrinda", "Weltron Urban", "Westwood LET", "Wide Latin", "Zapf Chancery", */
"Zapfino"];
// Compare against the reference fonts. Return true if it produces a different size than at least one of them.
@@ -143,7 +264,7 @@ var _CPFontDetectFontAvailable = function(font)
if (_CPFontDetectCompareFonts(_CPFontDetectReferenceFonts[i], font))
return true;
return false;
}
};
var _CPFontDetectCache = {};
@@ -165,7 +286,7 @@ var _CPFontDetectCompareFonts = function(fontA, fontB)
bHeight = _CPFontDetectSpan.offsetHeight;
return (a.w != bWidth || a.h != bHeight);
}
};
// Test the candidate fonts pairwise until we find two that are different. Otherwise return the first.
var _CPFontDetectPickTwoDifferentFonts = function(candidates)
@@ -175,6 +296,6 @@ var _CPFontDetectPickTwoDifferentFonts = function(candidates)
if (_CPFontDetectCompareFonts(candidates[i], candidates[j]))
return [candidates[i], candidates[j]];
return [candidates[0]];
}
};
[CPFontManager setFontManagerFactory:[CPFontManager class]];
+132
View File
@@ -0,0 +1,132 @@
/*
* CPGradient.j
* AppKit
*
* Created by Alexander Ljungberg.
* Copyright 2012, SlevenBits Ltd.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import <Foundation/CPObject.j>
@import <Foundation/CPException.j>
@import <Foundation/CPMutableArray.j>
@import "CGColor.j"
@import "CGColorSpace.j"
@import "CGGradient.j"
@import "CPGraphicsContext.j"
CPGradientDrawsBeforeStartingLocation = kCGGradientDrawsBeforeStartLocation;
CPGradientDrawsAfterEndingLocation = kCGGradientDrawsAfterEndLocation;
/*!
A class for drawing linear and radial gradients with a convenient API.
*/
@implementation CPGradient : CPObject
{
CGGradient _gradient;
}
- (id)initWithColors:(CPArray)someColors
{
var count = [someColors count];
if (count < 2)
[CPException raise:CPInvalidArgumentException reason:@"at least 2 colors required"];
var distance = 1.0 / (count - 1),
locations = [CPMutableArray array],
location = 0.0;
for (var i = 0; i < count; i++)
{
[locations addObject:location];
location += distance;
}
return [self initWithColors:someColors atLocations:locations colorSpace:nil];
}
- (id)initWithColors:(CPArray)someColors atLocations:(CPArray)someLocations colorSpace:(CPColorSpace)aColorSpace
{
if (self = [super init])
{
var cgColors = [],
count = [someColors count],
colorSpace = [aColorSpace CGColorSpace] || CGColorSpaceCreateDeviceRGB;
for (var i = 0; i < count; i++)
cgColors.push(CGColorCreate(colorSpace, [someColors[i] components]));
_gradient = CGGradientCreateWithColors(colorSpace, cgColors, someLocations);
}
return self;
}
- (void)drawInRect:(CGRect)rect angle:(float)angle
{
var ctx = [[CPGraphicsContext currentContext] graphicsPort];
CGContextSaveGState(ctx);
CGContextClipToRect(ctx, rect);
CGContextAddRect(ctx, rect);
var startPoint,
endPoint;
// Modulo of negative values doesn't work as expected in JS.
angle = ((angle % 360.0) + 360.0) % 360.0;
if (angle < 90.0)
startPoint = _CGPointMake(_CGRectGetMinX(rect), _CGRectGetMinY(rect));
else if (angle < 180.0)
startPoint = _CGPointMake(_CGRectGetMaxX(rect), _CGRectGetMinY(rect));
else if (angle < 270.0)
startPoint = _CGPointMake(_CGRectGetMaxX(rect), _CGRectGetMaxY(rect));
else
startPoint = _CGPointMake(_CGRectGetMinX(rect), _CGRectGetMaxY(rect));
// A line segment comes out of the starting point at the given angle, with the first colour
// at the starting point and the last at the end. To do what drawInRect: is supposed to do
// we want the opposite corner of the starting corner to just reach the final colour stop.
// So when the angle isn't a right angle, the segment has to extend beyond the edge of the
// rectangle just far enough. This is hard to describe without a picture but if we place
// another line through the opposite corner at -90 degrees, it'll help form some triangles
// from which we can derive this formula:
//
// length = cos(angle) * (rectWidth + rectHeight * tan(angle))
//
// This simplifies down to (in the first quadrant) rectWidth * cos(a) + rectHeight * sin(a).
var radians = PI * angle / 180.0,
length = ABS(_CGRectGetWidth(rect) * COS(radians)) + ABS(_CGRectGetHeight(rect) * SIN(radians));
endPoint = _CGPointMake(startPoint.x + length * COS(radians),
startPoint.y + length * SIN(radians));
[self drawFromPoint:startPoint toPoint:endPoint options:CPGradientDrawsBeforeStartingLocation | CPGradientDrawsAfterEndingLocation];
CGContextRestoreGState(ctx);
}
- (void)drawFromPoint:(NSPoint)startingPoint toPoint:(NSPoint)endingPoint options:(NSGradientDrawingOptions)options
{
var ctx = [[CPGraphicsContext currentContext] graphicsPort];
// TODO kCGGradientDrawsBeforeStartLocation and kCGGradientDrawsAfterEndLocation are not actually supported
// by CGContextDrawLinearGradient yet.
CGContextDrawLinearGradient(ctx, _gradient, startingPoint, endingPoint, options);
}
@end
+15 -2
View File
@@ -23,6 +23,16 @@
@import "CPColor.j"
@import "CPGraphicsContext.j"
CPCalibratedWhiteColorSpace = @"CalibratedWhiteColorSpace";
CPCalibratedBlackColorSpace = @"CalibratedBlackColorSpace";
CPCalibratedRGBColorSpace = @"CalibratedRGBColorSpace";
CPDeviceWhiteColorSpace = @"DeviceWhiteColorSpace";
CPDeviceBlackColorSpace = @"DeviceBlackColorSpace";
CPDeviceRGBColorSpace = @"DeviceRGBColorSpace";
CPDeviceCMYKColorSpace = @"DeviceCMYKColorSpace";
CPNamedColorSpace = @"NamedColorSpace";
CPPatternColorSpace = @"PatternColorSpace";
CPCustomColorSpace = @"CustomColorSpace";
function CPDrawTiledRects(
/* CGRect */ boundsRect,
@@ -70,7 +80,10 @@ function CPDrawColorTiledRects(
if (_CGRectIsEmpty(slice))
continue;
var minX, maxX, minY, maxY;
var minX,
maxX,
minY,
maxY;
if (side == CPMinXEdge || side == CPMaxXEdge)
{
@@ -105,4 +118,4 @@ function CPDrawColorTiledRects(
CGContextRestoreGState(context);
return resultRect;
}
}
+47 -1
View File
@@ -25,7 +25,8 @@
@import "CGContext.j"
var CPGraphicsContextCurrent = nil;
var CPGraphicsContextCurrent = nil,
CPGraphicsContextThreadStack = nil;
/*!
@ingroup appkit
@@ -52,6 +53,28 @@ var CPGraphicsContextCurrent = nil;
CPGraphicsContextCurrent = aGraphicsContext;
}
+ (void)saveGraphicsState
{
if (!CPGraphicsContextCurrent)
return;
if (!CPGraphicsContextThreadStack)
CPGraphicsContextThreadStack = [CPMutableArray array];
[CPGraphicsContextThreadStack addObject:CPGraphicsContextCurrent];
[CPGraphicsContextCurrent saveGraphicsState];
}
+ (void)restoreGraphicsState
{
var lastContext = [CPGraphicsContextThreadStack lastObject];
if (lastContext)
{
[lastContext restoreGraphicsState];
[CPGraphicsContextThreadStack removeLastObject];
}
}
/*!
Creates a graphics context with a provided port.
@param aContext the context to initialize with
@@ -86,4 +109,27 @@ var CPGraphicsContextCurrent = nil;
return _graphicsPort;
}
/*!
(Not implemented. Always returns Cappuccino's default, `YES`.)
Return `isFlipped` of the receiver's focused view, unless no view is focused in which case the receiver's
`flipped` flag, as set by `graphicsContextWithGraphicsPort:flipped:`, is returned.
Note: Cappuccino is flipped by default.
*/
- (BOOL)isFlipped
{
return YES;
}
- (void)saveGraphicsState
{
CGContextSaveGState(_graphicsPort);
}
- (void)restoreGraphicsState
{
CGContextRestoreGState(_graphicsPort);
}
@end
+107 -13
View File
@@ -25,9 +25,10 @@
@import <Foundation/CPObject.j>
@import <Foundation/CPRunLoop.j>
@import <Foundation/CPString.j>
@import <Foundation/CPData.j>
@import "CPGeometry.j"
@import "CGGeometry.j"
@import "CPCompatibility.j"
CPImageLoadStatusInitialized = 0;
CPImageLoadStatusLoading = 1;
@@ -44,20 +45,50 @@ CPImageNameColorPanel = @"CPImageNameColorPanel";
CPImageNameColorPanelHighlighted = @"CPImageNameColorPanelHighlighted";
var imagesForNames = { },
AppKitImageForNames = { };
AppKitImageForNames = { },
ImageDescriptionFormat = "%s {\n filename: \"%s\",\n size: { width:%f, height:%f }\n}";
AppKitImageForNames[CPImageNameColorPanel] = CGSizeMake(26.0, 29.0);
AppKitImageForNames[CPImageNameColorPanelHighlighted] = CGSizeMake(26.0, 29.0);
function CPImageInBundle(aFilename, aSize, aBundle)
/*!
Returns a resource image with a relative path and size
in a bundle.
@param filename A filename or relative path to a resource image.
@param width Width of the image. May be omitted.
@param height Height of the image. May be omitted if width is omitted.
@param size Instead of passing width/height, a CGSize may be passed.
@param bundle Bundle in which the image resource can be found.
If omitted, defaults to the main bundle.
@return CPImage
*/
function CPImageInBundle()
{
if (!aBundle)
aBundle = [CPBundle mainBundle];
var filename = arguments[0],
size = nil,
bundle = nil;
if (aSize)
return [[CPImage alloc] initWithContentsOfFile:[aBundle pathForResource:aFilename] size:aSize];
if (typeof(arguments[1]) === "number")
{
if (arguments[1] !== nil && arguments[1] === undefined)
size = CGSizeMake(arguments[1], arguments[2]);
return [[CPImage alloc] initWithContentsOfFile:[aBundle pathForResource:aFilename]];
bundle = arguments[3];
}
else if (typeof(arguments[1]) === "object")
{
size = arguments[1];
bundle = arguments[2];
}
if (!bundle)
bundle = [CPBundle mainBundle];
if (size)
return [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:filename] size:size];
return [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:filename]];
}
function CPAppKitImage(aFilename, aSize)
@@ -117,7 +148,7 @@ function CPAppKitImage(aFilename, aSize)
if (self)
{
_size = CPSizeCreateCopy(aSize);
_size = CGSizeCreateCopy(aSize);
_filename = aFilename;
_loadStatus = CPImageLoadStatusInitialized;
}
@@ -157,6 +188,20 @@ function CPAppKitImage(aFilename, aSize)
return self;
}
/*!
Initializes the receiver with the specified data. The method loads the data into memory.
@param someData the CPData object representing the image
@return the initialized image
*/
- (id)initWithData:(CPData)someData
{
var base64 = [someData base64],
type = [base64 hasPrefix:@"/9j/4AAQSkZJRgABAQEASABIAAD/"] ? @"jpg" : @"png",
dataURL = "data:image/" + type + ";base64," + base64;
return [self initWithContentsOfFile:dataURL];
}
/*!
Returns the path of the file associated with this image.
*/
@@ -165,6 +210,37 @@ function CPAppKitImage(aFilename, aSize)
return _filename;
}
/*!
Returns the data associated with this image.
@discussion Returns nil if the reciever was not initialized with -initWithData: and the browser does not support the canvas feature;
*/
- (CPData)data
{
#if PLATFORM(DOM)
var dataURL;
if ([_filename hasPrefix:@"data:image"])
dataURL = _filename;
else if (CPFeatureIsCompatible(CPHTMLCanvasFeature))
{
var canvas = document.createElement("canvas"),
ctx = canvas.getContext("2d");
canvas.width = _image.width,
canvas.height = _image.height;
ctx.drawImage(_image, 0, 0);
dataURL = canvas.toDataURL("image/png");
}
else
return nil;
var base64 = dataURL.replace(/^data:image\/png;base64,/, "");
return [CPData dataWithBase64:base64];
#endif
}
/*!
Sets the size of the image.
@param the size of the image
@@ -280,7 +356,7 @@ function CPAppKitImage(aFilename, aSize)
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
}
[self _derefFromImage];
}
};
_image.onerror = function ()
{
@@ -292,7 +368,7 @@ function CPAppKitImage(aFilename, aSize)
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
}
[self _derefFromImage];
}
};
_image.onabort = function ()
{
@@ -304,7 +380,7 @@ function CPAppKitImage(aFilename, aSize)
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
}
[self _derefFromImage];
}
};
_image.src = _filename;
@@ -324,6 +400,24 @@ function CPAppKitImage(aFilename, aSize)
return NO;
}
- (CPString)description
{
var filename = [self filename],
size = [self size];
if (filename.indexOf("data:") === 0)
{
var index = filename.indexOf(",");
if (index > 0)
filename = [CPString stringWithFormat:@"%s,%s...%s", filename.substr(0, index), filename.substr(index + 1, 10), filename.substr(filename.length - 10)];
else
filename = "data:<unknown type>";
}
return [CPString stringWithFormat:ImageDescriptionFormat, [super description], filename, size.width, size.height];
}
/* @ignore */
- (void)_derefFromImage
{
+82 -50
View File
@@ -26,10 +26,8 @@
@import "CPImage.j"
@import "CPShadowView.j"
CPScaleProportionally = 0;
CPScaleToFit = 1;
CPScaleNone = 2;
@global CPImagesPboardType
@global appkit_tag_dom_elements
CPImageAlignCenter = 0;
CPImageAlignTop = 1;
@@ -41,15 +39,7 @@ CPImageAlignBottomLeft = 6;
CPImageAlignBottomRight = 7;
CPImageAlignRight = 8;
var CPImageViewShadowBackgroundColor = nil,
CPImageViewEmptyPlaceholderImage = nil;
var LEFT_SHADOW_INSET = 3.0,
RIGHT_SHADOW_INSET = 3.0,
TOP_SHADOW_INSET = 3.0,
BOTTOM_SHADOW_INSET = 5.0,
VERTICAL_SHADOW_INSET = TOP_SHADOW_INSET + BOTTOM_SHADOW_INSET,
HORIZONTAL_SHADOW_INSET = LEFT_SHADOW_INSET + RIGHT_SHADOW_INSET;
var CPImageViewEmptyPlaceholderImage = nil;
/*!
@ingroup appkit
@@ -72,11 +62,22 @@ var LEFT_SHADOW_INSET = 3.0,
+ (void)initialize
{
if (self !== [CPImageView class])
return;
var bundle = [CPBundle bundleForClass:[CPView class]];
CPImageViewEmptyPlaceholderImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"empty.png"]];
}
+ (Class)_binderClassForBinding:(CPString)theBinding
{
if (theBinding === CPValueBinding || theBinding === CPValueURLBinding || theBinding === CPValuePathBinding || theBinding === CPDataBinding)
return [CPImageViewValueBinder class];
return [super _binderClassForBinding:theBinding];
}
- (id)initWithFrame:(CGRect)aFrame
{
self = [super initWithFrame:aFrame];
@@ -240,7 +241,7 @@ var LEFT_SHADOW_INSET = 3.0,
[super setImageScaling:anImageScaling];
#if PLATFORM(DOM)
if ([self currentValueForThemeAttribute:@"image-scaling"] === CPScaleToFit)
if ([self currentValueForThemeAttribute:@"image-scaling"] === CPImageScaleAxesIndependently)
{
CPDOMDisplayServerSetStyleLeftTop(_DOMImageElement, NULL, 0.0, 0.0);
}
@@ -297,19 +298,19 @@ var LEFT_SHADOW_INSET = 3.0,
imageScaling = [self currentValueForThemeAttribute:@"image-scaling"],
x = 0.0,
y = 0.0,
insetWidth = (_hasShadow ? HORIZONTAL_SHADOW_INSET : 0.0),
insetHeight = (_hasShadow ? VERTICAL_SHADOW_INSET : 0.0),
insetWidth = (_hasShadow ? [_shadowView horizontalInset] : 0.0),
insetHeight = (_hasShadow ? [_shadowView verticalInset] : 0.0),
boundsWidth = _CGRectGetWidth(bounds),
boundsHeight = _CGRectGetHeight(bounds),
width = boundsWidth - insetWidth,
height = boundsHeight - insetHeight;
if (imageScaling === CPScaleToFit)
if (imageScaling === CPImageScaleAxesIndependently)
{
#if PLATFORM(DOM)
_DOMImageElement.width = ROUND(width);
_DOMImageElement.height = ROUND(height);
#endif
#if PLATFORM(DOM)
_DOMImageElement.width = ROUND(width);
_DOMImageElement.height = ROUND(height);
#endif
}
else
{
@@ -318,17 +319,19 @@ var LEFT_SHADOW_INSET = 3.0,
if (size.width == -1 && size.height == -1)
return;
if (imageScaling === CPScaleProportionally)
switch (imageScaling)
{
// The max size it can be is size.width x size.height, so only
// only proportion otherwise.
if (width >= size.width && height >= size.height)
{
width = size.width;
height = size.height;
}
else
{
case CPImageScaleProportionallyDown:
if (width >= size.width && height >= size.height)
{
width = size.width;
height = size.height;
break;
}
// intentionally fall through to the next case
case CPImageScaleProportionallyUpOrDown:
var imageRatio = size.width / size.height,
viewRatio = width / height;
@@ -336,26 +339,19 @@ var LEFT_SHADOW_INSET = 3.0,
width = height * imageRatio;
else
height = width / imageRatio;
}
break;
#if PLATFORM(DOM)
case CPImageScaleAxesIndependently:
case CPImageScaleNone:
width = size.width;
height = size.height;
break;
}
#if PLATFORM(DOM)
_DOMImageElement.width = ROUND(width);
_DOMImageElement.height = ROUND(height);
#endif
}
else
{
width = size.width;
height = size.height;
}
if (imageScaling == CPScaleNone)
{
#if PLATFORM(DOM)
_DOMImageElement.width = ROUND(size.width);
_DOMImageElement.height = ROUND(size.height);
#endif
}
#endif
var x,
y;
@@ -406,7 +402,7 @@ var LEFT_SHADOW_INSET = 3.0,
_imageRect = _CGRectMake(x, y, width, height);
if (_hasShadow)
[_shadowView setFrame:_CGRectMake(x - LEFT_SHADOW_INSET, y - TOP_SHADOW_INSET, width + insetWidth, height + insetHeight)];
[_shadowView setFrame:_CGRectMake(x - [_shadowView leftInset], y - [_shadowView topInset], width + insetWidth, height + insetHeight)];
}
- (void)mouseDown:(CPEvent)anEvent
@@ -457,6 +453,39 @@ var LEFT_SHADOW_INSET = 3.0,
@end
@implementation CPImageViewValueBinder : CPBinder
{
}
- (void)_updatePlaceholdersWithOptions:(CPDictionary)options
{
[self _setPlaceholder:nil forMarker:CPMultipleValuesMarker isDefault:YES];
[self _setPlaceholder:nil forMarker:CPNoSelectionMarker isDefault:YES];
[self _setPlaceholder:nil forMarker:CPNotApplicableMarker isDefault:YES];
[self _setPlaceholder:nil forMarker:CPNullMarker isDefault:YES];
}
- (void)setPlaceholderValue:(id)aValue withMarker:(CPString)aMarker forBinding:(CPString)aBinding
{
[_source setImage:nil];
}
- (void)setValue:(id)aValue forBinding:(CPString)aBinding
{
var image;
if (aBinding === CPDataBinding)
image = [[CPImage alloc] initWithData:aValue];
else if (aBinding === CPValueURLBinding || aBinding === CPValuePathBinding)
image = [[CPImage alloc] initWithContentsOfFile:aValue];
else if (aBinding === CPValueBinding)
image = aValue;
[_source setImage:image];
}
@end
var CPImageViewImageKey = @"CPImageViewImageKey",
CPImageViewImageScalingKey = @"CPImageViewImageScalingKey",
CPImageViewImageAlignmentKey = @"CPImageViewImageAlignmentKey",
@@ -483,6 +512,9 @@ var CPImageViewImageKey = @"CPImageViewImageKey",
_DOMImageElement.setAttribute("draggable", "true");
_DOMImageElement.style["-khtml-user-drag"] = "element";
}
if (typeof(appkit_tag_dom_elements) !== "undefined" && !!appkit_tag_dom_elements)
_DOMImageElement.setAttribute("data-cappuccino-view", [self className]);
#endif
self = [super initWithCoder:aCoder];
@@ -496,7 +528,7 @@ var CPImageViewImageKey = @"CPImageViewImageKey",
[self setHasShadow:[aCoder decodeBoolForKey:CPImageViewHasShadowKey]];
[self setImageAlignment:[aCoder decodeIntForKey:CPImageViewImageAlignmentKey]];
if ([aCoder decodeBoolForKey:CPImageViewIsEditableKey] || NO)
if ([aCoder decodeBoolForKey:CPImageViewIsEditableKey])
[self setEditable:YES];
[self setNeedsLayout];
+5 -3
View File
@@ -21,13 +21,15 @@
*/
@import <Foundation/CPObject.j>
@import <Foundation/CPArray.j>
@import "CPEvent.j"
@import "CPEvent_Constants.j"
@import "CPText.j"
CPStandardKeyBindings = {
@"@.": @"cancelOperation:",
@"@a": @"selectAll:",
@"^a": @"moveToBeginningOfParagraph:",
@"^$a": @"moveToBeginningOfParagraphAndModifySelection:",
@"^b": @"moveBackward:",
@@ -152,7 +154,7 @@ var CPKeyBindingCache = {};
+ (void)initialize
{
if ([self class] !== CPKeyBinding)
if (self !== [CPKeyBinding class])
return;
[self createKeyBindingsFromJSObject:CPStandardKeyBindings];
+127 -23
View File
@@ -27,6 +27,7 @@
@import <Foundation/CPArray.j>
@import <Foundation/CPDictionary.j>
@import <Foundation/CPValueTransformer.j>
@import <Foundation/CPKeyValueObserving.j>
var exposedBindingsMap = [CPDictionary new],
@@ -41,6 +42,7 @@ var CPBindingOperationAnd = 0,
id _source;
JSObject _suppressedNotifications;
JSObject _placeholderForMarker;
}
+ (void)exposeBinding:(CPString)aBinding forClass:(Class)aClass
@@ -125,10 +127,13 @@ var CPBindingOperationAnd = 0,
_source = aSource;
_info = [CPDictionary dictionaryWithObjects:[aDestination, aKeyPath] forKeys:[CPObservedObjectKey, CPObservedKeyPathKey]];
_suppressedNotifications = {};
_placeholderForMarker = {};
if (options)
[_info setObject:options forKey:CPOptionsKey];
[self _updatePlaceholdersWithOptions:options forBinding:aName];
[aDestination addObserver:self forKeyPath:aKeyPath options:CPKeyValueObservingOptionNew context:aBinding];
var bindings = [bindingsMap objectForKey:[_source UID]];
@@ -145,15 +150,40 @@ var CPBindingOperationAnd = 0,
return self;
}
- (void)setValueFor:(CPString)aBinding
- (void)setValueFor:(CPString)theBinding
{
var destination = [_info objectForKey:CPObservedObjectKey],
keyPath = [_info objectForKey:CPObservedKeyPathKey],
options = [_info objectForKey:CPOptionsKey],
newValue = [destination valueForKeyPath:keyPath];
newValue = [destination valueForKeyPath:keyPath],
isPlaceholder = CPIsControllerMarker(newValue);
newValue = [self transformValue:newValue withOptions:options];
[_source setValue:newValue forKey:aBinding];
if (isPlaceholder)
{
if (newValue === CPNotApplicableMarker && [options objectForKey:CPRaisesForNotApplicableKeysBindingOption])
{
[CPException raise:CPGenericException
reason:@"Cannot transform non-applicable key on: " + _source + " key path: " + keyPath + " value: " + newValue];
}
var value = [self _placeholderForMarker:newValue];
[self setPlaceholderValue:value withMarker:newValue forBinding:theBinding];
}
else
{
var value = [self transformValue:newValue withOptions:options];
[self setValue:value forBinding:theBinding];
}
}
- (void)setPlaceholderValue:(id)aValue withMarker:(CPString)aMarker forBinding:(CPString)aBinding
{
[_source setValue:aValue forKey:aBinding];
}
- (void)setValue:(id)aValue forBinding:(CPString)aBinding
{
[_source setValue:aValue forKey:aBinding];
}
- (void)reverseSetValueFor:(CPString)aBinding
@@ -161,10 +191,18 @@ var CPBindingOperationAnd = 0,
var destination = [_info objectForKey:CPObservedObjectKey],
keyPath = [_info objectForKey:CPObservedKeyPathKey],
options = [_info objectForKey:CPOptionsKey],
newValue = [_source valueForKeyPath:aBinding];
newValue = [self valueForBinding:aBinding];
newValue = [self reverseTransformValue:newValue withOptions:options];
[self suppressSpecificNotificationFromObject:destination keyPath:keyPath];
[destination setValue:newValue forKeyPath:keyPath];
[self unsuppressSpecificNotificationFromObject:destination keyPath:keyPath];
}
- (id)valueForBinding:(CPString)aBinding
{
return [_source valueForKeyPath:aBinding];
}
- (void)observeValueForKeyPath:(CPString)aKeyPath ofObject:(id)anObject change:(CPDictionary)changes context:(id)context
@@ -204,14 +242,13 @@ var CPBindingOperationAnd = 0,
if (valueTransformer)
aValue = [valueTransformer transformedValue:aValue];
if (aValue === undefined || aValue === nil || aValue === [CPNull null])
aValue = [options objectForKey:CPNullPlaceholderBindingOption] || nil;
return aValue;
}
- (id)reverseTransformValue:(id)aValue withOptions: (CPDictionary)options
- (id)reverseTransformValue:(id)aValue withOptions:(CPDictionary)options
{
var valueTransformerName = [options objectForKey:CPValueTransformerNameBindingOption],
valueTransformer;
@@ -271,6 +308,47 @@ var CPBindingOperationAnd = 0,
delete objectSuppressions[aKeyPath];
}
- (void)_updatePlaceholdersWithOptions:(CPDictionary)options
{
var count = [CPBinderPlaceholderMarkers count];
while (count--)
{
var marker = CPBinderPlaceholderMarkers[count],
optionName = CPBinderPlaceholderOptions[count],
isExplicit = [options containsKey:optionName],
placeholder = isExplicit ? [options objectForKey:optionName] : nil;
[self _setPlaceholder:placeholder forMarker:marker isDefault:!isExplicit];
}
}
- (void)_updatePlaceholdersWithOptions:(CPDictionary)options forBinding:(CPString)aBinding
{
[self _updatePlaceholdersWithOptions:options];
}
- (void)_placeholderForMarker:aMarker
{
var placeholder = _placeholderForMarker[aMarker];
if (placeholder)
return placeholder['value'];
return nil;
}
- (void)_setPlaceholder:(id)aPlaceholder forMarker:(id)aMarker isDefault:(BOOL)isDefault
{
if (isDefault)
{
var existingPlaceholder = _placeholderForMarker[aMarker];
// Don't overwrite an explicitly set placeholder with a default.
if (existingPlaceholder && !existingPlaceholder['isDefault'])
return;
}
_placeholderForMarker[aMarker] = { 'isDefault': isDefault, 'value': aPlaceholder };
}
@end
@implementation CPObject (KeyValueBindingCreation)
@@ -311,10 +389,10 @@ var CPBindingOperationAnd = 0,
- (void)bind:(CPString)aBinding toObject:(id)anObject withKeyPath:(CPString)aKeyPath options:(CPDictionary)options
{
if (!anObject || !aKeyPath)
return CPLog.error("Invalid object or path on "+self+" for "+aBinding);
return CPLog.error("Invalid object or path on " + self + " for " + aBinding);
//if (![[self exposedBindings] containsObject:aBinding])
// CPLog.warn("No binding exposed on "+self+" for "+aBinding);
// CPLog.warn("No binding exposed on " + self + " for " + aBinding);
var binderClass = [[self class] _binderClassForBinding:aBinding];
@@ -404,7 +482,7 @@ var CPBindingOperationAnd = 0,
@end
var resolveMultipleValues = function resolveMultipleValues(/*CPString*/key, /*CPDictionary*/bindings, /*GSBindingOperationKind*/operation)
var resolveMultipleValues = function(/*CPString*/key, /*CPDictionary*/bindings, /*GSBindingOperationKind*/operation)
{
var bindingName = key,
theBinding,
@@ -426,9 +504,9 @@ var resolveMultipleValues = function resolveMultipleValues(/*CPString*/key, /*CP
}
return !operation;
}
};
var invokeAction = function invokeAction(/*CPString*/targetKey, /*CPString*/argumentKey, /*CPDictionary*/bindings)
var invokeAction = function(/*CPString*/targetKey, /*CPString*/argumentKey, /*CPDictionary*/bindings)
{
var theBinding = [bindings objectForKey:targetKey],
infoDictionary = theBinding._info,
@@ -463,7 +541,7 @@ var invokeAction = function invokeAction(/*CPString*/targetKey, /*CPString*/argu
}
[invocation invoke];
}
};
// Keys in options dictionary
@@ -479,15 +557,37 @@ CPNotApplicableMarker = @"CPNotApplicableMarker";
CPNullMarker = @"CPNullMarker";
// Binding name constants
CPAlignmentBinding = @"alignment";
CPEditableBinding = @"editable";
CPEnabledBinding = @"enabled";
CPFontBinding = @"font";
CPHiddenBinding = @"hidden";
CPSelectedIndexBinding = @"selectedIndex";
CPTextColorBinding = @"textColor";
CPToolTipBinding = @"toolTip";
CPValueBinding = @"value";
CPAlignmentBinding = @"alignment";
CPContentArrayBinding = @"contentArray";
CPContentBinding = @"content";
CPContentObjectBinding = @"contentObject";
CPContentObjectsBinding = @"contentObjects";
CPContentValuesBinding = @"contentValues";
CPEditableBinding = @"editable";
CPEnabledBinding = @"enabled";
CPFontBinding = @"font";
CPFontNameBinding = @"fontName";
CPFontBoldBinding = @"fontBold";
CPHiddenBinding = @"hidden";
CPFilterPredicateBinding = @"filterPredicate";
CPMaxValueBinding = @"maxValue";
CPMinValueBinding = @"minValue";
CPPredicateBinding = @"predicate";
CPSelectedIndexBinding = @"selectedIndex";
CPSelectedLabelBinding = @"selectedLabel";
CPSelectedObjectBinding = @"selectedObject";
CPSelectedObjectsBinding = @"selectedObjects";
CPSelectedTagBinding = @"selectedTag";
CPSelectedValueBinding = @"selectedValue";
CPSelectedValuesBinding = @"selectedValues";
CPSelectionIndexesBinding = @"selectionIndexes";
CPTextColorBinding = @"textColor";
CPTitleBinding = @"title";
CPToolTipBinding = @"toolTip";
CPValueBinding = @"value";
CPValueURLBinding = @"valueURL";
CPValuePathBinding = @"valuePath";
CPDataBinding = @"data";
//Binding options constants
CPAllowsEditingMultipleValuesSelectionBindingOption = @"CPAllowsEditingMultipleValuesSelection";
@@ -518,4 +618,8 @@ CPValueTransformerBindingOption = @"CPValueTransformer";
CPIsControllerMarker = function(/*id*/anObject)
{
return anObject === CPMultipleValuesMarker || anObject === CPNoSelectionMarker || anObject === CPNotApplicableMarker || anObject === CPNullMarker;
}
};
var CPBinderPlaceholderMarkers = [CPMultipleValuesMarker, CPNoSelectionMarker, CPNotApplicableMarker, CPNullMarker],
CPBinderPlaceholderOptions = [CPMultipleValuesPlaceholderBindingOption, CPNoSelectionPlaceholderBindingOption, CPNotApplicablePlaceholderBindingOption, CPNullPlaceholderBindingOption];
+27 -64
View File
@@ -21,6 +21,9 @@
*/
@import "CPControl.j"
@import "CPWindow_Constants.j"
@global CPApp
CPTickMarkBelow = 0;
CPTickMarkAbove = 1;
@@ -32,14 +35,6 @@ CPContinuousCapacityLevelIndicatorStyle = 1;
CPDiscreteCapacityLevelIndicatorStyle = 2;
CPRatingLevelIndicatorStyle = 3;
var _CPLevelIndicatorBezelColor = nil,
_CPLevelIndicatorSegmentEmptyColor = nil,
_CPLevelIndicatorSegmentNormalColor = nil,
_CPLevelIndicatorSegmentWarningColor = nil,
_CPLevelIndicatorSegmentCriticalColor = nil,
_CPLevelIndicatorSpacing = 1;
/*!
@ingroup appkit
@class CPLevelIndicator
@@ -62,56 +57,23 @@ var _CPLevelIndicatorBezelColor = nil,
BOOL _isTracking;
}
+ (void)initialize
+ (CPString)defaultThemeClass
{
var bundle = [CPBundle bundleForClass:CPLevelIndicator];
_CPLevelIndicatorBezelColor = [CPColor colorWithPatternImage:[[CPThreePartImage alloc] initWithImageSlices:
[
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPLevelIndicator/level-indicator-bezel-left.png"] size:CGSizeMake(3.0, 18.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPLevelIndicator/level-indicator-bezel-center.png"] size:CGSizeMake(1.0, 18.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPLevelIndicator/level-indicator-bezel-right.png"] size:CGSizeMake(3.0, 18.0)]
]
isVertical:NO
]];
_CPLevelIndicatorSegmentEmptyColor = [CPColor colorWithPatternImage:[[CPThreePartImage alloc] initWithImageSlices:
[
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPLevelIndicator/level-indicator-segment-empty-left.png"] size:CGSizeMake(3.0, 17.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPLevelIndicator/level-indicator-segment-empty-center.png"] size:CGSizeMake(1.0, 17.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPLevelIndicator/level-indicator-segment-empty-right.png"] size:CGSizeMake(3.0, 17.0)]
]
isVertical:NO
]];
_CPLevelIndicatorSegmentNormalColor = [CPColor colorWithPatternImage:[[CPThreePartImage alloc] initWithImageSlices:
[
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPLevelIndicator/level-indicator-segment-normal-left.png"] size:CGSizeMake(3.0, 17.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPLevelIndicator/level-indicator-segment-normal-center.png"] size:CGSizeMake(1.0, 17.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPLevelIndicator/level-indicator-segment-normal-right.png"] size:CGSizeMake(3.0, 17.0)]
]
isVertical:NO
]];
_CPLevelIndicatorSegmentWarningColor = [CPColor colorWithPatternImage:[[CPThreePartImage alloc] initWithImageSlices:
[
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPLevelIndicator/level-indicator-segment-warning-left.png"] size:CGSizeMake(3.0, 17.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPLevelIndicator/level-indicator-segment-warning-center.png"] size:CGSizeMake(1.0, 17.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPLevelIndicator/level-indicator-segment-warning-right.png"] size:CGSizeMake(3.0, 17.0)]
]
isVertical:NO
]];
_CPLevelIndicatorSegmentCriticalColor = [CPColor colorWithPatternImage:[[CPThreePartImage alloc] initWithImageSlices:
[
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPLevelIndicator/level-indicator-segment-critical-left.png"] size:CGSizeMake(3.0, 17.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPLevelIndicator/level-indicator-segment-critical-center.png"] size:CGSizeMake(1.0, 17.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPLevelIndicator/level-indicator-segment-critical-right.png"] size:CGSizeMake(3.0, 17.0)]
]
isVertical:NO
]];
return "level-indicator";
}
+ (id)themeAttributes
{
return [CPDictionary dictionaryWithObjectsAndKeys:[CPNull null], @"bezel-color",
[CPNull null], @"color-empty",
[CPNull null], @"color-normal",
[CPNull null], @"color-warning",
[CPNull null], @"color-critical",
1.0, @"spacing"];
}
- (id)initWithFrame:(CGRect)aFrame
{
self = [super initWithFrame:aFrame];
@@ -139,20 +101,20 @@ var _CPLevelIndicatorBezelColor = nil,
positioned:CPWindowBelow
relativeToEphemeralSubviewNamed:nil];
// TODO Make themable.
[bezelView setBackgroundColor:_CPLevelIndicatorBezelColor];
[bezelView setBackgroundColor:[self valueForThemeAttribute:@"bezel-color"]];
var segmentCount = _maxValue - _minValue;
if (segmentCount <= 0)
return;
var filledColor = _CPLevelIndicatorSegmentNormalColor,
var filledColor = [self valueForThemeAttribute:@"color-normal"],
value = [self doubleValue];
if (value <= _criticalValue)
filledColor = _CPLevelIndicatorSegmentCriticalColor;
filledColor = [self valueForThemeAttribute:@"color-critical"];
else if (value <= _warningValue)
filledColor = _CPLevelIndicatorSegmentWarningColor;
filledColor = [self valueForThemeAttribute:@"color-warning"];
for (var i = 0; i < segmentCount; i++)
{
@@ -160,7 +122,7 @@ var _CPLevelIndicatorBezelColor = nil,
positioned:CPWindowAbove
relativeToEphemeralSubviewNamed:bezelView];
[segmentView setBackgroundColor:(_minValue + i) < value ? filledColor : _CPLevelIndicatorSegmentEmptyColor];
[segmentView setBackgroundColor:(_minValue + i) < value ? filledColor : [self valueForThemeAttribute:@"color-empty"]];
}
}
@@ -191,11 +153,12 @@ var _CPLevelIndicatorBezelColor = nil,
return _CGRectMakeZero();
var basicSegmentWidth = bounds.size.width / segmentCount,
segmentFrame = CGRectCreateCopy([self bounds]);
segmentFrame = CGRectCreateCopy([self bounds]),
spacing = [self valueForThemeAttribute:@"spacing"];
segmentFrame.origin.y = (_CGRectGetHeight(bounds) - bezelHeight) / 2.0;
segmentFrame.origin.x = FLOOR(segment * basicSegmentWidth);
segmentFrame.size.width = (segment == segmentCount - 1) ? bounds.size.width - segmentFrame.origin.x : FLOOR(((segment + 1) * basicSegmentWidth)) - FLOOR((segment * basicSegmentWidth)) - _CPLevelIndicatorSpacing;
segmentFrame.size.width = (segment == segmentCount - 1) ? bounds.size.width - segmentFrame.origin.x : FLOOR(((segment + 1) * basicSegmentWidth)) - FLOOR((segment * basicSegmentWidth)) - spacing;
segmentFrame.size.height = segmentHeight;
return segmentFrame;
@@ -223,7 +186,7 @@ var _CPLevelIndicatorBezelColor = nil,
return _isEditable;
}
- (CPView)hitTest:(CPPoint)aPoint
- (CPView)hitTest:(CGPoint)aPoint
{
// Don't swallow clicks when displayed in a table.
if (![self isEditable])
@@ -253,7 +216,7 @@ var _CPLevelIndicatorBezelColor = nil,
var location = [self convertPoint:[anEvent locationInWindow] fromView:nil],
bounds = [self bounds],
oldValue = [self doubleValue];
oldValue = [self doubleValue],
newValue = oldValue;
// Moving the mouse outside of the widget to the left sets it
+20 -24
View File
@@ -25,12 +25,9 @@
@import <Foundation/CPNotificationCenter.j>
@import <Foundation/CPString.j>
@import "_CPMenuManager.j"
@import "CPApplication.j"
@import "CPClipView.j"
@import "CPMenuItem.j"
@import "CPPanel.j"
@global CPApp
CPMenuDidAddItemNotification = @"CPMenuDidAddItemNotification";
CPMenuDidChangeItemNotification = @"CPMenuDidChangeItemNotification";
@@ -38,12 +35,8 @@ CPMenuDidRemoveItemNotification = @"CPMenuDidRemoveItemNotification";
CPMenuDidEndTrackingNotification = @"CPMenuDidEndTrackingNotification";
var MENUBAR_HEIGHT = 28.0;
var _CPMenuBarVisible = NO,
_CPMenuBarTitle = @"",
_CPMenuBarIconImage = nil,
_CPMenuBarIconImageAlphaValue = 1.0,
_CPMenuBarAttributes = nil,
_CPMenuBarSharedWindow = nil;
@@ -80,7 +73,7 @@ var _CPMenuBarVisible = NO,
+ (void)initialize
{
if (self !== CPMenu)
if (self !== [CPMenu class])
return;
[[self class] setMenuBarAttributes:[CPDictionary dictionary]];
@@ -109,8 +102,8 @@ var _CPMenuBarVisible = NO,
[_CPMenuBarSharedWindow setMenu:[CPApp mainMenu]];
[_CPMenuBarSharedWindow setTitle:_CPMenuBarTitle];
[_CPMenuBarSharedWindow setIconImage:_CPMenuBarIconImage];
[_CPMenuBarSharedWindow setIconImageAlphaValue:_CPMenuBarIconImageAlphaValue];
[_CPMenuBarSharedWindow setIconImage:[[CPTheme defaultTheme] valueForAttributeWithName:@"menu-bar-icon-image" forClass:_CPMenuView]];
[_CPMenuBarSharedWindow setIconImageAlphaValue:[[CPTheme defaultTheme] valueForAttributeWithName:@"menu-bar-icon-image-alpha-value" forClass:_CPMenuView]];
[_CPMenuBarSharedWindow setColor:[_CPMenuBarAttributes objectForKey:@"CPMenuBarBackgroundColor"]];
[_CPMenuBarSharedWindow setTextColor:[_CPMenuBarAttributes objectForKey:@"CPMenuBarTextColor"]];
@@ -178,8 +171,8 @@ var _CPMenuBarVisible = NO,
else if (!textColor && !titleColor)
{
[_CPMenuBarAttributes setObject:[CPColor colorWithRed:0.051 green:0.2 blue:0.275 alpha:1.0] forKey:@"CPMenuBarTextColor"];
[_CPMenuBarAttributes setObject:[CPColor colorWithRed:0.051 green:0.2 blue:0.275 alpha:1.0] forKey:@"CPMenuBarTitleColor"];
[_CPMenuBarAttributes setObject:[[CPTheme defaultTheme] valueForAttributeWithName:@"menu-bar-text-color" forClass:_CPMenuView] forKey:@"CPMenuBarTextColor"];
[_CPMenuBarAttributes setObject:[[CPTheme defaultTheme] valueForAttributeWithName:@"menu-bar-title-color" forClass:_CPMenuView] forKey:@"CPMenuBarTitleColor"];
}
if (!textShadowColor && titleShadowColor)
@@ -190,18 +183,18 @@ var _CPMenuBarVisible = NO,
else if (!textShadowColor && !titleShadowColor)
{
[_CPMenuBarAttributes setObject:[CPColor whiteColor] forKey:@"CPMenuBarTextShadowColor"];
[_CPMenuBarAttributes setObject:[CPColor whiteColor] forKey:@"CPMenuBarTitleShadowColor"];
[_CPMenuBarAttributes setObject:[[CPTheme defaultTheme] valueForAttributeWithName:@"menu-bar-text-shadow-color" forClass:_CPMenuView] forKey:@"CPMenuBarTextShadowColor"];
[_CPMenuBarAttributes setObject:[[CPTheme defaultTheme] valueForAttributeWithName:@"menu-bar-title-shadow-color" forClass:_CPMenuView] forKey:@"CPMenuBarTitleShadowColor"];
}
if (!highlightColor)
[_CPMenuBarAttributes setObject:[CPColor colorWithCalibratedRed:94.0 / 255.0 green:130.0 / 255.0 blue:186.0 / 255.0 alpha:1.0] forKey:@"CPMenuBarHighlightColor"];
[_CPMenuBarAttributes setObject:[[CPTheme defaultTheme] valueForAttributeWithName:@"menu-bar-highlight-color" forClass:_CPMenuView] forKey:@"CPMenuBarHighlightColor"];
if (!highlightTextColor)
[_CPMenuBarAttributes setObject:[CPColor whiteColor] forKey:@"CPMenuBarHighlightTextColor"];
[_CPMenuBarAttributes setObject:[[CPTheme defaultTheme] valueForAttributeWithName:@"menu-bar-highlight-text-color" forClass:_CPMenuView] forKey:@"CPMenuBarHighlightTextColor"];
if (!highlightTextShadowColor)
[_CPMenuBarAttributes setObject:[CPColor blackColor] forKey:@"CPMenuBarHighlightTextShadowColor"];
[_CPMenuBarAttributes setObject:[[CPTheme defaultTheme] valueForAttributeWithName:@"menu-bar-highlight-text-shadow-color" forClass:_CPMenuView] forKey:@"CPMenuBarHighlightTextShadowColor"];
if (_CPMenuBarSharedWindow)
{
@@ -230,14 +223,14 @@ var _CPMenuBarVisible = NO,
- (float)menuBarHeight
{
if (self === [CPApp mainMenu])
return MENUBAR_HEIGHT;
return [[CPTheme defaultTheme] valueForAttributeWithName:@"menu-bar-height" forClass:_CPMenuView];
return 0.0;
}
+ (float)menuBarHeight
{
return MENUBAR_HEIGHT;
return [[CPTheme defaultTheme] valueForAttributeWithName:@"menu-bar-height" forClass:_CPMenuView];
}
// Creating a CPMenu Object
@@ -352,8 +345,12 @@ var _CPMenuBarVisible = NO,
while (count--)
[_items[count] setMenu:nil];
_items = [CPMutableArray array];
_highlightedIndex = CPNotFound;
// Because we are changing _items directly, be sure to notify KVO
[self willChangeValueForKey:@"items"];
_items = [CPMutableArray array];
[self didChangeValueForKey:@"items"];
}
/*!
@@ -802,7 +799,7 @@ var _CPMenuBarVisible = NO,
[aMenu _menuWillOpen];
if (!aFont)
aFont = [CPFont systemFontOfSize:12.0];
aFont = [CPFont systemFontOfSize:[CPFont systemFontSize]];
var theWindow = [aView window],
menuWindow = [_CPMenuWindow menuWindowWithMenu:aMenu font:aFont];
@@ -972,8 +969,7 @@ var _CPMenuBarVisible = NO,
for (; index < count; ++index)
{
var item = _items[index],
modifierMask = [item keyEquivalentModifierMask];
var item = _items[index];
if ([anEvent _triggersKeyEquivalent:[item keyEquivalent] withModifierMask:[item keyEquivalentModifierMask]])
{
+42 -132
View File
@@ -1,14 +1,33 @@
/*
* _CPMenuBarWindow.j
* AppKit
*
* Created by Francisco Tolmasky.
* Copyright 2009, 280 North, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "CPPanel.j"
@import "_CPMenuWindow.j"
@import "_CPMenuManager.j"
@class _CPMenuView
var MENUBAR_HEIGHT = 28.0,
MENUBAR_MARGIN = 10.0,
MENUBAR_LEFT_MARGIN = 10.0,
MENUBAR_RIGHT_MARGIN = 10.0;
var _CPMenuBarWindowBackgroundColor = nil,
_CPMenuBarWindowFont = nil;
@global CPMenuDidAddItemNotification
@global CPMenuDidChangeItemNotification
@global CPMenuDidRemoveItemNotification
@implementation _CPMenuBarWindow : CPPanel
{
@@ -32,19 +51,9 @@ var _CPMenuBarWindowBackgroundColor = nil,
CPColor _highlightTextShadowColor;
}
+ (void)initialize
{
if (self != [_CPMenuBarWindow class])
return;
var bundle = [CPBundle bundleForClass:self];
_CPMenuBarWindowFont = [CPFont boldSystemFontOfSize:12.0];
}
+ (CPFont)font
{
return _CPMenuBarWindowFont;
return [[CPTheme defaultTheme] valueForAttributeWithName:@"menu-bar-window-font" forClass:_CPMenuView];
}
- (id)init
@@ -52,7 +61,7 @@ var _CPMenuBarWindowBackgroundColor = nil,
// This only shows up in browser land, so don't bother calculating metrics in desktop.
var contentRect = [[CPPlatformWindow primaryPlatformWindow] contentBounds];
contentRect.size.height = MENUBAR_HEIGHT;
contentRect.size.height = [[CPTheme defaultTheme] valueForAttributeWithName:@"menu-bar-window-height" forClass:_CPMenuView];
self = [super initWithContentRect:contentRect styleMask:CPBorderlessWindowMask];
@@ -74,7 +83,7 @@ var _CPMenuBarWindowBackgroundColor = nil,
_titleField = [[CPTextField alloc] initWithFrame:CGRectMakeZero()];
[_titleField setFont:[CPFont boldSystemFontOfSize:13.0]];
[_titleField setFont:[CPFont boldSystemFontOfSize:[CPFont systemFontSize] + 1]];
[_titleField setAlignment:CPCenterTextAlignment];
[_titleField setTextShadowOffset:CGSizeMake(0, 1)];
@@ -119,12 +128,7 @@ var _CPMenuBarWindowBackgroundColor = nil,
- (void)setColor:(CPColor)aColor
{
if (!aColor)
{
if (!_CPMenuBarWindowBackgroundColor)
_CPMenuBarWindowBackgroundColor = [CPColor colorWithPatternImage:[[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:[_CPMenuBarWindow class]] pathForResource:@"_CPMenuBarWindow/_CPMenuBarWindowBackground.png"] size:CGSizeMake(1.0, 28.0)]];
[[self contentView] setBackgroundColor:_CPMenuBarWindowBackgroundColor];
}
[[self contentView] setBackgroundColor:[[CPTheme defaultTheme] valueForAttributeWithName:@"menu-bar-window-background-color" forClass:_CPMenuView]];
else
[[self contentView] setBackgroundColor:aColor];
}
@@ -257,7 +261,7 @@ var _CPMenuBarWindowBackgroundColor = nil,
items = [_menu itemArray],
count = items.length;
for (index = 0; index < count; ++index)
for (var index = 0; index < count; ++index)
{
var item = items[index],
menuItemView = [item _menuItemView];
@@ -316,6 +320,11 @@ var _CPMenuBarWindowBackgroundColor = nil,
[self tile];
}
- (BOOL)acceptsFirstMouse:(CPEvent)anEvent
{
return YES;
}
- (void)mouseDown:(CPEvent)anEvent
{
var constraintRect = CGRectInset([[self platformWindow] visibleFrame], 5.0, 0.0);
@@ -335,7 +344,7 @@ var _CPMenuBarWindowBackgroundColor = nil,
- (CPFont)font
{
[CPFont systemFontOfSize:12.0];
[CPFont systemFontOfSize:[CPFont systemFontSize]];
}
- (void)tile
@@ -344,7 +353,7 @@ var _CPMenuBarWindowBackgroundColor = nil,
index = 0,
count = items.length,
x = MENUBAR_LEFT_MARGIN,
x = [[CPTheme defaultTheme] valueForAttributeWithName:@"menu-bar-window-left-margin" forClass:_CPMenuView],
y = 0.0,
isLeftAligned = YES;
@@ -354,7 +363,7 @@ var _CPMenuBarWindowBackgroundColor = nil,
if ([item isSeparatorItem])
{
x = CGRectGetWidth([self frame]) - MENUBAR_RIGHT_MARGIN;
x = CGRectGetWidth([self frame]) - [[CPTheme defaultTheme] valueForAttributeWithName:@"menu-bar-window-right-margin" forClass:_CPMenuView];
isLeftAligned = NO;
continue;
@@ -368,13 +377,13 @@ var _CPMenuBarWindowBackgroundColor = nil,
if (isLeftAligned)
{
[menuItemView setFrame:CGRectMake(x, 0.0, CGRectGetWidth(frame), MENUBAR_HEIGHT)];
[menuItemView setFrame:CGRectMake(x, 0.0, CGRectGetWidth(frame), [[CPTheme defaultTheme] valueForAttributeWithName:@"menu-bar-window-height" forClass:_CPMenuView])];
x += CGRectGetWidth([menuItemView frame]);
}
else
{
[menuItemView setFrame:CGRectMake(x - CGRectGetWidth(frame), 0.0, CGRectGetWidth(frame), MENUBAR_HEIGHT)];
[menuItemView setFrame:CGRectMake(x - CGRectGetWidth(frame), 0.0, CGRectGetWidth(frame), [[CPTheme defaultTheme] valueForAttributeWithName:@"menu-bar-window-height" forClass:_CPMenuView])];
x = CGRectGetMinX([menuItemView frame]);
}
@@ -452,102 +461,3 @@ var _CPMenuBarWindowBackgroundColor = nil,
}
@end
@implementation _CPMenuBarView : _CPMenuView
{
}
- (CGRect)rectForItemAtIndex:(int)anIndex
{
return [_menuItemViews[anIndex === CPNotFound ? 0 : anIndex] frame];
}
- (int)itemIndexAtPoint:(CGPoint)aPoint
{
var bounds = [self bounds];
if (!CGRectContainsPoint(bounds, aPoint))
return CPNotFound;
var x = aPoint.x,
low = 0,
high = _visibleMenuItemInfos.length - 1;
while (low <= high)
{
var middle = FLOOR(low + (high - low) / 2),
info = _visibleMenuItemInfos[middle],
frame = [info.view frame];
if (x < CGRectGetMinX(frame))
high = middle - 1;
else if (x > CGRectGetMaxX(frame))
low = middle + 1;
else
return info.index;
}
return CPNotFound;
}
- (void)tile
{
var items = [_menu itemArray],
index = 0,
count = items.length,
x = MENUBAR_LEFT_MARGIN,
y = 0.0,
isLeftAligned = YES;
for (; index < count; ++index)
{
var item = items[index];
if ([item isSeparatorItem])
{
x = CGRectGetWidth([self frame]) - MENUBAR_RIGHT_MARGIN;
isLeftAligned = NO;
continue;
}
if ([item isHidden])
continue;
var menuItemView = [item _menuItemView],
frame = [menuItemView frame];
if (isLeftAligned)
{
[menuItemView setFrameOrigin:CGPointMake(x, (MENUBAR_HEIGHT - 1.0 - CGRectGetHeight(frame)) / 2.0)];
x += CGRectGetWidth([menuItemView frame]) + MENUBAR_MARGIN;
}
else
{
[menuItemView setFrameOrigin:CGPointMake(x - CGRectGetWidth(frame), (MENUBAR_HEIGHT - 1.0 - CGRectGetHeight(frame)) / 2.0)];
x = CGRectGetMinX([menuItemView frame]) - MENUBAR_MARGIN;
}
}
var bounds = [[self contentView] bounds],
titleFrame = [_titleField frame];
if ([_iconImageView isHidden])
[_titleField setFrameOrigin:CGPointMake((CGRectGetWidth(bounds) - CGRectGetWidth(titleFrame)) / 2.0, (CGRectGetHeight(bounds) - CGRectGetHeight(titleFrame)) / 2.0)];
else
{
var iconFrame = [_iconImageView frame],
iconWidth = CGRectGetWidth(iconFrame),
totalWidth = iconWidth + CGRectGetWidth(titleFrame);
[_iconImageView setFrameOrigin:CGPointMake((CGRectGetWidth(bounds) - totalWidth) / 2.0, (CGRectGetHeight(bounds) - CGRectGetHeight(iconFrame)) / 2.0)];
[_titleField setFrameOrigin:CGPointMake((CGRectGetWidth(bounds) - totalWidth) / 2.0 + iconWidth, (CGRectGetHeight(bounds) - CGRectGetHeight(titleFrame)) / 2.0)];
}
}
@end
+107 -41
View File
@@ -1,17 +1,51 @@
/*
* _CPMenuManager.j
* AppKit
*
* Created by Francisco Tolmasky.
* Copyright 2009, 280 North, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import <Foundation/CPObject.j>
@import <Foundation/CPNotificationCenter.j>
@import "CPEvent.j"
@import "CPKeyBinding.j"
@class CPWindow
@class _CPMenuWindow
_CPMenuManagerScrollingStateUp = -1,
_CPMenuManagerScrollingStateDown = 1,
@global CPApp
@global CPMenuDidEndTrackingNotification
@global _CPMenuWindowMenuBarBackgroundStyle
@global _CPMenuWindowPopUpBackgroundStyle
_CPMenuManagerScrollingStateUp = -1;
_CPMenuManagerScrollingStateDown = 1;
_CPMenuManagerScrollingStateNone = 0;
var STICKY_TIME_INTERVAL = 500,
var STICKY_TIME_INTERVAL = 0.5,
SharedMenuManager = nil;
@implementation _CPMenuManager: CPObject
{
CPTimeInterval _startTime;
BOOL _hasMouseGoneUpAfterStartedTracking;
BOOL _mouseWasDragged;
int _scrollingState;
CGPoint _lastGlobalLocation;
@@ -26,6 +60,8 @@ var STICKY_TIME_INTERVAL = 500,
CPMenuItem _previousActiveItem;
int _showTimerID;
int _menuBarButtonItemIndex;
}
+ (_CPMenuManager)sharedMenuManager
@@ -66,7 +102,7 @@ var STICKY_TIME_INTERVAL = 500,
CPApp._activeMenu = menu;
_startTime = [anEvent timestamp];//new Date();
_startTime = [anEvent timestamp];
_scrollingState = _CPMenuManagerScrollingStateNone;
_constraintRect = aRect;
@@ -85,13 +121,13 @@ var STICKY_TIME_INTERVAL = 500,
activeItem = activeItemIndex !== CPNotFound ? [menu itemAtIndex:activeItemIndex] : nil;
_menuBarButtonItemIndex = activeItemIndex;
_menuBarButtonMenuContainer = aMenuContainer;
// _menuBarButtonMenuContainer = aMenuContainer;
if ([activeItem _isMenuBarButton])
return [self trackMenuBarButtonEvent:anEvent];
}
_hasMouseGoneUpAfterStartedTracking = NO;
_mouseWasDragged = NO;
[self trackEvent:anEvent];
}
@@ -125,22 +161,10 @@ var STICKY_TIME_INTERVAL = 500,
return;
}
if (_keyBuffer)
{
if (([CPDate date] - _startTime) > (STICKY_TIME_INTERVAL + [activeMenu numberOfItems] / 2))
[self selectNextItemBeginningWith:_keyBuffer inMenu:menu clearBuffer:YES];
if (type === CPPeriodic)
return;
}
// Periodic events don't have a valid location.
var globalLocation = type === CPPeriodic ? _lastGlobalLocation : [anEvent globalLocation];
// Remember this for the next periodic event.
_lastGlobalLocation = globalLocation;
if (!_lastGlobalLocation)
if (!globalLocation)
return;
// Find which menu window the mouse is currently on top of
@@ -152,6 +176,23 @@ var STICKY_TIME_INTERVAL = 500,
activeItemIndex = activeMenuContainer ? [activeMenuContainer itemIndexAtPoint:menuLocation] : CPNotFound,
activeItem = activeItemIndex !== CPNotFound ? [activeMenu itemAtIndex:activeItemIndex] : nil;
if (_keyBuffer)
{
if (([anEvent timestamp] - _startTime) > (STICKY_TIME_INTERVAL + [activeMenu numberOfItems] / 2))
[self selectNextItemBeginningWith:_keyBuffer inMenu:menu clearBuffer:YES];
if (type === CPPeriodic)
return;
}
// unhighlight when mouse is moved off the menu
if (_lastGlobalLocation && CGRectContainsPoint([activeMenuContainer globalFrame], _lastGlobalLocation)
&& !CGRectContainsPoint([activeMenuContainer globalFrame], globalLocation))
[activeMenu _highlightItemAtIndex:CPNotFound];
// Remember this for the next periodic event.
_lastGlobalLocation = globalLocation;
// If the item isn't enabled its as if we clicked on nothing.
if (![activeItem isEnabled] || [activeItem _isMenuBarButton])
{
@@ -161,7 +202,7 @@ var STICKY_TIME_INTERVAL = 500,
var mouseOverMenuView = [activeItem view];
if (type === CPScrollWheel)
if (type === CPScrollWheel && ![activeMenuContainer isMenuBar])
[activeMenuContainer scrollByDelta:[anEvent deltaY]];
if (type === CPPeriodic)
@@ -189,7 +230,7 @@ var STICKY_TIME_INTERVAL = 500,
var menuContainerWindow = activeMenuContainer;
if (![menuContainerWindow isKindOfClass:[CPWindow class]])
if (![menuContainerWindow isKindOfClass:CPWindow])
menuContainerWindow = [menuContainerWindow window];
[menuContainerWindow
@@ -211,10 +252,14 @@ var STICKY_TIME_INTERVAL = 500,
_lastMouseOverMenuView = nil;
}
[activeMenu _highlightItemAtIndex:activeItemIndex];
if (activeItemIndex != CPNotFound)
[activeMenu _highlightItemAtIndex:activeItemIndex];
if (type === CPMouseMoved || type === CPLeftMouseDragged || type === CPLeftMouseDown || type === CPPeriodic)
{
if (type === CPLeftMouseDragged)
_mouseWasDragged = YES;
var oldScrollingState = _scrollingState;
_scrollingState = [activeMenuContainer scrollingStateForPoint:globalLocation];
@@ -229,17 +274,35 @@ var STICKY_TIME_INTERVAL = 500,
}
else if (type === CPLeftMouseUp || type === CPRightMouseUp)
{
if (_hasMouseGoneUpAfterStartedTracking)
{
// Don't close the menu if the current item has a submenu
// and did not override it's default action
if ([activeItem action] === @selector(submenuAction:))
return;
/*
There are a few possibilites:
[trackingMenu cancelTracking];
1. The user clicks and releases without dragging within the sticky time.
This is considered a regular mouse click and not a drag. In this case
we allow the user to track the menu by moving the mouse. The next
mouse up will end tracking.
2. The user clicks and releases without dragging after the sticky time.
This is considered a drag and release and tracking ends.
3. The user clicks, drags and then releases. Tracking ends.
*/
if (_mouseWasDragged || ([anEvent timestamp] - _startTime > STICKY_TIME_INTERVAL))
{
/*
Close the menu if:
1. The mouse was dragged.
2. The mouse is released in the menubar.
3. The current item has a submenu with a custom action.
*/
if (_mouseWasDragged ||
[activeMenuContainer isMenuBar] ||
[activeItem action] !== @selector(submenuAction:))
{
[trackingMenu cancelTracking];
}
}
else
_hasMouseGoneUpAfterStartedTracking = YES;
}
}
@@ -252,7 +315,7 @@ var STICKY_TIME_INTERVAL = 500,
}
// If the item has a submenu, show it.
if ([activeItem hasSubmenu])// && [activeItem action] === @selector(submenuAction:))
if ([activeItem hasSubmenu]) // && [activeItem action] === @selector(submenuAction:))
{
var activeItemRect = [activeMenuContainer rectForItemAtIndex:activeItemIndex],
newMenuOrigin;
@@ -406,7 +469,7 @@ var STICKY_TIME_INTERVAL = 500,
break;
// If this menu is already being shown, unhighlight and return.
if (menu === newMenu)//&& [menu supermenu] === baseMenu)
if (menu === newMenu) //&& [menu supermenu] === baseMenu)
return [newMenu _highlightItemAtIndex:CPNotFound];
[menuContainer orderOut:self];
@@ -452,7 +515,7 @@ var STICKY_TIME_INTERVAL = 500,
var iter = [selectorNames objectEnumerator],
obj;
while (obj = [iter nextObject])
while ((obj = [iter nextObject]) !== nil)
{
var aSelector = CPSelectorFromString(obj);
@@ -464,7 +527,7 @@ var STICKY_TIME_INTERVAL = 500,
{
if (!_keyBuffer)
{
_startTime = [CPDate date];
_startTime = [anEvent timestamp];
_keyBuffer = character;
[CPEvent stopPeriodicEvents];
@@ -483,7 +546,7 @@ var STICKY_TIME_INTERVAL = 500,
var iter = [[menu itemArray] objectEnumerator],
obj;
while (obj = [iter nextObject])
while ((obj = [iter nextObject]) !== nil)
{
if ([obj isHidden] || ![obj isEnabled])
continue;
@@ -501,7 +564,7 @@ var STICKY_TIME_INTERVAL = 500,
_keyBuffer = Nil;
}
else
_startTime = [CPDate date];
_startTime = [CPEvent currentTimestamp];
}
- (void)scrollToBeginningOfDocument:(CPMenu)menu
@@ -529,7 +592,7 @@ var STICKY_TIME_INTERVAL = 500,
return;
}
next = current + (last - first);
var next = current + (last - first);
if (next < [menu numberOfItems])
[menu _highlightItemAtIndex:next];
@@ -557,7 +620,7 @@ var STICKY_TIME_INTERVAL = 500,
return;
}
next = current - (last - first);
var next = current - (last - first);
if (next < 0)
[menu _highlightItemAtIndex:0];
@@ -645,8 +708,11 @@ var STICKY_TIME_INTERVAL = 500,
var index = menu._highlightedIndex - 1;
if (index < 0)
{
if (index != CPNotFound)
[menu _highlightItemAtIndex:[menu numberOfItems] - 1];
return;
}
[menu _highlightItemAtIndex:index];
var item = [menu highlightedItem];
+99 -75
View File
@@ -1,5 +1,29 @@
@import "CPWindow.j"
/*
* _CPMenuWindow.j
* AppKit
*
* Created by Francisco Tolmasky.
* Copyright 2009, 280 North, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "CPClipView.j"
@import "CPImageView.j"
@import "CPWindow.j"
@import "_CPMenuManager.j"
var _CPMenuWindowPool = [],
_CPMenuWindowPoolCapacity = 5,
@@ -10,14 +34,7 @@ _CPMenuWindowMenuBarBackgroundStyle = 0;
_CPMenuWindowPopUpBackgroundStyle = 1;
_CPMenuWindowAttachedMenuBackgroundStyle = 2;
var STICKY_TIME_INTERVAL = 500,
TOP_MARGIN = 5.0,
LEFT_MARGIN = 1.0,
RIGHT_MARGIN = 1.0,
BOTTOM_MARGIN = 5.0,
SCROLL_INDICATOR_HEIGHT = 16.0;
var STICKY_TIME_INTERVAL = 500;
/*
@ignore
@@ -63,17 +80,6 @@ var STICKY_TIME_INTERVAL = 500,
_CPMenuWindowPool.push(aMenuWindow);
}
+ (void)initialize
{
if (self != [_CPMenuWindow class])
return;
var bundle = [CPBundle bundleForClass:self];
_CPMenuWindowMoreAboveImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuWindow/_CPMenuWindowMoreAbove.png"] size:CGSizeMake(38.0, 18.0)];
_CPMenuWindowMoreBelowImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuWindow/_CPMenuWindowMoreBelow.png"] size:CGSizeMake(38.0, 18.0)];
}
- (id)initWithContentRect:(CGRect)aRect styleMask:(unsigned)aStyleMask
{
_constraintRect = _CGRectMakeZero();
@@ -92,26 +98,24 @@ var STICKY_TIME_INTERVAL = 500,
_menuView = [[_CPMenuView alloc] initWithFrame:CGRectMakeZero()];
_menuClipView = [[CPClipView alloc] initWithFrame:CGRectMake(LEFT_MARGIN, TOP_MARGIN, 0.0, 0.0)];
_menuClipView = [[CPClipView alloc] initWithFrame:CGRectMake([_menuView valueForThemeAttribute:@"menu-window-margin-inset"].left, [_menuView valueForThemeAttribute:@"menu-window-margin-inset"].top, 0.0, 0.0)];
[_menuClipView setDocumentView:_menuView];
[contentView addSubview:_menuClipView];
_moreAboveView = [[CPImageView alloc] initWithFrame:CGRectMakeZero()];
[_moreAboveView setImage:_CPMenuWindowMoreAboveImage];
[_moreAboveView setFrameSize:[_CPMenuWindowMoreAboveImage size]];
[_moreAboveView setImage:[_menuView valueForThemeAttribute:@"menu-window-more-above-image"]];
[_moreAboveView setFrameSize:[[_menuView valueForThemeAttribute:@"menu-window-more-above-image"] size]];
[contentView addSubview:_moreAboveView];
_moreBelowView = [[CPImageView alloc] initWithFrame:CGRectMakeZero()];
[_moreBelowView setImage:_CPMenuWindowMoreBelowImage];
[_moreBelowView setFrameSize:[_CPMenuWindowMoreBelowImage size]];
[_moreBelowView setImage:[_menuView valueForThemeAttribute:@"menu-window-more-below-image"]];
[_moreBelowView setFrameSize:[[_menuView valueForThemeAttribute:@"menu-window-more-below-image"] size]];
[contentView addSubview:_moreBelowView];
[self setShadowStyle:CPWindowShadowStyleMenu];
}
return self;
@@ -119,7 +123,7 @@ var STICKY_TIME_INTERVAL = 500,
+ (float)_standardLeftMargin
{
return LEFT_MARGIN;
return [[CPTheme defaultTheme] valueForAttributeWithName:@"menu-window-margin-inset" forClass:_CPMenuView].left;
}
- (void)setFont:(CPFont)aFont
@@ -141,36 +145,10 @@ var STICKY_TIME_INTERVAL = 500,
var bundle = [CPBundle bundleForClass:[self class]];
if (aBackgroundStyle == _CPMenuWindowPopUpBackgroundStyle)
color = [CPColor colorWithPatternImage:[[CPNinePartImage alloc] initWithImageSlices:
[
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuWindow/_CPMenuWindowRounded0.png"] size:CGSizeMake(4.0, 4.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuWindow/_CPMenuWindow1.png"] size:CGSizeMake(1.0, 4.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuWindow/_CPMenuWindowRounded2.png"] size:CGSizeMake(4.0, 4.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuWindow/_CPMenuWindow3.png"] size:CGSizeMake(4.0, 1.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuWindow/_CPMenuWindow4.png"] size:CGSizeMake(1.0, 1.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuWindow/_CPMenuWindow5.png"] size:CGSizeMake(4.0, 1.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuWindow/_CPMenuWindowRounded6.png"] size:CGSizeMake(4.0, 4.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuWindow/_CPMenuWindow7.png"] size:CGSizeMake(1.0, 4.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuWindow/_CPMenuWindowRounded8.png"] size:CGSizeMake(4.0, 4.0)]
]]];
color = [[CPTheme defaultTheme] valueForAttributeWithName:@"menu-window-pop-up-background-style-color" forClass:_CPMenuView];
else if (aBackgroundStyle == _CPMenuWindowMenuBarBackgroundStyle)
color = [CPColor colorWithPatternImage:[[CPNinePartImage alloc] initWithImageSlices:
[
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuWindow/_CPMenuWindow3.png"] size:CGSizeMake(4.0, 0.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuWindow/_CPMenuWindow4.png"] size:CGSizeMake(1.0, 0.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuWindow/_CPMenuWindow5.png"] size:CGSizeMake(4.0, 0.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuWindow/_CPMenuWindow3.png"] size:CGSizeMake(4.0, 1.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuWindow/_CPMenuWindow4.png"] size:CGSizeMake(1.0, 1.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuWindow/_CPMenuWindow5.png"] size:CGSizeMake(4.0, 1.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuWindow/_CPMenuWindowRounded6.png"] size:CGSizeMake(4.0, 4.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuWindow/_CPMenuWindow7.png"] size:CGSizeMake(1.0, 4.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuWindow/_CPMenuWindowRounded8.png"] size:CGSizeMake(4.0, 4.0)]
]]];
color = [[CPTheme defaultTheme] valueForAttributeWithName:@"menu-window-menu-bar-background-style-color" forClass:_CPMenuView];
_CPMenuWindowBackgroundColors[aBackgroundStyle] = color;
}
@@ -188,12 +166,13 @@ var STICKY_TIME_INTERVAL = 500,
[aMenu _setMenuWindow:self];
[_menuView setMenu:aMenu];
var menuViewSize = [_menuView frame].size;
var menuViewSize = [_menuView frame].size,
marginInset = [_menuView valueForThemeAttribute:@"menu-window-margin-inset"];
[self setFrameSize:CGSizeMake(LEFT_MARGIN + menuViewSize.width + RIGHT_MARGIN, TOP_MARGIN + menuViewSize.height + BOTTOM_MARGIN)];
[self setFrameSize:CGSizeMake(marginInset.left + menuViewSize.width + marginInset.right, marginInset.top + menuViewSize.height + marginInset.bottom)];
[_menuView scrollPoint:CGPointMake(0.0, 0.0)];
[_menuClipView setFrame:CGRectMake(LEFT_MARGIN, TOP_MARGIN, menuViewSize.width, menuViewSize.height)];
[_menuClipView setFrame:CGRectMake(marginInset.left, marginInset.top, menuViewSize.width, menuViewSize.height)];
}
- (void)setMinWidth:(float)aWidth
@@ -251,7 +230,9 @@ var STICKY_TIME_INTERVAL = 500,
// FIXME: This gets called far too often.
_unconstrainedFrame = _CGRectMakeCopy(aFrame);
var constrainedFrame = CGRectIntersection(_unconstrainedFrame, _constraintRect);
var constrainedFrame = CGRectIntersection(_unconstrainedFrame, _constraintRect),
marginInset = [_menuView valueForThemeAttribute:@"menu-window-margin-inset"],
scrollIndicatorHeight = [_menuView valueForThemeAttribute:@"menu-window-scroll-indicator-height"];
// We don't want to simply intersect the visible frame and the unconstrained frame.
// We should be allowing as much of the width to fit as possible (pushing back and forward).
@@ -270,41 +251,41 @@ var STICKY_TIME_INTERVAL = 500,
[super setFrame:constrainedFrame display:shouldDisplay animate:shouldAnimate];
// This needs to happen before changing the frame.
var menuViewOrigin = CGPointMake(CGRectGetMinX(aFrame) + LEFT_MARGIN, CGRectGetMinY(aFrame) + TOP_MARGIN),
moreAbove = menuViewOrigin.y < CGRectGetMinY(constrainedFrame) + TOP_MARGIN,
moreBelow = menuViewOrigin.y + CGRectGetHeight([_menuView frame]) > CGRectGetMaxY(constrainedFrame) - BOTTOM_MARGIN,
var menuViewOrigin = CGPointMake(CGRectGetMinX(aFrame) + marginInset.left, CGRectGetMinY(aFrame) + marginInset.top),
moreAbove = menuViewOrigin.y < CGRectGetMinY(constrainedFrame) + marginInset.top,
moreBelow = menuViewOrigin.y + CGRectGetHeight([_menuView frame]) > CGRectGetMaxY(constrainedFrame) - marginInset.bottom,
topMargin = TOP_MARGIN,
bottomMargin = BOTTOM_MARGIN,
topMargin = marginInset.top,
bottomMargin = marginInset.bottom,
contentView = [self contentView],
bounds = [contentView bounds];
if (moreAbove)
{
topMargin += SCROLL_INDICATOR_HEIGHT;
topMargin += scrollIndicatorHeight;
var frame = [_moreAboveView frame];
[_moreAboveView setFrameOrigin:CGPointMake((CGRectGetWidth(bounds) - CGRectGetWidth(frame)) / 2.0, (TOP_MARGIN + SCROLL_INDICATOR_HEIGHT - CGRectGetHeight(frame)) / 2.0)];
[_moreAboveView setFrameOrigin:CGPointMake((CGRectGetWidth(bounds) - CGRectGetWidth(frame)) / 2.0, (marginInset.top + scrollIndicatorHeight - CGRectGetHeight(frame)) / 2.0)];
}
[_moreAboveView setHidden:!moreAbove];
if (moreBelow)
{
bottomMargin += SCROLL_INDICATOR_HEIGHT;
bottomMargin += scrollIndicatorHeight;
[_moreBelowView setFrameOrigin:CGPointMake((CGRectGetWidth(bounds) - CGRectGetWidth([_moreBelowView frame])) / 2.0, CGRectGetHeight(bounds) - SCROLL_INDICATOR_HEIGHT - BOTTOM_MARGIN)];
[_moreBelowView setFrameOrigin:CGPointMake((CGRectGetWidth(bounds) - CGRectGetWidth([_moreBelowView frame])) / 2.0, CGRectGetHeight(bounds) - scrollIndicatorHeight - marginInset.bottom)];
}
[_moreBelowView setHidden:!moreBelow];
var clipFrame = CGRectMakeZero();
clipFrame.origin.x = LEFT_MARGIN;
clipFrame.origin.x = marginInset.left;
clipFrame.origin.y = topMargin;
clipFrame.size.width = CGRectGetWidth(constrainedFrame) - LEFT_MARGIN - RIGHT_MARGIN;
clipFrame.size.width = CGRectGetWidth(constrainedFrame) - marginInset.left - marginInset.right;
clipFrame.size.height = CGRectGetHeight(constrainedFrame) - topMargin - bottomMargin;
[_menuClipView setFrame:clipFrame];
@@ -400,15 +381,15 @@ var STICKY_TIME_INTERVAL = 500,
- (_CPManagerScrollingState)scrollingStateForPoint:(CGPoint)aGlobalLocation
{
var frame = [self frame];
if (!CPRectContainsPoint(frame,aGlobalLocation) || ![self canScroll])
if (!CGRectContainsPoint(frame,aGlobalLocation) || ![self canScroll])
return _CPMenuManagerScrollingStateNone;
// If we're at or above of the top scroll indicator...
if (aGlobalLocation.y < CGRectGetMinY(frame) + TOP_MARGIN + SCROLL_INDICATOR_HEIGHT && ![_moreAboveView isHidden])
if (aGlobalLocation.y < CGRectGetMinY(frame) + [_menuView valueForThemeAttribute:@"menu-window-margin-inset"].top + [_menuView valueForThemeAttribute:@"menu-window-scroll-indicator-height"] && ![_moreAboveView isHidden])
return _CPMenuManagerScrollingStateUp;
// If we're at or below the bottom scroll indicator...
if (aGlobalLocation.y > CGRectGetMaxY(frame) - BOTTOM_MARGIN - SCROLL_INDICATOR_HEIGHT && ![_moreBelowView isHidden])
if (aGlobalLocation.y > CGRectGetMaxY(frame) - [_menuView valueForThemeAttribute:@"menu-window-margin-inset"].bottom - [_menuView valueForThemeAttribute:@"menu-window-scroll-indicator-height"] && ![_moreBelowView isHidden])
return _CPMenuManagerScrollingStateDown;
return _CPMenuManagerScrollingStateNone;
@@ -416,7 +397,7 @@ var STICKY_TIME_INTERVAL = 500,
- (float)deltaYForItemAtIndex:(int)anIndex
{
return TOP_MARGIN + CGRectGetMinY([_menuView rectForItemAtIndex:anIndex]);
return [_menuView valueForThemeAttribute:@"menu-window-margin-inset"].top + CGRectGetMinY([_menuView rectForItemAtIndex:anIndex]);
}
- (CGPoint)rectForItemAtIndex:(int)anIndex
@@ -447,6 +428,49 @@ var STICKY_TIME_INTERVAL = 500,
CPFont _font @accessors(property=font);
}
+ (CPString)defaultThemeClass
{
return "menu-view";
}
+ (id)themeAttributes
{
return [CPDictionary dictionaryWithObjects:[ [CPNull null], [CPNull null], [CPNull null], [CPNull null], CGInsetMake(5.0, 1.0, 1.0, 5.0), 16.0,
[CPNull null], [CPNull null], [CPNull null], 30.0, 10.0, 10.0, 10.0,
[CPNull null], [CPNull null], [CPNull null], [CPNull null], [CPNull null], [CPNull null], [CPNull null], 28.0, [CPNull null], 1.0,
[CPNull null], [CPNull null], [CPNull null]]
forKeys:[ @"menu-window-more-above-image",
@"menu-window-more-below-image",
@"menu-window-pop-up-background-style-color",
@"menu-window-menu-bar-background-style-color",
@"menu-window-margin-inset",
@"menu-window-scroll-indicator-height",
@"menu-bar-window-background-color",
@"menu-bar-window-background-selected-color",
@"menu-bar-window-font",
@"menu-bar-window-height",
@"menu-bar-window-margin",
@"menu-bar-window-left-margin",
@"menu-bar-window-right-margin",
@"menu-bar-text-color",
@"menu-bar-title-color",
@"menu-bar-text-shadow-color",
@"menu-bar-title-shadow-color",
@"menu-bar-highlight-color",
@"menu-bar-highlight-text-color",
@"menu-bar-highlight-text-shadow-color",
@"menu-bar-height",
@"menu-bar-icon-image",
@"menu-bar-icon-image-alpha-value",
@"menu-general-icon-new",
@"menu-general-icon-save",
@"menu-general-icon-open"]];
}
- (unsigned)numberOfUnhiddenItems
{
return _visibleMenuItemInfos.length;
+35 -32
View File
@@ -25,29 +25,33 @@
@import <Foundation/CPString.j>
@import "CPImage.j"
@import "CPMenu.j"
@import "CPText.j"
@import "CPView.j"
@import "_CPMenuItemView.j"
@class CPMenu
var CPMenuItemStringRepresentationDictionary = [CPDictionary dictionary];
[CPMenuItemStringRepresentationDictionary setObject:"\u238B" forKey:CPEscapeFunctionKey];
[CPMenuItemStringRepresentationDictionary setObject:"\u21E5" forKey:CPTabCharacter];
[CPMenuItemStringRepresentationDictionary setObject:"\u21E4" forKey:CPBackTabCharacter];
[CPMenuItemStringRepresentationDictionary setObject:"\u2423" forKey:CPSpaceFunctionKey];
[CPMenuItemStringRepresentationDictionary setObject:"\u23CE" forKey:CPCarriageReturnCharacter];
[CPMenuItemStringRepresentationDictionary setObject:"\u232B" forKey:CPBackspaceCharacter];
[CPMenuItemStringRepresentationDictionary setObject:"\u232B" forKey:CPDeleteFunctionKey];
[CPMenuItemStringRepresentationDictionary setObject:"\u2326" forKey:CPDeleteCharacter];
[CPMenuItemStringRepresentationDictionary setObject:"\u21F1" forKey:CPHomeFunctionKey];
[CPMenuItemStringRepresentationDictionary setObject:"\u21F2" forKey:CPEndFunctionKey];
[CPMenuItemStringRepresentationDictionary setObject:"\u21DE" forKey:CPPageUpFunctionKey];
[CPMenuItemStringRepresentationDictionary setObject:"\u21DF" forKey:CPPageDownFunctionKey];
[CPMenuItemStringRepresentationDictionary setObject:"\u2191" forKey:CPUpArrowFunctionKey];
[CPMenuItemStringRepresentationDictionary setObject:"\u2193" forKey:CPDownArrowFunctionKey];
[CPMenuItemStringRepresentationDictionary setObject:"\u2190" forKey:CPLeftArrowFunctionKey];
[CPMenuItemStringRepresentationDictionary setObject:"\u2192" forKey:CPRightArrowFunctionKey];
[CPMenuItemStringRepresentationDictionary setObject:"\u2327" forKey:CPClearDisplayFunctionKey];
@global CPApp
var CPMenuItemStringRepresentationDictionary = [CPDictionary dictionaryWithObjectsAndKeys:
"\u238B", CPEscapeFunctionKey,
"\u21E5", CPTabCharacter,
"\u21E4", CPBackTabCharacter,
"\u2423", CPSpaceFunctionKey,
"\u23CE", CPCarriageReturnCharacter,
"\u232B", CPBackspaceCharacter,
"\u232B", CPDeleteFunctionKey,
"\u2326", CPDeleteCharacter,
"\u21F1", CPHomeFunctionKey,
"\u21F2", CPEndFunctionKey,
"\u21DE", CPPageUpFunctionKey,
"\u21DF", CPPageDownFunctionKey,
"\u2191", CPUpArrowFunctionKey,
"\u2193", CPDownArrowFunctionKey,
"\u2190", CPLeftArrowFunctionKey,
"\u2192", CPRightArrowFunctionKey,
"\u2327", CPClearDisplayFunctionKey
];
/*!
@ingroup appkit
@@ -281,7 +285,7 @@ var CPMenuItemStringRepresentationDictionary = [CPDictionary dictionary];
*/
- (void)setFont:(CPFont)aFont
{
if (_font == aFont)
if ([_font isEqual:aFont])
return;
_font = aFont;
@@ -932,34 +936,33 @@ var CPMenuItemIsSeparatorKey = @"CPMenuItemIsSeparatorKey",
_action = [aCoder decodeObjectForKey:CPMenuItemActionKey];
_isEnabled = DEFAULT_VALUE(CPMenuItemIsEnabledKey, YES);
_isHidden = DEFAULT_VALUE(CPMenuItemIsHiddenKey, NO);
_tag = DEFAULT_VALUE(CPMenuItemTagKey, 0);
_state = DEFAULT_VALUE(CPMenuItemStateKey, CPOffState);
_isHidden = [aCoder decodeBoolForKey:CPMenuItemIsHiddenKey];
_tag = [aCoder decodeIntForKey:CPMenuItemTagKey];
_state = [aCoder decodeIntForKey:CPMenuItemStateKey];
_image = DEFAULT_VALUE(CPMenuItemImageKey, nil);
_alternateImage = DEFAULT_VALUE(CPMenuItemAlternateImageKey, nil);
_image = [aCoder decodeObjectForKey:CPMenuItemImageKey];
_alternateImage = [aCoder decodeObjectForKey:CPMenuItemAlternateImageKey];
// CPImage _onStateImage;
// CPImage _offStateImage;
// CPImage _mixedStateImage;
// This order matters because setSubmenu: needs _menu to be around.
_menu = DEFAULT_VALUE(CPMenuItemMenuKey, nil);
[self setSubmenu:DEFAULT_VALUE(CPMenuItemSubmenuKey, nil)];
_menu = [aCoder decodeObjectForKey:CPMenuItemMenuKey];
[self setSubmenu:[aCoder decodeObjectForKey:CPMenuItemSubmenuKey]];
_keyEquivalent = [aCoder decodeObjectForKey:CPMenuItemKeyEquivalentKey] || @"";
_keyEquivalentModifierMask = [aCoder decodeObjectForKey:CPMenuItemKeyEquivalentModifierMaskKey] || 0;
_keyEquivalentModifierMask = [aCoder decodeIntForKey:CPMenuItemKeyEquivalentModifierMaskKey];
// int _mnemonicLocation;
// BOOL _isAlternate;
// Default is 0.
[self setIndentationLevel:[aCoder decodeIntForKey:CPMenuItemIndentationLevelKey] || 0];
[self setIndentationLevel:[aCoder decodeIntForKey:CPMenuItemIndentationLevelKey]];
// CPString _toolTip;
_representedObject = DEFAULT_VALUE(CPMenuItemRepresentedObjectKey, nil);
_view = DEFAULT_VALUE(CPMenuItemViewKey, nil);
_representedObject = [aCoder decodeObjectForKey:CPMenuItemRepresentedObjectKey];
_view = [aCoder decodeObjectForKey:CPMenuItemViewKey];
}
return self;
+44 -41
View File
@@ -1,17 +1,30 @@
@import "CPView.j"
/*
* _CPMenuItemMenuBarView.j
* AppKit
*
* Created by Francisco Tolmasky.
* Copyright 2009, 280 North, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "CPControl.j"
@import "_CPImageAndTextView.j"
var HORIZONTAL_MARGIN = 8.0,
SUBMENU_INDICATOR_MARGIN = 3.0,
VERTICAL_MARGIN = 4.0;
var SelectionColor = nil,
SUBMENU_INDICATOR_COLOR = nil,
_CPMenuItemSelectionColor = nil,
_CPMenuItemTextShadowColor = nil,
_CPMenuItemDefaultStateImages = [],
_CPMenuItemDefaultStateHighlightedImages = [];
@class _CPMenuBarWindow
@class _CPMenuView
@implementation _CPMenuItemMenuBarView : CPView
{
@@ -27,28 +40,20 @@ var SelectionColor = nil,
CPView _submenuIndicatorView;
}
+ (void)initialize
+ (CPString)defaultThemeClass
{
if (self !== [_CPMenuItemMenuBarView class])
return;
return "menu-item-bar-view";
}
var bundle = [CPBundle bundleForClass:self];
SelectionColor = [CPColor colorWithPatternImage:[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"_CPMenuBarWindow/_CPMenuBarWindowBackgroundSelected.png"] size:CGSizeMake(1.0, 28.0)]];
SUBMENU_INDICATOR_COLOR = [CPColor grayColor];
_CPMenuItemSelectionColor = [CPColor colorWithCalibratedRed:95.0 / 255.0 green:131.0 / 255.0 blue:185.0 / 255.0 alpha:1.0];
_CPMenuItemTextShadowColor = [CPColor colorWithCalibratedRed:26.0 / 255.0 green: 73.0 / 255.0 blue:109.0 / 255.0 alpha:1.0];
_CPMenuItemDefaultStateImages[CPOffState] = nil;
_CPMenuItemDefaultStateHighlightedImages[CPOffState] = nil;
_CPMenuItemDefaultStateImages[CPOnState] = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPMenuItem/CPMenuItemOnState.png"] size:CGSizeMake(14.0, 14.0)];
_CPMenuItemDefaultStateHighlightedImages[CPOnState] = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPMenuItem/CPMenuItemOnStateHighlighted.png"] size:CGSizeMake(14.0, 14.0)];
_CPMenuItemDefaultStateImages[CPMixedState] = nil;
_CPMenuItemDefaultStateHighlightedImages[CPMixedState] = nil;
+ (id)themeAttributes
{
return [CPDictionary dictionaryWithObjects:[[CPNull null], [CPNull null], [CPNull null], 8.0, 3.0, 4.0]
forKeys:[ @"submenu-indicator-color",
@"menu-item-selection-color",
@"menu-item-text-shadow-color",
@"horizontal-margin",
@"submenu-indicator-margin",
@"vertical-margin"]];
}
+ (id)view
@@ -62,7 +67,7 @@ var SelectionColor = nil,
if (self)
{
_imageAndTextView = [[_CPImageAndTextView alloc] initWithFrame:CGRectMake(HORIZONTAL_MARGIN, 0.0, 0.0, 0.0)];
_imageAndTextView = [[_CPImageAndTextView alloc] initWithFrame:CGRectMake([self valueForThemeAttribute:@"horizontal-margin"], 0.0, 0.0, 0.0)];
[_imageAndTextView setImagePosition:CPImageLeft];
[_imageAndTextView setImageOffset:3.0];
@@ -101,7 +106,7 @@ var SelectionColor = nil,
- (void)update
{
var x = HORIZONTAL_MARGIN,
var x = [self valueForThemeAttribute:@"horizontal-margin"],
height = 0.0;
[_imageAndTextView setFont:[_menuItem font] || [_CPMenuBarWindow font]];
@@ -129,7 +134,7 @@ var SelectionColor = nil,
var submenuViewFrame = [_submenuIndicatorView frame];
submenuViewFrame.origin.x = x + SUBMENU_INDICATOR_MARGIN;
submenuViewFrame.origin.x = x + [self valueForThemeAttribute:@"submenu-indicator-margin"];
x = CGRectGetMaxX(submenuViewFrame);
height = MAX(height, CGRectGetHeight(submenuViewFrame));
@@ -137,7 +142,7 @@ var SelectionColor = nil,
else
[_submenuIndicatorView setHidden:YES];
height += 2.0 * VERTICAL_MARGIN;
height += 2.0 * [self valueForThemeAttribute:@"vertical-margin"];
imageAndTextViewFrame.origin.y = FLOOR((height - CGRectGetHeight(imageAndTextViewFrame)) / 2.0);
[_imageAndTextView setFrame:imageAndTextViewFrame];
@@ -148,10 +153,8 @@ var SelectionColor = nil,
[_submenuIndicatorView setFrame:submenuViewFrame];
}
_minSize = CGSizeMake(x + HORIZONTAL_MARGIN, height);
[self setAutoresizesSubviews:NO];
[self setFrameSize:_minSize];
[self setFrameSize:CGSizeMake(x + [self valueForThemeAttribute:@"horizontal-margin"], height)];
[self setAutoresizesSubviews:YES];
}
@@ -164,11 +167,11 @@ var SelectionColor = nil,
if (shouldHighlight)
{
if (![_menuItem _isMenuBarButton])
[self setBackgroundColor:SelectionColor];
[self setBackgroundColor:[[CPTheme defaultTheme] valueForAttributeWithName:@"menu-bar-window-background-selected-color" forClass:_CPMenuView]];
[_imageAndTextView setImage:[_menuItem alternateImage] || [_menuItem image]];
[_imageAndTextView setTextColor:[CPColor whiteColor]];
[_imageAndTextView setTextShadowColor:_CPMenuItemTextShadowColor];
[_imageAndTextView setTextShadowColor:[self valueForThemeAttribute:@"menu-item-text-shadow-color"]];
[_submenuIndicatorView setColor:[CPColor whiteColor]];
[_submenuIndicatorView setShadowColor:[CPColor colorWithWhite:0.1 alpha:0.7]];
+22 -1
View File
@@ -1,3 +1,24 @@
/*
* _CPMenuItemSeparatorView.j
* AppKit
*
* Created by Francisco Tolmasky.
* Copyright 2009, 280 North, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "CPView.j"
@@ -35,4 +56,4 @@
CGContextStrokePath(context);
}
@end
@end
+126 -62
View File
@@ -1,21 +1,28 @@
/*
* _CPMenuItemStandardView.j
* AppKit
*
* Created by Francisco Tolmasky.
* Copyright 2009, 280 North, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "CPControl.j"
var LEFT_MARGIN = 3.0,
RIGHT_MARGIN = 14.0 + 3.0,
STATE_COLUMN_WIDTH = 14.0,
INDENTATION_WIDTH = 17.0,
VERTICAL_MARGIN = 4.0,
RIGHT_COLUMNS_MARGIN = 30.0,
KEY_EQUIVALENT_MARGIN = 10.0;
var SUBMENU_INDICATOR_COLOR = nil,
_CPMenuItemSelectionColor = nil,
_CPMenuItemTextShadowColor = nil,
_CPMenuItemDefaultStateImages = [],
_CPMenuItemDefaultStateHighlightedImages = [];
@import "CPImageView.j"
@import "_CPImageAndTextView.j"
@implementation _CPMenuItemStandardView : CPView
{
@@ -34,26 +41,29 @@ var SUBMENU_INDICATOR_COLOR = nil,
CPView _submenuIndicatorView;
}
+ (void)initialize
+ (CPString)defaultThemeClass
{
if (self !== [_CPMenuItemStandardView class])
return;
return "menu-item-standard-view";
}
SUBMENU_INDICATOR_COLOR = [CPColor grayColor];
_CPMenuItemSelectionColor = [CPColor colorWithCalibratedRed:95.0 / 255.0 green:131.0 / 255.0 blue:185.0 / 255.0 alpha:1.0];
_CPMenuItemTextShadowColor = [CPColor colorWithCalibratedRed:26.0 / 255.0 green: 73.0 / 255.0 blue:109.0 / 255.0 alpha:1.0];
var bundle = [CPBundle bundleForClass:self];
_CPMenuItemDefaultStateImages[CPOffState] = nil;
_CPMenuItemDefaultStateHighlightedImages[CPOffState] = nil;
_CPMenuItemDefaultStateImages[CPOnState] = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPMenuItem/CPMenuItemOnState.png"] size:CGSizeMake(14.0, 14.0)];
_CPMenuItemDefaultStateHighlightedImages[CPOnState] = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPMenuItem/CPMenuItemOnStateHighlighted.png"] size:CGSizeMake(14.0, 14.0)];
_CPMenuItemDefaultStateImages[CPMixedState] = nil;
_CPMenuItemDefaultStateHighlightedImages[CPMixedState] = nil;
+ (id)themeAttributes
{
return [CPDictionary dictionaryWithObjects:[[CPNull null], [CPNull null], [CPNull null], [CPNull null], [CPNull null], [CPNull null], [CPNull null], [CPNull null], [CPNull null], 3.0, 17.0, 14.0, 17.0, 4.0, 30.0]
forKeys:[ @"submenu-indicator-color",
@"menu-item-selection-color",
@"menu-item-text-shadow-color",
@"menu-item-default-off-state-image",
@"menu-item-default-off-state-highlighted-image",
@"menu-item-default-on-state-image",
@"menu-item-default-on-state-highlighted-image",
@"menu-item-default-mixed-state-image",
@"menu-item-default-mixed-state-highlighted-image",
@"left-margin",
@"right-margin",
@"state-column-width",
@"indentation-width",
@"vertical-margin",
@"right-columns-margin"]];
}
+ (id)view
@@ -63,7 +73,7 @@ var SUBMENU_INDICATOR_COLOR = nil,
+ (float)_standardLeftMargin
{
return LEFT_MARGIN + STATE_COLUMN_WIDTH;
return [[CPTheme defaultTheme] valueForAttributeWithName:@"left-margin" forClass:[self class]] + [[CPTheme defaultTheme] valueForAttributeWithName:@"state-column-width" forClass:[self class]];
}
- (id)initWithFrame:(CGRect)aFrame
@@ -74,7 +84,7 @@ var SUBMENU_INDICATOR_COLOR = nil,
{
_stateView = [[CPImageView alloc] initWithFrame:CGRectMake(0.0, 0.0, 0.0, 0.0)];
[_stateView setImageScaling:CPScaleNone];
[_stateView setImageScaling:CPImageScaleNone];
[self addSubview:_stateView];
@@ -95,7 +105,7 @@ var SUBMENU_INDICATOR_COLOR = nil,
_submenuIndicatorView = [[_CPMenuItemSubmenuIndicatorView alloc] initWithFrame:CGRectMake(0.0, 0.0, 8.0, 10.0)];
[_submenuIndicatorView setColor:SUBMENU_INDICATOR_COLOR];
[_submenuIndicatorView setColor:[self valueForThemeAttribute:@"submenu-indicator-color"]];
[_submenuIndicatorView setAutoresizingMask:CPViewMinXMargin];
[self addSubview:_submenuIndicatorView];
@@ -129,16 +139,34 @@ var SUBMENU_INDICATOR_COLOR = nil,
- (void)update
{
var x = LEFT_MARGIN + [_menuItem indentationLevel] * INDENTATION_WIDTH,
var x = [self valueForThemeAttribute:@"left-margin"] + [_menuItem indentationLevel] * [self valueForThemeAttribute:@"indentation-width"],
height = 0.0,
hasStateColumn = [[_menuItem menu] showsStateColumn];
if (hasStateColumn)
{
[_stateView setHidden:NO];
[_stateView setImage:_CPMenuItemDefaultStateImages[[_menuItem state]] || nil];
//[_stateView setImage:_CPMenuItemDefaultStateImages[[_menuItem state]] || nil];
x += STATE_COLUMN_WIDTH;
switch ([_menuItem state])
{
case CPOnState:
[_stateView setImage:[self valueForThemeAttribute:@"menu-item-default-on-state-image"]];
break;
case CPOffState:
[_stateView setImage:[self valueForThemeAttribute:@"menu-item-default-off-state-image"]];
break;
case CPMixedState:
[_stateView setImage:[self valueForThemeAttribute:@"menu-item-default-mixed-state-image"]];
break;
default:
break;
}
x += [self valueForThemeAttribute:@"state-column-width"];
}
else
[_stateView setHidden:YES];
@@ -162,7 +190,7 @@ var SUBMENU_INDICATOR_COLOR = nil,
hasSubmenu = [_menuItem hasSubmenu];
if (hasKeyEquivalent || hasSubmenu)
x += RIGHT_COLUMNS_MARGIN;
x += [self valueForThemeAttribute:@"right-columns-margin"];
if (hasKeyEquivalent)
{
@@ -173,9 +201,9 @@ var SUBMENU_INDICATOR_COLOR = nil,
[_keyEquivalentView setTextColor:[self textColor]];
[_keyEquivalentView setTextShadowColor:[self textShadowColor]];
[_keyEquivalentView setTextShadowOffset:CGSizeMake(0, 1)];
[_keyEquivalentView setFrameOrigin:CGPointMake(x, VERTICAL_MARGIN)];
[_keyEquivalentView setFrameOrigin:CGPointMake(x, [self valueForThemeAttribute:@"vertical-margin"])];
[_keyEquivalentView sizeToFit];
var keyEquivalentViewFrame = [_keyEquivalentView frame];
keyEquivalentViewFrame.origin.x = x;
@@ -183,7 +211,7 @@ var SUBMENU_INDICATOR_COLOR = nil,
height = MAX(height, CGRectGetHeight(keyEquivalentViewFrame));
if (hasSubmenu)
x += RIGHT_COLUMNS_MARGIN;
x += [self valueForThemeAttribute:@"right-columns-margin"];
}
else
[_keyEquivalentView setHidden:YES];
@@ -202,28 +230,28 @@ var SUBMENU_INDICATOR_COLOR = nil,
else
[_submenuIndicatorView setHidden:YES];
height += 2.0 * VERTICAL_MARGIN;
height += 2.0 * [self valueForThemeAttribute:@"vertical-margin"];
imageAndTextViewFrame.origin.y = FLOOR((height - CGRectGetHeight(imageAndTextViewFrame)) / 2.0);
[_imageAndTextView setFrame:imageAndTextViewFrame];
if (hasStateColumn)
[_stateView setFrameSize:CGSizeMake(STATE_COLUMN_WIDTH, height)];
[_stateView setFrameSize:CGSizeMake([self valueForThemeAttribute:@"state-column-width"], height)];
if (hasKeyEquivalent)
{
keyEquivalentViewFrame.origin.y = FLOOR((height - CGRectGetHeight(keyEquivalentViewFrame)) / 2.0);
[_keyEquivalentView setFrame:keyEquivalentViewFrame];
}
if (hasSubmenu)
{
submenuViewFrame.origin.y = FLOOR((height - CGRectGetHeight(submenuViewFrame)) / 2.0);
[_submenuIndicatorView setFrame:submenuViewFrame];
}
_minSize = CGSizeMake(x + RIGHT_MARGIN, height);
_minSize = CGSizeMake(x + [self valueForThemeAttribute:@"right-margin"], height);
[self setAutoresizesSubviews:NO];
[self setFrameSize:_minSize];
[self setAutoresizesSubviews:YES];
@@ -233,19 +261,19 @@ var SUBMENU_INDICATOR_COLOR = nil,
{
// FIXME: This should probably be even throw.
if (![_menuItem isEnabled])
return;
return;
if (shouldHighlight)
{
[self setBackgroundColor:_CPMenuItemSelectionColor];
[self setBackgroundColor:[self valueForThemeAttribute:@"menu-item-selection-color"]];
[_imageAndTextView setImage:[_menuItem alternateImage] || [_menuItem image]];
[_imageAndTextView setTextColor:[CPColor whiteColor]];
[_keyEquivalentView setTextColor:[CPColor whiteColor]];
[_submenuIndicatorView setColor:[CPColor whiteColor]];
[_imageAndTextView setTextShadowColor:_CPMenuItemTextShadowColor];
[_keyEquivalentView setTextShadowColor:_CPMenuItemTextShadowColor];
[_imageAndTextView setTextShadowColor:[self valueForThemeAttribute:@"menu-item-text-shadow-color"]];
[_keyEquivalentView setTextShadowColor:[self valueForThemeAttribute:@"menu-item-text-shadow-color"]];
}
else
{
@@ -254,18 +282,54 @@ var SUBMENU_INDICATOR_COLOR = nil,
[_imageAndTextView setImage:[_menuItem image]];
[_imageAndTextView setTextColor:[self textColor]];
[_keyEquivalentView setTextColor:[self textColor]];
[_submenuIndicatorView setColor:SUBMENU_INDICATOR_COLOR];
[_submenuIndicatorView setColor:[self valueForThemeAttribute:@"submenu-indicator-color"]];
[_imageAndTextView setTextShadowColor:[self textShadowColor]];
[_keyEquivalentView setTextShadowColor:[self textShadowColor]];
}
if ([[_menuItem menu] showsStateColumn])
{
if (shouldHighlight)
[_stateView setImage:_CPMenuItemDefaultStateHighlightedImages[[_menuItem state]] || nil];
{
switch ([_menuItem state])
{
case CPOnState:
[_stateView setImage:[self valueForThemeAttribute:@"menu-item-default-on-state-highlighted-image"]];
break;
case CPOffState:
[_stateView setImage:[self valueForThemeAttribute:@"menu-item-default-off-state-highlighted-image"]];
break;
case CPMixedState:
[_stateView setImage:[self valueForThemeAttribute:@"menu-item-default-mixed-state-highlighted-image"]];
break;
default:
break;
}
}
else
[_stateView setImage:_CPMenuItemDefaultStateImages[[_menuItem state]] || nil];
{
switch ([_menuItem state])
{
case CPOnState:
[_stateView setImage:[self valueForThemeAttribute:@"menu-item-default-on-state-image"]];
break;
case CPOffState:
[_stateView setImage:[self valueForThemeAttribute:@"menu-item-default-off-state-image"]];
break;
case CPMixedState:
[_stateView setImage:[self valueForThemeAttribute:@"menu-item-default-mixed-state-image"]];
break;
default:
break;
}
}
}
}
@@ -290,15 +354,15 @@ var SUBMENU_INDICATOR_COLOR = nil,
{
var context = [[CPGraphicsContext currentContext] graphicsPort],
bounds = [self bounds];
CGContextBeginPath(context);
CGContextMoveToPoint(context, CGRectGetMinX(bounds), CGRectGetMinY(bounds));
CGContextAddLineToPoint(context, CGRectGetMaxX(bounds), CGRectGetMidY(bounds));
CGContextAddLineToPoint(context, CGRectGetMinX(bounds), CGRectGetMaxY(bounds));
CGContextClosePath(context);
CGContextSetFillColor(context, _color);
CGContextFillPath(context);
}
+40 -32
View File
@@ -1,22 +1,38 @@
/*
* _CPMenuItemView.j
* AppKit
*
* Created by Francisco Tolmasky.
* Copyright 2009, 280 North, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import <AppKit/CPControl.j>
@import "CPControl.j"
@import "_CPMenuItemSeparatorView.j"
@import "_CPMenuItemStandardView.j"
@import "_CPMenuItemMenuBarView.j"
@global CPApp
var LEFT_MARGIN = 3.0,
RIGHT_MARGIN = 16.0,
STATE_COLUMN_WIDTH = 14.0,
INDENTATION_WIDTH = 17.0,
VERTICAL_MARGIN = 4.0;
var _CPMenuItemSelectionColor = nil,
_CPMenuItemTextShadowColor = nil,
_CPMenuItemDefaultStateImages = [],
_CPMenuItemDefaultStateHighlightedImages = [];
// var LEFT_MARGIN = 3.0,
// RIGHT_MARGIN = 16.0,
// STATE_COLUMN_WIDTH = 14.0,
// INDENTATION_WIDTH = 17.0,
// VERTICAL_MARGIN = 4.0;
/*
@ignore
@@ -38,31 +54,23 @@ var _CPMenuItemSelectionColor = nil,
CPView _submenuView;
}
+ (void)initialize
+ (CPString)defaultThemeClass
{
if (self != [_CPMenuItemView class])
return;
_CPMenuItemSelectionColor = [CPColor colorWithCalibratedRed:95.0 / 255.0 green:131.0 / 255.0 blue:185.0 / 255.0 alpha:1.0];
_CPMenuItemTextShadowColor = [CPColor colorWithCalibratedRed:26.0 / 255.0 green: 73.0 / 255.0 blue:109.0 / 255.0 alpha:1.0];
var bundle = [CPBundle bundleForClass:self];
_CPMenuItemDefaultStateImages[CPOffState] = nil;
_CPMenuItemDefaultStateHighlightedImages[CPOffState] = nil;
_CPMenuItemDefaultStateImages[CPOnState] = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPMenuItem/CPMenuItemOnState.png"] size:CGSizeMake(14.0, 14.0)];
_CPMenuItemDefaultStateHighlightedImages[CPOnState] = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPMenuItem/CPMenuItemOnStateHighlighted.png"] size:CGSizeMake(14.0, 14.0)];
_CPMenuItemDefaultStateImages[CPMixedState] = nil;
_CPMenuItemDefaultStateHighlightedImages[CPMixedState] = nil;
return "menu-item-view";
}
+ (float)leftMargin
+ (id)themeAttributes
{
return LEFT_MARGIN + STATE_COLUMN_WIDTH;
return [CPDictionary dictionaryWithObjects:[]
forKeys:[]];
}
// Not used in the Appkit
// + (float)leftMargin
// {
// return LEFT_MARGIN + STATE_COLUMN_WIDTH;
// }
- (id)initWithFrame:(CGRect)aFrame forMenuItem:(CPMenuItem)aMenuItem
{
self = [super initWithFrame:aFrame];
@@ -176,7 +184,7 @@ var _CPMenuItemSelectionColor = nil,
- (void)setFont:(CPFont)aFont
{
if (_font === aFont)
if ([_font isEqual:aFont])
return;
_font = aFont;
+16 -10
View File
@@ -24,6 +24,7 @@
@import <Foundation/CPCountedSet.j>
@import "CPController.j"
@import "CPKeyValueBinding.j"
/*!
@class
@@ -51,6 +52,9 @@
+ (id)initialize
{
if (self !== [CPObjectController class])
return;
[self exposeBinding:@"editable"];
[self exposeBinding:@"contentObject"];
}
@@ -131,8 +135,8 @@
_contentObject = aContent;
[self didChangeValueForKey:@"contentObject"];
[self _selectionDidChange];
[self didChangeValueForKey:@"contentObject"];
}
/*!
@@ -371,7 +375,7 @@ var CPObjectControllerContentKey = @"CPObjectControllerCo
[self setObjectClass:objectClass || [CPMutableDictionary class]];
[self setEditable:[aCoder decodeBoolForKey:CPObjectControllerIsEditableKey]];
[self setAutomaticallyPreparesContent:[aCoder decodeBoolForKey:CPObjectControllerAutomaticallyPreparesContentKey] || NO];
[self setAutomaticallyPreparesContent:[aCoder decodeBoolForKey:CPObjectControllerAutomaticallyPreparesContentKey]];
[self setContent:[aCoder decodeObjectForKey:CPObjectControllerContentKey]];
_observedKeys = [[CPCountedSet alloc] init];
@@ -579,6 +583,8 @@ var CPObjectControllerContentKey = @"CPObjectControllerCo
- (void)removeObjectAtIndex:(unsigned)anIndex
{
var currentObject = [self objectAtIndex:anIndex];
for (var i = 0, count = [_observationProxies count]; i < count; i++)
{
var proxy = [_observationProxies objectAtIndex:i],
@@ -588,7 +594,7 @@ var CPObjectControllerContentKey = @"CPObjectControllerCo
if (operator)
[self willChangeValueForKey:keyPath];
[anObject removeObserver:proxy forKeyPath:keyPath];
[currentObject removeObserver:proxy forKeyPath:keyPath];
if (operator)
[self didChangeValueForKey:keyPath];
@@ -663,7 +669,8 @@ var CPObjectControllerContentKey = @"CPObjectControllerCo
- (id)_controllerMarkerForValues:(CPArray)theValues
{
var count = [theValues count];
var count = [theValues count],
value;
if (!count)
value = CPNoSelectionMarker;
@@ -677,7 +684,7 @@ var CPObjectControllerContentKey = @"CPObjectControllerCo
{
value = [theValues objectAtIndex:0];
for (var i = 0, count= [theValues count]; i < count && value != CPMultipleValuesMarker; i++)
for (var i = 0, count = [theValues count]; i < count && value != CPMultipleValuesMarker; i++)
{
if (![value isEqual:[theValues objectAtIndex:i]])
value = CPMultipleValuesMarker;
@@ -693,8 +700,8 @@ var CPObjectControllerContentKey = @"CPObjectControllerCo
- (id)valueForKeyPath:(CPString)theKeyPath
{
var values = [[_controller selectedObjects] valueForKeyPath:theKeyPath];
value = [self _controllerMarkerForValues:values];
var values = [[_controller selectedObjects] valueForKeyPath:theKeyPath],
value = [self _controllerMarkerForValues:values];
[_cachedValues setObject:value forKey:theKeyPath];
@@ -776,8 +783,7 @@ var CPObjectControllerContentKey = @"CPObjectControllerCo
[proxy setNotifyObject:YES];
[_observationProxies addObject:proxy];
// We keep are reference to the observed objects
// because the removeObserver: will be called after the selection changes
// We keep a reference to the observed objects because removeObserver: will be called after the selection changes.
var observedObjects = [_controller selectedObjects];
_observedObjectsByKeyPath[aKeyPath] = observedObjects;
[observedObjects addObserver:proxy forKeyPath:aKeyPath options:options context:context];
@@ -793,7 +799,7 @@ var CPObjectControllerContentKey = @"CPObjectControllerCo
[_observationProxies removeObjectAtIndex:index];
_observedObjects = nil;
_observedObjectsByKeyPath[aKeyPath] = nil;
}
@end
+2 -2
View File
@@ -47,9 +47,9 @@
var options = { directoryURL: [self directoryURL],
canChooseFiles: [self canChooseFiles],
canChooseDirectories: [self canChooseDirectories],
allowsMultipleSelection: [self allowsMultipleSelection] };
allowsMultipleSelection: [self allowsMultipleSelection] },
var result = window.cpOpenPanel(options);
result = window.cpOpenPanel(options);
_URLs = result.URLs;
+102 -58
View File
@@ -20,9 +20,11 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "CPButton.j"
@import "CPTableColumn.j"
@import "CPTableView.j"
@global CPApp
CPOutlineViewColumnDidMoveNotification = @"CPOutlineViewColumnDidMoveNotification";
CPOutlineViewColumnDidResizeNotification = @"CPOutlineViewColumnDidResizeNotification";
@@ -62,7 +64,7 @@ var CPOutlineViewDelegate_outlineView_dataViewForTableColumn_item_
CPOutlineViewDelegate_outlineView_shouldReorderColumn_toColumn_ = 1 << 12,
CPOutlineViewDelegate_outlineView_shouldSelectItem_ = 1 << 13,
CPOutlineViewDelegate_outlineView_shouldSelectTableColumn_ = 1 << 14,
CPOutlineViewDelegate_outlineView_shouldShowOutlineViewForItem_ = 1 << 15,
CPOutlineViewDelegate_outlineView_shouldShowOutlineDisclosureControlForItem_ = 1 << 15,
CPOutlineViewDelegate_outlineView_shouldShowViewExpansionForTableColumn_item_ = 1 << 16,
CPOutlineViewDelegate_outlineView_shouldTrackView_forTableColumn_item_ = 1 << 17,
CPOutlineViewDelegate_outlineView_shouldTypeSelectForEvent_withCurrentSearchString_ = 1 << 18,
@@ -80,6 +82,10 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
CPOutlineViewCoalesceSelectionNotificationStateOn = 1,
CPOutlineViewCoalesceSelectionNotificationStateDid = 2;
#define SELECTION_SHOULD_CHANGE(anOutlineView) (!((anOutlineView)._implementedOutlineViewDelegateMethods & CPOutlineViewDelegate_selectionShouldChangeInOutlineView_) || [(anOutlineView)._outlineViewDelegate selectionShouldChangeInOutlineView:(anOutlineView)])
#define SHOULD_SELECT_ITEM(anOutlineView, anItem) (!((anOutlineView)._implementedOutlineViewDelegateMethods & CPOutlineViewDelegate_outlineView_shouldSelectItem_) || [(anOutlineView)._outlineViewDelegate outlineView:(anOutlineView) shouldSelectItem:(anItem)])
/*!
@ingroup appkit
@class CPOutlineView
@@ -136,7 +142,7 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
_selectionHighlightStyle = CPTableViewSelectionHighlightStyleSourceList;
// The root item has weight "0", thus represents the weight solely of its descendants.
_rootItemInfo = { isExpanded:YES, isExpandable:NO, level:-1, row:-1, children:[], weight:0 };
_rootItemInfo = { isExpanded:YES, isExpandable:NO, shouldShowOutlineDisclosureControl:NO, level:-1, row:-1, children:[], weight:0 };
_itemsForRows = [];
_itemInfosForItems = { };
@@ -147,7 +153,6 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
_retargedChildIndex = nil;
_shouldRetargetChildIndex = NO;
_startHoverTime = nil;
[self setIndentationPerLevel:16.0];
[self setIndentationMarkerFollowsDataView:YES];
@@ -294,6 +299,19 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
return itemInfo.isExpandable;
}
- (BOOL)_shouldShowOutlineDisclosureControlForItem:(id)anItem
{
if (!anItem)
return YES;
var itemInfo = _itemInfosForItems[[anItem UID]];
if (!itemInfo)
return YES;
return itemInfo.shouldShowOutlineDisclosureControl;
}
/*!
Used to find if an item is already expanded.
@@ -360,9 +378,8 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
var previousRowCount = [self numberOfRows];
itemInfo.isExpanded = YES;
// XXX Shouldn't the items reload before the notification is sent?
[self _noteItemDidExpand:anItem];
[self reloadItem:anItem reloadChildren:YES];
[self _noteItemDidExpand:anItem];
// Shift selection indexes below so that the same items remain selected.
var rowCountDelta = [self numberOfRows] - previousRowCount;
@@ -453,9 +470,8 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
}
itemInfo.isExpanded = NO;
// XXX Shouldn't the items reload before the notification is sent?
[self _noteItemDidCollapse:anItem];
[self reloadItem:anItem reloadChildren:YES];
[self _noteItemDidCollapse:anItem];
// Send selection notifications only after the items have loaded so that
// the new selection is consistent with the actual rows for any observers.
@@ -690,11 +706,13 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
*/
- (CGRect)frameOfOutlineDisclosureControlAtRow:(CPInteger)aRow
{
if (![self isExpandable:[self itemAtRow:aRow]])
var theItem = [self itemAtRow:aRow];
if (![self isExpandable:theItem] || ![self _shouldShowOutlineDisclosureControlForItem:theItem])
return _CGRectMakeZero();
var dataViewFrame = [self _frameOfOutlineDataViewAtRow:aRow],
frame = _CGRectMake(_CGRectGetMinX(dataViewFrame) - 10, _CGRectGetMinY(dataViewFrame), 10, _CGRectGetHeight(dataViewFrame));
disclosureWidth = _CGRectGetWidth([_disclosureControlPrototype frame]),
frame = _CGRectMake(_CGRectGetMinX(dataViewFrame) - disclosureWidth, _CGRectGetMinY(dataViewFrame), disclosureWidth, _CGRectGetHeight(dataViewFrame));
return frame;
}
@@ -822,29 +840,24 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
name:CPOutlineViewSelectionIsChangingNotification
object:self];
if ([_outlineViewDelegate respondsToSelector:@selector(outlineViewItemWillExpand:)])
[defaultCenter
removeObserver:_outlineViewDelegate
name:CPOutlineViewItemWillExpandNotification
object:self];
if ([_outlineViewDelegate respondsToSelector:@selector(outlineViewItemDidExpand:)])
[defaultCenter
removeObserver:_outlineViewDelegate
name:CPOutlineViewItemDidExpandNotification
object:self];
if ([_outlineViewDelegate respondsToSelector:@selector(outlineViewItemWillCollapse:)])
[defaultCenter
removeObserver:_outlineViewDelegate
name:CPOutlineViewItemWillCollapseNotification
object:self];
if ([_outlineViewDelegate respondsToSelector:@selector(outlineViewItemDidCollapse:)])
[defaultCenter
removeObserver:_outlineViewDelegate
@@ -870,7 +883,7 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
CPOutlineViewDelegate_outlineView_shouldReorderColumn_toColumn_ , @selector(outlineView:shouldReorderColumn:toColumn:),
CPOutlineViewDelegate_outlineView_shouldSelectItem_ , @selector(outlineView:shouldSelectItem:),
CPOutlineViewDelegate_outlineView_shouldSelectTableColumn_ , @selector(outlineView:shouldSelectTableColumn:),
CPOutlineViewDelegate_outlineView_shouldShowOutlineViewForItem_ , @selector(outlineView:shouldShowOutlineViewForItem:),
CPOutlineViewDelegate_outlineView_shouldShowOutlineDisclosureControlForItem_ , @selector(outlineView:shouldShowOutlineDisclosureControlForItem:),
CPOutlineViewDelegate_outlineView_shouldShowViewExpansionForTableColumn_item_ , @selector(outlineView:shouldShowViewExpansionForTableColumn:item:),
CPOutlineViewDelegate_outlineView_shouldTrackView_forTableColumn_item_ , @selector(outlineView:shouldTrackView:forTableColumn:item:),
CPOutlineViewDelegate_outlineView_shouldTypeSelectForEvent_withCurrentSearchString_ , @selector(outlineView:shouldTypeSelectForEvent:withCurrentSearchString:),
@@ -921,7 +934,6 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
name:CPOutlineViewSelectionIsChangingNotification
object:self];
if ([_outlineViewDelegate respondsToSelector:@selector(outlineViewItemWillExpand:)])
[defaultCenter
addObserver:_outlineViewDelegate
@@ -984,7 +996,7 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
_disclosureControlData = nil;
_disclosureControlQueue = [];
// fIXME: really?
// FIXME: really?
[self reloadData];
}
@@ -1042,11 +1054,12 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
@ignore
We need to offset the dataview and add the disclosure triangle.
*/
- (CPView)_dragViewForColumn:(int)theColumnIndex event:(CPEvent)theDragEvent offset:(CPPointPointer)theDragViewOffset
- (CPView)_dragViewForColumn:(int)theColumnIndex event:(CPEvent)theDragEvent offset:(CGPoint)theDragViewOffset
{
var dragView = [[_CPColumnDragView alloc] initWithLineColor:[self gridColor]],
tableColumn = [[self tableColumns] objectAtIndex:theColumnIndex],
bounds = _CGRectMake(0.0, 0.0, [tableColumn width], _CGRectGetHeight([self exposedRect]) + 23.0),
defaultRowHeight = [self valueForThemeAttribute:@"default-row-height"],
bounds = _CGRectMake(0.0, 0.0, [tableColumn width], _CGRectGetHeight([self exposedRect]) + defaultRowHeight),
columnRect = [self rectOfColumn:theColumnIndex],
headerView = [tableColumn headerView],
row = [_exposedRows firstIndex];
@@ -1060,7 +1073,7 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
dataViewFrame.origin.x = 0.0;
// Offset by table header height - scroll position
dataViewFrame.origin.y = ( _CGRectGetMinY(dataViewFrame) - _CGRectGetMinY([self exposedRect]) ) + 23.0;
dataViewFrame.origin.y = ( _CGRectGetMinY(dataViewFrame) - _CGRectGetMinY([self exposedRect]) ) + defaultRowHeight;
[dataView setFrame:dataViewFrame];
[dataView setObjectValue:[self _objectValueForTableColumn:tableColumn row:row]];
@@ -1120,13 +1133,14 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
if (_dragHoverTimer)
[_dragHoverTimer invalidate];
var autoExpandCallBack = function(){
var autoExpandCallBack = function()
{
if (_dropItem)
{
[_dropOperationFeedbackView blink];
[CPTimer scheduledTimerWithTimeInterval:.3 callback:objj_msgSend(self, "expandItem:", _dropItem) repeats:NO];
}
}
};
_dragHoverTimer = [CPTimer scheduledTimerWithTimeInterval:.8 callback:autoExpandCallBack repeats:NO];
}
@@ -1173,7 +1187,7 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
/*!
@ignore
*/
- (id)_parentItemForUpperRow:(int)theUpperRowIndex andLowerRow:(int)theLowerRowIndex atMouseOffset:(CPPoint)theOffset
- (id)_parentItemForUpperRow:(int)theUpperRowIndex andLowerRow:(int)theLowerRowIndex atMouseOffset:(CGPoint)theOffset
{
if (_shouldRetargetItem)
return _retargetedItem;
@@ -1203,7 +1217,7 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
/*!
@ignore
*/
- (CPRect)_rectForDropHighlightViewBetweenUpperRow:(int)theUpperRowIndex andLowerRow:(int)theLowerRowIndex offset:(CPPoint)theOffset
- (CGRect)_rectForDropHighlightViewBetweenUpperRow:(int)theUpperRowIndex andLowerRow:(int)theLowerRowIndex offset:(CGPoint)theOffset
{
// Call super and the update x to reflect the current indentation level
var rect = [super _rectForDropHighlightViewBetweenUpperRow:theUpperRowIndex andLowerRow:theLowerRowIndex offset:theOffset],
@@ -1284,7 +1298,12 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
item = _itemsForRows[row],
isExpandable = [self isExpandable:item];
if (!isExpandable)
if (!isExpandable)
continue;
var disclosureControlFrame = [self frameOfOutlineDisclosureControlAtRow:row];
if (_CGRectIsEmpty(disclosureControlFrame))
continue;
var control = [self _dequeueDisclosureControl];
@@ -1294,7 +1313,7 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
[control setState:[self isItemExpanded:item] ? CPOnState : CPOffState];
var selector = [self isRowSelected:row] ? @"setThemeState:" : @"unsetThemeState:";
[control performSelector:CPSelectorFromString(selector) withObject:CPThemeStateSelected];
[control setFrame:[self frameOfOutlineDisclosureControlAtRow:row]];
[control setFrame:disclosureControlFrame];
[self addSubview:control];
}
@@ -1347,7 +1366,7 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
[self collapseItem:item];
else
[self expandItem:item];
[self expandItem:item expandChildren:([[CPApp currentEvent] modifierFlags] & CPAlternateKeyMask)];
}
/*!
@@ -1458,7 +1477,6 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
userInfo:[CPDictionary dictionaryWithObject:item forKey:"CPObject"]];
}
- (void)keyDown:(CPEvent)anEvent
{
var character = [anEvent charactersIgnoringModifiers],
@@ -1467,7 +1485,7 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
// Check for the key events manually, as opposed to waiting for CPWindow to sent the actual action message
// in _processKeyboardUIKey:, because we might not want to handle the arrow events.
if (character !== CPRightArrowFunctionKey && character !== CPLeftArrowFunctionKey)
if (character !== CPRightArrowFunctionKey && character !== CPLeftArrowFunctionKey)
return [super keyDown:anEvent];
var rows = [self selectedRowIndexes],
@@ -1481,7 +1499,6 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
for (; i < c; i++)
items.push([self itemAtRow:indexes[i]]);
if (character === CPRightArrowFunctionKey)
{
@@ -1490,12 +1507,32 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
}
else if (character === CPLeftArrowFunctionKey)
{
// When a single, collapsed item is selected and the left arrow key is pressed, the parent
// should be selected if possible.
if (c == 1)
{
var theItem = items[0];
if (![self isItemExpanded:theItem])
{
var parent = [self parentForItem:theItem],
shouldSelect = parent && SELECTION_SHOULD_CHANGE(self) && SHOULD_SELECT_ITEM(self, parent);
if (shouldSelect)
{
var rowIndex = [self rowForItem:parent];
[self selectRowIndexes:[CPIndexSet indexSetWithIndex:rowIndex] byExtendingSelection:NO];
[self scrollRowToVisible:rowIndex];
return;
}
}
}
for (var i = 0; i < c; i++)
[self collapseItem:items[i]];
[self collapseItem:items[i]];
}
[super keyDown:anEvent];
}
@end
// FIX ME: We're using with() here because Safari fails if we use anOutlineView._itemInfosForItems or whatever...
@@ -1534,8 +1571,9 @@ var _reloadItem = function(/*CPOutlineView*/ anOutlineView, /*id*/ anItem)
itemInfo.isExpandable = [dataSource outlineView:anOutlineView isItemExpandable:newItem];
itemInfo.isExpanded = itemInfo.isExpandable && itemInfo.isExpanded;
itemInfo.shouldShowOutlineDisclosureControl = !(_implementedOutlineViewDelegateMethods & CPOutlineViewDelegate_outlineView_shouldShowOutlineDisclosureControlForItem_) || [_outlineViewDelegate outlineView:self shouldShowOutlineDisclosureControlForItem:newItem];
}
}
};
// FIX ME: We're using with() here because Safari fails if we use anOutlineView._itemInfosForItems or whatever...
var _loadItemInfoForItem = function(/*CPOutlineView*/ anOutlineView, /*id*/ anItem, /*BOOL*/ isIntermediate)
@@ -1559,6 +1597,7 @@ var _loadItemInfoForItem = function(/*CPOutlineView*/ anOutlineView, /*id*/ anIt
return [];
itemInfo.isExpandable = [dataSource outlineView:anOutlineView isItemExpandable:anItem];
itemInfo.shouldShowOutlineDisclosureControl = !(_implementedOutlineViewDelegateMethods & CPOutlineViewDelegate_outlineView_shouldShowOutlineDisclosureControlForItem_) || [_outlineViewDelegate outlineView:self shouldShowOutlineDisclosureControlForItem:anItem];
// If we were previously expanded, but now no longer expandable, "de-expand".
// NOTE: we are *not* collapsing, thus no notification is posted.
@@ -1589,7 +1628,7 @@ var _loadItemInfoForItem = function(/*CPOutlineView*/ anOutlineView, /*id*/ anIt
if (!childItemInfo)
{
childItemInfo = { isExpanded:NO, isExpandable:NO, children:[], weight:1 };
childItemInfo = { isExpanded:NO, isExpandable:NO, shouldShowOutlineDisclosureControl:YES, children:[], weight:1 };
itemInfosForItems[[childItem UID]] = childItemInfo;
}
@@ -1640,7 +1679,7 @@ var _loadItemInfoForItem = function(/*CPOutlineView*/ anOutlineView, /*id*/ anIt
}
}//end of with
return descendants;
}
};
@implementation _CPOutlineViewTableViewDataSource : CPObject
{
@@ -1691,7 +1730,7 @@ var _loadItemInfoForItem = function(/*CPOutlineView*/ anOutlineView, /*id*/ anIt
return [_outlineView._outlineViewDataSource outlineView:_outlineView writeItems:items toPasteboard:thePasteboard];
}
- (int)_childIndexForDropOperation:(CPTableViewDropOperation)theDropOperation row:(int)theRow offset:(CPPoint)theOffset
- (int)_childIndexForDropOperation:(CPTableViewDropOperation)theDropOperation row:(int)theRow offset:(CGPoint)theOffset
{
if (_outlineView._shouldRetargetChildIndex)
return _outlineView._retargedChildIndex;
@@ -1715,7 +1754,7 @@ var _loadItemInfoForItem = function(/*CPOutlineView*/ anOutlineView, /*id*/ anIt
return childIndex;
}
- (void)_parentItemForDropOperation:(CPTableViewDropOperation)theDropOperation row:(int)theRow offset:(CPPoint)theOffset
- (void)_parentItemForDropOperation:(CPTableViewDropOperation)theDropOperation row:(int)theRow offset:(CGPoint)theOffset
{
if (theDropOperation === CPTableViewDropAbove)
return [_outlineView _parentItemForUpperRow:theRow - 1 andLowerRow:theRow atMouseOffset:theOffset]
@@ -1792,9 +1831,9 @@ var _loadItemInfoForItem = function(/*CPOutlineView*/ anOutlineView, /*id*/ anIt
var dataView = nil;
if ((_outlineView._implementedOutlineViewDelegateMethods & CPOutlineViewDelegate_outlineView_dataViewForTableColumn_item_))
dataView = [_outlineView._outlineViewDelegate outlineView:_outlineView
dataViewForTableColumn:theTableColumn
item:[_outlineView itemAtRow:theRow]];
dataView = [_outlineView._outlineViewDelegate outlineView:_outlineView
dataViewForTableColumn:theTableColumn
item:[_outlineView itemAtRow:theRow]];
if (!dataView)
dataView = [theTableColumn dataViewForRow:theRow];
@@ -1804,10 +1843,12 @@ var _loadItemInfoForItem = function(/*CPOutlineView*/ anOutlineView, /*id*/ anIt
- (BOOL)tableView:(CPTableView)theTableView shouldSelectRow:(int)theRow
{
if ((_outlineView._implementedOutlineViewDelegateMethods & CPOutlineViewDelegate_outlineView_shouldSelectItem_))
return [_outlineView._outlineViewDelegate outlineView:_outlineView shouldSelectItem:[_outlineView itemAtRow:theRow]];
return SHOULD_SELECT_ITEM(_outlineView, [_outlineView itemAtRow:theRow]);
}
return YES;
- (BOOL)selectionShouldChangeInTableView:(CPTableView)theTableView
{
return SELECTION_SHOULD_CHANGE(_outlineView);
}
- (BOOL)tableView:(CPTableView)aTableView shouldEditTableColumn:(CPTableColumn)aColumn row:(int)aRow
@@ -1851,7 +1892,9 @@ var _loadItemInfoForItem = function(/*CPOutlineView*/ anOutlineView, /*id*/ anIt
return [_outlineView._outlineViewDelegate outlineView:_outlineView menuForTableColumn:aTableColumn item:item]
}
return nil;
// We reimplement CPView menuForEvent: because we can't call it directly. CPTableView implements menuForEvent:
// to call this delegate method.
return [_outlineView menu] || [[_outlineView class] defaultMenu];
}
@end
@@ -1885,16 +1928,22 @@ var _loadItemInfoForItem = function(/*CPOutlineView*/ anOutlineView, /*id*/ anIt
- (void)drawRect:(CGRect)aRect
{
var bounds = [self bounds],
context = [[CPGraphicsContext currentContext] graphicsPort];
context = [[CPGraphicsContext currentContext] graphicsPort],
width = _CGRectGetWidth(bounds),
height = _CGRectGetHeight(bounds);
CGContextBeginPath(context);
CGContextTranslateCTM(context, _CGRectGetWidth(bounds) / 2.0, _CGRectGetHeight(bounds) / 2.0);
CGContextRotateCTM(context, _angle);
CGContextTranslateCTM(context, -_CGRectGetWidth(bounds) / 2.0, -_CGRectGetHeight(bounds) / 2.0);
if (_angle)
{
var centre = _CGPointMake(FLOOR(width / 2.0), FLOOR(height / 2.0));
CGContextTranslateCTM(context, centre.x, centre.y);
CGContextRotateCTM(context, _angle);
CGContextTranslateCTM(context, -centre.x, -centre.y);
}
// Center, but crisp.
CGContextTranslateCTM(context, FLOOR((_CGRectGetWidth(bounds) - 9.0) / 2.0), FLOOR((_CGRectGetHeight(bounds) - 8.0) / 2.0));
CGContextTranslateCTM(context, FLOOR((width - 9.0) / 2.0), FLOOR((height - 8.0) / 2.0));
CGContextMoveToPoint(context, 0.0, 0.0);
CGContextAddLineToPoint(context, 9.0, 0.0);
@@ -1907,20 +1956,14 @@ var _loadItemInfoForItem = function(/*CPOutlineView*/ anOutlineView, /*id*/ anIt
[self hasThemeState:CPThemeStateHighlighted]));
CGContextFillPath(context);
CGContextBeginPath(context);
CGContextMoveToPoint(context, 0.0, 0.0);
CGContextAddLineToPoint(context, 4.5, 8.0);
if (_angle === 0.0)
{
CGContextAddLineToPoint(context, 4.5, 8.0);
CGContextAddLineToPoint(context, 9.0, 0.0);
}
else
CGContextAddLineToPoint(context, 4.5, 8.0);
CGContextSetStrokeColor(context, [CPColor colorWithCalibratedWhite:1.0 alpha: 0.8]);
CGContextSetStrokeColor(context, [CPColor colorWithCalibratedWhite:1.0 alpha: 0.7]);
CGContextStrokePath(context);
}
@@ -1984,7 +2027,8 @@ var CPOutlineViewIndentationPerLevelKey = @"CPOutlineViewIndentationPerLevelKey"
@end
var colorForDisclosureTriangle = function(isSelected, isHighlighted) {
var colorForDisclosureTriangle = function(isSelected, isHighlighted)
{
return isSelected
? (isHighlighted
? [CPColor colorWithCalibratedWhite:0.9 alpha: 1.0]
@@ -1992,4 +2036,4 @@ var colorForDisclosureTriangle = function(isSelected, isHighlighted) {
: (isHighlighted
? [CPColor colorWithCalibratedWhite:0.4 alpha: 1.0]
: [CPColor colorWithCalibratedWhite:0.5 alpha: 1.0]);
}
};
+5
View File
@@ -114,4 +114,9 @@ CPDocModalWindowMask = 1 << 6;
return NO;
}
- (BOOL)canBecomeKeyWindow
{
return YES;
}
@end
+3 -2
View File
@@ -22,6 +22,7 @@
@import <Foundation/CPObject.j>
@import <Foundation/CPArray.j>
@import <Foundation/CPData.j>
@import <Foundation/CPDictionary.j>
@import <Foundation/CPPropertyListSerialization.j>
@@ -73,7 +74,7 @@ var CPPasteboards = nil,
*/
+ (void)initialize
{
if (self != [CPPasteboard class])
if (self !== [CPPasteboard class])
return;
[self setVersion:1.0];
@@ -117,7 +118,7 @@ var CPPasteboards = nil,
if (self)
{
_name = aName;
// _name = aName;
_types = [];
_owners = [CPDictionary dictionary];
+296 -23
View File
@@ -20,12 +20,12 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "CGGeometry.j"
@import "CPButton.j"
@import "CPGeometry.j"
@import "CPKeyValueBinding.j"
@import "CPMenu.j"
@import "CPMenuItem.j"
var VISIBLE_MARGIN = 7.0;
CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
@@ -86,7 +86,7 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
[self setPullsDown:shouldPullDown];
var options = CPKeyValueObservingOptionNew |CPKeyValueObservingOptionOld;/* |CPKeyValueObservingOptionInitial;*/
var options = CPKeyValueObservingOptionNew | CPKeyValueObservingOptionOld; // | CPKeyValueObservingOptionInitial;
[self addObserver:self forKeyPath:@"menu.items" options:options context:nil];
[self addObserver:self forKeyPath:@"_firstItem.changeCount" options:options context:nil];
[self addObserver:self forKeyPath:@"selectedItem.changeCount" options:options context:nil];
@@ -193,6 +193,7 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
- (void)removeAllItems
{
[[self menu] removeAllItems];
[self synchronizeTitleAndSelectedItem];
}
/*!
@@ -245,22 +246,6 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
return _selectedIndex;
}
/*!
@ignore
*/
- (int)selectedTag
{
return [[self selectedItem] tag];
}
/*!
@ignore
*/
- (void)_setSelectedTag:(int)aTag
{
[self selectItemWithTag:aTag];
}
// Setting the Current Selection
/*!
Selects the specified menu item.
@@ -586,10 +571,18 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
if ([indexes containsIndex:0] && [self pullsDown])
[self _firstItemDidChange];
// See whether the index has changed, despite the actual item not changing.
while ((index = [indexes indexGreaterThanIndex:index]) !== CPNotFound &&
index <= indexOfSelectedItem)
--indexOfSelectedItem;
if (![self pullsDown] && [indexes containsIndex:indexOfSelectedItem])
{
// If the selected item is removed the first item becomes selected.
indexOfSelectedItem = 0;
}
else
{
// See whether the index has changed, despite the actual item not changing.
while ((index = [indexes indexGreaterThanIndex:index]) !== CPNotFound &&
index <= indexOfSelectedItem)
--indexOfSelectedItem;
}
[self selectItemAtIndex:indexOfSelectedItem];
}
@@ -775,6 +768,286 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
[[self selectedItem] setState:CPOffState];
}
- (void)_reverseSetBinding
{
[_CPPopUpButtonSelectionBinder reverseSetValueForObject:self];
[super _reverseSetBinding];
}
@end
@implementation CPPopUpButton (BindingSupport)
+ (Class)_binderClassForBinding:(CPString)aBinding
{
if (aBinding == CPSelectedIndexBinding ||
aBinding == CPSelectedObjectBinding ||
aBinding == CPSelectedTagBinding ||
aBinding == CPSelectedValueBinding ||
aBinding == CPContentBinding ||
aBinding == CPContentObjectsBinding ||
aBinding == CPContentValuesBinding)
{
var capitalizedBinding = aBinding.charAt(0).toUpperCase() + aBinding.substr(1);
return [CPClassFromString(@"_CPPopUpButton" + capitalizedBinding + "Binder") class];
}
return [super _binderClassForBinding:aBinding];
}
@end
@implementation _CPPopUpButtonContentBinder : CPBinder
{
}
- (CPInteger)_getInsertNullOffset
{
var options = [_info objectForKey:CPOptionsKey];
return [options objectForKey:CPInsertsNullPlaceholderBindingOption] ? 1 : 0;
}
- (CPString)_getNullPlaceholder
{
var options = [_info objectForKey:CPOptionsKey],
placeholder = [options objectForKey:CPNullPlaceholderBindingOption] || @"";
if (placeholder === [CPNull null])
placeholder = @"";
return placeholder;
}
- (id)transformValue:(CPArray)contentArray withOptions:(CPDictionary)options
{
// Desactivate the full array transformation forced by super because we don't want this. We want individual transformations (see below).
return contentArray;
}
- (void)setValue:(CPArray)contentArray forBinding:(CPString)aBinding
{
[self _setContent:contentArray];
[self _setContentValuesIfNeeded:contentArray];
}
- (void)valueForBinding:(CPString)aBinding
{
return [self _content];
}
- (void)_setContent:(CPArray)aValue
{
var count = [aValue count],
options = [_info objectForKey:CPOptionsKey],
offset = [self _getInsertNullOffset];
if (count + offset != [_source numberOfItems])
{
[_source removeAllItems];
if (offset)
[_source addItemWithTitle:[self _getNullPlaceholder]];
for (var i = 0; i < count; i++)
{
var item = [[CPMenuItem alloc] initWithTitle:@"" action:NULL keyEquivalent:nil];
[self _setValue:[aValue objectAtIndex:i] forItem:item withOptions:options];
[_source addItem:item];
}
}
else
{
for (var i = 0; i < count; i++)
{
[self _setValue:[aValue objectAtIndex:i] forItem:[_source itemAtIndex:i + offset] withOptions:options];
}
}
}
- (void)_setContentValuesIfNeeded:(CPArray)values
{
var offset = [self _getInsertNullOffset];
if (![_source infoForBinding:CPContentValuesBinding])
{
if (offset)
[[_source itemAtIndex:0] setTitle:[self _getNullPlaceholder]];
var count = [values count];
for (var i = 0; i < count; i++)
[[_source itemAtIndex:i + offset] setTitle:[[values objectAtIndex:i] description]];
}
}
- (void)_setValue:(id)aValue forItem:(CPMenuItem)aMenuItem withOptions:(CPDictionary)options
{
var value = [self _transformValue:aValue withOptions:options];
[aMenuItem setRepresentedObject:value];
}
- (id)_transformValue:(id)aValue withOptions:(CPDictionary)options
{
return [super transformValue:aValue withOptions:options];
}
- (CPArray)_content
{
return [_source valueForKeyPath:@"itemArray.representedObject"];
}
@end
@implementation _CPPopUpButtonContentValuesBinder : _CPPopUpButtonContentBinder
{
}
- (void)setValue:(id)aValue forBinding:(CPString)aBinding
{
[super _setContent:aValue];
}
- (void)_setValue:(id)aValue forItem:(CPMenuItem)aMenuItem withOptions:(CPDictionary)options
{
if (aValue === [CPNull null])
aValue = nil;
var value = [self _transformValue:aValue withOptions:options];
[aMenuItem setTitle:value];
}
- (CPArray)_content
{
return [_source valueForKeyPath:@"itemArray.title"];
}
@end
var binderForObject = {};
@implementation _CPPopUpButtonSelectionBinder : CPBinder
{
CPString _selectionBinding @accessors;
}
- (id)initWithBinding:(CPString)aBinding name:(CPString)aName to:(id)aDestination keyPath:(CPString)aKeyPath options:(CPDictionary)options from:(id)aSource
{
self = [super initWithBinding:aBinding name:aName to:aDestination keyPath:aKeyPath options:options from:aSource];
if (self)
{
binderForObject[[aSource UID]] = self;
_selectionBinding = aName;
}
return self;
}
+ (void)reverseSetValueForObject:(id)aSource
{
var binder = binderForObject[[aSource UID]];
[binder reverseSetValueFor:[binder _selectionBinding]];
}
- (void)setPlaceholderValue:(id)aValue withMarker:(CPString)aMarker forBinding:(CPString)aBinding
{
[self setValue:aValue forBinding:aBinding];
}
- (CPInteger)_getInsertNullOffset
{
var options = [[CPBinder infoForBinding:CPContentBinding forObject:_source] objectForKey:CPOptionsKey];
return [options objectForKey:CPInsertsNullPlaceholderBindingOption] ? 1 : 0;
}
@end
@implementation _CPPopUpButtonSelectedIndexBinder : _CPPopUpButtonSelectionBinder
{
}
- (void)setValue:(id)aValue forBinding:(CPString)aBinding
{
[_source selectItemAtIndex:aValue + [self _getInsertNullOffset]];
}
- (id)valueForBinding:(CPString)aBinding
{
return [_source indexOfSelectedItem] - [self _getInsertNullOffset];
}
@end
@implementation _CPPopUpButtonSelectedObjectBinder : _CPPopUpButtonSelectionBinder
{
}
- (void)setValue:(id)aValue forBinding:(CPString)aBinding
{
var index = [_source indexOfItemWithRepresentedObject:aValue],
offset = [self _getInsertNullOffset];
// If the content binding has the option CPNullPlaceholderBindingOption and the object to select is nil, select the first item (i.e., the placeholder).
// Other cases to consider:
// 1. no binding:
// 1.1 there's no item with a represented object matching the object to select.
// 1.2 the object to select is nil/CPNull
// 2. there's a binding:
// 2.1 there's a CPNullPlaceholderBindingOption:
// 2.1.1 there's no item with a represented object matching the object to select?
// 2.1.2 the object to select is nil/CPNull
// 2.2 there's no CPNullPlaceholderBindingOption:
// 2.2.1 there's no item with a represented object matching the object to select?
// 2.2.2 the object to select is nil/CPNull
// More cases? Behaviour that depends on array controller settings?
if (offset === 1 && index === CPNotFound)
index = 0;
[_source selectItemAtIndex:index];
}
- (id)valueForBinding:(CPString)aBinding
{
return [[_source selectedItem] representedObject];
}
@end
@implementation _CPPopUpButtonSelectedTagBinder : _CPPopUpButtonSelectionBinder
{
}
- (void)setValue:(id)aValue forBinding:(CPString)aBinding
{
[_source selectItemWithTag:aValue];
}
- (id)valueForBinding:(CPString)aBinding
{
return [[_source selectedItem] tag];
}
@end
@implementation _CPPopUpButtonSelectedValueBinder : _CPPopUpButtonSelectionBinder
{
}
- (void)setValue:(id)aValue forBinding:(CPString)aBinding
{
[_source selectItemWithTitle:aValue];
}
- (id)valueForBinding:(CPString)aBinding
{
return [_source titleOfSelectedItem];
}
@end
var DEPRECATED_CPPopUpButtonMenuKey = @"CPPopUpButtonMenuKey",
+153 -90
View File
@@ -28,33 +28,35 @@
@import "CPImageView.j"
@import "CPResponder.j"
@import "CPView.j"
@import "_CPAttachedWindow.j"
@import "_CPPopoverWindow.j"
CPPopoverBehaviorApplicationDefined = 0;
CPPopoverBehaviorTransient = 1;
CPPopoverBehaviorSemitransient = 2;
var CPPopoverDelegate_popover_willShow_ = 1 << 0,
CPPopoverDelegate_popover_didShow_ = 1 << 1,
CPPopoverDelegate_popover_shouldClose_ = 1 << 2,
CPPopoverDelegate_popover_willClose_ = 1 << 3,
CPPopoverDelegate_popover_willClose_ = 1 << 3,
CPPopoverDelegate_popover_didClose_ = 1 << 4;
/*! @ingroup appkit
@class CPPopover
This class represent a widget that displays a attached
This class represent a widget that displays a popover
view relative to another one.
Delegate can implement:
popoverShouldClose:(CPPopover)aPopOver
popoverWillShow:(CPPopover)aPopOver
popoverDidShow:(CPPopover)aPopOver
popoverWillClose:(CPPopover)aPopOver
popoverDidClose:(CPPopover)aPopOver
@code
popoverShouldClose:(CPPopover)aPopOver
popoverWillShow:(CPPopover)aPopOver
popoverDidShow:(CPPopover)aPopOver
popoverWillClose:(CPPopover)aPopOver
popoverDidClose:(CPPopover)aPopOver
@endcode
*/
@implementation CPPopover : CPResponder
{
@@ -62,33 +64,29 @@ var CPPopoverDelegate_popover_willShow_ = 1 << 0,
@outlet id _delegate @accessors(getter=delegate);
BOOL _animates @accessors(property=animates);
BOOL _shown @accessors(getter=shown);
int _appearance @accessors(property=appearance);
int _behavior @accessors(getter=behavior);
BOOL _needsCompute;
_CPAttachedWindow _attachedWindow;
_CPPopoverWindow _popoverWindow;
int _implementedDelegateMethods;
}
#pragma mark -
#pragma mark INitialization
#pragma mark Initialization
/*!
Initialize the CPPopover witn default values
@returns anInitialized CPPopover
@returns an initialized CPPopover
*/
- (CPPopover)init
{
if (self = [super init])
{
_animates = YES;
_appearance = CPPopoverAppearanceMinimal;
_behavior = CPPopoverBehaviorApplicationDefined;
_needsCompute = YES;
_shown = NO;
_animates = YES;
_appearance = CPPopoverAppearanceMinimal;
_behavior = CPPopoverBehaviorApplicationDefined;
}
return self;
@@ -101,34 +99,37 @@ var CPPopoverDelegate_popover_willShow_ = 1 << 0,
/*!
Returns the current rect of the popover
@return CPRect represeting the frame of the popover
@return CGRect representing the frame of the popover
*/
- (CPRect)positionningRect
- (CGRect)positioningRect
{
if (!_attachedWindow || ![_attachedWindow isVisible])
return nil;
return [_attachedWindow frame];
if (![_popoverWindow isVisible])
return CGRectMakeZero();
return [_popoverWindow frame];
}
/*! Sets the frame of the popover
@param aRect the desired frame
*/
- (void)setPositionningRect:(CPRect)aRect
- (void)setPositioningRect:(CGRect)aRect
{
if (!_attachedWindow || ![_attachedWindow isVisible])
if (![_popoverWindow isVisible])
return;
[_attachedWindow setFrame:aRect];
[_popoverWindow setFrame:aRect];
}
/*!
Returns the size of the popover's view
@return CPSize represeting the size of the popover's view
@return CGSize representing the size of the popover's view
*/
- (CPRect)contentSize
- (CGSize)contentSize
{
if (!_attachedWindow || ![_attachedWindow isVisible])
return nil;
if (![_popoverWindow isVisible])
return CGRectMakeZero();
return [[_contentViewController view] frameSize];
}
@@ -137,7 +138,7 @@ var CPPopoverDelegate_popover_willShow_ = 1 << 0,
@param aSize the desired size
*/
- (void)setContentSize:(CPSize)aSize
- (void)setContentSize:(CGSize)aSize
{
[[_contentViewController view] setFrameSize:aSize];
}
@@ -145,32 +146,30 @@ var CPPopoverDelegate_popover_willShow_ = 1 << 0,
/*!
Indicates if CPPopover is visible
@returns YES if visible
@returns \c YES if visible
*/
- (BOOL)shown
- (BOOL)isShown
{
if (!_attachedWindow)
return NO;
return [_attachedWindow isVisible];
return [_popoverWindow isVisible];
}
/*!
Set the behaviour of the CPPopover. It can be
- CPPopoverBehaviorTransient: the popover will be close if another control outside the popover become the responder
- CPPopoverBehaviorApplicationDefined: (DEFAULT) the application is responsible for closing the popover
Set the behavior of the CPPopover. It can be:
@param aBehaviour the desired behaviour
- \c CPPopoverBehaviorTransient: the popover will close if another control outside the popover becomes the responder
- \c CPPopoverBehaviorApplicationDefined: (DEFAULT) the application is responsible for closing the popover
@param aBehavior the desired behavior
*/
- (void)setBehaviour:(int)aBehaviour
- (void)setBehavior:(int)aBehavior
{
if (_behavior == aBehaviour)
if (_behavior == aBehavior)
return;
_behavior = aBehaviour;
_needsCompute = YES;
_behavior = aBehavior;
[_popoverWindow setStyleMask:[self styleMaskForBehavior]];
}
- (void)setDelegate:(id)aDelegate
{
if (_delegate === aDelegate)
@@ -196,62 +195,75 @@ var CPPopoverDelegate_popover_willShow_ = 1 << 0,
}
#pragma mark -
#pragma mark Positionning
#pragma mark Positioning
/*!
Show the popover
@param positioningRect if set, the popover will be positionned to a random rect relative to the window
@param positioningView if set, the popover will be positioned relative to this view
@param preferredEdge: CPRectEdge representing the prefered positionning.
@param preferredEdge: \c CPRectEdge representing the preferred positioning.
*/
- (void)showRelativeToRect:(CPRect)positioningRect ofView:(CPView)positioningView preferredEdge:(CPRectEdge)preferredEdge
- (void)showRelativeToRect:(CGRect)positioningRect ofView:(CPView)positioningView preferredEdge:(CPRectEdge)preferredEdge
{
if (!positioningView)
[CPException raise:CPInvalidArgumentException reason:"positionView must not be nil"];
if (!_contentViewController)
[CPException raise:CPInternalInconsistencyException reason:@"contentViewController must not be nil"];
// If the popover is currently closing, do nothing. That is what Cocoa does.
if ([_popoverWindow isClosing])
return;
if (_implementedDelegateMethods & CPPopoverDelegate_popover_willShow_)
[_delegate popoverWillShow:self];
if (!_contentViewController)
[CPException raise:CPInternalInconsistencyException reason:@"contentViewController must not be nil"];
if (_needsCompute)
if (!_popoverWindow)
{
var styleMask = (_behavior == CPPopoverBehaviorTransient) ? CPClosableOnBlurWindowMask : nil;
_attachedWindow = [[_CPAttachedWindow alloc] initWithContentRect:CPRectMakeZero() styleMask:styleMask];
_popoverWindow = [[_CPPopoverWindow alloc] initWithContentRect:CGRectMakeZero() styleMask:[self styleMaskForBehavior]];
}
[_attachedWindow setAppearance:_appearance];
[_attachedWindow setAnimates:_animates];
[_attachedWindow setMovableByWindowBackground:NO];
[_attachedWindow setFrame:[_attachedWindow frameRectForContentRect:[[_contentViewController view] frame]]];
[_attachedWindow setContentView:[_contentViewController view]];
[_popoverWindow setAppearance:_appearance];
[_popoverWindow setAnimates:_animates];
[_popoverWindow setDelegate:self];
[_popoverWindow setMovableByWindowBackground:NO];
[_popoverWindow setFrame:[_popoverWindow frameRectForContentRect:[[_contentViewController view] frame]]];
[_popoverWindow setContentView:[_contentViewController view]];
[_popoverWindow positionRelativeToRect:positioningRect ofView:positioningView preferredEdge:preferredEdge];
if (positioningRect)
[_attachedWindow positionRelativeToRect:positioningRect preferredEdge:preferredEdge];
else if (positioningView)
[_attachedWindow positionRelativeToView:positioningView preferredEdge:preferredEdge];
else
[CPException raise:CPInvalidArgumentException reason:@"you must set positioningRect or positioningRect"];
if (_implementedDelegateMethods & CPPopoverDelegate_popover_didShow_)
if (!_animates && _implementedDelegateMethods & CPPopoverDelegate_popover_didShow_)
[_delegate popoverDidShow:self];
}
- (unsigned)styleMaskForBehavior
{
return (_behavior == CPPopoverBehaviorTransient) ? CPClosableOnBlurWindowMask : 0;
}
/*!
Closes the popover
*/
- (void)close
{
if (_implementedDelegateMethods & CPPopoverDelegate_popover_shouldClose_)
if (![_delegate popoverShouldClose:self])
return;
[self _close];
}
/*!
Closes the popover
*/
- (void)_close
{
if ([_popoverWindow isClosing] || ![self isShown])
return;
if (_implementedDelegateMethods & CPPopoverDelegate_popover_willClose_)
[_delegate popoverWillClose:self];
[_attachedWindow close];
[_popoverWindow close];
if (_implementedDelegateMethods & CPPopoverDelegate_popover_didClose_)
[_delegate popoverDidClose:self];
// popoverDidClose will be sent from popoverWindowDidClose, since
// the popover window will close asynchronously when animating.
}
@@ -261,15 +273,68 @@ var CPPopoverDelegate_popover_willShow_ = 1 << 0,
/*!
Close the popover
@param aSender the sender of the action
@param sender the sender of the action
*/
- (IBAction)performClose:(id)aSender
- (IBAction)performClose:(id)sender
{
[self close];
if ([_popoverWindow isClosing])
return;
if (_implementedDelegateMethods & CPPopoverDelegate_popover_shouldClose_)
if (![_delegate popoverShouldClose:self])
return;
[self _close];
}
#pragma mark -
#pragma mark Delegates
/*! @ignore */
- (BOOL)popoverWindowShouldClose:(_CPPopoverWindow)aPopoverWindow
{
[self performClose:self];
// We return NO, because we want the CPPopover to determine
// if the popover window can be closed and to give us a chance
// to send delegate messages.
return NO;
}
/*! @ignore */
- (void)popoverWindowDidClose:(_CPPopoverWindow)aPopoverWindow
{
if (_implementedDelegateMethods & CPPopoverDelegate_popover_didClose_)
[_delegate popoverDidClose:self];
}
/*! @ignore */
- (void)popoverWindowDidShow:(_CPPopoverWindow)aPopoverWindow
{
if (_implementedDelegateMethods & CPPopoverDelegate_popover_didShow_)
[_delegate popoverDidShow:self];
}
@end
@implementation CPPopover (Deprecated)
- (void)setBehaviour:(int)aBehavior
{
_CPReportLenientDeprecation(self, _cmd, @selector(setBehavior:));
[self setBehavior:aBehavior];
}
@end
var CPPopoverNeedsNewPopoverWindowKey = @"CPPopoverNeedsNewPopoverWindowKey",
CPPopoverAppearanceKey = @"CPPopoverAppearanceKey",
CPPopoverAnimatesKey = @"CPPopoverAnimatesKey",
CPPopoverContentViewControllerKey = @"CPPopoverContentViewControllerKey",
CPPopoverDelegateKey = @"CPPopoverDelegateKey",
CPPopoverBehaviorKey = @"CPPopoverBehaviorKey";
@implementation CPPopover (CPCoding)
@@ -279,12 +344,11 @@ var CPPopoverDelegate_popover_willShow_ = 1 << 0,
if (self)
{
_needsCompute = [aCoder decodeIntForKey:@"_needsCompute"];
_appearance = [aCoder decodeIntForKey:@"_appearance"];
_animates = [aCoder decodeBoolForKey:@"_animates"];
_contentViewController = [aCoder decodeObjectForKey:@"_contentViewController"];
[self setDelegate:[aCoder decodeObjectForKey:@"_delegate"]];
[self setBehaviour:[aCoder decodeIntForKey:@"_behavior"]];
_appearance = [aCoder decodeIntForKey:CPPopoverAppearanceKey];
_animates = [aCoder decodeBoolForKey:CPPopoverAnimatesKey];
_contentViewController = [aCoder decodeObjectForKey:CPPopoverContentViewControllerKey];
[self setDelegate:[aCoder decodeObjectForKey:CPPopoverDelegateKey]];
[self setBehavior:[aCoder decodeIntForKey:CPPopoverBehaviorKey]];
}
return self;
}
@@ -293,12 +357,11 @@ var CPPopoverDelegate_popover_willShow_ = 1 << 0,
{
[super encodeWithCoder:aCoder];
[aCoder encodeInt:_behavior forKey:@"_behavior"];
[aCoder encodeInt:_appearance forKey:@"_appearance"];
[aCoder encodeBool:_needsCompute forKey:@"_needsCompute"];
[aCoder encodeObject:_contentViewController forKey:@"_contentViewController"];
[aCoder encodeObject:_delegate forKey:@"_delegate"];
[aCoder encodeObject:_animates forKey:@"_animates"];
[aCoder encodeInt:_appearance forKey:CPPopoverAppearanceKey];
[aCoder encodeBool:_animates forKey:CPPopoverAnimatesKey];
[aCoder encodeObject:_contentViewController forKey:CPPopoverContentViewControllerKey];
[aCoder encodeObject:_delegate forKey:CPPopoverDelegateKey];
[aCoder encodeInt:_behavior forKey:CPPopoverBehaviorKey];
}
@end
@end
+68 -102
View File
@@ -23,6 +23,7 @@
@import "CGGeometry.j"
@import "CPImageView.j"
@import "CPView.j"
@import "CPWindow_Constants.j"
/*
@@ -41,11 +42,7 @@ CPProgressIndicatorSpinningStyle = 1;
*/
CPProgressIndicatorHUDBarStyle = 2;
var CPProgressIndicatorSpinningStyleColors = nil,
CPProgressIndicatorClassName = nil,
CPProgressIndicatorStyleIdentifiers = nil,
CPProgressIndicatorStyleSizes = nil;
var CPProgressIndicatorSpinningStyleColors = nil;
/*!
@ingroup appkit
@@ -71,70 +68,17 @@ var CPProgressIndicatorSpinningStyleColors = nil,
BOOL _isDisplayedWhenStoppedSet;
BOOL _isDisplayedWhenStopped;
CPView _barView;
}
/*
@ignore
*/
+ (void)initialize
+ (CPString)defaultThemeClass
{
if (self != [CPProgressIndicator class])
return;
return @"progress-indicator";
}
var bundle = [CPBundle bundleForClass:self];
CPProgressIndicatorSpinningStyleColors = [];
CPProgressIndicatorSpinningStyleColors[CPMiniControlSize] = [CPColor colorWithPatternImage:[[CPImage alloc] initWithContentsOfFile:
[bundle pathForResource:@"CPProgressIndicator/CPProgressIndicatorSpinningStyleRegular.gif"] size:CGSizeMake(64.0, 64.0)]];
CPProgressIndicatorSpinningStyleColors[CPSmallControlSize] = [CPColor colorWithPatternImage:[[CPImage alloc] initWithContentsOfFile:
[bundle pathForResource:@"CPProgressIndicator/CPProgressIndicatorSpinningStyleRegular.gif"] size:CGSizeMake(64.0, 64.0)]];
CPProgressIndicatorSpinningStyleColors[CPRegularControlSize] = [CPColor colorWithPatternImage:[[CPImage alloc] initWithContentsOfFile:
[bundle pathForResource:@"CPProgressIndicator/CPProgressIndicatorSpinningStyleRegular.gif"] size:CGSizeMake(64.0, 64.0)]];
CPProgressIndicatorBezelBorderViewPool = [];
var start = CPProgressIndicatorBarStyle,
end = CPProgressIndicatorHUDBarStyle;
for (; start <= end; ++start)
{
CPProgressIndicatorBezelBorderViewPool[start] = [];
CPProgressIndicatorBezelBorderViewPool[start][CPMiniControlSize] = [];
CPProgressIndicatorBezelBorderViewPool[start][CPSmallControlSize] = [];
CPProgressIndicatorBezelBorderViewPool[start][CPRegularControlSize] = [];
}
CPProgressIndicatorClassName = [self className];
CPProgressIndicatorStyleIdentifiers = [];
CPProgressIndicatorStyleIdentifiers[CPProgressIndicatorBarStyle] = @"Bar";
CPProgressIndicatorStyleIdentifiers[CPProgressIndicatorSpinningStyle] = @"Spinny";
CPProgressIndicatorStyleIdentifiers[CPProgressIndicatorHUDBarStyle] = @"HUDBar";
var regularIdentifier = _CPControlIdentifierForControlSize(CPRegularControlSize),
smallIdentifier = _CPControlIdentifierForControlSize(CPSmallControlSize),
miniIdentifier = _CPControlIdentifierForControlSize(CPMiniControlSize);
CPProgressIndicatorStyleSizes = [];
// Bar Style
var prefixes = [
CPProgressIndicatorClassName + @"BezelBorder" + CPProgressIndicatorStyleIdentifiers[CPProgressIndicatorBarStyle],
CPProgressIndicatorClassName + @"Bar" + CPProgressIndicatorStyleIdentifiers[CPProgressIndicatorBarStyle],
CPProgressIndicatorClassName + @"BezelBorder" + CPProgressIndicatorStyleIdentifiers[CPProgressIndicatorHUDBarStyle],
CPProgressIndicatorClassName + @"Bar" + CPProgressIndicatorStyleIdentifiers[CPProgressIndicatorHUDBarStyle]
];
for (var i = 0, count = prefixes.length; i < count; i++)
{
var prefix = prefixes[i];
CPProgressIndicatorStyleSizes[prefix + regularIdentifier] = [_CGSizeMake(3.0, 16.0), _CGSizeMake(1.0, 16.0), _CGSizeMake(3.0, 16.0)];
CPProgressIndicatorStyleSizes[prefix + smallIdentifier] = [_CGSizeMake(3.0, 16.0), _CGSizeMake(1.0, 16.0), _CGSizeMake(3.0, 16.0)];
CPProgressIndicatorStyleSizes[prefix + miniIdentifier] = [_CGSizeMake(3.0, 16.0), _CGSizeMake(1.0, 16.0), _CGSizeMake(3.0, 16.0)];
}
+ (CPDictionary)themeAttributes
{
return [CPDictionary dictionaryWithObjects:[[CPNull null], [CPNull null], 25, [CPNull null], [CPNull null], [CPNull null], [CPNull null]]
forKeys:[@"indeterminate-bar-color", @"bar-color", @"default-height", @"bezel-color", @"spinning-mini-gif", @"spinning-small-gif", @"spinning-regular-gif"]];
}
- (id)initWithFrame:(CGRect)aFrame
@@ -153,8 +97,7 @@ var CPProgressIndicatorSpinningStyleColors = nil,
_controlSize = CPRegularControlSize;
[self updateBackgroundColor];
[self drawBar];
[self setNeedsLayout];
}
return self;
@@ -345,6 +288,8 @@ var CPProgressIndicatorSpinningStyleColors = nil,
_style = aStyle;
[self setTheme:(_style === CPProgressIndicatorHUDBarStyle) ? [CPTheme defaultHudTheme] : [CPTheme defaultTheme]];
[self updateBackgroundColor];
}
@@ -356,8 +301,7 @@ var CPProgressIndicatorSpinningStyleColors = nil,
if (_style == CPProgressIndicatorSpinningStyle)
[self setFrameSize:[[CPProgressIndicatorSpinningStyleColors[_controlSize] patternImage] size]];
else
[self setFrameSize:CGSizeMake(CGRectGetWidth([self frame]), CPProgressIndicatorStyleSizes[
CPProgressIndicatorClassName + @"BezelBorder" + CPProgressIndicatorStyleIdentifiers[CPProgressIndicatorBarStyle] + _CPControlIdentifierForControlSize(_controlSize)][0].height)];
[self setFrameSize:CGSizeMake(CGRectGetWidth([self frame]), [self valueForThemeAttribute:@"default-height"])];
}
/*!
@@ -407,56 +351,71 @@ var CPProgressIndicatorSpinningStyleColors = nil,
/* @ignore */
- (void)drawBar
{
if (_style == CPProgressIndicatorSpinningStyle)
return;
[self setNeedsLayout];
}
if (!_barView)
- (CPView)createEphemeralSubviewNamed:(CPString)aName
{
return [[CPView alloc] initWithFrame:_CGRectMakeZero()];
}
- (CGRect)rectForEphemeralSubviewNamed:(CPString)aViewName
{
if (aViewName === @"bar-view" && _style !== CPProgressIndicatorSpinningStyle)
{
_barView = [[CPView alloc] initWithFrame:CGRectMake(0.0, 0.0, 0.0, 16.0)];
[self addSubview:_barView];
var width = CGRectGetWidth([self bounds]),
barWidth = width * ((_doubleValue - _minValue) / (_maxValue - _minValue));
if (barWidth > 0.0 && barWidth < 4.0)
barWidth = 4.0;
if (_isIndeterminate)
barWidth = width;
return _CGRectMake(0, 0, barWidth, [self valueForThemeAttribute:@"default-height"]);
}
[_barView setBackgroundColor:_CPControlThreePartImagePattern(
NO,
CPProgressIndicatorStyleSizes,
CPProgressIndicatorClassName,
@"Bar",
CPProgressIndicatorStyleIdentifiers[_style],
_CPControlIdentifierForControlSize(_controlSize))];
var width = CGRectGetWidth([self bounds]),
barWidth = width * ((_doubleValue - _minValue) / (_maxValue - _minValue));
if (barWidth > 0.0 && barWidth < 4.0)
barWidth = 4.0;
[_barView setFrameSize:CGSizeMake(barWidth, 16.0)];
return nil;
}
/* @ignore */
- (void)updateBackgroundColor
{
[self setNeedsLayout];
}
- (void)layoutSubviews
{
CPProgressIndicatorSpinningStyleColors = [];
CPProgressIndicatorSpinningStyleColors[CPMiniControlSize] = [self valueForThemeAttribute:@"spinning-mini-gif"];
CPProgressIndicatorSpinningStyleColors[CPSmallControlSize] = [self valueForThemeAttribute:@"spinning-small-gif"];
CPProgressIndicatorSpinningStyleColors[CPRegularControlSize] = [self valueForThemeAttribute:@"spinning-regular-gif"];
if (YES)//_isBezeled)
{
if (_style == CPProgressIndicatorSpinningStyle)
{
[_barView removeFromSuperview];
_barView = nil;
// This will cause the bar view to go away due to having a nil rect when _style == CPProgressIndicatorSpinningStyle.
[self layoutEphemeralSubviewNamed:"bar-view"
positioned:CPWindowBelow
relativeToEphemeralSubviewNamed:nil];
[self setBackgroundColor:CPProgressIndicatorSpinningStyleColors[_controlSize]];
}
else
{
[self setBackgroundColor:_CPControlThreePartImagePattern(
NO,
CPProgressIndicatorStyleSizes,
CPProgressIndicatorClassName,
@"BezelBorder",
CPProgressIndicatorStyleIdentifiers[_style],
_CPControlIdentifierForControlSize(_controlSize))];
[self setBackgroundColor:[self currentValueForThemeAttribute:@"bezel-color"]];
var barView = [self layoutEphemeralSubviewNamed:"bar-view"
positioned:CPWindowBelow
relativeToEphemeralSubviewNamed:nil];
if (_isIndeterminate)
[barView setBackgroundColor:[self currentValueForThemeAttribute:@"indeterminate-bar-color"]];
else
[barView setBackgroundColor:[self currentValueForThemeAttribute:@"bar-color"]];
[self drawBar];
}
}
else
@@ -477,10 +436,12 @@ var CPProgressIndicatorSpinningStyleColors = nil,
_doubleValue = [aCoder decodeObjectForKey:@"_doubleValue"];
_controlSize = [aCoder decodeObjectForKey:@"_controlSize"];
_isIndeterminate = [aCoder decodeObjectForKey:@"_isIndeterminate"];
_style = [aCoder decodeObjectForKey:@"_style"];
_style = [aCoder decodeIntForKey:@"_style"];
_isAnimating = [aCoder decodeObjectForKey:@"_isAnimating"];
_isDisplayedWhenStoppedSet = [aCoder decodeObjectForKey:@"_isDisplayedWhenStoppedSet"];
_isDisplayedWhenStopped = [aCoder decodeObjectForKey:@"_isDisplayedWhenStopped"];
[self updateBackgroundColor];
}
return self;
@@ -488,14 +449,19 @@ var CPProgressIndicatorSpinningStyleColors = nil,
- (void)encodeWithCoder:(CPCoder)aCoder
{
// Don't encode the background colour. It can be recreated based on the flags and if encoded causes hardcoded
// image paths in the cib while just wasting space.
var backgroundColor = [self backgroundColor];
[self setBackgroundColor:nil];
[super encodeWithCoder:aCoder];
[self setBackgroundColor:backgroundColor];
[aCoder encodeObject:_minValue forKey:@"_minValue"];
[aCoder encodeObject:_maxValue forKey:@"_maxValue"];
[aCoder encodeObject:_doubleValue forKey:@"_doubleValue"];
[aCoder encodeObject:_controlSize forKey:@"_controlSize"];
[aCoder encodeObject:_isIndeterminate forKey:@"_isIndeterminate"];
[aCoder encodeObject:_style forKey:@"_style"];
[aCoder encodeInt:_style forKey:@"_style"];
[aCoder encodeObject:_isAnimating forKey:@"_isAnimating"];
[aCoder encodeObject:_isDisplayedWhenStoppedSet forKey:@"_isDisplayedWhenStoppedSet"];
[aCoder encodeObject:_isDisplayedWhenStopped forKey:@"_isDisplayedWhenStopped"];
+27 -2
View File
@@ -25,6 +25,8 @@
@import "CPButton.j"
@global CPApp
/*!
@ingroup appkit
@@ -150,6 +152,14 @@ CPRadioImageOffset = 4.0;
[_radioGroup _setSelectedRadio:self];
}
- (void)sendAction:(SEL)anAction to:(id)anObject
{
[super sendAction:anAction to:anObject];
if (_radioGroup)
[CPApp sendAction:[_radioGroup action] to:[_radioGroup target] from:_radioGroup];
}
@end
var CPRadioRadioGroupKey = @"CPRadioRadioGroupKey";
@@ -173,6 +183,23 @@ var CPRadioRadioGroupKey = @"CPRadioRadioGroupKey";
[aCoder encodeObject:_radioGroup forKey:CPRadioRadioGroupKey];
}
- (CPImage)image
{
return [self currentValueForThemeAttribute:@"image"];
}
- (CPImage)alternateImage
{
return [self currentValueForThemeAttribute:@"image"];
}
- (BOOL)startTrackingAt:(CGPoint)aPoint
{
var startedTracking = [super startTrackingAt:aPoint];
[self highlight:YES];
return startedTracking;
}
@end
@implementation CPRadioGroup : CPObject
@@ -220,8 +247,6 @@ var CPRadioRadioGroupKey = @"CPRadioRadioGroupKey";
[_selectedRadio setState:CPOffState];
_selectedRadio = aRadio;
[CPApp sendAction:_action to:_target from:self];
}
- (CPRadio)selectedRadio
+4
View File
@@ -21,7 +21,11 @@
*/
@import <Foundation/CPObject.j>
@import <Foundation/CPObjJRuntime.j>
@import "CPEvent.j"
@class CPKeyBinding
CPDeleteKeyCode = 8;
CPTabKeyCode = 9;
+76 -27
View File
@@ -82,6 +82,22 @@
}
/*! @cond */
+ (Class)_binderClassForBinding:(CPString)theBinding
{
if (theBinding == CPValueBinding)
return [CPPredicateEditorValueBinder class];
return [super _binderClassForBinding:theBinding];
}
- (id)_replacementKeyPathForBinding:(CPString)aBinding
{
if (aBinding == CPValueBinding)
return @"predicate";
return [super _replacementKeyPathForBinding:aBinding];
}
- (void)_initRuleEditorShared
{
[super _initRuleEditorShared];
@@ -157,28 +173,40 @@
return trees;
}
- (id)_mergeTree:(id)tree
- (CPMutableArray)_mergeTree:(CPArray)aTree
{
var merged = [CPMutableArray array],
titles = [CPMutableArray array],
count = [tree count];
var mergedTree = [CPMutableArray array];
if (aTree == nil)
return mergedTree;
for (var i = 0; i < count; i++)
var icount = [aTree count];
for (var i = 0; i < icount; i++)
{
var t = tree[i],
title = [CPString stringWithString:[t title]];
var anode = [aTree objectAtIndex:i],
jcount = [mergedTree count],
merged = NO;
if ([titles containsObject:title])
for (var j = 0; j < jcount; j++)
{
CPLogConsole("CPPredicateEditor does not support templates merging yet. Ignoring duplicate template: " + [t description]);
continue;
var mergednode = [mergedTree objectAtIndex:j];
if ([[mergednode title] isEqualToString:[anode title]])
{
var children1 = [mergednode children],
children2 = [anode children],
children12 = [children1 arrayByAddingObjectsFromArray:children2],
mergedChildren = [self _mergeTree:children12];
[mergednode setChildren:mergedChildren];
merged = YES;
}
}
[merged addObject:t];
[titles addObject:title];
if (!merged)
[mergedTree addObject:anode];
}
return merged;
return mergedTree;
}
- (id)_constructTreeForTemplate:(CPPredicateEditorRowTemplate)aTemplate
@@ -192,7 +220,7 @@
var children = [CPArray array],
itemsCount = 0,
menuIndex = -1,
itemsArray,
itemArray,
templateView = [templateViews objectAtIndex:count],
isPopup = [templateView isKindOfClass:[CPPopUpButton class]];
@@ -200,7 +228,7 @@
if (isPopup)
{
itemArray = [[templateView itemArray] valueForKey:@"title"];
itemsCount = [itemArray count],
itemsCount = [itemArray count];
menuIndex = 0;
}
@@ -227,14 +255,19 @@
- (void)setObjectValue:(id)objectValue
{
if (![[objectValue predicateFormat] isEqualToString:[[super predicate] predicateFormat]]) // ??
var ov = [self objectValue];
if ((ov == nil) != (objectValue == nil) || ![ov isEqual:objectValue])
{
[self _setPredicate:objectValue];
[self _reflectPredicate:objectValue];
}
}
- (void)_reflectPredicate:(id)predicate
{
var animation = _currentAnimation;
_currentAnimation = nil;
_sendAction = NO;
if (predicate != nil)
{
@@ -311,9 +344,9 @@
treeChild = [rootItems objectAtIndex:i];
var currentView = [templateViews objectAtIndex:[treeChild indexIntoTemplate]],
menuItemIndex = [treeChild menuItemIndex];
title = [treeChild title];
if (menuItemIndex == -1 || [[treeChild title] isEqual:[currentView titleOfSelectedItem]])
if (title == nil || [title isEqual:[currentView titleOfSelectedItem]])
{
var node = [_CPPredicateEditorRowNode rowNodeFromTree:treeChild];
[node applyTemplate:aTemplate withViews:templateViews forOriginalTemplate:originalTemplate];
@@ -336,16 +369,15 @@
- (void)_updatePredicate
{
[self willChangeValueForKey:@"objectValue"];
[self _updatePredicateFromRows];
[self didChangeValueForKey:@"objectValue"];
}
- (void)_updatePredicateFromRows
{
var rootRowsArray = [super _rootRowsArray],
subpredicates = [CPMutableArray array],
count = count2 = [rootRowsArray count],
count,
count2 = count = [rootRowsArray count],
predicate;
while (count--)
@@ -362,7 +394,7 @@
else
predicate = [[CPCompoundPredicate alloc] initWithType:[self _compoundPredicateTypeForRootRows] subpredicates:subpredicates];
[super _setPredicate:predicate];
[self _setPredicate:predicate];
}
- (id)_predicateFromRowItem:(id)rowItem
@@ -373,12 +405,13 @@
if (rowType == CPRuleEditorRowTypeCompound)
{
var subrows = [rowItem valueForKey:_subrowsArrayKeyPath],
count = [subrows count];
count = [subrows count];
for (var i = 0; i < count; i++)
{
var subrow = [subrows objectAtIndex:i];
var predicate = [self _predicateFromRowItem:subrow];
var subrow = [subrows objectAtIndex:i],
predicate = [self _predicateFromRowItem:subrow];
[subpredicates addObject:predicate];
}
}
@@ -414,7 +447,6 @@
- (void)_sendRuleAction
{
[self _updatePredicate];
[super _sendRuleAction];
}
@@ -483,9 +515,11 @@ var CPPredicateTemplatesKey = @"CPPredicateTemplates";
- (id)initWithCoder:(id)aCoder
{
self = [super initWithCoder:aCoder];
if (self != nil)
{
var nibTemplates = [aCoder decodeObjectForKey:CPPredicateTemplatesKey];
if (nibTemplates != nil)
[self setRowTemplates:nibTemplates];
}
@@ -501,4 +535,19 @@ var CPPredicateTemplatesKey = @"CPPredicateTemplates";
@end
/*! @endcond */
@implementation CPPredicateEditorValueBinder : CPBinder
{
}
- (void)setPlaceholderValue:(id)aValue withMarker:(CPString)aMarker forBinding:(CPString)aBinding
{
[_source _reflectPredicate:nil];
}
- (void)setValue:(id)aValue forBinding:(CPString)aBinding
{
[_source _reflectPredicate:aValue];
}
@end
/*! @endcond */
@@ -20,17 +20,28 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
CPUndefinedAttributeType = 0,
CPInteger16AttributeType = 100,
CPInteger32AttributeType = 200,
CPInteger64AttributeType = 300,
CPDecimalAttributeType = 400,
CPDoubleAttributeType = 500,
CPFloatAttributeType = 600,
CPStringAttributeType = 700,
CPBooleanAttributeType = 800,
CPDateAttributeType = 900,
CPBinaryDataAttributeType = 1000,
@import <Foundation/CPPredicate.j>
@import "CPCheckBox.j"
@import "CPPopUpButton.j"
@import "CPMenuItem.j"
@import "CPTextField.j"
// NOTE: CPDatePicker is not implemented yet
@class CPDatePicker
CPUndefinedAttributeType = 0;
CPInteger16AttributeType = 100;
CPInteger32AttributeType = 200;
CPInteger64AttributeType = 300;
CPDecimalAttributeType = 400;
CPDoubleAttributeType = 500;
CPFloatAttributeType = 600;
CPStringAttributeType = 700;
CPBooleanAttributeType = 800;
CPDateAttributeType = 900;
CPBinaryDataAttributeType = 1000;
CPTransformableAttributeType = 1800;
@implementation CPPredicateEditorRowTemplate : CPObject
@@ -185,7 +196,8 @@ CPTransformableAttributeType = 1800;
if (![[self operators] containsObject:[predicate predicateOperatorType]])
return 0;
if (!_rightIsWildcard && ![[self rightExpressions] containsObject:[predicate rightExpression]]) return 0;
if (!_rightIsWildcard && ![[self rightExpressions] containsObject:[predicate rightExpression]])
return 0;
return 1;
}
@@ -280,7 +292,7 @@ CPTransformableAttributeType = 1800;
*/
- (CPArray)leftExpressions
{
if (_templateType ==1 && !_leftIsWildcard)
if (_templateType == 1 && !_leftIsWildcard)
{
var view = [_views objectAtIndex:0];
return [[view itemArray] valueForKey:@"representedObject"];
@@ -582,7 +594,7 @@ CPTransformableAttributeType = 1800;
- (CPPopUpButton)_viewFromExpressions:(CPArray)expressions
{
var popup = [[CPPopUpButton alloc] initWithFrame:CPMakeRect(0, 0, 100, 18)],
var popup = [[CPPopUpButton alloc] initWithFrame:CGRectMake(0, 0, 100, 18)],
count = [expressions count];
for (var i = 0; i < count; i++)
@@ -685,6 +697,7 @@ CPTransformableAttributeType = 1800;
[textField setBordered:YES];
[textField setEditable:YES];
[textField setFont:[CPFont systemFontOfSize:10]];
[textField setSendsActionOnEndEditing:YES];
return textField;
}
@@ -785,4 +798,4 @@ var CPPredicateTemplateTypeKey = @"CPPredicateTemplateType",
}
@end
/*! @endcond */
/*! @endcond */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,40 @@
/*
* CPRuleEditor_Constants.j
* AppKit
*
* Created by cacaodev.
* Copyright 2011, cacaodev.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
CPRuleEditorPredicateLeftExpression = "CPRuleEditorPredicateLeftExpression";
CPRuleEditorPredicateRightExpression = "CPRuleEditorPredicateRightExpression";
CPRuleEditorPredicateComparisonModifier = "CPRuleEditorPredicateComparisonModifier";
CPRuleEditorPredicateOptions = "CPRuleEditorPredicateOptions";
CPRuleEditorPredicateOperatorType = "CPRuleEditorPredicateOperatorType";
CPRuleEditorPredicateCustomSelector = "CPRuleEditorPredicateCustomSelector";
CPRuleEditorPredicateCompoundType = "CPRuleEditorPredicateCompoundType";
CPRuleEditorRowsDidChangeNotification = "CPRuleEditorRowsDidChangeNotification";
CPRuleEditorRulesDidChangeNotification = "CPRuleEditorRulesDidChangeNotification";
CPRuleEditorNestingModeSingle = 0; // Only a single row is allowed. Plus/minus buttons will not be shown
CPRuleEditorNestingModeList = 1; // Allows a single list, with no nesting and no compound rows
CPRuleEditorNestingModeCompound = 2; // Unlimited nesting and compound rows; this is the default
CPRuleEditorNestingModeSimple = 3; // One compound row at the top with subrows beneath it, and no further nesting allowed
CPRuleEditorRowTypeSimple = 0;
CPRuleEditorRowTypeCompound = 1;
+36 -23
View File
@@ -1,9 +1,25 @@
/*
* Created by cacaodev@gmail.com.
* Copyright (c) 2011 Pear, Inc. All rights reserved.
* Created by cacaodev@gmail.com.
* Copyright (c) 2011 Pear, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@class _CPPredicateEditorTree;
@import <Foundation/CPObject.j>
@import <Foundation/CPString.j>
@implementation _CPPredicateEditorRowNode : CPObject
{
_CPPredicateEditorTree tree @accessors;
@@ -14,25 +30,21 @@
+ (id)rowNodeFromTree:(id)aTree
{
var mapTable = {};
return [_CPPredicateEditorRowNode _rowNodeFromTree:aTree withTemplateTable:mapTable];
return [_CPPredicateEditorRowNode _rowNodeFromTree:aTree withTemplateTable:{}];
}
+ (id)_rowNodeFromTree:(id)aTree withTemplateTable:(id)templateTable
{
var node,
views,
var views,
copiedContainer;
node = [[_CPPredicateEditorRowNode alloc] init];
node.tree = aTree;
var uuid = [[aTree template] UID],
cachedNode = templateTable[uuid],
node = [[_CPPredicateEditorRowNode alloc] init];
var template = [aTree template],
uuid = [template UID];
[node setTree:aTree];
var cachedNode = templateTable[uuid];
if (cachedNode == nil)
if (!cachedNode)
{
views = [CPMutableArray array];
copiedContainer = [CPMutableArray array];
@@ -44,8 +56,8 @@
copiedContainer = [cachedNode copiedTemplateContainer];
}
node.templateViews = views;
node.copiedTemplateContainer = copiedContainer;
[node setTemplateViews:views];
[node setCopiedTemplateContainer:copiedContainer];
var nodeChildren = [CPMutableArray array],
treeChildren = [aTree children],
@@ -66,7 +78,9 @@
- (BOOL)applyTemplate:(id)template withViews:(id)views forOriginalTemplate:(id)originalTemplate
{
var t = [tree template];
var t = [tree template],
count = [children count];
if (t !== template)
{
[templateViews setArray:views];
@@ -74,8 +88,7 @@
[copiedTemplateContainer addObject:template];
}
var count = [children count];
for (var i; i < count; i++)
for (var i = 0; i < count; i++)
[children[i] applyTemplate:template withViews:views forOriginalTemplate:originalTemplate];
}
@@ -89,9 +102,8 @@
- (void)copyTemplateIfNecessary
{
if ([copiedTemplateContainer count] == 0)
if ([copiedTemplateContainer count] === 0)
{
CPLogConsole("COPYING TEMPLATE");
var copy = [[tree template] copy];
[copiedTemplateContainer addObject:copy];
[templateViews addObjectsFromArray:[copy templateViews]];
@@ -118,7 +130,8 @@
- (id)displayValue
{
var title = [self title];
if (title != nil)
if (title !== nil)
return title;
return [self templateView];
@@ -129,4 +142,4 @@
return [CPString stringWithFormat:@"<%@ %@ %@ tree:%@ tviews:%@", [self className],[self UID], [self title], [tree UID], [templateViews description]];
}
@end
@end
+19 -2
View File
@@ -1,8 +1,25 @@
/*
* Created by cacaodev@gmail.com.
* Copyright (c) 2011 Pear, Inc. All rights reserved.
* Created by cacaodev@gmail.com.
* Copyright (c) 2011 Pear, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import <Foundation/CPObject.j>
@import <Foundation/CPString.j>
@implementation _CPPredicateEditorTree : CPObject
{
CPPredicateEditorRowTemplate template @accessors;
+34 -12
View File
@@ -1,19 +1,35 @@
/*
* Created by cacaodev@gmail.com.
* Copyright (c) 2011 Pear, Inc. All rights reserved.
* Created by cacaodev@gmail.com.
* Copyright (c) 2011 Pear, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import <Foundation/CPObject.j>
@import <Foundation/CPDictionary.j>
@import <Foundation/CPString.j>
@import <Foundation/CPURLConnection.j>
@import <Foundation/CPURLRequest.j>
var regex = new RegExp("\"(.+)\"\\s*=\\s*\"(.+)\"\\s*;\\s*(//.+)?");
var LocalizerStringsRegex = new RegExp("\"(.+)\"\\s*=\\s*\"(.+)\"\\s*;\\s*(//.+)?");
@implementation _CPRuleEditorLocalizer : CPObject
{
CPDictionary _dictionary @accessors(property=dictionary);
CPURLConnection connection;
CPURLRequest resquest;
CPURLRequest request;
}
- (void)loadContentOfURL:(CPURL)aURL
@@ -24,9 +40,10 @@ var regex = new RegExp("\"(.+)\"\\s*=\\s*\"(.+)\"\\s*;\\s*(//.+)?");
- (void)reloadIfNeeded
{
if (connection != nil) // Connection waiting
if (connection !== nil) // Connection waiting
{
connection = nil;
var data = [CPURLConnection sendSynchronousRequest:request returningResponse:NULL];
[self loadContent:[data rawString]];
}
@@ -34,7 +51,7 @@ var regex = new RegExp("\"(.+)\"\\s*=\\s*\"(.+)\"\\s*;\\s*(//.+)?");
- (void)connection:(CPURLConnection)aConnection didReceiveData:(CPString)rawString
{
if (connection != nil && rawString != nil)
if (connection !== nil && rawString !== nil)
[self loadContent:rawString];
connection = nil;
@@ -49,10 +66,12 @@ var regex = new RegExp("\"(.+)\"\\s*=\\s*\"(.+)\"\\s*;\\s*(//.+)?");
for (var i = 0 ; i < count ; i++)
{
var line = [lines objectAtIndex:i];
if (line.length > 1)
{
var match = regex.exec(line);
if (match.length >= 3)
var match = LocalizerStringsRegex.exec(line);
if (match && match.length >= 3)
[dict setObject:match[2] forKey:match[1]];
}
}
@@ -64,12 +83,15 @@ var regex = new RegExp("\"(.+)\"\\s*=\\s*\"(.+)\"\\s*;\\s*(//.+)?");
{
[self reloadIfNeeded];
if (_dictionary != nil && aString != nil)
if (_dictionary !== nil && aString !== nil)
{
var localized = [_dictionary objectForKey:aString];
if (localized != nil)
return localized;
if (localized !== nil)
return localized;
}
return aString;
}
}
@end
+104 -58
View File
@@ -1,64 +1,103 @@
/*
* Created by cacaodev@gmail.com.
* Copyright (c) 2011 Pear, Inc. All rights reserved.
* Created by cacaodev@gmail.com.
* Copyright (c) 2011 Pear, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "CPBezierPath.j"
@import "CPPopUpButton.j"
@class _CPRuleEditorViewSlice
var GRADIENT_START_COLOR = "#fcfcfc",
GRADIENT_END_COLOR = "#dfdfdf",
BORDER_COLOR = "#BDBDBD";
var GRADIENT_NORMAL,
GRADIENT_HIGHLIGHTED,
IE_FILTER = "progid:DXImageTransform.Microsoft.gradient(startColorstr='#fcfcfc', endColorstr='#dfdfdf')";
GRADIENT_PROPERTY;
if (CPBrowserIsEngine(CPWebKitBrowserEngine))
{
GRADIENT_NORMAL = "-webkit-gradient(linear, left top, left bottom, from(" + GRADIENT_START_COLOR + "), to(" + GRADIENT_END_COLOR + "))",
GRADIENT_HIGHLIGHTED = "-webkit-gradient(linear, left top, left bottom, from(" + GRADIENT_END_COLOR + "), to(" + GRADIENT_START_COLOR + "))";
GRADIENT_PROPERTY = "background";
}
else if (CPBrowserIsEngine(CPGeckoBrowserEngine))
{
GRADIENT_NORMAL = "-moz-linear-gradient(top, " + GRADIENT_START_COLOR + ", " + GRADIENT_END_COLOR + ")",
GRADIENT_HIGHLIGHTED = "-moz-linear-gradient(top, " + GRADIENT_END_COLOR + ", " + GRADIENT_START_COLOR + ")";
GRADIENT_PROPERTY = "background";
}
else if (CPBrowserIsEngine(CPInternetExplorerBrowserEngine))
{
GRADIENT_NORMAL = "progid:DXImageTransform.Microsoft.gradient(startColorstr='" + GRADIENT_START_COLOR + "', endColorstr='" + GRADIENT_END_COLOR + "')";
GRADIENT_HIGHLIGHTED = "progid:DXImageTransform.Microsoft.gradient(startColorstr='" + GRADIENT_END_COLOR + "', endColorstr='" + GRADIENT_START_COLOR + "')";
GRADIENT_PROPERTY = "filter";
}else
{
GRADIENT_NORMAL = GRADIENT_START_COLOR;
GRADIENT_HIGHLIGHTED = GRADIENT_END_COLOR;
GRADIENT_PROPERTY = "background";
}
@implementation _CPRuleEditorPopUpButton : CPPopUpButton
{
CPInteger radius;
}
+ (void)initialize
- (void)_sharedInit
{
if (CPBrowserIsEngine(CPWebKitBrowserEngine))
{
GRADIENT_NORMAL = "-webkit-gradient(linear, left top, left bottom, from(rgb(252, 252, 252)), to(rgb(223, 223, 223)))",
GRADIENT_HIGHLIGHTED = "-webkit-gradient(linear, left top, left bottom, from(rgb(223, 223, 223)), to(rgb(252, 252, 252)))";
}
else if (CPBrowserIsEngine(CPGeckoBrowserEngine))
{
GRADIENT_NORMAL = "-moz-linear-gradient(top, rgb(252, 252, 252), rgb(223, 223, 223))",
GRADIENT_HIGHLIGHTED = "-moz-linear-gradient(top, rgb(223, 223, 223), rgb(252, 252, 252))";
}
[self setBordered:NO];
#if PLATFORM(DOM)
var style = _DOMElement.style;
style.border = "1px solid " + BORDER_COLOR;
style[GRADIENT_PROPERTY] = GRADIENT_NORMAL;
#endif
}
- (id)initWithFrame:(CGRect)aFrame
{
if (self = [super initWithFrame:aFrame])
{
var style = _DOMElement.style;
style.backgroundImage = GRADIENT_NORMAL;
style.border = "1px solid rgb(189, 189, 189)";
style.filter = IE_FILTER;
[self setTextColor:[CPColor colorWithWhite:101/255 alpha:1]];
[self setBordered:NO];
}
[self _sharedInit];
return self;
}
- (id)hitTest:(CPPoint)point
- (id)initWithCoder:(CPCoder)aCoder
{
var slice = [self superview];
if (!CPRectContainsPoint([self frame], point) || ![self sliceIsEditable])
self = [super initWithCoder:aCoder];
[self _sharedInit];
return self;
}
- (id)hitTest:(CGPoint)point
{
if (!CGRectContainsPoint([self frame], point) || ![self sliceIsEditable])
return nil;
return self;
}
- (void)setHighlighted:(BOOL)shouldHighlight
{
_DOMElement.style.backgroundImage = (shouldHighlight) ? GRADIENT_HIGHLIGHTED : GRADIENT_NORMAL;
}
- (BOOL)sliceIsEditable
{
return [[self superview] isEditable];
var superview = [self superview];
return ![superview isKindOfClass:[_CPRuleEditorViewSlice]] || [superview isEditable];
}
- (BOOL)trackMouse:(CPEvent)theEvent
@@ -80,34 +119,32 @@ var GRADIENT_NORMAL,
- (void)layoutSubviews
{
radius = FLOOR(CGRectGetHeight([self bounds])/2);
#if PLATFORM(DOM)
radius = FLOOR(CGRectGetHeight([self bounds]) / 2);
var style = _DOMElement.style,
radiusCSS = radius + "px";
//style.webkitBorderRadius = radiusCSS;
//style.mozBorderRadius = radiusCSS;
style.borderRadius = radiusCSS;
#endif
[super layoutSubviews];
}
- (void)drawRect:(CGRect)aRect
{
var bounds = [self bounds],
context = [[CPGraphicsContext currentContext] graphicsPort];
var arrow_width = FLOOR(CGRectGetHeight(bounds)/3.5);
var context = [[CPGraphicsContext currentContext] graphicsPort],
bounds = [self bounds],
arrow_width = FLOOR(CGRectGetHeight(bounds) / 3.5);
CGContextTranslateCTM(context, CGRectGetWidth(bounds) - radius - arrow_width, CGRectGetHeight(bounds) / 2);
var arrowsPath = [CPBezierPath bezierPath];
[arrowsPath moveToPoint:CGPointMake(0, 1)];
[arrowsPath lineToPoint:CGPointMake(arrow_width, 1)];
[arrowsPath lineToPoint:CGPointMake(arrow_width/2, arrow_width + 1)];
[arrowsPath lineToPoint:CGPointMake(arrow_width / 2, arrow_width + 1)];
[arrowsPath closePath];
CGContextSetFillColor(context, [CPColor colorWithWhite:101/255 alpha:1]);
CGContextSetFillColor(context, [CPColor colorWithWhite:101 / 255 alpha:1]);
[arrowsPath fill];
CGContextScaleCTM(context, 1 , -1);
@@ -121,37 +158,46 @@ var GRADIENT_NORMAL,
CPInteger radius;
}
- (void)_sharedInit
{
[self setBordered:NO];
#if PLATFORM(DOM)
var style = _DOMElement.style;
style.border = "1px solid " + BORDER_COLOR;
style[GRADIENT_PROPERTY] = GRADIENT_NORMAL;
#endif
}
- (id)initWithFrame:(CGRect)aFrame
{
self = [super initWithFrame:aFrame];
if (self)
{
[self setFont:[CPFont boldFontWithName:@"Apple Symbol" size:12.0]];
[self setTextColor:[CPColor colorWithWhite:150/255 alpha:1]];
[self setAlignment:CPCenterTextAlignment];
[self setAutoresizingMask:CPViewMinXMargin];
[self setImagePosition:CPImageOnly];
[self setBordered:NO];
var style = _DOMElement.style;
style.border = "1px solid rgb(189, 189, 189)";
style.filter = IE_FILTER;
}
if (self = [super initWithFrame:aFrame])
[self _sharedInit];
return self;
}
- (id)initWithCoder:(CPCoder)aCoder
{
self = [super initWithCoder:aCoder];
[self _sharedInit];
return self;
}
- (void)layoutSubviews
{
radius = FLOOR(CGRectGetHeight([self bounds])/2);
#if PLATFORM(DOM)
radius = FLOOR(CGRectGetHeight([self bounds]) / 2);
var style = _DOMElement.style,
radiusCSS = radius + "px";
style.borderRadius = radiusCSS;
style.backgroundImage = ([self isHighlighted]) ? GRADIENT_HIGHLIGHTED : GRADIENT_NORMAL;
style[GRADIENT_PROPERTY] = ([self isHighlighted]) ? GRADIENT_HIGHLIGHTED : GRADIENT_NORMAL;
#endif
[super layoutSubviews];
}
@end
+28 -11
View File
@@ -1,17 +1,34 @@
/*
* Created by cacaodev@gmail.com.
* Copyright (c) 2011 Pear, Inc. All rights reserved.
* Created by cacaodev@gmail.com.
* Copyright (c) 2011 Pear, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "CPView.j"
@implementation _CPRuleEditorViewSlice : CPView
{
CPRuleEditor _ruleEditor;
int _indentation @accessors(property=indentation);
int _rowIndex @accessors(property=rowIndex);
CPRect _animationTargetRect @accessors(property=_animationTargetRect);
CGRect _animationTargetRect @accessors(property=_animationTargetRect);
BOOL _selected @accessors(getter=_isSelected, setter=_setSelected:);
BOOL _lastSelected @accessors(getter=_isLastSelected, setter=_setLastSelected:);
CPColor _backgroundColor @accessors(property=backgroundColor);
BOOL _editable @accessors(getter=isEditable, setter=setEditable:);
}
- (void)removeFromSuperview
@@ -41,11 +58,11 @@
_selected = select;
}
- (void)drawRect:(CPRect)rect
- (void)drawRect:(CGRect)rect
{
var context = [[CPGraphicsContext currentContext] graphicsPort],
bounds = [self bounds],
maxX = CGRectGetWidth(bounds) - 2,
maxX = CGRectGetWidth(bounds),
maxY = CGRectGetHeight(bounds);
// Draw background
@@ -63,7 +80,7 @@
// Draw Top Border
CGContextBeginPath(context);
CGContextMoveToPoint(context, 1, 0);
CGContextMoveToPoint(context, 0, 0);
CGContextAddLineToPoint(context, maxX, 0);
CGContextClosePath(context);
CGContextSetStrokeColor(context, [_ruleEditor _sliceTopBorderColor]);
@@ -71,8 +88,8 @@
// Draw Bottom Border
CGContextBeginPath(context);
CGContextMoveToPoint(context, 1, maxY - 0.5);
CGContextAddLineToPoint(context, maxX, maxY - 0.5);
CGContextMoveToPoint(context, 0, maxY);
CGContextAddLineToPoint(context, maxX, maxY);
CGContextClosePath(context);
var bottomColor = (_rowIndex == [_ruleEditor _lastRow]) ? [_ruleEditor _sliceLastBottomBorderColor] : [_ruleEditor _sliceBottomBorderColor];
CGContextSetStrokeColor(context, bottomColor);
@@ -81,13 +98,13 @@
- (void)mouseDown:(CPEvent)theEvent
{
if (editable)
if (_editable)
[_ruleEditor _mouseDownOnSlice:self withEvent:theEvent];
}
- (void)mouseUp:(CPEvent)theEvent
{
if (editable)
if (_editable)
[_ruleEditor _mouseUpOnSlice:self withEvent:theEvent];
}
@@ -106,4 +123,4 @@
return [CPString stringWithFormat:@"<%@ %p index:%d indentation:%d>",[self className],self,[self rowIndex],[self indentation]];
}
@end
@end
+79 -62
View File
@@ -1,11 +1,27 @@
/*
* Created by cacaodev@gmail.com.
* Copyright (c) 2011 Pear, Inc. All rights reserved.
* Created by cacaodev@gmail.com.
* Copyright (c) 2011 Pear, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "CPRuleEditor_Constants.j"
@import "_CPRuleEditorViewSlice.j"
@import "_CPRuleEditorPopUpButton.j"
@import "CPRuleEditor.j"
@global CPApp
var CONTROL_HEIGHT = 16.,
BUTTON_HEIGHT = 16.;
@@ -18,7 +34,7 @@ var CONTROL_HEIGHT = 16.,
CPMutableArray _ruleOptionInitialViewFrames;
CPButton _addButton;
CPButton _subtractButton;
BOOL editable;
CPRuleEditorRowType _rowType @accessors;
CPRuleEditorRowType _plusButtonRowType;
}
@@ -37,14 +53,14 @@ var CONTROL_HEIGHT = 16.,
_ruleOptionFrames = [[CPMutableArray alloc] init];
_ruleOptionInitialViewFrames = [[CPMutableArray alloc] init];
_ruleOptionViews = [[CPMutableArray alloc] init];
editable = [_ruleEditor isEditable];
_editable = [_ruleEditor isEditable];
_addButton = [self _createAddRowButton];
_subtractButton = [self _createDeleteRowButton];
//[_addButton setToolTip:[_ruleEditor _toolTipForAddSimpleRowButton]];
//[_subtractButton setToolTip:[_ruleEditor _toolTipForDeleteRowButton]];
[_addButton setHidden:!editable];
[_subtractButton setHidden:!editable];
[_addButton setToolTip:[_ruleEditor _toolTipForAddSimpleRowButton]];
[_subtractButton setToolTip:[_ruleEditor _toolTipForDeleteRowButton]];
[_addButton setHidden:!_editable];
[_subtractButton setHidden:!_editable];
[self addSubview:_addButton];
[self addSubview:_subtractButton];
@@ -54,26 +70,36 @@ var CONTROL_HEIGHT = 16.,
[center addObserver:self selector:@selector(_textDidChange:) name:CPControlTextDidChangeNotification object:nil];
}
- (CPButton)_createAddRowButton
- (CPButton)_createRowButton
{
var button = [[_CPRuleEditorButton alloc] initWithFrame:CGRectMakeZero()];
[button setImage:[_ruleEditor _addImage]];
[button setFont:[CPFont boldFontWithName:@"Apple Symbol" size:12.0]];
[button setTextColor:[CPColor colorWithWhite:150 / 255 alpha:1]];
[button setAlignment:CPCenterTextAlignment];
[button setAutoresizingMask:CPViewMinXMargin];
[button setImagePosition:CPImageOnly];
return button;
}
- (CPButton)_createAddRowButton
{
var button = [self _createRowButton];
[button setImage:[_ruleEditor _addImage]];
[button setAction:@selector(_addOption:)];
[button setTarget:self];
[button setAutoresizingMask:CPViewMinXMargin];
return button;
}
- (CPButton)_createDeleteRowButton
{
var button = [[_CPRuleEditorButton alloc] initWithFrame:CGRectMakeZero()];
[button setImage:[_ruleEditor _removeImage]];
var button = [self _createRowButton];
[button setImage:[_ruleEditor _removeImage]];
[button setAction:@selector(_deleteOption:)];
[button setTarget:self];
[button setAutoresizingMask:CPViewMinXMargin];
return button;
}
@@ -87,12 +113,14 @@ var CONTROL_HEIGHT = 16.,
- (CPPopUpButton)_createPopUpButtonWithItems:(CPArray)itemsArray selectedItemIndex:(int)index
{
var title = [[itemsArray objectAtIndex:index] title];
var font = [_ruleEditor font],
var title = [[itemsArray objectAtIndex:index] title],
font = [_ruleEditor font],
width = [title sizeWithFont:font].width + 20,
rect = CGRectMake(0, 0, (width - width % 40) + 80, CONTROL_HEIGHT);
rect = CGRectMake(0, 0, (width - width % 40) + 80, CONTROL_HEIGHT),
var popup = [[_CPRuleEditorPopUpButton alloc] initWithFrame:rect];
popup = [[_CPRuleEditorPopUpButton alloc] initWithFrame:rect];
[popup setTextColor:[CPColor colorWithWhite:101 / 255 alpha:1]];
[popup setValue:font forThemeAttribute:@"font"];
var count = [itemsArray count];
@@ -109,16 +137,18 @@ var CONTROL_HEIGHT = 16.,
return [CPMenuItem separatorItem];
}
- (_CPRuleEditorTextField)_createStaticTextFieldWithStringValue:(CPString )text
- (_CPRuleEditorTextField)_createStaticTextFieldWithStringValue:(CPString)text
{
text = [[_ruleEditor standardLocalizer] localizedStringForString:text];
var textField = [[_CPRuleEditorTextField alloc] initWithFrame:CGRectMakeZero()],
ruleEditorFont = [_ruleEditor font],
font = [CPFont fontWithName:[ruleEditorFont familyName] size:[ruleEditorFont size] + 2],
localizedText = [[_ruleEditor standardLocalizer] localizedStringForString:text],
size = [localizedText sizeWithFont:font];
[textField setFrameSize:CGSizeMake(size.width + 4, CONTROL_HEIGHT + 2)];
var textField = [[_CPRuleEditorTextField alloc] initWithFrame:CPMakeRect(0, 0, 200, CONTROL_HEIGHT)];
var font = [_ruleEditor font];
font = [CPFont fontWithName:font._name size:font._size + 2];
[textField setValue:font forThemeAttribute:@"font"];
[textField setStringValue:text];
[textField sizeToFit];
[textField setStringValue:localizedText];
return textField;
}
@@ -182,9 +212,10 @@ var CONTROL_HEIGHT = 16.,
parent,
numberOfCriteria,
numberOfChildren,
firstResponderIndex;
firstResponderIndex,
var ruleItems = [CPMutableArray array];
ruleItems = [CPMutableArray array],
responder = [[self window] firstResponder];
[self _emptyRulePartSubviews];
@@ -192,7 +223,6 @@ var CONTROL_HEIGHT = 16.,
numberOfCriteria = [criteria count];
firstResponderIndex = numberOfCriteria - 1;
var responder = [[self window] firstResponder];
if (responder)
firstResponderIndex = [_ruleOptionViews indexOfObjectIdenticalTo:responder];
@@ -213,16 +243,16 @@ var CONTROL_HEIGHT = 16.,
numberOfChildren = [childItems count];
if (numberOfChildren > 1)
{
var menuItems = [CPMutableArray arrayWithCapacity:numberOfChildren];
var menuItems = [CPMutableArray arrayWithCapacity:numberOfChildren],
selectedIndex = [childItems indexOfObject:criterion];
var selectedIndex = [childItems indexOfObject:criterion];
if (selectedIndex == CPNotFound)
break;
for (var j = 0; j < numberOfChildren; ++j)
{
var childItem = [childItems objectAtIndex:j];
var childValue = [childValues objectAtIndex:j];
var childItem = [childItems objectAtIndex:j],
childValue = [childValues objectAtIndex:j];
if ([childValue isKindOfClass:[CPMenuItem class]])
{
@@ -250,8 +280,8 @@ var CONTROL_HEIGHT = 16.,
}
else
{
var value = [childValues objectAtIndex:0];
var type = [value valueType];
var value = [childValues objectAtIndex:0],
type = [value valueType];
if (type === 0)
ruleView = [self _createStaticTextFieldWithStringValue:value];
@@ -287,7 +317,7 @@ var CONTROL_HEIGHT = 16.,
[_correspondingRuleItems setArray:ruleItems];
if (!editable)
if (!_editable)
[self _updateEnabledStateForSubviews];
[self _relayoutSubviewsWidthChanged:YES];
@@ -308,7 +338,6 @@ var CONTROL_HEIGHT = 16.,
- (void)layoutSubviews
{
// CPLogConsole(_cmd);
[self _relayoutSubviewsWidthChanged:YES];
}
@@ -319,11 +348,11 @@ var CONTROL_HEIGHT = 16.,
leftButtonMinX,
rowHeight = [_ruleEditor rowHeight],
count = [_ruleOptionViews count],
sliceFrame = [self frame];
sliceFrame = [self frame],
buttonFrame = CGRectMake(CGRectGetWidth(sliceFrame) - BUTTON_HEIGHT - [self _rowButtonsRightHorizontalPadding], ([_ruleEditor rowHeight] - BUTTON_HEIGHT) / 2 - 2, BUTTON_HEIGHT, BUTTON_HEIGHT);
var buttonFrame = CGRectMake(CGRectGetWidth(sliceFrame) - BUTTON_HEIGHT - [self _rowButtonsRightHorizontalPadding], ([_ruleEditor rowHeight] - BUTTON_HEIGHT)/2 - 2, BUTTON_HEIGHT, BUTTON_HEIGHT);
[_addButton setFrame:buttonFrame];
buttonFrame.origin.x -= BUTTON_HEIGHT + [self _rowButtonsInterviewHorizontalPadding];
[_subtractButton setFrame:buttonFrame];
@@ -339,7 +368,8 @@ var CONTROL_HEIGHT = 16.,
var ruleOptionView = _ruleOptionViews[i],
optionFrame = _ruleOptionFrames[i];
optionFrame.origin.y = (rowHeight - CGRectGetHeight(optionFrame))/2 - 2;
optionFrame.origin.y = (rowHeight - CGRectGetHeight(optionFrame)) / 2 - 2;
if (widthChanged)
{
optionFrame.origin.x = optionViewOriginX;
@@ -369,14 +399,9 @@ var CONTROL_HEIGHT = 16.,
[self _setRowTypeToAddFromPlusButton:type];
}
- (BOOL)isEditable
{
return editable;
}
- (void)setEditable:(BOOL)value
{
editable = value;
[super setEditable:value]
// [self _updateEnabledStateForSubviews];
[self _updateButtonVisibilities];
}
@@ -418,7 +443,7 @@ var CONTROL_HEIGHT = 16.,
- (float)_rowButtonsRightHorizontalPadding
{
return 10.;
return ([[_ruleEditor superview] isKindOfClass:[CPClipView class]]) ? 18. : 10.;
}
- (void)_setRowTypeToAddFromPlusButton:(int)type
@@ -452,7 +477,7 @@ var CONTROL_HEIGHT = 16.,
[self layoutSubviews];
}
- (void)drawRect:(CPRect)rect
- (void)drawRect:(CGRect)rect
{
[super drawRect:rect];
}
@@ -464,22 +489,16 @@ var CONTROL_HEIGHT = 16.,
return NO;
}
- (BOOL)_isRuleStaticTextField:(CPView)view
{
if ([view isKindOfClass:[_CPRuleEditorTextField class]])
return YES;
return NO;
}
- (void)_sendRuleAction:(id)sender
{
[_ruleEditor _updatePredicate];
[_ruleEditor _sendRuleAction];
}
- (void)_textDidChange:(CPNotification)aNotif
{
if ([[aNotif object] superview] == self && [_ruleEditor _sendsActionOnIncompleteTextChange])
[_ruleEditor _sendRuleAction];
[self _sendRuleAction:nil];
}
@end
@@ -491,19 +510,17 @@ var CONTROL_HEIGHT = 16.,
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self != nil)
if (self)
{
[self setBordered:NO];
[self setEditable:NO];
[self setDrawsBackground:NO];
}
return self;
}
- (id)hitTest:(CPPoint)point
- (id)hitTest:(CGPoint)point
{
if (!CPRectContainsPoint([self frame], point))
if (!CGRectContainsPoint([self frame], point))
return nil;
return [self superview];
+849 -475
View File
File diff suppressed because it is too large Load Diff
+284 -73
View File
@@ -5,6 +5,9 @@
* Created by Francisco Tolmasky.
* Copyright 2008, 280 North, Inc.
*
* Modified to match Lion style by Antoine Mercadal 2011
* <antoine.mercadal@archipelproject.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
@@ -20,8 +23,14 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "CPControl.j"
#include "../Foundation/Foundation.h"
@import "CPAnimation.j"
@import "CPControl.j"
@import "CPWindow_Constants.j"
@import "CPViewAnimation.j"
@global CPApp
// CPScroller Constants
CPScrollerNoPart = 0;
@@ -54,6 +63,17 @@ NAMES_FOR_PARTS[CPScrollerKnobSlot] = @"knob-slot";
NAMES_FOR_PARTS[CPScrollerKnob] = @"knob";
CPScrollerStyleLegacy = 0;
CPScrollerStyleOverlay = 1;
CPScrollerKnobStyleDefault = 0;
CPScrollerKnobStyleDark = 1;
CPScrollerKnobStyleLight = 2;
CPThemeStateScrollViewLegacy = CPThemeState("scroller-style-legacy");
CPThemeStateScrollerKnobLight = CPThemeState("scroller-knob-light");
CPThemeStateScrollerKnobDark = CPThemeState("scroller-knob-dark");
@implementation CPScroller : CPControl
{
CPControlSize _controlSize;
@@ -68,8 +88,19 @@ NAMES_FOR_PARTS[CPScrollerKnob] = @"knob";
CPScrollerPart _trackingPart;
float _trackingFloatValue;
CGPoint _trackingStartPoint;
CPViewAnimation _animationScroller;
BOOL _allowFadingOut @accessors(getter=allowFadingOut);
int _style;
CPTimer _timerFadeOut;
BOOL _isMouseOver;
}
#pragma mark -
#pragma mark Class methods
+ (CPString)defaultThemeClass
{
return "scroller";
@@ -78,49 +109,43 @@ NAMES_FOR_PARTS[CPScrollerKnob] = @"knob";
+ (id)themeAttributes
{
return [CPDictionary dictionaryWithJSObject:{
@"scroller-width": 15.0,
@"knob-slot-color": [CPColor lightGrayColor],
@"scroller-width": 7.0,
@"knob-slot-color": [CPNull null],
@"decrement-line-color": [CPNull null],
@"increment-line-color": [CPNull null],
@"knob-color": [CPColor grayColor],
@"knob-color": [CPNull null],
@"decrement-line-size":_CGSizeMakeZero(),
@"increment-line-size":_CGSizeMakeZero(),
@"track-inset":_CGInsetMakeZero(),
@"knob-inset": _CGInsetMakeZero(),
@"minimum-knob-length":21.0
}]
@"minimum-knob-length":21.0,
@"track-border-overlay": 9.0
}];
}
// Calculating Layout
- (id)initWithFrame:(CGRect)aFrame
+ (float)scrollerWidth
{
self = [super initWithFrame:aFrame];
if (self)
{
_controlSize = CPRegularControlSize;
_partRects = [];
[self setFloatValue:0.0];
[self setKnobProportion:1.0];
_hitPart = CPScrollerNoPart;
[self _calculateIsVertical];
}
return self;
return [self scrollerWidthInStyle:CPScrollerStyleLegacy];
}
// Determining CPScroller Size
/*!
Returns the CPScroller's width for a CPRegularControlSize.
*/
+ (float)scrollerWidth
+ (float)scrollerWidthInStyle:(int)aStyle
{
return [[[CPScroller alloc] init] currentValueForThemeAttribute:@"scroller-width"];
var scroller = [[self alloc] init];
if (aStyle == CPScrollerStyleLegacy)
return [scroller valueForThemeAttribute:@"scroller-width" inState:CPThemeStateScrollViewLegacy];
return [scroller currentValueForThemeAttribute:@"scroller-width"];
}
/*!
Returns the CPScroller's overlay value.
*/
+ (float)scrollerOverlay
{
return [[[self alloc] init] currentValueForThemeAttribute:@"track-border-overlay"];
}
/*!
@@ -132,6 +157,87 @@ NAMES_FOR_PARTS[CPScrollerKnob] = @"knob";
return [self scrollerWidth];
}
#pragma mark -
#pragma mark Initialization
- (id)initWithFrame:(CGRect)aFrame
{
if (self = [super initWithFrame:aFrame])
{
_controlSize = CPRegularControlSize;
_partRects = [];
[self setFloatValue:0.0];
[self setKnobProportion:1.0];
_hitPart = CPScrollerNoPart;
_allowFadingOut = YES;
_isMouseOver = NO;
_style = CPScrollerStyleOverlay;
var paramAnimFadeOut = [CPDictionary dictionaryWithObjects:[self, CPViewAnimationFadeOutEffect]
forKeys:[CPViewAnimationTargetKey, CPViewAnimationEffectKey]];
_animationScroller = [[CPViewAnimation alloc] initWithDuration:0.2 animationCurve:CPAnimationEaseInOut];
[_animationScroller setViewAnimations:[paramAnimFadeOut]];
[_animationScroller setDelegate:self];
[self setAlphaValue:0.0];
[self _calculateIsVertical];
}
return self;
}
#pragma mark -
#pragma mark Getters / Setters
/*!
Returns the scroller's style
*/
- (void)style
{
return _style;
}
/*!
Set the scroller's control size
@param aStyle the scroller style: CPScrollerStyleLegacy or CPScrollerStyleOverlay
*/
- (void)setStyle:(id)aStyle
{
if (_style != nil && _style === aStyle)
return;
_style = aStyle;
if (_style === CPScrollerStyleLegacy)
{
[self fadeIn];
[self setThemeState:CPThemeStateScrollViewLegacy];
}
else
{
_allowFadingOut = YES;
[self unsetThemeState:CPThemeStateScrollViewLegacy];
}
//[self _adjustScrollerSize];
}
- (void)setObjectValue:(id)aValue
{
[super setObjectValue:MIN(1.0, MAX(0.0, +aValue))];
}
/*!
Returns the scroller's control size
*/
- (CPControlSize)controlSize
{
return _controlSize;
}
/*!
Sets the scroller's size.
@param aControlSize the scroller's size
@@ -147,27 +253,6 @@ NAMES_FOR_PARTS[CPScrollerKnob] = @"knob";
[self setNeedsDisplay:YES];
}
/*!
Returns the scroller's control size
*/
- (CPControlSize)controlSize
{
return _controlSize;
}
- (void)setObjectValue:(id)aValue
{
[super setObjectValue:MIN(1.0, MAX(0.0, +aValue))];
}
- (void)setKnobProportion:(float)aProportion
{
_knobProportion = MIN(1.0, MAX(0.0001, aProportion));
[self setNeedsDisplay:YES];
[self setNeedsLayout];
}
/*!
Return's the knob's proportion
*/
@@ -176,17 +261,50 @@ NAMES_FOR_PARTS[CPScrollerKnob] = @"knob";
return _knobProportion;
}
- (id)currentValueForThemeAttribute:(CPString)anAttributeName
/*!
Set the knob's proportion
@param aProportion the desired proportion
*/
- (void)setKnobProportion:(float)aProportion
{
var themeState = _themeState;
if (!_IS_NUMERIC(aProportion))
[CPException raise:CPInvalidArgumentException reason:"aProportion must be numeric"];
if (NAMES_FOR_PARTS[_hitPart] + "-color" !== anAttributeName)
themeState &= ~CPThemeStateHighlighted;
_knobProportion = MIN(1.0, MAX(0.0001, aProportion));
return [self valueForThemeAttribute:anAttributeName inState:themeState];
[self setNeedsDisplay:YES];
[self setNeedsLayout];
}
// Calculating Layout
#pragma mark -
#pragma mark Privates
/*! @ignore */
- (void)_adjustScrollerSize
{
var frame = [self frame],
scrollerWidth = [self currentValueForThemeAttribute:@"scroller-width"];
if ([self isVertical] && CGRectGetWidth(frame) !== scrollerWidth)
frame.size.width = scrollerWidth;
if (![self isVertical] && CGRectGetHeight(frame) !== scrollerWidth)
frame.size.height = scrollerWidth;
[self setFrame:frame];
}
/*! @ignore */
- (void)_performFadeOut:(CPTimer)aTimer
{
[self fadeOut];
_timerFadeOut = nil;
}
#pragma mark -
#pragma mark Utilities
- (CGRect)rectForPart:(CPScrollerPart)aPart
{
@@ -208,6 +326,9 @@ NAMES_FOR_PARTS[CPScrollerKnob] = @"knob";
// The ordering of these tests is important. We check the knob and
// page rects first since they may overlap with the arrows.
if (![self hasThemeState:CPThemeStateSelected])
return CPScrollerNoPart;
if (CGRectContainsPoint([self rectForPart:CPScrollerKnob], aPoint))
return CPScrollerKnob;
@@ -330,7 +451,35 @@ NAMES_FOR_PARTS[CPScrollerKnob] = @"knob";
return _usableParts;
}
// Drawing the Parts
/*!
Display the scroller
*/
- (void)fadeIn
{
if (_isMouseOver && _knobProportion != 1.0)
[self setThemeState:CPThemeStateSelected];
if (_timerFadeOut)
[_timerFadeOut invalidate];
[self setAlphaValue:1.0];
}
/*!
Start the fade out anination
*/
- (void)fadeOut
{
if ([self hasThemeState:CPThemeStateScrollViewLegacy])
return;
[_animationScroller startAnimation];
}
#pragma mark -
#pragma mark Drawing
/*!
Draws the specified arrow and sets the highlight.
@param anArrow the arrow to draw
@@ -379,10 +528,12 @@ NAMES_FOR_PARTS[CPScrollerKnob] = @"knob";
- (void)layoutSubviews
{
[self _adjustScrollerSize];
[self checkSpaceForParts];
var index = 0,
count = PARTS_ARRANGEMENT.length;
count = PARTS_ARRANGEMENT.length,
view;
for (; index < count; ++index)
{
@@ -457,7 +608,7 @@ NAMES_FOR_PARTS[CPScrollerKnob] = @"knob";
}
[CPApp setTarget:self selector:@selector(trackKnob:) forNextEventMatchingMask:CPLeftMouseDraggedMask | CPLeftMouseUpMask untilDate:nil inMode:nil dequeue:YES];
if (type === CPLeftMouseDragged)
[self sendAction:[self action] to:[self target]];
}
@@ -565,6 +716,20 @@ NAMES_FOR_PARTS[CPScrollerKnob] = @"knob";
[self setNeedsLayout];
}
#pragma mark -
#pragma mark Overrides
- (id)currentValueForThemeAttribute:(CPString)anAttributeName
{
var themeState = _themeState;
if (NAMES_FOR_PARTS[_hitPart] + "-color" !== anAttributeName)
themeState &= ~CPThemeStateHighlighted;
return [self valueForThemeAttribute:anAttributeName inState:themeState];
}
- (void)mouseDown:(CPEvent)anEvent
{
if (![self isEnabled])
@@ -583,10 +748,53 @@ NAMES_FOR_PARTS[CPScrollerKnob] = @"knob";
}
}
- (void)mouseEntered:(CPEvent)anEvent
{
[super mouseEntered:anEvent];
if (_timerFadeOut)
[_timerFadeOut invalidate];
if (![self isEnabled])
return;
_allowFadingOut = NO;
_isMouseOver = YES;
if ([self alphaValue] > 0 && _knobProportion != 1.0)
[self setThemeState:CPThemeStateSelected];
}
- (void)mouseExited:(CPEvent)anEvent
{
[super mouseExited:anEvent];
if ([self isHidden] || ![self isEnabled] || !_isMouseOver)
return;
_allowFadingOut = YES;
_isMouseOver = NO;
if (_timerFadeOut)
[_timerFadeOut invalidate];
_timerFadeOut = [CPTimer scheduledTimerWithTimeInterval:1.2 target:self selector:@selector(_performFadeOut:) userInfo:nil repeats:NO];
}
#pragma mark -
#pragma mark Delegates
- (void)animationDidEnd:(CPAnimation)animation
{
[self unsetThemeState:CPThemeStateSelected];
}
@end
var CPScrollerControlSizeKey = "CPScrollerControlSize",
CPScrollerKnobProportionKey = "CPScrollerKnobProportion";
var CPScrollerControlSizeKey = @"CPScrollerControlSize",
CPScrollerKnobProportionKey = @"CPScrollerKnobProportion",
CPScrollerStyleKey = @"CPScrollerStyleKey";
@implementation CPScroller (CPCoding)
@@ -595,10 +803,12 @@ var CPScrollerControlSizeKey = "CPScrollerControlSize",
if (self = [super initWithCoder:aCoder])
{
_controlSize = CPRegularControlSize;
if ([aCoder containsValueForKey:CPScrollerControlSizeKey])
_controlSize = [aCoder decodeIntForKey:CPScrollerControlSizeKey];
_knobProportion = 1.0;
if ([aCoder containsValueForKey:CPScrollerKnobProportionKey])
_knobProportion = [aCoder decodeFloatForKey:CPScrollerKnobProportionKey];
@@ -606,20 +816,20 @@ var CPScrollerControlSizeKey = "CPScrollerControlSize",
_hitPart = CPScrollerNoPart;
_allowFadingOut = YES;
_isMouseOver = NO;
var paramAnimFadeOut = [CPDictionary dictionaryWithObjects:[self, CPViewAnimationFadeOutEffect]
forKeys:[CPViewAnimationTargetKey, CPViewAnimationEffectKey]];
_animationScroller = [[CPViewAnimation alloc] initWithDuration:0.2 animationCurve:CPAnimationEaseInOut];
[_animationScroller setViewAnimations:[paramAnimFadeOut]];
[_animationScroller setDelegate:self];
[self setAlphaValue:0.0];
[self _calculateIsVertical];
// Adjust the size of the scroller if the size from cib
// isn't equal to the scrollerWidth
var frame = [self frame],
scrollerWidth = [CPScroller scrollerWidth];
if ([self isVertical] && CGRectGetWidth(frame) !== scrollerWidth)
frame.size.width = scrollerWidth;
if (![self isVertical] && CGRectGetHeight(frame) !== scrollerWidth)
frame.size.height = scrollerWidth;
[self setFrame:frame];
[self setStyle:[aCoder decodeIntForKey:CPScrollerStyleKey]];
}
return self;
@@ -631,6 +841,7 @@ var CPScrollerControlSizeKey = "CPScrollerControlSize",
[aCoder encodeInt:_controlSize forKey:CPScrollerControlSizeKey];
[aCoder encodeFloat:_knobProportion forKey:CPScrollerKnobProportionKey];
[aCoder encodeInt:_style forKey:CPScrollerStyleKey];
}
@end
+33 -27
View File
@@ -21,22 +21,19 @@
*/
@import "CPButton.j"
@import "CPMenu.j"
@import "CPMenuItem.j"
@import "CPTextField.j"
@class CPUserDefaults
@global CPApp
CPSearchFieldRecentsTitleMenuItemTag = 1000;
CPSearchFieldRecentsMenuItemTag = 1001;
CPSearchFieldClearRecentsMenuItemTag = 1002;
CPSearchFieldNoRecentsMenuItemTag = 1003;
var CPSearchFieldSearchImage = nil,
CPSearchFieldFindImage = nil,
CPSearchFieldCancelImage = nil,
CPSearchFieldCancelPressedImage = nil;
var SEARCH_BUTTON_DEFAULT_WIDTH = 25.0,
CANCEL_BUTTON_DEFAULT_WIDTH = 22.0,
BUTTON_DEFAULT_HEIGHT = 22.0;
var CPAutosavedRecentsChangedNotification = @"CPAutosavedRecentsChangedNotification";
var RECENT_SEARCH_PREFIX = @" ";
@@ -70,16 +67,15 @@ var RECENT_SEARCH_PREFIX = @" ";
return @"searchfield"
}
+ (void)initialize
+ (CPDictionary)themeAttributes
{
if (self != [CPSearchField class])
return;
var bundle = [CPBundle bundleForClass:self];
CPSearchFieldSearchImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPSearchField/CPSearchFieldSearch.png"] size:_CGSizeMake(SEARCH_BUTTON_DEFAULT_WIDTH, BUTTON_DEFAULT_HEIGHT)];
CPSearchFieldFindImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPSearchField/CPSearchFieldFind.png"] size:_CGSizeMake(SEARCH_BUTTON_DEFAULT_WIDTH, BUTTON_DEFAULT_HEIGHT)];
CPSearchFieldCancelImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPSearchField/CPSearchFieldCancel.png"] size:_CGSizeMake(CANCEL_BUTTON_DEFAULT_WIDTH, BUTTON_DEFAULT_HEIGHT)];
CPSearchFieldCancelPressedImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPSearchField/CPSearchFieldCancelPressed.png"] size:_CGSizeMake(CANCEL_BUTTON_DEFAULT_WIDTH, BUTTON_DEFAULT_HEIGHT)];
return [CPDictionary dictionaryWithJSObject:
{
@"image-search": [CPNull null],
@"image-find": [CPNull null],
@"image-cancel": [CPNull null],
@"image-cancel-pressed": [CPNull null]
}];
}
- (id)initWithFrame:(CGRect)frame
@@ -170,10 +166,10 @@ var RECENT_SEARCH_PREFIX = @" ";
- (void)resetSearchButton
{
var button = [self searchButton],
searchButtonImage = (_searchMenuTemplate === nil) ? CPSearchFieldSearchImage : CPSearchFieldFindImage;
searchButtonImage = (_searchMenuTemplate === nil) ? [self valueForThemeAttribute:@"image-search"] : [self valueForThemeAttribute:@"image-find"];
[button setBordered:NO];
[button setImageScaling:CPScaleToFit];
[button setImageScaling:CPImageScaleAxesIndependently];
[button setImage:searchButtonImage];
[button setAutoresizingMask:CPViewMaxXMargin];
}
@@ -193,6 +189,7 @@ var RECENT_SEARCH_PREFIX = @" ";
[_cancelButton setAutoresizingMask:CPViewMinXMargin];
[_cancelButton setTarget:self];
[_cancelButton setAction:@selector(cancelOperation:)];
[_cancelButton setButtonType:CPMomentaryChangeButton];
[self _updateCancelButtonVisibility];
[self addSubview:_cancelButton];
}
@@ -215,9 +212,9 @@ var RECENT_SEARCH_PREFIX = @" ";
{
var button = [self cancelButton];
[button setBordered:NO];
[button setImageScaling:CPScaleToFit];
[button setImage:CPSearchFieldCancelImage];
[button setAlternateImage:CPSearchFieldCancelPressedImage];
[button setImageScaling:CPImageScaleAxesIndependently];
[button setImage:[self valueForThemeAttribute:@"image-cancel"]];
[button setAlternateImage:[self valueForThemeAttribute:@"image-cancel-pressed"]];
[button setAutoresizingMask:CPViewMinXMargin];
[button setTarget:self];
[button setAction:@selector(cancelOperation:)];
@@ -258,7 +255,9 @@ var RECENT_SEARCH_PREFIX = @" ";
*/
- (CGRect)searchButtonRectForBounds:(CGRect)rect
{
return _CGRectMake(5, (_CGRectGetHeight(rect) - BUTTON_DEFAULT_HEIGHT) / 2, SEARCH_BUTTON_DEFAULT_WIDTH, BUTTON_DEFAULT_HEIGHT);
var size = [[self valueForThemeAttribute:@"image-search"] size] || CGSizeMakeZero();
return _CGRectMake(5, (_CGRectGetHeight(rect) - size.height) / 2, size.width, size.height);
}
/*!
@@ -268,7 +267,9 @@ var RECENT_SEARCH_PREFIX = @" ";
*/
- (CGRect)cancelButtonRectForBounds:(CGRect)rect
{
return _CGRectMake(_CGRectGetWidth(rect) - CANCEL_BUTTON_DEFAULT_WIDTH - 5, (_CGRectGetHeight(rect) - CANCEL_BUTTON_DEFAULT_WIDTH) / 2, BUTTON_DEFAULT_HEIGHT, BUTTON_DEFAULT_HEIGHT);
var size = [[self valueForThemeAttribute:@"image-cancel"] size] || CGSizeMakeZero();
return _CGRectMake(_CGRectGetWidth(rect) - size.width - 5, (_CGRectGetHeight(rect) - size.width) / 2, size.height, size.height);
}
// Managing Menu Templates
@@ -501,7 +502,12 @@ var RECENT_SEARCH_PREFIX = @" ";
if (_CGRectContainsPoint([self searchButtonRectForBounds:[self bounds]], point))
{
if (_searchMenuTemplate == nil)
[self _sendAction:self];
{
if ([_searchButton target] && [_searchButton action])
[_searchButton mouseDown:anEvent];
else
[self _sendAction:self];
}
else
[self _showMenu];
}
@@ -674,7 +680,7 @@ var RECENT_SEARCH_PREFIX = @" ";
return;
var aFrame = [[self superview] convertRect:[self frame] toView:nil],
location = CPMakePoint(aFrame.origin.x + 10, aFrame.origin.y + aFrame.size.height - 4);
location = CGPointMake(aFrame.origin.x + 10, aFrame.origin.y + aFrame.size.height - 4);
var anEvent = [CPEvent mouseEventWithType:CPRightMouseDown location:location modifierFlags:0 timestamp:[[CPApp currentEvent] timestamp] windowNumber:[[self window] windowNumber] context:nil eventNumber:1 clickCount:1 pressure:0];
+19 -10
View File
@@ -23,7 +23,10 @@
@import <Foundation/CPArray.j>
@import "CPControl.j"
@import "CPWindow_Constants.j"
@import "_CPImageAndTextView.j"
@global CPApp
CPSegmentSwitchTrackingSelectOne = 0;
CPSegmentSwitchTrackingSelectAny = 1;
@@ -55,7 +58,7 @@ CPSegmentSwitchTrackingMomentary = 2;
+ (id)themeAttributes
{
return [CPDictionary dictionaryWithObjects:[CPCenterTextAlignment, CPCenterVerticalTextAlignment, CPImageLeft, CPScaleNone, _CGInsetMakeZero(), _CGInsetMakeZero(), [CPNull null], [CPNull null], [CPNull null], [CPNull null], 1.0, 24.0]
return [CPDictionary dictionaryWithObjects:[CPCenterTextAlignment, CPCenterVerticalTextAlignment, CPImageLeft, CPImageScaleNone, _CGInsetMakeZero(), _CGInsetMakeZero(), [CPNull null], [CPNull null], [CPNull null], [CPNull null], 1.0, 24.0]
forKeys:[@"alignment", @"vertical-alignment", @"image-position", @"image-scaling", @"bezel-inset", @"content-inset", @"left-segment-bezel-color", @"right-segment-bezel-color", @"center-segment-bezel-color", @"divider-bezel-color", @"divider-thickness", @"default-height"]];
}
@@ -115,13 +118,15 @@ CPSegmentSwitchTrackingMomentary = 2;
if (_selectedSegment >= _segments.length)
_selectedSegment = -1;
// Make space for/remove space used by dividers.
var thickness = [self currentValueForThemeAttribute:@"divider-thickness"],
delta = thickness * (dividersAfter - dividersBefore),
frame = [self frame];
frame = [self frame],
widthOfAllSegments = 0,
dividerExtraSpace = ([_segments count] - 1) * thickness;
if (delta)
[self setFrameSize:CGSizeMake(frame.size.width + delta, frame.size.height)];
for (var i = 0; i < [_segments count]; i++)
widthOfAllSegments += [_segments[i] width];
[self setFrameSize:CGSizeMake(widthOfAllSegments + dividerExtraSpace, frame.size.height)];
[self tileWithChangedSegment:0];
}
@@ -366,11 +371,14 @@ CPSegmentSwitchTrackingMomentary = 2;
@param aSegment the segment to enable/disable
@throws CPRangeException if \c aSegment is out of bounds
*/
- (void)setEnabled:(BOOL)isEnabled forSegment:(unsigned)aSegment
- (void)setEnabled:(BOOL)shouldBeEnabled forSegment:(unsigned)aSegment
{
[_segments[aSegment] setEnabled:isEnabled];
if ([_segments[aSegment] enabled] === shouldBeEnabled)
return;
if (isEnabled)
[_segments[aSegment] setEnabled:shouldBeEnabled];
if (shouldBeEnabled)
_themeStates[aSegment] &= ~CPThemeStateDisabled;
else
_themeStates[aSegment] |= CPThemeStateDisabled;
@@ -460,7 +468,7 @@ CPSegmentSwitchTrackingMomentary = 2;
}
else if (aName === "right-segment-bezel")
{
return CPRectMake(CGRectGetWidth([self bounds]) - contentInset.right,
return CGRectMake(CGRectGetWidth([self bounds]) - contentInset.right,
bezelInset.top,
contentInset.right,
height);
@@ -796,6 +804,7 @@ CPSegmentSwitchTrackingMomentary = 2;
return;
var highlighted = [self testSegment:location] === _trackingSegment;
if (highlighted != _trackingHighlighted)
{
_trackingHighlighted = highlighted;
+4 -4
View File
@@ -31,7 +31,7 @@
*/
@implementation CPShadow : CPObject
{
CPSize _offset;
CGSize _offset;
float _blurRadius;
CPColor _color;
@@ -51,7 +51,7 @@
}
/* @ignore */
- (id)_initWithOffset:(CPSize)anOffset blurRadius:(float)aBlurRadius color:(CPColor)aColor
- (id)_initWithOffset:(CGSize)anOffset blurRadius:(float)aBlurRadius color:(CPColor)aColor
{
self = [super init];
@@ -61,7 +61,7 @@
_blurRadius = aBlurRadius;
_color = aColor;
_cssString = [_color cssString] + " " + Math.round(anOffset.width) + @"px " + Math.round(anOffset.height) + @"px " + Math.round(_blurRadius) + @"px";
_cssString = [_color cssString] + " " + ROUND(anOffset.width) + @"px " + ROUND(anOffset.height) + @"px " + ROUND(_blurRadius) + @"px";
}
return self;
@@ -99,4 +99,4 @@
return _cssString;
}
@end
@end
+55 -81
View File
@@ -24,71 +24,44 @@
@import "CGGeometry.j"
@import "CPImage.j"
@import "CPImageView.j"
@import "CPView.j"
CPLightShadow = 0;
CPHeavyShadow = 1;
var CPShadowViewLightBackgroundColor = nil,
CPShadowViewHeavyBackgroundColor = nil;
CPThemeStateShadowViewLight = CPThemeState("shadowview-style-light");
CPThemeStateShadowViewHeavy = CPThemeState("shadowview-style-heavy");
var LIGHT_LEFT_INSET = 3.0,
LIGHT_RIGHT_INSET = 3.0,
LIGHT_TOP_INSET = 3.0,
LIGHT_BOTTOM_INSET = 5.0,
HEAVY_LEFT_INSET = 7.0,
HEAVY_RIGHT_INSET = 7.0,
HEAVY_TOP_INSET = 5.0,
HEAVY_BOTTOM_INSET = 5.0;
/*!
@ingroup appkit
*/
@implementation CPShadowView : CPView
{
CPShadowWeight _weight;
}
+ (void)initialize
+ (CPString)defaultThemeClass
{
if (self != [CPShadowView class])
return;
return "shadow-view";
}
var bundle = [CPBundle bundleForClass:[self class]];
+ (id)themeAttributes
{
return [CPDictionary dictionaryWithJSObject:
{
@"bezel-color": [CPNull null],
@"content-inset": CGInsetMakeZero()
}];
}
CPShadowViewLightBackgroundColor = [CPColor colorWithPatternImage:[[CPNinePartImage alloc] initWithImageSlices:
[
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPShadowView/CPShadowViewLightTopLeft.png"] size:CGSizeMake(9.0, 9.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPShadowView/CPShadowViewLightTop.png"] size:CGSizeMake(1.0, 9.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPShadowView/CPShadowViewLightTopRight.png"] size:CGSizeMake(9.0, 9.0)],
+ (CGRect)frameForContentFrame:(CGRect)aFrame withWeight:(CPShadowWeight)aWeight
{
var shadowView = [CPShadowView new],
inset = [shadowView valueForThemeAttribute:@"content-inset" inState:(aWeight == CPLightShadow) ? CPThemeStateShadowViewLight : CPThemeStateShadowViewHeavy];
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPShadowView/CPShadowViewLightLeft.png"] size:CGSizeMake(9.0, 1.0)],
nil,
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPShadowView/CPShadowViewLightRight.png"] size:CGSizeMake(9.0, 1.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPShadowView/CPShadowViewLightBottomLeft.png"] size:CGSizeMake(9.0, 9.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPShadowView/CPShadowViewLightBottom.png"] size:CGSizeMake(1.0, 9.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPShadowView/CPShadowViewLightBottomRight.png"] size:CGSizeMake(9.0, 9.0)]
]]];
CPShadowViewHeavyBackgroundColor = [CPColor colorWithPatternImage:[[CPNinePartImage alloc] initWithImageSlices:
[
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPShadowView/CPShadowViewHeavyTopLeft.png"] size:CGSizeMake(17.0, 17.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPShadowView/CPShadowViewHeavyTop.png"] size:CGSizeMake(1.0, 17.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPShadowView/CPShadowViewHeavyTopRight.png"] size:CGSizeMake(17.0, 17.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPShadowView/CPShadowViewHeavyLeft.png"] size:CGSizeMake(17.0, 1.0)],
nil,
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPShadowView/CPShadowViewHeavyRight.png"] size:CGSizeMake(17.0, 1.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPShadowView/CPShadowViewHeavyBottomLeft.png"] size:CGSizeMake(17.0, 17.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPShadowView/CPShadowViewHeavyBottom.png"] size:CGSizeMake(1.0, 17.0)],
[[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPShadowView/CPShadowViewHeavyBottomRight.png"] size:CGSizeMake(17.0, 17.0)]
]]];
return CGRectMake(_CGRectGetMinX(aFrame) - inset.left, _CGRectGetMinY(aFrame) - inset.top, _CGRectGetWidth(aFrame) + inset.left + inset.right, _CGRectGetHeight(aFrame) + inset.top + inset.bottom);
}
+ (id)shadowViewEnclosingView:(CPView)aView
@@ -98,20 +71,25 @@ var LIGHT_LEFT_INSET = 3.0,
+ (id)shadowViewEnclosingView:(CPView)aView withWeight:(CPShadowWeight)aWeight
{
var shadowView = [[CPShadowView alloc] initWithFrame:[aView frame]];
[shadowView setWeight:aWeight];
var shadowView = [[self alloc] initWithFrame:[aView frame]];
var size = [shadowView frame].size,
width = size.width - [shadowView leftInset] - [shadowView rightInset],
height = size.height - [shadowView topInset] - [shadowView bottomInset],
enclosingView = [aView superview];
if (shadowView)
{
[shadowView setWeight:aWeight];
[shadowView setHitTests:[aView hitTests]];
[shadowView setAutoresizingMask:[aView autoresizingMask]];
[aView removeFromSuperview];
[shadowView addSubview:aView];
[aView setFrame:CGRectMake([shadowView leftInset], [shadowView topInset], width, height)]
[enclosingView addSubview:shadowView];
var size = [shadowView frame].size,
inset = [shadowView currentValueForThemeAttribute:@"content-inset"],
width = size.width - inset.left - inset.right,
height = size.height - inset.top - inset.bottom,
enclosingView = [aView superview];
[shadowView setHitTests:[aView hitTests]];
[shadowView setAutoresizingMask:[aView autoresizingMask]];
[aView removeFromSuperview];
[shadowView addSubview:aView];
[aView setFrame:CGRectMake(inset.left, inset.top, width, height)];
[enclosingView addSubview:shadowView];
}
return shadowView;
}
@@ -122,9 +100,7 @@ var LIGHT_LEFT_INSET = 3.0,
if (self)
{
_weight = CPLightShadow;
[self setBackgroundColor:CPShadowViewLightBackgroundColor];
[self setWeight:CPLightShadow];
[self setHitTests:NO];
}
@@ -140,54 +116,45 @@ var LIGHT_LEFT_INSET = 3.0,
_weight = aWeight;
if (_weight == CPLightShadow)
[self setBackgroundColor:CPShadowViewLightBackgroundColor];
[self setThemeState:CPThemeStateShadowViewLight];
else
[self setBackgroundColor:CPShadowViewHeavyBackgroundColor];
[self setThemeState:CPThemeStateShadowViewHeavy];
[self setNeedsLayout];
}
- (float)leftInset
{
return _weight == CPLightShadow ? LIGHT_LEFT_INSET : HEAVY_LEFT_INSET;
return [self currentValueForThemeAttribute:@"content-inset"].left;
}
- (float)rightInset
{
return _weight == CPLightShadow ? LIGHT_RIGHT_INSET : HEAVY_RIGHT_INSET;
return [self currentValueForThemeAttribute:@"content-inset"].right;
}
- (float)topInset
{
return _weight == CPLightShadow ? LIGHT_TOP_INSET : HEAVY_TOP_INSET;
return [self currentValueForThemeAttribute:@"content-inset"].top;
}
- (float)bottomInset
{
return _weight == CPLightShadow ? LIGHT_BOTTOM_INSET : HEAVY_BOTTOM_INSET;
return [self currentValueForThemeAttribute:@"content-inset"].bottom;
}
- (float)horizontalInset
{
if (_weight == CPLightShadow)
return LIGHT_LEFT_INSET + LIGHT_RIGHT_INSET;
var currentContentInset = [self currentValueForThemeAttribute:@"content-inset"];
return HEAVY_LEFT_INSET + HEAVY_RIGHT_INSET;
return currentContentInset.left + currentContentInset.right;
}
- (float)verticalInset
{
if (_weight == CPLightShadow)
return LIGHT_TOP_INSET + LIGHT_BOTTOM_INSET;
var currentContentInset = [self currentValueForThemeAttribute:@"content-inset"];
return HEAVY_TOP_INSET + HEAVY_BOTTOM_INSET;
}
+ (CGRect)frameForContentFrame:(CGRect)aFrame withWeight:(CPShadowWeight)aWeight
{
if (aWeight == CPLightShadow)
return CGRectMake(_CGRectGetMinX(aFrame) - LIGHT_LEFT_INSET, _CGRectGetMinY(aFrame) - LIGHT_TOP_INSET, _CGRectGetWidth(aFrame) + LIGHT_LEFT_INSET + LIGHT_RIGHT_INSET, _CGRectGetHeight(aFrame) + LIGHT_TOP_INSET + LIGHT_BOTTOM_INSET);
else
return CGRectMake(_CGRectGetMinX(aFrame) - HEAVY_LEFT_INSET, _CGRectGetMinY(aFrame) - HEAVY_TOP_INSET, _CGRectGetWidth(aFrame) + HEAVY_LEFT_INSET + HEAVY_RIGHT_INSET, _CGRectGetHeight(aFrame) + HEAVY_TOP_INSET + HEAVY_BOTTOM_INSET);
return currentContentInset.top + currentContentInset.bottom;
}
- (CGRect)frameForContentFrame:(CGRect)aFrame
@@ -200,4 +167,11 @@ var LIGHT_LEFT_INSET = 3.0,
[self setFrame:[self frameForContentFrame:aFrame]];
}
- (void)layoutSubviews
{
[super layoutSubviews];
[self setBackgroundColor:[self currentValueForThemeAttribute:@"bezel-color"]];
}
@end
+3
View File
@@ -21,6 +21,7 @@
*/
@import "CPControl.j"
@import "CPWindow_Constants.j"
/*! SLIDER STATES */
@@ -39,6 +40,8 @@ CPCircularSlider = 1;
double _altIncrementValue;
BOOL _isVertical;
CGSize _dragOffset;
}
+ (CPString)defaultThemeClass
+149 -143
View File
@@ -20,8 +20,14 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "CPView.j"
@import "CPColorPicker.j"
@import "CPSlider.j"
@import "CPTextField.j"
@import "CPView.j"
@global CPColorPickerViewWidth
@global CPColorPickerViewHeight
@global CPSliderColorPickerMode
/*
@@ -60,166 +66,166 @@
- (id)initWithPickerMask:(int)mask colorPanel:(CPColorPanel)owningColorPanel
{
return [super initWithPickerMask:mask colorPanel: owningColorPanel];
return [super initWithPickerMask:mask colorPanel:owningColorPanel];
}
- (id)initView
{
aFrame = CGRectMake(0, 0, CPColorPickerViewWidth, CPColorPickerViewHeight);
var aFrame = CGRectMake(0, 0, CPColorPickerViewWidth, CPColorPickerViewHeight);
_contentView = [[CPView alloc] initWithFrame:aFrame];
[_contentView setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
_rgbLabel = [[CPTextField alloc] initWithFrame: CGRectMake(0, 10, 100, 20)];
[_rgbLabel setStringValue: "Red, Green, Blue"];
_rgbLabel = [[CPTextField alloc] initWithFrame:CGRectMake(0, 10, 100, 20)];
[_rgbLabel setStringValue:"Red, Green, Blue"];
[_rgbLabel setTextColor:[CPColor blackColor]];
_redLabel = [[CPTextField alloc] initWithFrame: CGRectMake(0, 37, 15, 20)];
[_redLabel setStringValue: "R"];
_redLabel = [[CPTextField alloc] initWithFrame:CGRectMake(0, 37, 15, 20)];
[_redLabel setStringValue:"R"];
[_redLabel setTextColor:[CPColor blackColor]];
_redSlider = [[CPSlider alloc] initWithFrame: CGRectMake(15, 35, aFrame.size.width - 70, 20)];
[_redSlider setMaxValue: 1.0];
[_redSlider setMinValue: 0.0];
[_redSlider setTarget: self];
[_redSlider setAction: @selector(sliderChanged:)];
[_redSlider setAutoresizingMask: CPViewWidthSizable];
_redSlider = [[CPSlider alloc] initWithFrame:CGRectMake(15, 35, aFrame.size.width - 70, 20)];
[_redSlider setMaxValue:1.0];
[_redSlider setMinValue:0.0];
[_redSlider setTarget:self];
[_redSlider setAction:@selector(sliderChanged:)];
[_redSlider setAutoresizingMask:CPViewWidthSizable];
// red value input box
_redValue = [[CPTextField alloc] initWithFrame: CGRectMake(aFrame.size.width - 45, 30, 45, 28)];
[_redValue setAutoresizingMask: CPViewMinXMargin];
[_redValue setEditable: YES];
[_redValue setBezeled: YES];
[_redValue setDelegate: self];
[_contentView addSubview: _redValue];
_redValue = [[CPTextField alloc] initWithFrame:CGRectMake(aFrame.size.width - 45, 30, 45, 28)];
[_redValue setAutoresizingMask:CPViewMinXMargin];
[_redValue setEditable:YES];
[_redValue setBezeled:YES];
[_redValue setDelegate:self];
[_contentView addSubview:_redValue];
_greenLabel = [[CPTextField alloc] initWithFrame: CGRectMake(0, 63, 15, 20)];
[_greenLabel setStringValue: "G"];
_greenLabel = [[CPTextField alloc] initWithFrame:CGRectMake(0, 63, 15, 20)];
[_greenLabel setStringValue:"G"];
[_greenLabel setTextColor:[CPColor blackColor]];
_greenSlider = [[CPSlider alloc] initWithFrame: CGRectMake(15, 61, aFrame.size.width - 70, 20)];
[_greenSlider setMaxValue: 1.0];
[_greenSlider setMinValue: 0.0];
[_greenSlider setTarget: self];
[_greenSlider setAction: @selector(sliderChanged:)];
[_greenSlider setAutoresizingMask: CPViewWidthSizable];
_greenSlider = [[CPSlider alloc] initWithFrame:CGRectMake(15, 61, aFrame.size.width - 70, 20)];
[_greenSlider setMaxValue:1.0];
[_greenSlider setMinValue:0.0];
[_greenSlider setTarget:self];
[_greenSlider setAction:@selector(sliderChanged:)];
[_greenSlider setAutoresizingMask:CPViewWidthSizable];
// green value input box
_greenValue = [[CPTextField alloc] initWithFrame: CGRectMake(aFrame.size.width - 45, 56, 45, 28)];
[_greenValue setAutoresizingMask: CPViewMinXMargin];
[_greenValue setEditable: YES];
[_greenValue setBezeled: YES];
[_greenValue setDelegate: self];
[_contentView addSubview: _greenValue];
_greenValue = [[CPTextField alloc] initWithFrame:CGRectMake(aFrame.size.width - 45, 56, 45, 28)];
[_greenValue setAutoresizingMask:CPViewMinXMargin];
[_greenValue setEditable:YES];
[_greenValue setBezeled:YES];
[_greenValue setDelegate:self];
[_contentView addSubview:_greenValue];
_blueLabel = [[CPTextField alloc] initWithFrame: CGRectMake(0, 90, 15, 20)];
[_blueLabel setStringValue: "B"];
_blueLabel = [[CPTextField alloc] initWithFrame:CGRectMake(0, 90, 15, 20)];
[_blueLabel setStringValue:"B"];
[_blueLabel setTextColor:[CPColor blackColor]];
_blueSlider = [[CPSlider alloc] initWithFrame: CGRectMake(15, 87, aFrame.size.width - 70, 20)];
[_blueSlider setMaxValue: 1.0];
[_blueSlider setMinValue: 0.0];
[_blueSlider setTarget: self];
[_blueSlider setAction: @selector(sliderChanged:)];
[_blueSlider setAutoresizingMask: CPViewWidthSizable];
_blueSlider = [[CPSlider alloc] initWithFrame:CGRectMake(15, 87, aFrame.size.width - 70, 20)];
[_blueSlider setMaxValue:1.0];
[_blueSlider setMinValue:0.0];
[_blueSlider setTarget:self];
[_blueSlider setAction:@selector(sliderChanged:)];
[_blueSlider setAutoresizingMask:CPViewWidthSizable];
// blue value input box
_blueValue = [[CPTextField alloc] initWithFrame: CGRectMake(aFrame.size.width - 45, 82, 45, 28)];
[_blueValue setAutoresizingMask: CPViewMinXMargin];
[_blueValue setEditable: YES];
[_blueValue setBezeled: YES];
[_blueValue setDelegate: self];
[_contentView addSubview: _blueValue];
_blueValue = [[CPTextField alloc] initWithFrame:CGRectMake(aFrame.size.width - 45, 82, 45, 28)];
[_blueValue setAutoresizingMask:CPViewMinXMargin];
[_blueValue setEditable:YES];
[_blueValue setBezeled:YES];
[_blueValue setDelegate:self];
[_contentView addSubview:_blueValue];
_hsbLabel = [[CPTextField alloc] initWithFrame: CGRectMake(0, 120, 190, 20)];
[_hsbLabel setStringValue: "Hue, Saturation, Brightness"];
_hsbLabel = [[CPTextField alloc] initWithFrame:CGRectMake(0, 120, 190, 20)];
[_hsbLabel setStringValue:"Hue, Saturation, Brightness"];
[_hsbLabel setTextColor:[CPColor blackColor]];
_hueLabel = [[CPTextField alloc] initWithFrame: CGRectMake(0, 145, 15, 20)];
[_hueLabel setStringValue: "H"];
_hueLabel = [[CPTextField alloc] initWithFrame:CGRectMake(0, 145, 15, 20)];
[_hueLabel setStringValue:"H"];
[_hueLabel setTextColor:[CPColor blackColor]];
_hueSlider = [[CPSlider alloc] initWithFrame: CGRectMake(15, 143, aFrame.size.width - 70, 20)];
[_hueSlider setMaxValue: 359.0];
[_hueSlider setMinValue: 0.0];
[_hueSlider setTarget: self];
[_hueSlider setAction: @selector(sliderChanged:)];
[_hueSlider setAutoresizingMask: CPViewWidthSizable];
_hueSlider = [[CPSlider alloc] initWithFrame:CGRectMake(15, 143, aFrame.size.width - 70, 20)];
[_hueSlider setMaxValue:359.0];
[_hueSlider setMinValue:0.0];
[_hueSlider setTarget:self];
[_hueSlider setAction:@selector(sliderChanged:)];
[_hueSlider setAutoresizingMask:CPViewWidthSizable];
// hue value input box
_hueValue = [[CPTextField alloc] initWithFrame: CGRectMake(aFrame.size.width - 45, 138, 45, 28)];
[_hueValue setAutoresizingMask: CPViewMinXMargin];
[_hueValue setEditable: YES];
[_hueValue setBezeled: YES];
[_hueValue setDelegate: self];
[_contentView addSubview: _hueValue];
_hueValue = [[CPTextField alloc] initWithFrame:CGRectMake(aFrame.size.width - 45, 138, 45, 28)];
[_hueValue setAutoresizingMask:CPViewMinXMargin];
[_hueValue setEditable:YES];
[_hueValue setBezeled:YES];
[_hueValue setDelegate:self];
[_contentView addSubview:_hueValue];
_saturationLabel = [[CPTextField alloc] initWithFrame: CGRectMake(0, 170, 15, 20)];
[_saturationLabel setStringValue: "S"];
_saturationLabel = [[CPTextField alloc] initWithFrame:CGRectMake(0, 170, 15, 20)];
[_saturationLabel setStringValue:"S"];
[_saturationLabel setTextColor:[CPColor blackColor]];
_saturationSlider = [[CPSlider alloc] initWithFrame: CGRectMake(15, 168, aFrame.size.width - 70, 20)];
[_saturationSlider setMaxValue: 100.0];
[_saturationSlider setMinValue: 0.0];
[_saturationSlider setTarget: self];
[_saturationSlider setAction: @selector(sliderChanged:)];
[_saturationSlider setAutoresizingMask: CPViewWidthSizable];
_saturationSlider = [[CPSlider alloc] initWithFrame:CGRectMake(15, 168, aFrame.size.width - 70, 20)];
[_saturationSlider setMaxValue:100.0];
[_saturationSlider setMinValue:0.0];
[_saturationSlider setTarget:self];
[_saturationSlider setAction:@selector(sliderChanged:)];
[_saturationSlider setAutoresizingMask:CPViewWidthSizable];
// saturation value input box
_saturationValue = [[CPTextField alloc] initWithFrame: CGRectMake(aFrame.size.width - 45, 164, 45, 28)];
[_saturationValue setAutoresizingMask: CPViewMinXMargin];
[_saturationValue setEditable: YES];
[_saturationValue setBezeled: YES];
[_saturationValue setDelegate: self];
[_contentView addSubview: _saturationValue];
_saturationValue = [[CPTextField alloc] initWithFrame:CGRectMake(aFrame.size.width - 45, 164, 45, 28)];
[_saturationValue setAutoresizingMask:CPViewMinXMargin];
[_saturationValue setEditable:YES];
[_saturationValue setBezeled:YES];
[_saturationValue setDelegate:self];
[_contentView addSubview:_saturationValue];
_brightnessLabel = [[CPTextField alloc] initWithFrame: CGRectMake(0, 196, 15, 20)];
[_brightnessLabel setStringValue: "B"];
_brightnessLabel = [[CPTextField alloc] initWithFrame:CGRectMake(0, 196, 15, 20)];
[_brightnessLabel setStringValue:"B"];
[_brightnessLabel setTextColor:[CPColor blackColor]];
_brightnessSlider = [[CPSlider alloc] initWithFrame: CGRectMake(15, 194, aFrame.size.width - 70, 20)];
[_brightnessSlider setMaxValue: 100.0];
[_brightnessSlider setMinValue: 0.0];
[_brightnessSlider setTarget: self];
[_brightnessSlider setAction: @selector(sliderChanged:)];
[_brightnessSlider setAutoresizingMask: CPViewWidthSizable];
_brightnessSlider = [[CPSlider alloc] initWithFrame:CGRectMake(15, 194, aFrame.size.width - 70, 20)];
[_brightnessSlider setMaxValue:100.0];
[_brightnessSlider setMinValue:0.0];
[_brightnessSlider setTarget:self];
[_brightnessSlider setAction:@selector(sliderChanged:)];
[_brightnessSlider setAutoresizingMask:CPViewWidthSizable];
// brightness value input box
_brightnessValue = [[CPTextField alloc] initWithFrame: CGRectMake(aFrame.size.width - 45, 190, 45, 28)];
[_brightnessValue setAutoresizingMask: CPViewMinXMargin];
[_brightnessValue setEditable: YES];
[_brightnessValue setBezeled: YES];
[_brightnessValue setDelegate: self];
[_contentView addSubview: _brightnessValue];
_brightnessValue = [[CPTextField alloc] initWithFrame:CGRectMake(aFrame.size.width - 45, 190, 45, 28)];
[_brightnessValue setAutoresizingMask:CPViewMinXMargin];
[_brightnessValue setEditable:YES];
[_brightnessValue setBezeled:YES];
[_brightnessValue setDelegate:self];
[_contentView addSubview:_brightnessValue];
_hexLabel = [[CPTextField alloc] initWithFrame: CGRectMake(0, 230, 30, 20)];
[_hexLabel setStringValue: "Hex"];
_hexLabel = [[CPTextField alloc] initWithFrame:CGRectMake(0, 230, 30, 20)];
[_hexLabel setStringValue:"Hex"];
[_hexLabel setTextColor:[CPColor blackColor]];
//hex input box
_hexValue = [[CPTextField alloc] initWithFrame: CGRectMake(32, 225, 80, 28)];
[_hexValue setEditable: YES];
[_hexValue setBezeled: YES];
[_hexValue setDelegate: self];
[_contentView addSubview: _hexValue];
_hexValue = [[CPTextField alloc] initWithFrame:CGRectMake(32, 225, 80, 28)];
[_hexValue setEditable:YES];
[_hexValue setBezeled:YES];
[_hexValue setDelegate:self];
[_contentView addSubview:_hexValue];
[_contentView addSubview: _rgbLabel];
[_contentView addSubview: _redLabel];
[_contentView addSubview: _greenLabel];
[_contentView addSubview: _blueLabel];
[_contentView addSubview: _redSlider];
[_contentView addSubview: _greenSlider];
[_contentView addSubview: _blueSlider];
[_contentView addSubview:_rgbLabel];
[_contentView addSubview:_redLabel];
[_contentView addSubview:_greenLabel];
[_contentView addSubview:_blueLabel];
[_contentView addSubview:_redSlider];
[_contentView addSubview:_greenSlider];
[_contentView addSubview:_blueSlider];
[_contentView addSubview: _hsbLabel];
[_contentView addSubview: _hueLabel];
[_contentView addSubview: _saturationLabel];
[_contentView addSubview: _brightnessLabel];
[_contentView addSubview: _hueSlider];
[_contentView addSubview: _saturationSlider];
[_contentView addSubview: _brightnessSlider];
[_contentView addSubview:_hsbLabel];
[_contentView addSubview:_hueLabel];
[_contentView addSubview:_saturationLabel];
[_contentView addSubview:_brightnessLabel];
[_contentView addSubview:_hueSlider];
[_contentView addSubview:_saturationSlider];
[_contentView addSubview:_brightnessSlider];
[_contentView addSubview: _hexLabel];
[_contentView addSubview:_hexLabel];
}
- (CPView)provideNewView:(BOOL)initialRequest
@@ -250,35 +256,35 @@
{
case _hueSlider:
case _saturationSlider:
case _brightnessSlider: newColor = [CPColor colorWithHue: [_hueSlider floatValue]
saturation: [_saturationSlider floatValue]
brightness: [_brightnessSlider floatValue]
alpha: alpha];
case _brightnessSlider: newColor = [CPColor colorWithHue:[_hueSlider floatValue]
saturation:[_saturationSlider floatValue]
brightness:[_brightnessSlider floatValue]
alpha:alpha];
[self updateRGBSliders: newColor];
[self updateRGBSliders:newColor];
break;
case _redSlider:
case _greenSlider:
case _blueSlider: newColor = [CPColor colorWithCalibratedRed: [_redSlider floatValue]
green: [_greenSlider floatValue]
blue: [_blueSlider floatValue]
alpha: alpha];
case _blueSlider: newColor = [CPColor colorWithCalibratedRed:[_redSlider floatValue]
green:[_greenSlider floatValue]
blue:[_blueSlider floatValue]
alpha:alpha];
[self updateHSBSliders: newColor];
[self updateHSBSliders:newColor];
break;
}
[self updateLabels];
[self updateHex: newColor];
[colorPanel setColor: newColor];
[self updateHex:newColor];
[colorPanel setColor:newColor];
}
- (void)setColor:(CPColor)aColor
{
[self updateRGBSliders: aColor];
[self updateHSBSliders: aColor];
[self updateHex: aColor];
[self updateRGBSliders:aColor];
[self updateHSBSliders:aColor];
[self updateHex:aColor];
[self updateLabels];
}
@@ -307,13 +313,13 @@
- (void)updateLabels
{
[_hueValue setStringValue: ROUND([_hueSlider floatValue])];
[_saturationValue setStringValue: ROUND([_saturationSlider floatValue])];
[_brightnessValue setStringValue: ROUND([_brightnessSlider floatValue])];
[_hueValue setStringValue:ROUND([_hueSlider floatValue])];
[_saturationValue setStringValue:ROUND([_saturationSlider floatValue])];
[_brightnessValue setStringValue:ROUND([_brightnessSlider floatValue])];
[_redValue setStringValue: ROUND([_redSlider floatValue] * 255)];
[_greenValue setStringValue: ROUND([_greenSlider floatValue] * 255)];
[_blueValue setStringValue: ROUND([_blueSlider floatValue] * 255)];
[_redValue setStringValue:ROUND([_redSlider floatValue] * 255)];
[_greenValue setStringValue:ROUND([_greenSlider floatValue] * 255)];
[_blueValue setStringValue:ROUND([_blueSlider floatValue] * 255)];
}
- (CPImage)provideNewButtonImage
@@ -333,12 +339,12 @@
if (field === _hexValue)
{
var newColor = [CPColor colorWithHexString: value];
var newColor = [CPColor colorWithHexString:value];
if (newColor)
{
[self setColor: newColor];
[[self colorPanel] setColor: newColor];
[self setColor:newColor];
[[self colorPanel] setColor:newColor];
}
}
else
@@ -346,27 +352,27 @@
switch (field)
{
case _redValue: [_redSlider setFloatValue:MAX(MIN(ROUND(value), 255) / 255.0, 0)];
[self sliderChanged: _redSlider];
[self sliderChanged:_redSlider];
break;
case _greenValue: [_greenSlider setFloatValue:MAX(MIN(ROUND(value), 255) / 255.0, 0)];
[self sliderChanged: _greenSlider];
[self sliderChanged:_greenSlider];
break;
case _blueValue: [_blueSlider setFloatValue:MAX(MIN(ROUND(value), 255) / 255.0, 0)];
[self sliderChanged: _blueSlider];
[self sliderChanged:_blueSlider];
break;
case _hueValue: [_hueSlider setFloatValue:MAX(MIN(ROUND(value), 360), 0)];
[self sliderChanged: _hueSlider];
[self sliderChanged:_hueSlider];
break;
case _saturationValue: [_saturationSlider setFloatValue:MAX(MIN(ROUND(value), 100), 0)];
[self sliderChanged: _saturationSlider];
[self sliderChanged:_saturationSlider];
break;
case _brightnessValue: [_brightnessSlider setFloatValue:MAX(MIN(ROUND(value), 100), 0)];
[self sliderChanged: _brightnessSlider];
[self sliderChanged:_brightnessSlider];
break;
}
}
+2 -1
View File
@@ -21,6 +21,7 @@
*/
@import <Foundation/CPObject.j>
@import <Foundation/CPRunLoop.j>
CPSoundLoadStateEmpty = 0;
CPSoundLoadStateLoading = 1;
@@ -59,7 +60,7 @@ CPSoundPlayBackStatePause = 2;
if (self = [super init])
{
_loadStatus = CPSoundLoadStateEmpty;
_loops = NO;
// _loops = NO;
_audioTag = document.createElement("audio");
_audioTag.preload = YES;
_playRequestBeforeLoad = NO;
+461 -102
View File
@@ -20,16 +20,44 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "../Foundation/Foundation.h"
@import "CPButtonBar.j"
@import "CPImage.j"
@import "CPView.j"
@import "CPCursor.j"
@class CPUserDefaults
@global CPApp
#define SPLIT_VIEW_MAYBE_POST_WILL_RESIZE() \
if ((_suppressResizeNotificationsMask & DidPostWillResizeNotification) === 0) \
{ \
[self _postNotificationWillResize]; \
_suppressResizeNotificationsMask |= DidPostWillResizeNotification; \
}
#define SPLIT_VIEW_MAYBE_POST_DID_RESIZE() \
if ((_suppressResizeNotificationsMask & ShouldSuppressResizeNotifications) !== 0) \
_suppressResizeNotificationsMask |= DidSuppressResizeNotification; \
else \
[self _postNotificationDidResize];
#define SPLIT_VIEW_DID_SUPPRESS_RESIZE_NOTIFICATION() \
((_suppressResizeNotificationsMask & DidSuppressResizeNotification) !== 0)
#define SPLIT_VIEW_SUPPRESS_RESIZE_NOTIFICATIONS(shouldSuppress) \
if (shouldSuppress) \
_suppressResizeNotificationsMask |= ShouldSuppressResizeNotifications; \
else \
_suppressResizeNotificationsMask = 0;
CPSplitViewDidResizeSubviewsNotification = @"CPSplitViewDidResizeSubviewsNotification";
CPSplitViewWillResizeSubviewsNotification = @"CPSplitViewWillResizeSubviewsNotification";
var CPSplitViewHorizontalImage = nil,
CPSplitViewVerticalImage = nil;
var ShouldSuppressResizeNotifications = 1,
DidPostWillResizeNotification = 1 << 1,
DidSuppressResizeNotification = 1 << 2;
/*!
@ingroup appkit
@@ -45,24 +73,29 @@ var CPSplitViewHorizontalImage = nil,
@implementation CPSplitView : CPView
{
id _delegate;
BOOL _isVertical;
BOOL _isPaneSplitter;
id _delegate;
BOOL _isVertical;
BOOL _isPaneSplitter;
int _currentDivider;
float _initialOffset;
float _preCollapsePosition;
int _currentDivider;
float _initialOffset;
CPDictionary _preCollapsePositions;
CPString _originComponent;
CPString _sizeComponent;
CPString _originComponent;
CPString _sizeComponent;
CPArray _DOMDividerElements;
CPString _dividerImagePath;
int _drawingDivider;
CPArray _DOMDividerElements;
CPString _dividerImagePath;
int _drawingDivider;
BOOL _needsResizeSubviews;
CPString _autosaveName;
BOOL _shouldAutosave;
CGSize _shouldRestoreFromAutosaveUnlessFrameSize;
CPArray _buttonBars;
BOOL _needsResizeSubviews;
int _suppressResizeNotificationsMask;
CPArray _buttonBars;
}
+ (CPString)defaultThemeClass
@@ -72,32 +105,31 @@ var CPSplitViewHorizontalImage = nil,
+ (id)themeAttributes
{
return [CPDictionary dictionaryWithObjects:[1.0, 10.0, [CPColor grayColor]]
forKeys:[@"divider-thickness", @"pane-divider-thickness", @"pane-divider-color"]];
}
/*
@ignore
*/
+ (void)initialize
{
if (self != [CPSplitView class])
return;
var bundle = [CPBundle bundleForClass:self];
CPSplitViewHorizontalImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPSplitView/CPSplitViewHorizontal.png"] size:CPSizeMake(5.0, 10.0)];
CPSplitViewVerticalImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPSplitView/CPSplitViewVertical.png"] size:CPSizeMake(10.0, 5.0)];
return [CPDictionary dictionaryWithObjects:[1.0,
10.0,
[CPColor grayColor],
[CPNull null],
[CPNull null]]
forKeys:[@"divider-thickness",
@"pane-divider-thickness",
@"pane-divider-color",
@"horizontal-divider-color",
@"vertical-divider-color"]];
}
- (id)initWithFrame:(CGRect)aFrame
{
if (self = [super initWithFrame:aFrame])
{
_suppressResizeNotificationsMask = 0;
_preCollapsePositions = [CPMutableDictionary new];
_currentDivider = CPNotFound;
_DOMDividerElements = [];
_buttonBars = [];
_shouldAutosave = YES;
[self _setVertical:YES];
}
@@ -142,14 +174,17 @@ var CPSplitViewHorizontalImage = nil,
count = _subviews.length;
if ([self isVertical])
{
for (; index < count; ++index)
[_subviews[index] setFrame:CGRectMake(ROUND((eachSize + dividerThickness) * index), 0, eachSize, frame.size.height)];
}
else
{
for (; index < count; ++index)
[_subviews[index] setFrame:CGRectMake(0, ROUND((eachSize + dividerThickness) * index), frame.size.width, eachSize)];
}
[self setNeedsDisplay:YES];
[self _postNotificationDidResize];
}
@@ -162,7 +197,7 @@ var CPSplitViewHorizontalImage = nil,
_originComponent = [self isVertical] ? "x" : "y";
_sizeComponent = [self isVertical] ? "width" : "height";
_dividerImagePath = [self isVertical] ? [CPSplitViewVerticalImage filename] : [CPSplitViewHorizontalImage filename];
_dividerImagePath = [self isVertical] ? [[self valueForThemeAttribute:@"vertical-divider-color"] filename] : [[self valueForThemeAttribute:@"horizontal-divider-color"] filename];
return changed;
}
@@ -225,7 +260,6 @@ var CPSplitViewHorizontalImage = nil,
rect = CGRectMakeZero();
rect.size = [self frame].size;
rect.size[_sizeComponent] = [self dividerThickness];
rect.origin[_originComponent] = frame.origin[_originComponent] + frame.size[_sizeComponent];
@@ -334,28 +368,33 @@ var CPSplitViewHorizontalImage = nil,
_needsResizeSubviews = NO;
[self resizeSubviewsWithOldSize:[self _calculateSize]];
}
- (CGSize)_calculateSize
{
var subviews = [self subviews],
count = subviews.length,
oldSize = CGSizeMakeZero();
size = CGSizeMakeZero();
if ([self isVertical])
{
oldSize.width += [self dividerThickness] * (count - 1);
oldSize.height = CGRectGetHeight([self frame]);
size.width += [self dividerThickness] * (count - 1);
size.height = CGRectGetHeight([self frame]);
}
else
{
oldSize.width = CGRectGetWidth([self frame]);
oldSize.height += [self dividerThickness] * (count - 1);
size.width = CGRectGetWidth([self frame]);
size.height += [self dividerThickness] * (count - 1);
}
while (count--)
oldSize[_sizeComponent] += [subviews[count] frame].size[_sizeComponent];
size[_sizeComponent] += [subviews[count] frame].size[_sizeComponent];
[self resizeSubviewsWithOldSize:oldSize];
return size;
}
- (BOOL)cursorAtPoint:(CPPoint)aPoint hitDividerAtIndex:(int)anIndex
- (BOOL)cursorAtPoint:(CGPoint)aPoint hitDividerAtIndex:(int)anIndex
{
var frame = [_subviews[anIndex] frame],
startPosition = frame.origin[_originComponent] + frame.size[_sizeComponent],
@@ -408,11 +447,14 @@ var CPSplitViewHorizontalImage = nil,
if (type == CPLeftMouseUp)
{
// We disabled autosaving during tracking.
_shouldAutosave = YES;
if (_currentDivider != CPNotFound)
{
_currentDivider = CPNotFound;
[self _autosave];
[self _updateResizeCursor:anEvent];
[self _postNotificationDidResize];
}
return;
@@ -420,10 +462,11 @@ var CPSplitViewHorizontalImage = nil,
if (type == CPLeftMouseDown)
{
var point = [self convertPoint:[anEvent locationInWindow] fromView:nil];
var point = [self convertPoint:[anEvent locationInWindow] fromView:nil],
count = [_subviews count] - 1;
_currentDivider = CPNotFound;
var count = [_subviews count] - 1;
for (var i = 0; i < count; i++)
{
var frame = [_subviews[i] frame],
@@ -436,19 +479,20 @@ var CPSplitViewHorizontalImage = nil,
[_delegate respondsToSelector:@selector(splitView:shouldCollapseSubview:forDoubleClickOnDividerAtIndex:)])
{
var minPosition = [self minPossiblePositionOfDividerAtIndex:i],
maxPosition = [self maxPossiblePositionOfDividerAtIndex:i];
maxPosition = [self maxPossiblePositionOfDividerAtIndex:i],
preCollapsePosition = [_preCollapsePositions objectForKey:"" + i] || 0;
if ([_delegate splitView:self canCollapseSubview:_subviews[i]] && [_delegate splitView:self shouldCollapseSubview:_subviews[i] forDoubleClickOnDividerAtIndex:i])
{
if ([self isSubviewCollapsed:_subviews[i]])
[self setPosition:_preCollapsePosition ? _preCollapsePosition : (minPosition + (maxPosition - minPosition) / 2) ofDividerAtIndex:i];
[self setPosition:preCollapsePosition ? preCollapsePosition : (minPosition + (maxPosition - minPosition) / 2) ofDividerAtIndex:i];
else
[self setPosition:minPosition ofDividerAtIndex:i];
}
else if ([_delegate splitView:self canCollapseSubview:_subviews[i + 1]] && [_delegate splitView:self shouldCollapseSubview:_subviews[i + 1] forDoubleClickOnDividerAtIndex:i])
{
if ([self isSubviewCollapsed:_subviews[i + 1]])
[self setPosition:_preCollapsePosition ? _preCollapsePosition : (minPosition + (maxPosition - minPosition) / 2) ofDividerAtIndex:i];
[self setPosition:preCollapsePosition ? preCollapsePosition : (minPosition + (maxPosition - minPosition) / 2) ofDividerAtIndex:i];
else
[self setPosition:maxPosition ofDividerAtIndex:i];
}
@@ -458,6 +502,8 @@ var CPSplitViewHorizontalImage = nil,
_currentDivider = i;
_initialOffset = startPosition - point[_originComponent];
// Don't autosave during a resize. We'll wait until it's done.
_shouldAutosave = NO;
[self _postNotificationWillResize];
}
}
@@ -526,19 +572,37 @@ var CPSplitViewHorizontalImage = nil,
// If we are currently tracking, keep the resize cursor active even outside of hit areas.
if (_currentDivider === i || (_currentDivider == CPNotFound && [self cursorAtPoint:point hitDividerAtIndex:i]))
{
var frame = [_subviews[i] frame],
size = frame.size[_sizeComponent],
startPosition = frame.origin[_originComponent] + size,
var frameA = [_subviews[i] frame],
sizeA = frameA.size[_sizeComponent],
startPosition = frameA.origin[_originComponent] + sizeA,
frameB = [_subviews[i + 1] frame],
sizeB = frameB.size[_sizeComponent],
canShrink = [self _realPositionForPosition:startPosition - 1 ofDividerAtIndex:i] < startPosition,
canGrow = [self _realPositionForPosition:startPosition + 1 ofDividerAtIndex:i] > startPosition,
cursor = [CPCursor arrowCursor];
if (size === 0)
if (sizeA === 0)
canGrow = YES; // Subview is collapsed.
else if (!canShrink &&
[_delegate respondsToSelector:@selector(splitView:canCollapseSubview:)] &&
[_delegate splitView:self canCollapseSubview:_subviews[i]])
[_delegate respondsToSelector:@selector(splitView:canCollapseSubview:)] &&
[_delegate splitView:self canCollapseSubview:_subviews[i]])
{
canShrink = YES; // Subview is collapsible.
}
if (sizeB === 0)
{
// Right/lower subview is collapsed.
canGrow = NO;
// It's safe to assume it can always be uncollapsed.
canShrink = YES;
}
else if (!canGrow &&
[_delegate respondsToSelector:@selector(splitView:canCollapseSubview:)] &&
[_delegate splitView:self canCollapseSubview:_subviews[i + 1]])
{
canGrow = YES; // Right/lower subview is collapsible.
}
if (_isVertical && canShrink && canGrow)
cursor = [CPCursor resizeLeftRightCursor];
@@ -597,7 +661,15 @@ var CPSplitViewHorizontalImage = nil,
{
// not sure where this should override other positions?
if ([_delegate respondsToSelector:@selector(splitView:constrainSplitPosition:ofSubviewAt:)])
position = [_delegate splitView:self constrainSplitPosition:position ofSubviewAt:dividerIndex];
{
var proposedPosition = [_delegate splitView:self constrainSplitPosition:position ofSubviewAt:dividerIndex];
// Silently ignore bad positions which could result from odd delegate responses. We don't want these
// bad results to go into the system and cause havoc with frame sizes as the split view tries to resize
// its subviews.
if (_IS_NUMERIC(proposedPosition))
position = proposedPosition;
}
var proposedMax = [self maxPossiblePositionOfDividerAtIndex:dividerIndex],
proposedMin = [self minPossiblePositionOfDividerAtIndex:dividerIndex],
@@ -605,19 +677,37 @@ var CPSplitViewHorizontalImage = nil,
actualMin = proposedMin;
if ([_delegate respondsToSelector:@selector(splitView:constrainMinCoordinate:ofSubviewAt:)])
actualMin = [_delegate splitView:self constrainMinCoordinate:proposedMin ofSubviewAt:dividerIndex];
{
var proposedActualMin = [_delegate splitView:self constrainMinCoordinate:proposedMin ofSubviewAt:dividerIndex];
if (_IS_NUMERIC(proposedActualMin))
actualMin = proposedActualMin;
}
if ([_delegate respondsToSelector:@selector(splitView:constrainMaxCoordinate:ofSubviewAt:)])
actualMax = [_delegate splitView:self constrainMaxCoordinate:proposedMax ofSubviewAt:dividerIndex];
{
var proposedActualMax = [_delegate splitView:self constrainMaxCoordinate:proposedMax ofSubviewAt:dividerIndex];
if (_IS_NUMERIC(proposedActualMax))
actualMax = proposedActualMax;
}
var viewA = _subviews[dividerIndex],
viewB = _subviews[dividerIndex + 1],
realPosition = MAX(MIN(position, actualMax), actualMin);
if (position < proposedMin + (actualMin - proposedMin) / 2)
// Is this position past the halfway point to collapse?
if (position < proposedMin + (actualMin - proposedMin) / 2)
if ([_delegate respondsToSelector:@selector(splitView:canCollapseSubview:)])
if ([_delegate splitView:self canCollapseSubview:viewA])
realPosition = proposedMin;
// We can also collapse to the right.
if (position > proposedMax - (proposedMax - actualMax) / 2)
if ([_delegate respondsToSelector:@selector(splitView:canCollapseSubview:)])
if ([_delegate splitView:self canCollapseSubview:viewB])
realPosition = proposedMax;
return realPosition;
}
@@ -628,43 +718,77 @@ var CPSplitViewHorizontalImage = nil,
*/
- (void)setPosition:(float)position ofDividerAtIndex:(int)dividerIndex
{
// Any manual changes to the divider position should override anything we are restoring from
// autosave.
_shouldRestoreFromAutosaveUnlessFrameSize = nil;
SPLIT_VIEW_SUPPRESS_RESIZE_NOTIFICATIONS(YES);
[self _adjustSubviewsWithCalculatedSize];
var realPosition = [self _realPositionForPosition:position ofDividerAtIndex:dividerIndex];
var viewA = _subviews[dividerIndex],
var realPosition = [self _realPositionForPosition:position ofDividerAtIndex:dividerIndex],
viewA = _subviews[dividerIndex],
frameA = [viewA frame],
viewB = _subviews[dividerIndex + 1],
frameB = [viewB frame];
frameB = [viewB frame],
preCollapsePosition = 0,
preSize = frameA.size[_sizeComponent];
_preCollapsePosition = 0;
var preSize = frameA.size[_sizeComponent];
frameA.size[_sizeComponent] = realPosition - frameA.origin[_originComponent];
if (preSize !== 0 && frameA.size[_sizeComponent] === 0)
_preCollapsePosition = preSize;
[_subviews[dividerIndex] setFrame:frameA];
preCollapsePosition = preSize;
if (preSize !== frameA.size[_sizeComponent])
{
SPLIT_VIEW_MAYBE_POST_WILL_RESIZE();
[_subviews[dividerIndex] setFrame:frameA];
SPLIT_VIEW_MAYBE_POST_DID_RESIZE();
}
preSize = frameB.size[_sizeComponent];
var preOrigin = frameB.origin[_originComponent];
frameB.size[_sizeComponent] = frameB.origin[_originComponent] + frameB.size[_sizeComponent] - realPosition - [self dividerThickness];
if (preSize !== 0 && frameB.size[_sizeComponent] === 0)
_preCollapsePosition = preSize;
preCollapsePosition = frameB.origin[_originComponent];
frameB.origin[_originComponent] = realPosition + [self dividerThickness];
[_subviews[dividerIndex + 1] setFrame:frameB];
if (preSize !== frameB.size[_sizeComponent] || preOrigin !== frameB.origin[_originComponent])
{
SPLIT_VIEW_MAYBE_POST_WILL_RESIZE();
[_subviews[dividerIndex + 1] setFrame:frameB];
SPLIT_VIEW_MAYBE_POST_DID_RESIZE();
}
if (preCollapsePosition)
[_preCollapsePositions setObject:preCollapsePosition forKey:"" + dividerIndex];
[self setNeedsDisplay:YES];
if (SPLIT_VIEW_DID_SUPPRESS_RESIZE_NOTIFICATION())
[self _postNotificationDidResize];
SPLIT_VIEW_SUPPRESS_RESIZE_NOTIFICATIONS(NO);
}
- (void)setFrameSize:(CGSize)aSize
{
[self _adjustSubviewsWithCalculatedSize];
if (_shouldRestoreFromAutosaveUnlessFrameSize)
_shouldAutosave = NO;
else
[self _adjustSubviewsWithCalculatedSize];
[super setFrameSize:aSize];
if (_shouldRestoreFromAutosaveUnlessFrameSize)
_shouldAutosave = YES;
[self setNeedsDisplay:YES];
}
- (void)resizeSubviewsWithOldSize:(CPSize)oldSize
- (void)resizeSubviewsWithOldSize:(CGSize)oldSize
{
if ([_delegate respondsToSelector:@selector(splitView:resizeSubviewsWithOldSize:)])
{
@@ -672,67 +796,104 @@ var CPSplitViewHorizontalImage = nil,
return;
}
[self adjustSubviews];
}
- (void)adjustSubviews
{
var count = [_subviews count];
if (!count)
return;
SPLIT_VIEW_MAYBE_POST_WILL_RESIZE();
[self _postNotificationWillResize];
var index = 0,
count = [_subviews count],
bounds = [self bounds],
boundsSize = bounds.size[_sizeComponent],
oldSize = [self _calculateSize],
dividerThickness = [self dividerThickness],
totalDividers = count - 1,
totalSizableSpace = 0,
nonSizableSpace = 0,
lastSizableIndex = -1,
oldFlexibleSpace = 0,
totalSizablePanes = 0,
isVertical = [self isVertical];
isSizableMap = {},
viewSizes = [],
delegateRespondsToShouldAdjust = [_delegate respondsToSelector:@selector(splitView:shouldAdjustSizeOfSubview:)];
// What we want to do is to preserve non resizable sizes first, and then to preserve the ratio of size to available
// non fixed space for every other subview. E.g. assume fixed space was 20 pixels initially, view 1 was 20 and
// view 2 was 30 pixels, for a total of 70 pixels. Then the new total size becomes 140 pixels. Now we want the fixed
// space to still be 20 pixels, view 1 to be 48 pixels and view 2 to be 72 pixels. This way the relative size of
// view 1 to view 2 remains the same - view 1 was 66% of view 2 initially and after the resize view 1 is still
// 66% of view 2's size.
//
// For this calculation, we can consider the dividers themselves to also be fixed size areas - they should remain
// the same size before and after.
// How much flexible size do we have in pre-resize pixels?
for (index = 0; index < count; ++index)
{
var view = _subviews[index],
isSizable = isVertical ? [view autoresizingMask] & CPViewWidthSizable : [view autoresizingMask] & CPViewHeightSizable;
isSizable = !delegateRespondsToShouldAdjust || [_delegate splitView:self shouldAdjustSizeOfSubview:view],
size = [view frame].size[_sizeComponent];
isSizableMap[index] = isSizable;
viewSizes.push(size);
if (isSizable)
{
totalSizableSpace += [view frame].size[_sizeComponent];
lastSizableIndex = index;
oldFlexibleSpace += size;
totalSizablePanes++;
}
}
if (totalSizablePanes === count)
totalSizableSpace = 0;
// nonSizableSpace is the number of fixed pixels in pre-resize terms and the desired number post-resize.
var nonSizableSpace = oldSize[_sizeComponent] - oldFlexibleSpace,
newFlexibleSpace = boundsSize - nonSizableSpace,
remainingFixedPixelsToRemove = 0;
var nonSizableSpace = totalSizableSpace ? bounds.size[_sizeComponent] - totalSizableSpace : 0,
remainingFlexibleSpace = bounds.size[_sizeComponent] - oldSize[_sizeComponent],
oldDimension = (oldSize[_sizeComponent] - totalDividers * dividerThickness - nonSizableSpace),
ratio = oldDimension <= 0 ? 0 : (bounds.size[_sizeComponent] - totalDividers * dividerThickness - nonSizableSpace) / oldDimension;
if (newFlexibleSpace < 0)
{
remainingFixedPixelsToRemove = -newFlexibleSpace;
newFlexibleSpace = 0;
}
var remainingFixedPanes = count - totalSizablePanes;
for (index = 0; index < count; ++index)
{
var view = _subviews[index],
viewFrame = CGRectMakeCopy(bounds),
isSizable = isVertical ? [view autoresizingMask] & CPViewWidthSizable : [view autoresizingMask] & CPViewHeightSizable;
isSizable = isSizableMap[index],
targetSize = 0;
// The last area must take up exactly the remaining space, fixed or not.
if (index + 1 === count)
viewFrame.size[_sizeComponent] = bounds.size[_sizeComponent] - viewFrame.origin[_originComponent];
else if (totalSizableSpace && isSizable && lastSizableIndex === index)
viewFrame.size[_sizeComponent] = MAX(0, ROUND([view frame].size[_sizeComponent] + remainingFlexibleSpace))
else if (isSizable || !totalSizableSpace)
targetSize = boundsSize - viewFrame.origin[_originComponent];
// Try to keep fixed size areas the same size.
else if (!isSizable)
{
viewFrame.size[_sizeComponent] = MAX(0, ROUND(ratio * [view frame].size[_sizeComponent]));
remainingFlexibleSpace -= (viewFrame.size[_sizeComponent] - [view frame].size[_sizeComponent]);
var removedFixedPixels = MIN(remainingFixedPixelsToRemove / remainingFixedPanes, viewSizes[index]);
targetSize = viewSizes[index] - removedFixedPixels;
remainingFixedPixelsToRemove -= removedFixedPixels;
remainingFixedPanes--;
}
// (new size / flexible size available) == (old size / old flexible size available)
else if (oldFlexibleSpace > 0)
targetSize = newFlexibleSpace * viewSizes[index] / oldFlexibleSpace;
// oldFlexibleSpace <= 0 so all flexible areas were crushed. When we get space, allocate it evenly.
// totalSizablePanes cannot be 0 since isSizable.
else
targetSize = newFlexibleSpace / totalSizablePanes;
else if (totalSizableSpace && !isSizable)
viewFrame.size[_sizeComponent] = [view frame].size[_sizeComponent];
bounds.origin[_originComponent] += viewFrame.size[_sizeComponent] + dividerThickness;
targetSize = MAX(0, ROUND(targetSize));
viewFrame.size[_sizeComponent] = targetSize;
[view setFrame:viewFrame];
bounds.origin[_originComponent] += targetSize + dividerThickness;
}
[self _postNotificationDidResize];
SPLIT_VIEW_MAYBE_POST_DID_RESIZE();
}
/*!
@@ -749,6 +910,11 @@ Notifies the delegate when the subviews will be resized.
- (void)splitViewWillResizeSubviews:(CPNotification)aNotification;
@endcode
Allows the delegate to specify which of the CPSplitView's subviews should adjust if the window is resized.
@code
- (BOOL)splitView:(CPSplitView)aSplitView shouldAdjustSizeOfSubview:(CPView)aSubView
@endcode
Lets the delegate specify a different rect for which the user can drag the splitView divider.
@code
- (CGRect)splitView:(CPSplitView)aSplitView effectiveRect:(CGRect)aRect forDrawnRect:(CGRect)aDrawnRect ofDividerAtIndex:(int)aDividerIndex;
@@ -831,6 +997,7 @@ The sum of the views and the sum of the dividers should be equal to the size of
@param CPButtonBar - The supplied button bar.
@param unsigned int - The divider index the button bar will be assigned to.
*/
// FIXME Should be renamed to setButtonBar:ofDividerAtIndex:.
- (void)setButtonBar:(CPButtonBar)aButtonBar forDividerAtIndex:(unsigned)dividerIndex
{
if (!aButtonBar)
@@ -862,12 +1029,161 @@ The sum of the views and the sum of the dividers should be equal to the size of
- (void)_postNotificationWillResize
{
[[CPNotificationCenter defaultCenter] postNotificationName:CPSplitViewWillResizeSubviewsNotification object:self];
var userInfo = nil;
if (_currentDivider !== CPNotFound)
userInfo = [CPDictionary dictionaryWithObject:_currentDivider forKey:@"CPSplitViewDividerIndex"];
[[CPNotificationCenter defaultCenter] postNotificationName:CPSplitViewWillResizeSubviewsNotification
object:self
userInfo:userInfo];
}
- (void)_postNotificationDidResize
{
[[CPNotificationCenter defaultCenter] postNotificationName:CPSplitViewDidResizeSubviewsNotification object:self];
var userInfo = nil;
if (_currentDivider !== CPNotFound)
userInfo = [CPDictionary dictionaryWithObject:_currentDivider forKey:@"CPSplitViewDividerIndex"];
[[CPNotificationCenter defaultCenter] postNotificationName:CPSplitViewDidResizeSubviewsNotification
object:self
userInfo:userInfo];
// TODO Cocoa always autosaves on "viewDidEndLiveResize". If Cappuccino adds support for this we
// should do the same.
[self _autosave];
}
/*!
Set the name under which the split view divider positions is automatically saved to CPUserDefaults.
@param autosaveName the name to save under or nil to not save
*/
- (void)setAutosaveName:(CPString)autosaveName
{
if (_autosaveName == autosaveName)
return;
_autosaveName = autosaveName;
}
/*!
Get the name under which the split view divider position is automatically saved to CPUserDefaults.
@return the name to save under or nil if no autosave is active
*/
- (CPString)autosaveName
{
return _autosaveName;
}
/*!
@ignore
*/
- (void)_autosave
{
if (_shouldRestoreFromAutosaveUnlessFrameSize || !_shouldAutosave || !_autosaveName)
return;
var userDefaults = [CPUserDefaults standardUserDefaults],
autosaveName = [self _framesKeyForAutosaveName:[self autosaveName]],
autosavePrecollapseName = [self _precollapseKeyForAutosaveName:[self autosaveName]],
count = [_subviews count],
positions = [CPMutableArray new],
preCollapseArray = [CPMutableArray new];
for (var i = 0; i < count; i++)
{
var frame = [_subviews[i] frame];
[positions addObject:CGStringFromRect(frame)];
[preCollapseArray addObject:[_preCollapsePositions objectForKey:"" + i]];
}
[userDefaults setObject:positions forKey:autosaveName];
[userDefaults setObject:preCollapseArray forKey:autosavePrecollapseName];
}
/*!
This is called sometime later after a split view has been restored from a Cib.
See notes in initWithCoder.
@ignore
*/
- (void)_restoreFromAutosaveIfNeeded
{
if (_shouldRestoreFromAutosaveUnlessFrameSize && !_CGSizeEqualToSize([self frameSize], _shouldRestoreFromAutosaveUnlessFrameSize))
{
[self _restoreFromAutosave];
}
_shouldRestoreFromAutosaveUnlessFrameSize = nil;
}
/*!
@ignore
*/
- (void)_restoreFromAutosave
{
if (!_autosaveName)
return;
var autosaveName = [self _framesKeyForAutosaveName:[self autosaveName]],
autosavePrecollapseName = [self _precollapseKeyForAutosaveName:[self autosaveName]],
userDefaults = [CPUserDefaults standardUserDefaults],
frames = [userDefaults objectForKey:autosaveName],
preCollapseArray = [userDefaults objectForKey:autosavePrecollapseName];
if (frames)
{
var dividerThickness = [self dividerThickness],
position = 0;
_shouldAutosave = NO;
for (var i = 0, count = [frames count] - 1; i < count; i++)
{
var frame = CGRectFromString(frames[i]);
position += frame.size[_sizeComponent];
[self setPosition:position ofDividerAtIndex:i];
position += dividerThickness;
}
_shouldAutosave = YES;
}
if (preCollapseArray)
{
_preCollapsePositions = [CPMutableDictionary new];
for (var i = 0, count = [preCollapseArray count]; i < count; i++)
[_preCollapsePositions setObject:preCollapseArray[i] forKey:i + ""];
}
}
/*!
@ignore
*/
- (CPString)_framesKeyForAutosaveName:(CPString)theAutosaveName
{
if (!theAutosaveName)
return nil;
return @"CPSplitView Subview Frames " + theAutosaveName;
}
/*!
@ignore
*/
- (CPString)_precollapseKeyForAutosaveName:(CPString)theAutosaveName
{
if (!theAutosaveName)
return nil;
return @"CPSplitView Subview Precollapse Positions " + theAutosaveName;
}
@end
@@ -875,7 +1191,8 @@ The sum of the views and the sum of the dividers should be equal to the size of
var CPSplitViewDelegateKey = "CPSplitViewDelegateKey",
CPSplitViewIsVerticalKey = "CPSplitViewIsVerticalKey",
CPSplitViewIsPaneSplitterKey = "CPSplitViewIsPaneSplitterKey",
CPSplitViewButtonBarsKey = "CPSplitViewButtonBarsKey";
CPSplitViewButtonBarsKey = "CPSplitViewButtonBarsKey",
CPSplitViewAutosaveNameKey = "CPSplitViewAutosaveNameKey";
@implementation CPSplitView (CPCoding)
@@ -885,11 +1202,43 @@ var CPSplitViewDelegateKey = "CPSplitViewDelegateKey",
*/
- (id)initWithCoder:(CPCoder)aCoder
{
// We need to restore this property before calling super's initWithCoder:.
_autosaveName = [aCoder decodeObjectForKey:CPSplitViewAutosaveNameKey];
/*
It is common for the main window of a Cappuccino app window to be resized to match the browser
window size at the end of the UI being loaded from a cib. But at decoding time (now) whatever
window size was originally saved will be in place, so if we try to restore the autosaved divider
positions now they might be constrained to the wrong positions due to the difference in frame size,
and in addition they might move later when the window is resized.
The workaround is to restore the position once now (so it's approximately correct during loading),
and then once more in the next runloop cycle when any `setFullPlatformWindow` calls are done.
(However if the frame size doesn't change before the next cycle, we should not restore the position
again because that would overwrite any changes the app developer might have made in user code.)
The other consideration is that any parent split views need to be restored before any child
subviews, otherwise the parent restore will also change the positioning of the child.
*/
if (_autosaveName)
{
// Schedule /before/ [super initWithCoder:]. This way this instance's _restoreFromAutosaveIfNeeded
// will happen before that of any subviews loaded by [super initWithCoder:].
[[CPRunLoop currentRunLoop] performSelector:@selector(_restoreFromAutosaveIfNeeded) target:self argument:nil order:0 modes:[CPDefaultRunLoopMode]];
}
self = [super initWithCoder:aCoder];
if (self)
{
_suppressResizeNotificationsMask = 0;
_preCollapsePositions = [CPMutableDictionary new];
_currentDivider = CPNotFound;
_shouldAutosave = YES;
_DOMDividerElements = [];
@@ -899,6 +1248,14 @@ var CPSplitViewDelegateKey = "CPSplitViewDelegateKey",
_isPaneSplitter = [aCoder decodeBoolForKey:CPSplitViewIsPaneSplitterKey];
[self _setVertical:[aCoder decodeBoolForKey:CPSplitViewIsVerticalKey]];
if (_autosaveName)
{
[self _restoreFromAutosave];
// Remember the frame size we had at this point so that we can restore again if it changes
// before the next runloop cycle. See above notes.
_shouldRestoreFromAutosaveUnlessFrameSize = [self frameSize];
}
}
return self;
@@ -919,6 +1276,8 @@ var CPSplitViewDelegateKey = "CPSplitViewDelegateKey",
[aCoder encodeBool:_isVertical forKey:CPSplitViewIsVerticalKey];
[aCoder encodeBool:_isPaneSplitter forKey:CPSplitViewIsPaneSplitterKey];
[aCoder encodeObject:_autosaveName forKey:CPSplitViewAutosaveNameKey];
}
@end
+147 -57
View File
@@ -20,20 +20,21 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import <AppKit/CPControl.j>
@import <AppKit/CPButton.j>
@import <AppKit/CPTextField.j>
@import "CPControl.j"
@import "CPButton.j"
@import "CPTextField.j"
var CPStepperButtonsSize = CPSizeMake(19, 13);
/*! CPStepper is an implementation of Cocoa NSStepper.
/*!
CPStepper is an implementation of Cocoa NSStepper.
This control display a two part button that can be used to increase or decrease a value with a given interval.
This control displays a two part button that can be used to increase or decrease a value with a given interval.
*/
@implementation CPStepper: CPControl
{
BOOL _valueWraps @accessors(property=valueWraps);
BOOL _autorepeat @accessors(getter=autorepeat);
int _increment @accessors(property=increment);
int _maxValue @accessors(property=maxValue);
int _minValue @accessors(property=minValue);
@@ -45,7 +46,8 @@ var CPStepperButtonsSize = CPSizeMake(19, 13);
#pragma mark -
#pragma mark Initialization
/*! Initializes a CPStepper with given values
/*!
Initializes a CPStepper with given values.
@param aValue the initial value of the CPStepper
@param minValue the minimal acceptable value of the stepper
@param maxValue the maximal acceptable value of the stepper
@@ -53,18 +55,24 @@ var CPStepperButtonsSize = CPSizeMake(19, 13);
*/
+ (CPStepper)stepperWithInitialValue:(float)aValue minValue:(float)aMinValue maxValue:(float)aMaxValue
{
var stepper = [[CPStepper alloc] initWithFrame:CPRectMake(0, 0, 19, 25)];
var stepper = [[CPStepper alloc] initWithFrame:_CGRectMakeZero()];
[stepper setDoubleValue:aValue];
[stepper setMinValue:aMinValue];
[stepper setMaxValue:aMaxValue];
// _sizeToFit will put the good size for the stepper depending of the current theme
[stepper _sizeToFit];
return stepper;
}
/*! Initializes a CPStepper with default values:
/*!
Initializes a CPStepper with default values:
- minValue = 0.0
- maxValue = 59.0
- value = 0.0
@return Initialized CPStepper
*/
+ (CPStepper)stepper
@@ -72,7 +80,24 @@ var CPStepperButtonsSize = CPSizeMake(19, 13);
return [CPStepper stepperWithInitialValue:0.0 minValue:0.0 maxValue:59.0];
}
/*! Initializes the CPStepper
+ (Class)_binderClassForBinding:(CPString)theBinding
{
if (theBinding == CPValueBinding || theBinding == CPMinValueBinding || theBinding == CPMaxValueBinding)
return [_CPStepperValueBinder class];
return [super _binderClassForBinding:theBinding];
}
- (id)_replacementKeyPathForBinding:(CPString)aBinding
{
if (aBinding == CPValueBinding)
return @"doubleValue";
return [super _replacementKeyPathForBinding:aBinding];
}
/*!
Initializes a CPStepper.
@param aFrame the frame of the control
@return initialized CPStepper
*/
@@ -84,33 +109,43 @@ var CPStepperButtonsSize = CPSizeMake(19, 13);
_minValue = 0.0;
_increment = 1.0;
_valueWraps = YES;
_autorepeat = YES;
[self setDoubleValue:0.0];
_buttonUp = [[CPButton alloc] initWithFrame:CPRectMake(aFrame.size.width - CPStepperButtonsSize.width, 0, CPStepperButtonsSize.width, CPStepperButtonsSize.height)];
[_buttonUp setContinuous:YES];
[_buttonUp setTarget:self];
[_buttonUp setAction:@selector(_buttonDidClick:)];
[_buttonUp setAutoresizingMask:CPViewNotSizable];
[self addSubview:_buttonUp];
_buttonDown = [[CPButton alloc] initWithFrame:CPRectMake(aFrame.size.width - CPStepperButtonsSize.width, CPStepperButtonsSize.height, CPStepperButtonsSize.width, CPStepperButtonsSize.height - 1)];
[_buttonDown setContinuous:YES];
[_buttonDown setTarget:self];
[_buttonDown setAction:@selector(_buttonDidClick:)];
[_buttonDown setAutoresizingMask:CPViewNotSizable];
[self addSubview:_buttonDown];
[self setNeedsLayout];
[self _init];
}
return self;
}
/*! @ignore */
- (void)_init
{
_buttonUp = [[CPButton alloc] initWithFrame:_CGRectMakeZero()];
[_buttonUp setContinuous:_autorepeat];
[_buttonUp setTarget:self];
[_buttonUp setAction:@selector(_buttonDidClick:)];
[_buttonUp setAutoresizingMask:CPViewNotSizable];
[self addSubview:_buttonUp];
_buttonDown = [[CPButton alloc] initWithFrame:_CGRectMakeZero()];
[_buttonDown setContinuous:_autorepeat];
[_buttonDown setTarget:self];
[_buttonDown setAction:@selector(_buttonDidClick:)];
[_buttonDown setAutoresizingMask:CPViewNotSizable];
[self setContinuous:_autorepeat];
[self addSubview:_buttonDown];
[self setNeedsLayout];
}
#pragma mark -
#pragma mark Superclass overrides
/*! set if the CPStepper is enabled or not
/*!
Set if the CPStepper is enabled or not.
@param shouldEnabled BOOL that define if stepper is enabled or not.
*/
- (void)setEnabled:(BOOL)shouldEnabled
@@ -121,19 +156,31 @@ var CPStepperButtonsSize = CPSizeMake(19, 13);
[_buttonDown setEnabled:shouldEnabled];
}
/*! set the frame of the CPStepper and check if width is not smaller than theme min-size
@param aFrame the frame
*/
- (void)setFrame:(CGRect)aFrame
{
if (aFrame.size.width >= CGRectGetWidth(aFrame))
[super setFrame:aFrame];
var upSize = [self valueForThemeAttribute:@"up-button-size"],
downSize = [self valueForThemeAttribute:@"down-button-size"],
minSize = _CGSizeMake(upSize.width, upSize.height + downSize.height),
frame = _CGRectMakeCopy(aFrame);
frame.size.width = MAX(minSize.width, frame.size.width);
frame.size.height = MAX(minSize.height, frame.size.height);
[super setFrame:frame];
}
/*! @ignore
*/
/*! @ignore */
- (void)layoutSubviews
{
var aFrame = [self frame],
upSize = [self valueForThemeAttribute:@"up-button-size"],
downSize = [self valueForThemeAttribute:@"down-button-size"],
upFrame = _CGRectMake(aFrame.size.width - upSize.width, 0, upSize.width, upSize.height),
downFrame = _CGRectMake(aFrame.size.width - downSize.width, upSize.height, downSize.width, downSize.height);
[_buttonUp setFrame:upFrame];
[_buttonDown setFrame:downFrame];
[_buttonUp setValue:[self valueForThemeAttribute:@"bezel-color-up-button" inState:CPThemeStateBordered] forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered];
[_buttonUp setValue:[self valueForThemeAttribute:@"bezel-color-up-button" inState:CPThemeStateBordered | CPThemeStateDisabled] forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered | CPThemeStateDisabled];
[_buttonUp setValue:[self valueForThemeAttribute:@"bezel-color-up-button" inState:CPThemeStateBordered | CPThemeStateHighlighted] forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered | CPThemeStateHighlighted];
@@ -142,16 +189,28 @@ var CPStepperButtonsSize = CPSizeMake(19, 13);
[_buttonDown setValue:[self valueForThemeAttribute:@"bezel-color-down-button" inState:CPThemeStateBordered | CPThemeStateHighlighted] forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered | CPThemeStateHighlighted];
}
/*! set if CPStepper should autorepeat
- (void)_sizeToFit
{
[self setFrame:CGRectMake([self frameOrigin].x, [self frameOrigin].y, 0, 0)];
}
/*!
Set if CPStepper should autorepeat.
@param shouldAutoRepeat if YES, the first mouse down does one increment (decrement) and, after each delay of 0.5 seconds
*/
- (void)setAutorepeat:(BOOL)shouldAutoRepeat
{
[_buttonUp setContinuous:shouldAutoRepeat];
[_buttonDown setContinuous:shouldAutoRepeat];
if (shouldAutoRepeat !== _autorepeat)
{
[_buttonUp setContinuous:shouldAutoRepeat];
[_buttonDown setContinuous:shouldAutoRepeat];
}
[self setContinuous:shouldAutoRepeat];
}
/*! set the current value of the stepper
/*!
Set the current value of the stepper.
@param aValue a float containing the value
*/
- (void)setDoubleValue:(float)aValue
@@ -167,8 +226,7 @@ var CPStepperButtonsSize = CPSizeMake(19, 13);
#pragma mark -
#pragma mark Actions
/*! @ignore
*/
/*! @ignore */
- (IBAction)_buttonDidClick:(id)aSender
{
if (![self isEnabled])
@@ -179,11 +237,11 @@ var CPStepperButtonsSize = CPSizeMake(19, 13);
else
[self setDoubleValue:([self doubleValue] - _increment)];
if (_target && _action && [_target respondsToSelector:_action])
[self sendAction:_action to:_target];
[self sendAction:[self action] to:[self target]];
}
/*! @perform a programatic click on up button
/*!
Perform a programatic click on up button.
@param aSender sender of the action
*/
- (IBAction)performClickUp:(id)aSender
@@ -191,7 +249,8 @@ var CPStepperButtonsSize = CPSizeMake(19, 13);
[_buttonUp performClick:aSender];
}
/*! @perform a programatic click on down button
/*!
Perform a programatic click on down button.
@param aSender sender of the action
*/
- (IBAction)performClickDown:(id)aSender
@@ -210,25 +269,51 @@ var CPStepperButtonsSize = CPSizeMake(19, 13);
+ (id)themeAttributes
{
return [CPDictionary dictionaryWithObjects:[[CPNull null], [CPNull null]]
forKeys:[@"bezel-color-up-button", @"bezel-color-down-button"]];
return [CPDictionary dictionaryWithObjects:[[CPNull null], [CPNull null], _CGSizeMakeZero(), _CGSizeMakeZero()]
forKeys:[@"bezel-color-up-button", @"bezel-color-down-button", @"up-button-size", @"down-button-size"]];
}
@end
@implementation _CPStepperValueBinder : CPBinder
{
}
@implementation CPStepper (CPCodingCompliance)
- (void)_updatePlaceholdersWithOptions:(CPDictionary)options forBinding:(CPString)aBinding
{
var placeholder = (aBinding == CPMaxValueBinding) ? [_source maxValue] : [_source minValue];
[super _updatePlaceholdersWithOptions:options];
[self _setPlaceholder:placeholder forMarker:CPMultipleValuesMarker isDefault:YES];
[self _setPlaceholder:placeholder forMarker:CPNoSelectionMarker isDefault:YES];
[self _setPlaceholder:placeholder forMarker:CPNotApplicableMarker isDefault:YES];
[self _setPlaceholder:placeholder forMarker:CPNullMarker isDefault:YES];
}
@end
var CPStepperMinValue = @"CPStepperMinValue",
CPStepperMaxValue = @"CPStepperMaxValue",
CPStepperValueWraps = @"CPStepperValueWraps",
CPStepperAutorepeat = @"CPStepperAutorepeat",
CPStepperIncrement = @"CPStepperIncrement";
@implementation CPStepper (CPCoding)
- (id)initWithCoder:(CPCoder)aCoder
{
if (self = [super initWithCoder:aCoder])
{
_maxValue = [aCoder decodeObjectForKey:@"_maxValue"];
_minValue = [aCoder decodeObjectForKey:@"_minValue"];
_increment = [aCoder decodeObjectForKey:@"_increment"];
_buttonUp = [aCoder decodeObjectForKey:@"_buttonUp"];
_buttonDown = [aCoder decodeObjectForKey:@"_buttonDown"];
_increment = [aCoder decodeIntForKey:CPStepperIncrement];
_minValue = [aCoder decodeIntForKey:CPStepperMinValue];
_maxValue = [aCoder decodeIntForKey:CPStepperMaxValue];
_valueWraps = [aCoder decodeBoolForKey:CPStepperValueWraps];
_autorepeat = [aCoder decodeBoolForKey:CPStepperAutorepeat];
[self _init];
}
return self;
}
@@ -236,11 +321,16 @@ var CPStepperButtonsSize = CPSizeMake(19, 13);
{
[super encodeWithCoder:aCoder];
[aCoder encodeObject:_maxValue forKey:@"_maxValue"];
[aCoder encodeObject:_minValue forKey:@"_minValue"];
[aCoder encodeObject:_increment forKey:@"_increment"];
[aCoder encodeObject:_buttonUp forKey:@"_buttonUp"];
[aCoder encodeObject:_buttonDown forKey:@"_buttonDown"];
[aCoder encodeInt:_increment forKey:CPStepperIncrement];
if (_minValue)
[aCoder encodeInt:_minValue forKey:CPStepperMinValue];
if (_maxValue)
[aCoder encodeInt:_maxValue forKey:CPStepperMaxValue];
if (_valueWraps)
[aCoder encodeBool:_valueWraps forKey:CPStepperValueWraps];
if (_autorepeat)
[aCoder encodeBool:_autorepeat forKey:CPStepperAutorepeat];
}
@end
+1
View File
@@ -22,6 +22,7 @@
@import <Foundation/CPString.j>
@import "CGGeometry.j"
@import "CPPlatformString.j"
+78 -41
View File
@@ -1,3 +1,25 @@
/*
* CPTabView.j
* AppKit
*
* Created by Derek Hammer.
* Copyright 2010, Derek Hammer.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "CPBox.j"
@import "CPSegmentedControl.j"
@import "CPTabViewItem.j"
@@ -45,7 +67,6 @@ var CPTabViewDidSelectTabViewItemSelector = 1,
if (self = [super initWithFrame:aFrame])
{
_items = [CPArray array];
_selectedIndex = CPNotFound;
[self _init];
[self setTabViewType:CPTopTabsBezelBorder];
@@ -56,18 +77,17 @@ var CPTabViewDidSelectTabViewItemSelector = 1,
- (void)_init
{
_tabs = [[CPSegmentedControl alloc] initWithFrame:CGRectMake(0, 0, 0, 0)];
_selectedIndex = CPNotFound;
_tabs = [[CPSegmentedControl alloc] initWithFrame:_CGRectMake(0, 0, 0, 0)];
[_tabs setHitTests:NO];
var height = [_tabs valueForThemeAttribute:@"default-height"];
[_tabs setFrameSize:CGSizeMake(0, height)];
[_tabs setFrameSize:_CGSizeMake(0, height)];
_box = [[CPBox alloc] initWithFrame:[self bounds]];
[self setBackgroundColor:[CPColor colorWithCalibratedWhite:0.95 alpha:1.0]];
[_box setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
[_tabs setAutoresizingMask:CPViewMinXMargin | CPViewMaxXMargin];
[self addSubview:_box];
[self addSubview:_tabs];
}
@@ -250,17 +270,15 @@ var CPTabViewDidSelectTabViewItemSelector = 1,
Selects the item at the specified index.
@param anIndex the index of the item to display.
*/
- (void)selectTabViewItemAtIndex:(unsigned)anIndex
- (BOOL)selectTabViewItemAtIndex:(unsigned)anIndex
{
var aTabViewItem = [_items objectAtIndex:anIndex];
if (anIndex === _selectedIndex)
return;
var aTabViewItem = [self tabViewItemAtIndex:anIndex];
if ((_delegateSelectors & CPTabViewShouldSelectTabViewItemSelector) && ![_delegate tabView:self shouldSelectTabViewItem:aTabViewItem])
return;
return NO;
if (_delegateSelectors & CPTabViewWillSelectTabViewItemSelector)
[_delegate tabView:self willSelectTabViewItem:aTabViewItem];
@@ -270,6 +288,8 @@ var CPTabViewDidSelectTabViewItemSelector = 1,
if (_delegateSelectors & CPTabViewDidSelectTabViewItemSelector)
[_delegate tabView:self didSelectTabViewItem:aTabViewItem];
return YES;
}
/*!
@@ -278,7 +298,10 @@ var CPTabViewDidSelectTabViewItemSelector = 1,
*/
- (CPTabViewItem)selectedTabViewItem
{
return [_items objectAtIndex:_selectedIndex];
if (_selectedIndex != CPNotFound)
return [_items objectAtIndex:_selectedIndex];
return nil;
}
// Modifying the font
@@ -317,21 +340,9 @@ var CPTabViewDidSelectTabViewItemSelector = 1,
_type = aTabViewType;
if (_type !== CPTopTabsBezelBorder && _type !== CPBottomTabsBezelBorder)
{
[_box setFrame:[self bounds]];
[_tabs removeFromSuperview];
}
else
{
var aFrame = [self frame],
segmentedHeight = CGRectGetHeight([_tabs frame]),
origin = _type === CPTopTabsBezelBorder ? segmentedHeight / 2 : 0;
[_box setFrame:CGRectMake(0, origin, CGRectGetWidth(aFrame),
CGRectGetHeight(aFrame) - segmentedHeight / 2)];
[self addSubview:_tabs];
}
switch (_type)
{
@@ -347,6 +358,29 @@ var CPTabViewDidSelectTabViewItemSelector = 1,
[_box setBorderType:CPNoBorder];
break;
}
[self setNeedsLayout];
}
- (void)layoutSubviews
{
// Even if CPTabView's autoresizesSubviews is NO, _tabs and _box has to be laid out.
// This means we can't rely on autoresize masks.
if (_type !== CPTopTabsBezelBorder && _type !== CPBottomTabsBezelBorder)
{
[_box setFrame:[self bounds]];
}
else
{
var aFrame = [self frame],
segmentedHeight = _CGRectGetHeight([_tabs frame]),
origin = _type === CPTopTabsBezelBorder ? segmentedHeight / 2 : 0;
[_box setFrame:_CGRectMake(0, origin, _CGRectGetWidth(aFrame),
_CGRectGetHeight(aFrame) - segmentedHeight / 2)];
[self _repositionTabs];
}
}
/*!
@@ -407,29 +441,30 @@ var CPTabViewDidSelectTabViewItemSelector = 1,
{
var segmentIndex = [_tabs testSegment:[_tabs convertPoint:[anEvent locationInWindow] fromView:nil]];
if (segmentIndex != CPNotFound)
{
[self selectTabViewItemAtIndex:segmentIndex];
if (segmentIndex != CPNotFound && [self selectTabViewItemAtIndex:segmentIndex])
[_tabs trackSegment:anEvent];
}
}
- (void)_repositionTabs
{
var horizontalCenterOfSelf = CGRectGetWidth([self bounds]) / 2,
verticalCenterOfTabs = CGRectGetHeight([_tabs bounds]) / 2;
var horizontalCenterOfSelf = _CGRectGetWidth([self bounds]) / 2,
verticalCenterOfTabs = _CGRectGetHeight([_tabs bounds]) / 2;
if (_type === CPBottomTabsBezelBorder)
[_tabs setCenter:CGPointMake(horizontalCenterOfSelf, CGRectGetHeight([self bounds]) - verticalCenterOfTabs)];
[_tabs setCenter:_CGPointMake(horizontalCenterOfSelf, _CGRectGetHeight([self bounds]) - verticalCenterOfTabs)];
else
[_tabs setCenter:CGPointMake(horizontalCenterOfSelf, verticalCenterOfTabs)];
[_tabs setCenter:_CGPointMake(horizontalCenterOfSelf, verticalCenterOfTabs)];
}
- (void)_setSelectedIndex:(CPNumber)index
{
_selectedIndex = index;
[self _setContentViewFromItem:[_items objectAtIndex:_selectedIndex]];
}
[_box setContentView:[[_items objectAtIndex:_selectedIndex] view]];
- (void)_setContentViewFromItem:(CPTabViewItem)anItem
{
[_box setContentView:[anItem view]];
}
- (void)_updateItems
@@ -444,9 +479,7 @@ var CPTabViewDidSelectTabViewItemSelector = 1,
}
if (_selectedIndex === CPNotFound)
{
[self selectFirstTabViewItem:self];
}
}
@end
@@ -469,18 +502,19 @@ var CPTabViewItemsKey = "CPTabViewItemsKey",
[_tabs setFont:_font];
_items = [aCoder decodeObjectForKey:CPTabViewItemsKey];
[_items makeObjectsPerformSelector:@selector(_setTabView:) withObject:self];
[self _updateItems];
[self _repositionTabs];
var selected = [aCoder decodeObjectForKey:CPTabViewSelectedItemKey];
if (selected)
[self selectTabViewItem:selected];
[self setDelegate:[aCoder decodeObjectForKey:CPTabViewDelegateKey]];
var selected = [aCoder decodeObjectForKey:CPTabViewSelectedItemKey];
if (selected)
[self selectTabViewItem:selected];
[self setTabViewType:[aCoder decodeIntForKey:CPTabViewTypeKey]];
[self setNeedsLayout];
}
return self;
@@ -491,7 +525,10 @@ var CPTabViewItemsKey = "CPTabViewItemsKey",
[super encodeWithCoder:aCoder];
[aCoder encodeObject:_items forKey:CPTabViewItemsKey];
[aCoder encodeObject:[self selectedTabViewItem] forKey:CPTabViewSelectedItemKey];
var selected = [self selectedTabViewItem];
if (selected)
[aCoder encodeObject:selected forKey:CPTabViewSelectedItemKey];
[aCoder encodeInt:_type forKey:CPTabViewTypeKey];
[aCoder encodeObject:_font forKey:CPTabViewFontKey];
+7
View File
@@ -60,6 +60,7 @@ CPPressedTab = 2;
CPView _auxiliaryView;
CPTabView _tabView;
unsigned _tabState; // Looks like it is not yet implemented
}
- (id)init
@@ -132,7 +133,13 @@ CPPressedTab = 2;
*/
- (void)setView:(CPView)aView
{
if (_view == aView)
return;
_view = aView;
if ([_tabView selectedTabViewItem] == self)
[_tabView _setContentViewFromItem:self];
}
/*!
+58 -12
View File
@@ -26,8 +26,11 @@
@import <Foundation/CPSortDescriptor.j>
@import <Foundation/CPString.j>
@import "CPTableHeaderView.j"
@import "CPTextField.j"
@global CPTableViewColumnDidResizeNotification
@class _CPTableColumnHeaderView
CPTableColumnNoResizing = 0;
CPTableColumnAutoresizingMask = 1 << 0;
@@ -132,7 +135,7 @@ CPTableColumnUserResizingMask = 1 << 1;
{
var min = [self minWidth],
max = [self maxWidth],
newWidth = MIN(MAX(width, min), max);
newWidth = ROUND(MIN(MAX(width, min), max));
[self setWidth:newWidth];
@@ -494,16 +497,23 @@ CPTableColumnUserResizingMask = 1 << 1;
*/
- (CPSortDescriptor)sortDescriptorPrototype
{
return _sortDescriptorPrototype;
if (_sortDescriptorPrototype)
return _sortDescriptorPrototype;
var binderClass = [[self class] _binderClassForBinding:CPValueBinding],
binding = [binderClass getBinding:CPValueBinding forObject:self];
return [binding _defaultSortDescriptorPrototype];
}
/*!
If NO the tablecolumn will no longer be visible in the tableview
If YES the tablecolumn will be visible in the tableview.
If YES the tablecolumn will no longer be visible in the tableview.
If NO the tablecolumn will be visible in the tableview.
*/
- (void)setHidden:(BOOL)shouldBeHidden
{
shouldBeHidden = !!shouldBeHidden
if (_isHidden === shouldBeHidden)
return;
@@ -569,6 +579,30 @@ CPTableColumnUserResizingMask = 1 << 1;
[tableView reloadDataForRowIndexes:rowIndexes columnIndexes:columnIndexes];
}
- (CPSortDescriptor)_defaultSortDescriptorPrototype
{
if (![self createsSortDescriptor])
return nil;
var keyPath = [_info objectForKey:CPObservedKeyPathKey],
dotIndex = keyPath.indexOf(".");
if (dotIndex === CPNotFound)
return nil;
var firstPart = keyPath.substring(0, dotIndex),
key = keyPath.substring(dotIndex + 1);
return [CPSortDescriptor sortDescriptorWithKey:key ascending:YES];
}
- (BOOL)createsSortDescriptor
{
var options = [_info objectForKey:CPOptionsKey],
optionValue = [options objectForKey:CPCreatesSortDescriptorBindingOption];
return optionValue === nil ? YES : [optionValue boolValue];
}
@end
@implementation CPTableColumn (Bindings)
@@ -594,7 +628,22 @@ CPTableColumnUserResizingMask = 1 << 1;
[super bind:aBinding toObject:anObject withKeyPath:aKeyPath options:options];
if (![aBinding isEqual:@"someListOfExceptedBindings(notAcceptedBindings)"])
[[self tableView] _establishBindingsIfUnbound:anObject];
{
// Bind the table to the array controller this column is bound to.
// Note that anObject might not be the array controller. E.g. the keypath could be something like
// somePathTo.anArrayController.arrangedObjects.aKey. Cocoa doesn't support this but it is consistent
// and it makes sense.
var acIndex = aKeyPath.lastIndexOf("arrangedObjects."),
arrayController = anObject;
if (acIndex > 1)
{
var firstPart = aKeyPath.substring(0, acIndex - 1);
arrayController = [anObject valueForKeyPath:firstPart];
}
[[self tableView] _establishBindingsIfUnbound:arrayController];
}
}
/*!
@@ -663,8 +712,11 @@ CPTableColumnUserResizingMask = 1 << 1;
bindingInfo = binding._info,
destination = [bindingInfo objectForKey:CPObservedObjectKey],
keyPath = [bindingInfo objectForKey:CPObservedKeyPathKey],
options = [bindingInfo objectForKey:CPOptionsKey],
dotIndex = keyPath.lastIndexOf(".");
newValue = [binding reverseTransformValue:newValue withOptions:options];
if (dotIndex === CPNotFound)
[[destination valueForKeyPath:keyPath] replaceObjectAtIndex:aRow withObject:newValue];
else
@@ -681,11 +733,6 @@ CPTableColumnUserResizingMask = 1 << 1;
}
}
//- (void)objectValue
//{
// return nil;
//}
@end
var CPTableColumnIdentifierKey = @"CPTableColumnIdentifierKey",
@@ -719,7 +766,6 @@ var CPTableColumnIdentifierKey = @"CPTableColumnIdentifierKey",
[self setIdentifier:[aCoder decodeObjectForKey:CPTableColumnIdentifierKey]];
[self setHeaderView:[aCoder decodeObjectForKey:CPTableColumnHeaderViewKey]];
[self setDataView:[aCoder decodeObjectForKey:CPTableColumnDataViewKey]];
[self setHeaderView:[aCoder decodeObjectForKey:CPTableColumnHeaderViewKey]];
_resizingMask = [aCoder decodeIntForKey:CPTableColumnResizingMaskKey];
_isHidden = [aCoder decodeBoolForKey:CPTableColumnIsHiddenKey];
+72 -7
View File
@@ -22,9 +22,15 @@
@import <Foundation/CPIndexSet.j>
@import "CPCursor.j"
@import "CPPasteboard.j"
@import "CPTableColumn.j"
@import "CPTableView.j"
@import "CPView.j"
@import "_CPImageAndTextView.j"
@class CPTableView
@global CPApp
@implementation _CPTableColumnHeaderView : CPView
@@ -39,13 +45,14 @@
+ (id)themeAttributes
{
return [CPDictionary dictionaryWithObjects:[[CPNull null], [CPNull null], CGInsetMakeZero(), [CPNull null], [CPNull null], [CPNull null], CGSizeMakeZero()]
forKeys:[@"background-color", @"text-alignment", @"text-inset", @"text-color", @"text-font", @"text-shadow-color", @"text-shadow-offset"]];
return [CPDictionary dictionaryWithObjects:[[CPNull null], CPLeftTextAlignment, CPLineBreakByTruncatingTail, CGInsetMakeZero(), [CPNull null], [CPNull null], [CPNull null], CGSizeMakeZero()]
forKeys:[@"background-color", @"text-alignment", @"line-break-mode", @"text-inset", @"text-color", @"font", @"text-shadow-color", @"text-shadow-offset"]];
}
- (void)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self)
[self _init];
@@ -74,10 +81,11 @@
[_textField setFrame:_CGRectMake(inset.right, inset.top, bounds.size.width - inset.right - inset.left, bounds.size.height - inset.top - inset.bottom)];
[_textField setTextColor:[self currentValueForThemeAttribute:@"text-color"]];
[_textField setFont:[self currentValueForThemeAttribute:@"text-font"]];
[_textField setFont:[self currentValueForThemeAttribute:@"font"]];
[_textField setTextShadowColor:[self currentValueForThemeAttribute:@"text-shadow-color"]];
[_textField setTextShadowOffset:[self currentValueForThemeAttribute:@"text-shadow-offset"]];
[_textField setAlignment:[self currentValueForThemeAttribute:@"text-alignment"]];
[_textField setLineBreakMode:[self currentValueForThemeAttribute:@"line-break-mode"]];
}
- (void)setStringValue:(CPString)string
@@ -102,7 +110,52 @@
- (void)setFont:(CPFont)aFont
{
[self setValue:aFont forThemeAttribute:"text-font"];
[self setValue:aFont forThemeAttribute:@"font"];
}
- (CPFont)font
{
return [self currentValueForThemeAttribute:@"font"]
}
- (void)setAlignment:(CPTextAlignment)alignment
{
[self setValue:alignment forThemeAttribute:@"text-alignment"];
}
- (CPTextAlignment)alignment
{
return [self currentValueForThemeAttribute:@"text-alignment"]
}
- (void)setLineBreakMode:(CPLineBreakMode)mode
{
[self setValue:mode forThemeAttribute:@"line-break-mode"];
}
- (CPLineBreakMode)lineBreakMode
{
return [self currentValueForThemeAttribute:@"line-break-mode"]
}
- (void)setTextColor:(CPColor)aColor
{
[self setValue:aColor forThemeAttribute:@"text-color"];
}
- (CPColor)textColor
{
return [self currentValueForThemeAttribute:@"text-color"]
}
- (void)setTextShadowColor:(CPColor)aColor
{
[self setValue:aColor forThemeAttribute:@"text-shadow-color"];
}
- (CPColor)textShadowColor
{
return [self currentValueForThemeAttribute:@"text-shadow-color"]
}
- (void)_setIndicatorImage:(CPImage)anImage
@@ -122,6 +175,10 @@
var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringValueKey",
_CPTableColumnHeaderViewFontKey = @"_CPTableColumnHeaderViewFontKey",
_CPTableColumnHeaderViewTextColorKey = @"_CPTableColumnHeaderViewTextColorKey",
_CPTableColumnHeaderViewTextShadowColorKey = @"_CPTableColumnHeaderViewTextShadowColorKey",
_CPTableColumnHeaderViewAlignmentKey = @"_CPTableColumnHeaderViewAlignmentKey",
_CPTableColumnHeaderViewLineBreakModeKey = @"_CPTableColumnHeaderViewLineBreakModeKey",
_CPTableColumnHeaderViewImageKey = @"_CPTableColumnHeaderViewImageKey";
@implementation _CPTableColumnHeaderView (CPCoding)
@@ -134,6 +191,10 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal
[self _setIndicatorImage:[aCoder decodeObjectForKey:_CPTableColumnHeaderViewImageKey]];
[self setStringValue:[aCoder decodeObjectForKey:_CPTableColumnHeaderViewStringValueKey]];
[self setFont:[aCoder decodeObjectForKey:_CPTableColumnHeaderViewFontKey]];
[self setTextColor:[aCoder decodeObjectForKey:_CPTableColumnHeaderViewTextColorKey]];
[self setTextShadowColor:[aCoder decodeObjectForKey:_CPTableColumnHeaderViewTextShadowColorKey]];
[self setAlignment:[aCoder decodeIntForKey:_CPTableColumnHeaderViewAlignmentKey]];
[self setLineBreakMode:[aCoder decodeIntForKey:_CPTableColumnHeaderViewLineBreakModeKey]];
}
return self;
@@ -145,7 +206,11 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal
[aCoder encodeObject:[_textField text] forKey:_CPTableColumnHeaderViewStringValueKey];
[aCoder encodeObject:[_textField image] forKey:_CPTableColumnHeaderViewImageKey];
[aCoder encodeObject:[_textField font] forKey:_CPTableColumnHeaderViewFontKey];
[aCoder encodeObject:[self font] forKey:_CPTableColumnHeaderViewFontKey];
[aCoder encodeObject:[self textColor] forKey:_CPTableColumnHeaderViewTextColorKey];
[aCoder encodeObject:[self textShadowColor] forKey:_CPTableColumnHeaderViewTextShadowColorKey];
[aCoder encodeInt:[self alignment] forKey:_CPTableColumnHeaderViewAlignmentKey];
[aCoder encodeInt:[self lineBreakMode] forKey:_CPTableColumnHeaderViewLineBreakModeKey];
}
@end
@@ -643,7 +708,7 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal
columnMaxX = _CGRectGetMaxX(columnToStroke);
CGContextMoveToPoint(context, FLOOR(columnMaxX) - 0.5, ROUND(_CGRectGetMinY(columnToStroke)));
CGContextAddLineToPoint(context, FLOOR(columnMaxX) - 0.5, ROUND(_CGRectGetMaxY(columnToStroke)));
CGContextAddLineToPoint(context, FLOOR(columnMaxX) - 0.5, ROUND(_CGRectGetMaxY(columnToStroke)) - 1.0);
}
CGContextClosePath(context);
CGContextStrokePath(context);
+255 -101
View File
@@ -23,12 +23,26 @@
@import <Foundation/CPArray.j>
@import <Foundation/CPIndexSet.j>
@import "CPDragServer_Constants.j"
@import "CGGradient.j"
@import "CPCompatibility.j"
@import "CPControl.j"
@import "CPTableColumn.j"
@import "_CPCornerView.j"
@import "CPImageView.j"
@import "CPScroller.j"
@import "CPScrollView.j"
@import "CPTableColumn.j"
@import "CPTableHeaderView.j"
@import "CPText.j"
@import "_CPCornerView.j"
@class CPButton
@class CPClipView
@class CPUserDefaults
@class CPTableHeaderView
@class CPClipView
@class CPButton
@global CPApp
CPTableViewColumnDidMoveNotification = @"CPTableViewColumnDidMoveNotification";
@@ -87,9 +101,9 @@ CPTableViewSelectionHighlightStyleNone = -1;
CPTableViewSelectionHighlightStyleRegular = 0;
CPTableViewSelectionHighlightStyleSourceList = 1;
CPTableViewGridNone = 0;
CPTableViewSolidVerticalGridLineMask = 1 << 0;
CPTableViewSolidHorizontalGridLineMask = 1 << 1;
CPTableViewGridNone = 0;
CPTableViewSolidVerticalGridLineMask = 1 << 0;
CPTableViewSolidHorizontalGridLineMask = 1 << 1;
CPTableViewNoColumnAutoresizing = 0;
CPTableViewUniformColumnAutoresizingStyle = 1; // FIX ME: This is FUBAR
@@ -221,6 +235,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
SEL _doubleAction;
CPInteger _clickedRow;
CPInteger _clickedColumn;
unsigned _columnAutoResizingStyle;
int _lastTrackedRowIndex;
@@ -239,6 +254,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
BOOL _disableAutomaticResizing @accessors(property=disableAutomaticResizing);
BOOL _lastColumnShouldSnap;
BOOL _implementsCustomDrawRow;
BOOL _contentBindingExpicitelySet;
CPTableColumn _draggedColumn;
CPArray _differedColumnDataToRemove;
@@ -257,8 +273,26 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
*/
+ (id)themeAttributes
{
return [CPDictionary dictionaryWithObjects:[[CPNull null], [CPNull null], [CPNull null], [CPNull null], [CPNull null], [CPNull null], [CPNull null]]
forKeys:["alternating-row-colors", "grid-color", "highlighted-grid-color", "selection-color", "sourcelist-selection-color", "sort-image", "sort-image-reversed"]];
return [CPDictionary dictionaryWithObjects:[[CPNull null],
[CPNull null],
[CPNull null],
[CPNull null],
[CPNull null],
[CPNull null],
[CPNull null],
[CPNull null],
[CPNull null],
25.0]
forKeys:[@"alternating-row-colors",
@"grid-color",
@"highlighted-grid-color",
@"selection-color",
@"sourcelist-selection-color",
@"sort-image",
@"sort-image-reversed",
@"selection-radius",
@"image-generic-file",
@"default-row-height"]];
}
- (id)initWithFrame:(CGRect)aFrame
@@ -288,7 +322,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
_numberOfHiddenColumns = 0;
_intercellSpacing = _CGSizeMake(3.0, 2.0);
_rowHeight = 23.0;
_rowHeight = [self valueForThemeAttribute:@"default-row-height"];
[self setGridColor:[CPColor colorWithHexString:@"dce0e2"]];
[self setGridStyleMask:CPTableViewGridNone];
@@ -305,6 +339,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
_retargetedDropOperation = nil;
_dragOperationDefaultMask = nil;
_destinationDragStyle = CPTableViewDraggingDestinationFeedbackStyleRegular;
_contentBindingExpicitelySet = NO;
[self setBackgroundColor:[CPColor whiteColor]];
[self _init];
@@ -321,8 +356,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
*/
- (void)_init
{
_tableViewFlags = 0;
_lastSelectedRow = -1;
_lastSelectedRow = _clickedColumn = _clickedRow = -1;
_selectedColumnIndexes = [CPIndexSet indexSet];
_selectedRowIndexes = [CPIndexSet indexSet];
@@ -335,19 +369,17 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
if (!_alternatingRowBackgroundColors)
_alternatingRowBackgroundColors = [[CPColor whiteColor], [CPColor colorWithHexString:@"e4e7ff"]];
_selectionHighlightColor = [CPColor colorWithHexString:@"5f83b9"];
_tableColumnRanges = [];
_dirtyTableColumnRangeIndex = 0;
_numberOfHiddenColumns = 0;
_objectValues = { };
_dataViewsForTableColumns = { };
_dataViews = [];
_numberOfRows = 0;
_exposedRows = [CPIndexSet indexSet];
_exposedColumns = [CPIndexSet indexSet];
_cachedDataViews = { };
_cachedRowHeights = [];
_groupRows = [CPIndexSet indexSet];
@@ -509,6 +541,11 @@ NOT YET IMPLEMENTED
_objectValues = { };
_cachedRowHeights = [];
// Otherwise, if we have a row marked as group with a
// index greater than the new number or rows
// it keeps the the graphical group style.
[_groupRows removeAllIndexes];
// This updates the size too.
[self noteNumberOfRowsChanged];
@@ -537,8 +574,12 @@ NOT YET IMPLEMENTED
}
/*
* - clickedColumn
Returns the index of the the column the user clicked to trigger an action, or -1 if no column was clicked.
*/
- (CPInteger)clickedColumn
{
return _clickedColumn;
}
/*!
Returns the index of the the row the user clicked to trigger an action, or -1 if no row was clicked.
@@ -678,6 +719,7 @@ NOT YET IMPLEMENTED
*/
- (void)setRowHeight:(unsigned)aRowHeight
{
// Accept row heights such as "0".
aRowHeight = +aRowHeight;
if (_rowHeight === aRowHeight)
@@ -721,7 +763,7 @@ NOT YET IMPLEMENTED
- (void)setAlternatingRowBackgroundColors:(CPArray)alternatingRowBackgroundColors
{
[self setValue:alternatingRowBackgroundColors forThemeAttribute:"alternating-row-colors"];
[self setValue:alternatingRowBackgroundColors forThemeAttribute:@"alternating-row-colors"];
[self setNeedsDisplay:YES];
}
@@ -763,10 +805,6 @@ NOT YET IMPLEMENTED
*/
- (void)setSelectionHighlightStyle:(unsigned)aSelectionHighlightStyle
{
//early return for IE.
if (aSelectionHighlightStyle == CPTableViewSelectionHighlightStyleSourceList && !CPFeatureIsCompatible(CPHTMLCanvasFeature))
return;
_selectionHighlightStyle = aSelectionHighlightStyle;
[self setNeedsDisplay:YES];
@@ -783,7 +821,7 @@ NOT YET IMPLEMENTED
*/
- (void)setSelectionHighlightColor:(CPColor)aColor
{
[self setValue:aColor forThemeAttribute:"selection-color"];
[self setValue:aColor forThemeAttribute:@"selection-color"];
[self setNeedsDisplay:YES];
}
@@ -809,7 +847,7 @@ NOT YET IMPLEMENTED
*/
- (void)setSelectionGradientColors:(CPDictionary)aDictionary
{
[self setValue:aDictionary forThemeAttribute:"sourcelist-selection-color"];
[self setValue:aDictionary forThemeAttribute:@"sourcelist-selection-color"];
[self setNeedsDisplay:YES];
}
@@ -833,7 +871,7 @@ NOT YET IMPLEMENTED
*/
- (void)setGridColor:(CPColor)aColor
{
[self setValue:aColor forThemeAttribute:"grid-color"];
[self setValue:aColor forThemeAttribute:@"grid-color"];
[self setNeedsDisplay:YES];
}
@@ -953,6 +991,7 @@ NOT YET IMPLEMENTED
*/
- (void)_moveColumn:(unsigned)fromIndex toColumn:(unsigned)toIndex
{
// Convert parameters such as "0" to 0.
fromIndex = +fromIndex;
toIndex = +toIndex;
@@ -976,6 +1015,13 @@ NOT YET IMPLEMENTED
columnIndexes = [CPIndexSet indexSetWithIndexesInRange:CPMakeRange(fromIndex, toIndex)];
[self reloadDataForRowIndexes:rowIndexes columnIndexes:columnIndexes];
// Notify even if programmatically moving a column as in Cocoa.
// TODO Only notify when a column drag operation ends, not each time a column reaches a new slot?
[[CPNotificationCenter defaultCenter] postNotificationName:CPTableViewColumnDidMoveNotification
object:self
userInfo:[CPDictionary dictionaryWithObjects:[fromIndex, toIndex]
forKeys:[@"CPOldColumn", @"CPNewColumn"]]];
}
/*!
@@ -1258,7 +1304,7 @@ NOT YET IMPLEMENTED
*/
- (int)selectedColumn
{
[_selectedColumnIndexes lastIndex];
return [_selectedColumnIndexes lastIndex];
}
/*!
@@ -1510,6 +1556,8 @@ NOT YET IMPLEMENTED
if ([scrollView isKindOfClass:[CPScrollView class]] && [scrollView documentView] === self)
[scrollView _updateCornerAndHeaderView];
[self setNeedsLayout];
}
// Complexity:
@@ -1561,6 +1609,7 @@ NOT YET IMPLEMENTED
*/
- (CGRect)rectOfColumn:(CPInteger)aColumnIndex
{
// Convert e.g. "0" to 0.
aColumnIndex = +aColumnIndex;
if (aColumnIndex < 0 || aColumnIndex >= NUMBER_OF_COLUMNS())
@@ -1790,7 +1839,7 @@ NOT YET IMPLEMENTED
{
if (_implementedDelegateMethods & CPTableViewDelegate_tableView_heightOfRow_)
{
return idx = [_cachedRowHeights indexOfObject:aPoint
return [_cachedRowHeights indexOfObject:aPoint
inSortedRange:nil
options:0
usingComparator:function(aPoint, rowCache)
@@ -1984,7 +2033,7 @@ NOT YET IMPLEMENTED
// so we should size the last resized to fit
// find the last visisble column
while (count-- && [_tableColumns[count] isHidden]) ;
while (count-- && [_tableColumns[count] isHidden]);
// find the max x, but subtract a single pixel since the spacing isn't applicable here.
var delta = superviewWidth - _CGRectGetMaxX([self rectOfColumn:count]) - ([self intercellSpacing].width || 1),
@@ -2632,7 +2681,7 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
if (_allowsColumnSelection)
{
[self _noteSelectionIsChanging];
if (modifierFlags & CPCommandKeyMask)
if (modifierFlags & CPPlatformActionKeyMask)
{
if ([self isColumnSelected:clickedColumn])
[self deselectColumn:clickedColumn];
@@ -2683,7 +2732,7 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
oldMainSortDescriptor = [[self sortDescriptors] objectAtIndex: 0];
// Remove every main descriptor equivalents (normally only one)
while ((descriptor = [e nextObject]) != nil)
while ((descriptor = [e nextObject]) !== nil)
{
if ([[descriptor key] isEqual: [newMainSortDescriptor key]])
[outdatedDescriptors addObject:descriptor];
@@ -2723,7 +2772,7 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
*/
- (CPImage)_tableHeaderSortImage
{
return [self currentValueForThemeAttribute:"sort-image"];
return [self currentValueForThemeAttribute:@"sort-image"];
}
/*!
@@ -2731,7 +2780,7 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
*/
- (CPImage)_tableHeaderReverseSortImage
{
return [self currentValueForThemeAttribute:"sort-image-reversed"];
return [self currentValueForThemeAttribute:@"sort-image-reversed"];
}
/*!
@@ -2785,7 +2834,7 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
*/
- (CPImage)dragImageForRowsWithIndexes:(CPIndexSet)dragRows tableColumns:(CPArray)theTableColumns event:(CPEvent)dragEvent offset:(CGPoint)dragImageOffset
{
return [[CPImage alloc] initWithContentsOfFile:@"Frameworks/AppKit/Resources/GenericFile.png" size:CGSizeMake(32,32)];
return [self valueForThemeAttribute:@"image-generic-file"];
}
/*!
@@ -2821,11 +2870,8 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
var dataView = [self _newDataViewForRow:row tableColumn:tableColumn];
[dataView setFrame:[self frameOfDataViewAtColumn:columnIndex row:row]];
[dataView setObjectValue:[self _objectValueForTableColumn:tableColumn row:row]];
// If the column uses content bindings, allow them to override the objectValueForTableColumn.
[tableColumn _prepareDataView:dataView forRow:row];
[self _setObjectValueForTableColumn:tableColumn row:row forView:dataView];
[view addSubview:dataView];
row = [theDraggedRows indexGreaterThanIndex:row];
@@ -2845,11 +2891,12 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
// Copy the dataviews add them to a transparent drag view and use that drag view
// to make it appear we are dragging images of those rows (as you would do in regular Cocoa)
*/
- (CPView)_dragViewForColumn:(int)theColumnIndex event:(CPEvent)theDragEvent offset:(CPPointPointer)theDragViewOffset
- (CPView)_dragViewForColumn:(int)theColumnIndex event:(CPEvent)theDragEvent offset:(CGPoint)theDragViewOffset
{
var dragView = [[_CPColumnDragView alloc] initWithLineColor:[self gridColor]],
tableColumn = [[self tableColumns] objectAtIndex:theColumnIndex],
bounds = _CGRectMake(0.0, 0.0, [tableColumn width], _CGRectGetHeight([self exposedRect]) + 23.0),
defaultRowHeight = [self valueForThemeAttribute:@"default-row-height"],
bounds = _CGRectMake(0.0, 0.0, [tableColumn width], _CGRectGetHeight([self exposedRect]) + defaultRowHeight),
columnRect = [self rectOfColumn:theColumnIndex],
headerView = [tableColumn headerView],
row = [_exposedRows firstIndex];
@@ -2863,22 +2910,17 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
dataViewFrame.origin.x = 0.0;
// Offset by table header height - scroll position
dataViewFrame.origin.y = ( _CGRectGetMinY(dataViewFrame) - _CGRectGetMinY([self exposedRect]) ) + 23.0;
dataViewFrame.origin.y = ( _CGRectGetMinY(dataViewFrame) - _CGRectGetMinY([self exposedRect]) ) + defaultRowHeight;
[dataView setFrame:dataViewFrame];
[dataView setObjectValue:[self _objectValueForTableColumn:tableColumn row:row]];
[self _setObjectValueForTableColumn:tableColumn row:row forView:dataView];
[dragView addSubview:dataView];
row = [_exposedRows indexGreaterThanIndex:row];
}
// Add the column header view
var headerFrame = [headerView frame];
headerFrame.origin = _CGPointMakeZero();
var columnHeaderView = [[_CPTableColumnHeaderView alloc] initWithFrame:headerFrame];
[columnHeaderView setStringValue:[headerView stringValue]];
[columnHeaderView setThemeState:[headerView themeState]];
// Add a copy of the header view.
var columnHeaderView = [CPKeyedUnarchiver unarchiveObjectWithData:[CPKeyedArchiver archivedDataWithRootObject:headerView]];
[dragView addSubview:columnHeaderView];
[dragView setBackgroundColor:[CPColor whiteColor]];
@@ -3044,7 +3086,6 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
return _sortDescriptors;
}
/*!
@ignore
*/
@@ -3266,11 +3307,8 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
isTextField = [dataView isKindOfClass:[CPTextField class]];
[dataView setFrame:[self frameOfDataViewAtColumn:column row:row]];
[dataView setObjectValue:[self _objectValueForTableColumn:tableColumn row:row]];
// This gives the table column an opportunity to apply its bindings.
// It will override the value set above if there is a binding.
[tableColumn _prepareDataView:dataView forRow:row];
[self _setObjectValueForTableColumn:tableColumn row:row forView:dataView];
if (isColumnSelected || [self isRowSelected:row])
[dataView setThemeState:CPThemeStateSelectedDataView];
@@ -3328,6 +3366,30 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
}
}
- (void)_setObjectValueForTableColumn:(CPTableColumn)aTableColumn row:(CPInteger)aRow forView:(CPView)aDataView
{
if (_implementedDataSourceMethods & CPTableViewDataSource_tableView_objectValueForTableColumn_row_)
[aDataView setObjectValue:[self _objectValueForTableColumn:aTableColumn row:aRow]];
// This gives the table column an opportunity to apply its bindings.
// It will override the value set above if there is a binding.
if (_contentBindingExpicitelySet)
[self _prepareContentBindedDataView:aDataView forRow:aRow];
else
// For both cell-based and view-based
[aTableColumn _prepareDataView:aDataView forRow:aRow];
}
- (void)_prepareContentBindedDataView:(CPView)dataView forRow:(CPInteger)aRow
{
var binder = [CPTableContentBinder getBinding:@"content" forObject:self],
content = [binder content],
rowContent = [content objectAtIndex:aRow];
[dataView setObjectValue:rowContent];
}
/*!
@ignore
*/
@@ -3351,12 +3413,15 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
rowIndex = 0,
rowsCount = rowArray.length;
for (; rowIndex < rowsCount; ++rowIndex)
if (dataViewsForTableColumn)
{
var row = rowArray[rowIndex],
dataView = dataViewsForTableColumn[row];
for (; rowIndex < rowsCount; ++rowIndex)
{
var row = rowArray[rowIndex],
dataView = dataViewsForTableColumn[row];
[dataView setFrame:[self frameOfDataViewAtColumn:column row:row]];
[dataView setFrame:[self frameOfDataViewAtColumn:column row:row]];
}
}
}
}
@@ -3368,6 +3433,14 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
*/
- (void)_commitDataViewObjectValue:(id)sender
{
/*
makeFirstResponder at the end of this method causes the dataview to resign.
If the dataview resigning triggers the action (as CPTextField does), we come right
back here and start an infinite loop. So we have to check this flag first.
*/
if ([sender respondsToSelector:@selector(sendsActionOnEndEditing)] && [sender sendsActionOnEndEditing] && _editingCellIndex === nil)
return;
_editingCellIndex = nil;
if (_implementedDataSourceMethods & CPTableViewDataSource_tableView_setObjectValue_forTableColumn_row_)
@@ -3425,7 +3498,6 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
[aTableColumn setDataView:dataView];
}
return [aTableColumn _newDataViewForRow:aRow];
}
@@ -3497,8 +3569,20 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
{
[super setNeedsDisplay:aFlag];
[_tableDrawView setNeedsDisplay:aFlag];
[[self headerView] setNeedsDisplay:YES];
}
/*!
@ignore
*/
- (void)setNeedsLayout
{
[super setNeedsLayout];
[[self headerView] setNeedsLayout];
}
/*!
@ignore
*/
@@ -3680,12 +3764,13 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
[_selectedColumnIndexes getIndexes:indexes maxCount:-1 inIndexRange:exposedRange];
}
var count = count2 = [indexes count];
var count,
count2 = count = [indexes count];
if (!count)
return;
var drawGradient = (_selectionHighlightStyle === CPTableViewSelectionHighlightStyleSourceList && [_selectedRowIndexes count] >= 1),
var drawGradient = (CPFeatureIsCompatible(CPHTMLCanvasFeature) && _selectionHighlightStyle === CPTableViewSelectionHighlightStyleSourceList && [_selectedRowIndexes count] >= 1),
deltaHeight = 0.5 * (_gridStyleMask & CPTableViewSolidHorizontalGridLineMask);
CGContextBeginPath(context);
@@ -3705,7 +3790,7 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
{
var topGroupLineColor = [CPColor colorWithCalibratedWhite:212.0 / 255.0 alpha:1.0],
bottomGroupLineColor = [CPColor colorWithCalibratedWhite:185.0 / 255.0 alpha:1.0],
gradientGroupColor = CGGradientCreateWithColorComponents(CGColorSpaceCreateDeviceRGB(), [212.0 / 255.0, 212.0 / 255.0, 212.0 / 255.0,1.0, 197.0 / 255.0, 197.0 / 255.0, 197.0 / 255.0,1.0], [0,1], 2);
gradientGroupColor = CGGradientCreateWithColorComponents(CGColorSpaceCreateDeviceRGB(), [212.0 / 255.0, 212.0 / 255.0, 212.0 / 255.0, 1.0, 197.0 / 255.0, 197.0 / 255.0, 197.0 / 255.0, 1.0], [0, 1], 2);
}
while (count--)
@@ -3752,7 +3837,25 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
CGContextStrokePath(context);
}
else
CGContextAddRect(context, rowRect);
{
var radius = [self currentValueForThemeAttribute:@"selection-radius"];
if (radius > 0)
{
var minX = CGRectGetMinX(rowRect),
maxX = CGRectGetMaxX(rowRect),
minY = CGRectGetMinY(rowRect),
maxY = CGRectGetMaxY(rowRect);
CGContextMoveToPoint(context, minX + radius, minY);
CGContextAddArcToPoint(context, maxX, minY, maxX, minY + radius, radius);
CGContextAddArcToPoint(context, maxX, maxY, maxX - radius, maxY, radius);
CGContextAddArcToPoint(context, minX, maxY, minX, maxY - radius, radius);
CGContextAddArcToPoint(context, minX, minY, minX + radius, minY, radius);
}
else
CGContextAddRect(context, rowRect);
}
}
CGContextClosePath(context);
@@ -3801,7 +3904,7 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
}
CGContextClosePath(context);
CGContextSetStrokeColor(context, [self currentValueForThemeAttribute:"highlighted-grid-color"]);
CGContextSetStrokeColor(context, [self currentValueForThemeAttribute:@"highlighted-grid-color"]);
CGContextStrokePath(context);
}
@@ -3812,7 +3915,7 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
*/
- (void)_drawGroupRowsForRects:(CPArray)rects
{
if (_selectionHighlightStyle === CPTableViewSelectionHighlightStyleSourceList || !rects.length)
if ((CPFeatureIsCompatible(CPHTMLCanvasFeature) && _selectionHighlightStyle === CPTableViewSelectionHighlightStyleSourceList) || !rects.length)
return;
var context = [[CPGraphicsContext currentContext] graphicsPort],
@@ -3823,8 +3926,8 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
var gradientCache = [self selectionGradientColors],
topLineColor = [CPColor colorWithHexString:"d3d3d3"],
bottomLineColor = [CPColor colorWithHexString:"bebebd"],
gradientColor = CGGradientCreateWithColorComponents(CGColorSpaceCreateDeviceRGB(), [220.0 / 255.0, 220.0 / 255.0, 220.0 / 255.0,1.0,
199.0 / 255.0, 199.0 / 255.0, 199.0 / 255.0,1.0], [0,1], 2),
gradientColor = CGGradientCreateWithColorComponents(CGColorSpaceCreateDeviceRGB(), [220.0 / 255.0, 220.0 / 255.0, 220.0 / 255.0, 1.0,
199.0 / 255.0, 199.0 / 255.0, 199.0 / 255.0, 1.0], [0, 1], 2),
drawGradient = YES;
while (i--)
@@ -3970,9 +4073,12 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
*/
- (BOOL)startTrackingAt:(CGPoint)aPoint
{
// Try to become the first responder, but if we can't, that's okay.
[[self window] makeFirstResponder:self];
var row = [self rowAtPoint:aPoint];
//if the user clicks outside a row then deselect everything
// If the user clicks outside a row then deselect everything.
if (row < 0 && _allowsEmptySelection)
[self selectRowIndexes:[CPIndexSet indexSet] byExtendingSelection:NO];
@@ -3997,7 +4103,6 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
if (row >= 0 && !(_implementedDataSourceMethods & CPTableViewDataSource_tableView_writeRowsWithIndexes_toPasteboard_))
[self _updateSelectionWithMouseAtRow:row];
[[self window] makeFirstResponder:self];
return YES;
}
@@ -4058,7 +4163,7 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
if ([self canDragRowsWithIndexes:_draggedRowIndexes atPoint:aPoint] && [_dataSource tableView:self writeRowsWithIndexes:_draggedRowIndexes toPasteboard:pboard])
{
var currentEvent = [CPApp currentEvent],
offset = CPPointMakeZero(),
offset = CGPointMakeZero(),
tableColumns = [_tableColumns objectsAtIndexes:_exposedColumns];
// We deviate from the default Cocoa implementation here by asking for a view in stead of an image
@@ -4075,13 +4180,13 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
tableColumns:tableColumns
event:currentEvent
offset:offset];
view = [[CPImageView alloc] initWithFrame:CPMakeRect(0, 0, [image size].width, [image size].height)];
view = [[CPImageView alloc] initWithFrame:CGRectMake(0, 0, [image size].width, [image size].height)];
[view setImage:image];
}
var bounds = [view bounds],
viewLocation = CPPointMake(aPoint.x - CGRectGetWidth(bounds) / 2 + offset.x, aPoint.y - CGRectGetHeight(bounds) / 2 + offset.y);
[self dragView:view at:viewLocation offset:CPPointMakeZero() event:[CPApp currentEvent] pasteboard:pboard source:self slideBack:YES];
viewLocation = CGPointMake(aPoint.x - CGRectGetWidth(bounds) / 2 + offset.x, aPoint.y - CGRectGetHeight(bounds) / 2 + offset.y);
[self dragView:view at:viewLocation offset:CGPointMakeZero() event:[CPApp currentEvent] pasteboard:pboard source:self slideBack:YES];
_startTrackingPoint = nil;
return NO;
@@ -4123,7 +4228,7 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
_isSelectingSession = NO;
var CLICK_TIME_DELTA = 1000,
columnIndex,
columnIndex = -1,
column,
rowIndex,
shouldEdit = YES;
@@ -4131,6 +4236,7 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
if (_implementedDataSourceMethods & CPTableViewDataSource_tableView_writeRowsWithIndexes_toPasteboard_)
{
rowIndex = [self rowAtPoint:aPoint];
if (rowIndex !== -1)
{
if ([_draggedRowIndexes count] > 0)
@@ -4152,12 +4258,15 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
|| [self infoForBinding:@"content"]))
{
columnIndex = [self columnAtPoint:lastPoint];
if (columnIndex !== -1)
{
column = _tableColumns[columnIndex];
if ([column isEditable])
{
rowIndex = [self rowAtPoint:aPoint];
if (rowIndex !== -1)
{
if (_implementedDelegateMethods & CPTableViewDelegate_tableView_shouldEditTableColumn_row_)
@@ -4177,6 +4286,7 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
if ([[CPApp currentEvent] clickCount] === 2 && _doubleAction)
{
_clickedRow = [self rowAtPoint:aPoint];
_clickedColumn = [self columnAtPoint:lastPoint];
[self sendAction:_doubleAction to:_target];
}
}
@@ -4255,7 +4365,7 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
// If there is no (the default) or to little inter cell spacing we create some room for the CPTableViewDropAbove indicator
// This probably doesn't work if the row height is smaller than or around 5.0
if ([self intercellSpacing].height < 5.0)
rowRect = CPRectInset(rowRect, 0.0, 5.0 - [self intercellSpacing].height);
rowRect = CGRectInset(rowRect, 0.0, 5.0 - [self intercellSpacing].height);
// If the altered row rect contains the drag point we show the drop on
// We don't show the drop on indicator if we are dragging below the last row
@@ -4303,7 +4413,7 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
/*!
@ignore
*/
- (CPRect)_rectForDropHighlightViewOnRow:(int)theRowIndex
- (CGRect)_rectForDropHighlightViewOnRow:(int)theRowIndex
{
if (theRowIndex >= [self numberOfRows])
theRowIndex = [self numberOfRows] - 1;
@@ -4314,7 +4424,7 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
/*!
@ignore
*/
- (CPRect)_rectForDropHighlightViewBetweenUpperRow:(int)theUpperRowIndex andLowerRow:(int)theLowerRowIndex offset:(CPPoint)theOffset
- (CGRect)_rectForDropHighlightViewBetweenUpperRow:(int)theUpperRowIndex andLowerRow:(int)theLowerRowIndex offset:(CGPoint)theOffset
{
if (theLowerRowIndex > [self numberOfRows])
theLowerRowIndex = [self numberOfRows];
@@ -4543,6 +4653,14 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
return YES;
}
/*!
@ignore
*/
- (BOOL)needsPanelToBecomeKey
{
return YES;
}
/*!
@ignore
*/
@@ -4637,19 +4755,19 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
while (![_delegate tableView:self shouldSelectRow:i] && (i < [self numberOfRows] || i > 0))
shouldGoUpward ? i-- : i++; //check to see if the row can be selected if it can't be then see if the next row can be selected
//if the index still can be selected after the loop then just return
if (![_delegate tableView:self shouldSelectRow:i])
return;
// If the index still can be selected after the loop then just return.
if (![_delegate tableView:self shouldSelectRow:i])
return;
}
// if we go upward and see that this row is already selected we should deselect the row below
if ([selectedIndexes containsIndex:i] && extend)
// If we go upward and see that this row is already selected we should deselect the row below.
if (extend && [selectedIndexes containsIndex:i])
{
// the row we're on is the last to be selected
// The row we're on is the last to be selected.
var differedLastSelectedRow = i;
// no remove the one before/after it
shouldGoUpward ? i++ : i--;
shouldGoUpward ? i++ : i--;
[selectedIndexes removeIndex:i];
@@ -4661,7 +4779,7 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
if ([selectedIndexes containsIndex:i])
{
i = shouldGoUpward ? [selectedIndexes firstIndex] -1 : [selectedIndexes lastIndex] + 1;
i = MIN(MAX(i,0), [self numberOfRows] - 1);
i = MIN(MAX(i, 0), [self numberOfRows] - 1);
}
[selectedIndexes addIndex:i];
@@ -4686,6 +4804,14 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
@implementation CPTableView (Bindings)
+ (id)_binderClassForBinding:(CPString)aBinding
{
if (aBinding == @"content")
return [CPTableContentBinder class];
return [super _binderClassForBinding:aBinding];
}
/*!
@ignore
*/
@@ -4703,17 +4829,45 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
- (void)_establishBindingsIfUnbound:(id)destination
{
if ([[self infoForBinding:@"content"] objectForKey:CPObservedObjectKey] !== destination)
[self bind:@"content" toObject:destination withKeyPath:@"arrangedObjects" options:nil];
{
[super bind:@"content" toObject:destination withKeyPath:@"arrangedObjects" options:nil];
_contentBindingExpicitelySet = NO;
}
if ([[self infoForBinding:@"selectionIndexes"] objectForKey:CPObservedObjectKey] !== destination)
[self bind:@"selectionIndexes" toObject:destination withKeyPath:@"selectionIndexes" options:nil];
// If the content binding was set manually assume the user is taking manual control of establishing bindings.
if (!_contentBindingExpicitelySet)
{
if ([[self infoForBinding:@"selectionIndexes"] objectForKey:CPObservedObjectKey] !== destination)
[self bind:@"selectionIndexes" toObject:destination withKeyPath:@"selectionIndexes" options:nil];
//[self bind:@"sortDescriptors" toObject:destination withKeyPath:@"sortDescriptors" options:nil];
if ([[self infoForBinding:@"sortDescriptors"] objectForKey:CPObservedObjectKey] !== destination)
[self bind:@"sortDescriptors" toObject:destination withKeyPath:@"sortDescriptors" options:nil];
}
}
- (void)setContent:(CPArray)content
- (void)bind:(CPString)aBinding toObject:(id)anObject withKeyPath:(CPString)aKeyPath options:(CPDictionary)options
{
[self reloadData];
[super bind:aBinding toObject:anObject withKeyPath:aKeyPath options:options];
if (aBinding == @"content")
_contentBindingExpicitelySet = YES;
}
@end
@implementation CPTableContentBinder : CPBinder
{
id _content @accessors(property=content);
}
- (void)setValueFor:(id)aBinding
{
var destination = [_info objectForKey:CPObservedObjectKey],
keyPath = [_info objectForKey:CPObservedKeyPathKey];
_content = [destination valueForKey:keyPath];
[_source reloadData];
}
@end
@@ -4761,15 +4915,14 @@ var CPTableViewDataSourceKey = @"CPTableViewDataSourceKey",
_tableColumns = [aCoder decodeObjectForKey:CPTableViewTableColumnsKey] || [];
[_tableColumns makeObjectsPerformSelector:@selector(setTableView:) withObject:self];
if ([aCoder containsValueForKey:CPTableViewRowHeightKey])
_rowHeight = [aCoder decodeFloatForKey:CPTableViewRowHeightKey];
else
_rowHeight = 23.0;
_rowHeight = [aCoder decodeFloatForKey:CPTableViewRowHeightKey] || [self valueForThemeAttribute:@"default-row-height"];
_intercellSpacing = [aCoder decodeSizeForKey:CPTableViewIntercellSpacingKey];
_intercellSpacing = [aCoder decodeSizeForKey:CPTableViewIntercellSpacingKey] || _CGSizeMake(3.0, 2.0);
if (_CGSizeEqualToSize(_intercellSpacing, _CGSizeMakeZero()))
_intercellSpacing = _CGSizeMake(3.0, 2.0);
[self setGridColor:[aCoder decodeObjectForKey:CPTableViewGridColorKey]];
_gridStyleMask = [aCoder decodeIntForKey:CPTableViewGridStyleMaskKey] || CPTableViewGridNone;
_gridStyleMask = [aCoder decodeIntForKey:CPTableViewGridStyleMaskKey];
_usesAlternatingRowBackgroundColors = [aCoder decodeObjectForKey:CPTableViewUsesAlternatingBackgroundKey];
[self setAlternatingRowBackgroundColors:[aCoder decodeObjectForKey:CPTableViewAlternatingRowColorsKey]];
@@ -4836,9 +4989,8 @@ var CPTableViewDataSourceKey = @"CPTableViewDataSourceKey",
while (index != CPNotFound)
{
var indexSet = (switchFlag) ? otherSet : self;
otherIndex = [indexSet indexGreaterThanOrEqualToIndex:index];
var indexSet = (switchFlag) ? otherSet : self,
otherIndex = [indexSet indexGreaterThanOrEqualToIndex:index];
if (otherIndex == index)
{
@@ -4938,15 +5090,17 @@ var CPTableViewDataSourceKey = @"CPTableViewDataSourceKey",
isBlinking = YES;
var showCallback = function() {
var showCallback = function()
{
objj_msgSend(self, "setHidden:", NO)
isBlinking = NO;
}
};
var hideCallback = function() {
var hideCallback = function()
{
objj_msgSend(self, "setHidden:", YES)
isBlinking = YES;
}
};
objj_msgSend(self, "setHidden:", YES);
[CPTimer scheduledTimerWithTimeInterval:0.1 callback:showCallback repeats:NO];
+261 -144
View File
@@ -1,4 +1,3 @@
/*
* CPTextField.j
* AppKit
@@ -26,17 +25,21 @@
@import "CPControl.j"
@import "CPStringDrawing.j"
@import "CPCompatibility.j"
@import "CPText.j"
@import "CPWindow_Constants.j"
@import "_CPImageAndTextView.j"
@class CPPasteboard
CPTextFieldSquareBezel = 0; /*! A textfield bezel with a squared corners. */
@global CPApp
@global CPStringPboardType
CPTextFieldSquareBezel = 0; /*! A textfield bezel with squared corners. */
CPTextFieldRoundedBezel = 1; /*! A textfield bezel with rounded corners. */
CPTextFieldDidFocusNotification = @"CPTextFieldDidFocusNotification";
CPTextFieldDidBlurNotification = @"CPTextFieldDidBlurNotification";
#if PLATFORM(DOM)
var CPTextFieldDOMInputElement = nil,
CPTextFieldDOMPasswordInputElement = nil,
CPTextFieldDOMStandardInputElement = nil,
@@ -47,12 +50,42 @@ var CPTextFieldDOMInputElement = nil,
CPTextFieldInputIsActive = NO,
CPTextFieldCachedSelectStartFunction = nil,
CPTextFieldCachedDragFunction = nil,
CPTextFieldBlurFunction = nil;
#endif
CPTextFieldBlurHandler = nil,
CPTextFieldInputFunction = nil;
var CPSecureTextFieldCharacter = "\u2022";
function CPTextFieldBlurFunction(anEvent, owner, domElement, inputElement, resigning, didBlurRef)
{
if (owner && domElement != inputElement.parentNode)
return;
if (!resigning && [[owner window] isKeyWindow])
{
/*
Browsers blur text fields when a click occurs anywhere outside the text field. That is normal for browsers, but in Cocoa the key view retains focus unless the click target accepts first responder. So if we lost focus but were not told to resign and our window is still key, restore focus.
*/
window.setTimeout(function()
{
inputElement.focus();
}, 0.0);
}
CPTextFieldHandleBlur(anEvent, AT_REF(owner));
AT_DEREF(didBlurRef, YES);
return true;
}
function CPTextFieldHandleBlur(anEvent, ownerRef)
{
AT_DEREF(ownerRef, nil);
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
}
@implementation CPString (CPTextFieldAdditions)
/*!
@@ -169,7 +202,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
+ (id)themeAttributes
{
return [CPDictionary dictionaryWithObjects:[_CGInsetMakeZero(), _CGInsetMake(2.0, 2.0, 2.0, 2.0), [CPNull null]]
return [CPDictionary dictionaryWithObjects:[_CGInsetMakeZero(), _CGInsetMake(1.0, 0.0, 0.0, 0.0), [CPNull null]]
forKeys:[@"bezel-inset", @"content-inset", @"bezel-color"]];
}
@@ -188,32 +221,45 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
CPTextFieldDOMInputElement.style.background = "transparent";
CPTextFieldDOMInputElement.style.outline = "none";
CPTextFieldBlurFunction = function(anEvent)
CPTextFieldBlurHandler = function(anEvent)
{
if (CPTextFieldInputOwner && CPTextFieldInputOwner._DOMElement != CPTextFieldDOMInputElement.parentNode)
return;
return CPTextFieldBlurFunction(
anEvent,
CPTextFieldInputOwner,
CPTextFieldInputOwner._DOMElement,
CPTextFieldDOMInputElement,
CPTextFieldInputResigning,
AT_REF(CPTextFieldInputDidBlur));
};
if (!CPTextFieldInputResigning)
if (CPFeatureIsCompatible(CPInputOnInputEventFeature))
{
CPTextFieldInputFunction = function(anEvent)
{
[[CPTextFieldInputOwner window] makeFirstResponder:nil];
return;
if (!CPTextFieldInputOwner)
return;
var cappEvent = [CPEvent keyEventWithType:CPKeyUp
location:_CGPointMakeZero()
modifierFlags:0
timestamp:[CPEvent currentTimestamp]
windowNumber:[[CPApp keyWindow] windowNumber]
context:nil
characters:nil
charactersIgnoringModifiers:nil
isARepeat:NO
keyCode:nil];
[CPTextFieldInputOwner keyUp:cappEvent];
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
}
CPTextFieldHandleBlur(anEvent, CPTextFieldDOMInputElement);
CPTextFieldInputDidBlur = YES;
return true;
CPTextFieldDOMInputElement.oninput = CPTextFieldInputFunction;
}
CPTextFieldHandleBlur = function(anEvent)
{
CPTextFieldInputOwner = nil;
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
}
//FIXME make this not onblur
CPTextFieldDOMInputElement.onblur = CPTextFieldBlurFunction;
// FIXME make this not onblur
CPTextFieldDOMInputElement.onblur = CPTextFieldBlurHandler;
CPTextFieldDOMStandardInputElement = CPTextFieldDOMInputElement;
}
@@ -242,7 +288,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
CPTextFieldDOMPasswordInputElement.style.outline = "none";
CPTextFieldDOMPasswordInputElement.type = "password";
CPTextFieldDOMPasswordInputElement.onblur = CPTextFieldBlurFunction;
CPTextFieldDOMPasswordInputElement.onblur = CPTextFieldBlurHandler;
}
CPTextFieldDOMInputElement = CPTextFieldDOMPasswordInputElement;
@@ -289,6 +335,11 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
if (shouldBeEditable)
_isSelectable = YES;
if (_isEditable)
[self setThemeState:CPThemeStateEditable];
else
[self unsetThemeState:CPThemeStateEditable];
// We only allow first responder status if the field is editable and enabled.
if (!shouldBeEditable && [[self window] firstResponder] === self)
[[self window] makeFirstResponder:nil];
@@ -470,31 +521,44 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
/* @ignore */
- (BOOL)becomeFirstResponder
{
#if PLATFORM(DOM)
if (CPTextFieldInputOwner && [CPTextFieldInputOwner window] !== [self window])
[[CPTextFieldInputOwner window] makeFirstResponder:nil];
#endif
// As long as we are the first responder we need to monitor the key status of our window.
[self _setObserveWindowKeyNotifications:YES];
_isEditing = NO;
if ([[self window] isKeyWindow])
[self _becomeFirstKeyResponder];
return YES;
}
/*!
A text field can be the first responder without necessarily being the focus of keyboard input. For example, it might be the first responder of window A but window B is the main and key window. It's important we don't put a focused input field into a text field in a non-key window, even if that field is the first responder, because the key window might also have a first responder text field which the user will expect to receive keyboard input.
Since a first responder but non-key window text field can't receive input it should not even look like an active text field (Cocoa has a "slightly active" text field look it uses when another window is the key window, but Cappuccino doesn't today.)
*/
- (void)_becomeFirstKeyResponder
{
[self setThemeState:CPThemeStateEditing];
[self _updatePlaceholderState];
[self setNeedsLayout];
_isEditing = NO;
_stringValue = [self stringValue];
#if PLATFORM(DOM)
var element = [self _inputElement],
font = [self currentValueForThemeAttribute:@"font"];
// generate the font metric
[font _getMetrics];
font = [self currentValueForThemeAttribute:@"font"],
lineHeight = [font defaultLineHeightForFont];
element.value = _stringValue;
element.style.color = [[self currentValueForThemeAttribute:@"text-color"] cssString];
element.style.font = [font cssString];
if (CPFeatureIsCompatible(CPInputSetFontOutsideOfDOM))
element.style.font = [font cssString];
element.style.zIndex = 1000;
switch ([self alignment])
@@ -512,42 +576,41 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
switch (verticalAlign)
{
case CPTopVerticalTextAlignment:
var topPoint = (_CGRectGetMinY(contentRect) + 1) + "px"; // for the same reason we have a -1 for the left, we also have a + 1 here
var topPoint = _CGRectGetMinY(contentRect) + "px";
break;
case CPCenterVerticalTextAlignment:
var topPoint = (_CGRectGetMidY(contentRect) - (font._lineHeight / 2) + 1) + "px";
var topPoint = (_CGRectGetMidY(contentRect) - (lineHeight / 2)) + "px";
break;
case CPBottomVerticalTextAlignment:
var topPoint = (_CGRectGetMaxY(contentRect) - font._lineHeight) + "px";
var topPoint = (_CGRectGetMaxY(contentRect) - lineHeight) + "px";
break;
default:
var topPoint = (_CGRectGetMinY(contentRect) + 1) + "px";
var topPoint = _CGRectGetMinY(contentRect) + "px";
break;
}
element.style.top = topPoint;
element.style.left = (_CGRectGetMinX(contentRect) - 1) + "px"; // why -1?
var left = _CGRectGetMinX(contentRect);
// If the browser has a built in left padding, compensate for it. We need the input text to be exactly on top of the original text.
if (CPFeatureIsCompatible(CPInput1PxLeftPadding))
left -= 1;
element.style.left = left + "px";
element.style.width = _CGRectGetWidth(contentRect) + "px";
element.style.height = font._lineHeight + "px"; // private ivar for the line height of the DOM text at this particular size
element.style.height = ROUND(lineHeight) + "px";
element.style.lineHeight = ROUND(lineHeight) + "px";
element.style.verticalAlign = "top";
element.style.cursor = "auto";
_DOMElement.appendChild(element);
window.setTimeout(function()
{
element.focus();
// Select the text if the textfield became first responder through keyboard interaction
if (!_willBecomeFirstResponderByClick)
[self selectText:self];
_willBecomeFirstResponderByClick = NO;
[self textDidFocus:[CPNotification notificationWithName:CPTextFieldDidFocusNotification object:self userInfo:nil]];
CPTextFieldInputOwner = self;
}, 0.0);
// The font change above doesn't work for some browsers if the element isn't already appendChild'ed.
if (!CPFeatureIsCompatible(CPInputSetFontOutsideOfDOM))
element.style.font = [font cssString];
[[[self window] platformWindow] _propagateCurrentDOMEvent:YES];
@@ -561,50 +624,94 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
[[self window] platformWindow]._DOMBodyElement.ondrag = function () {};
[[self window] platformWindow]._DOMBodyElement.onselectstart = function () {};
}
#endif
return YES;
CPTextFieldInputOwner = self;
window.setTimeout(function()
{
/*
setTimeout handlers are not guaranteed to fire in the order they were initiated. This can cause a race condition when several windows with text fields are opened quickly, resulting in several instances of this timeout function being fired, perhaps out of order. So we have to check that by the time this function is fired, CPTextFieldInputOwner has not been changed to another text field in the meantime.
*/
if (CPTextFieldInputOwner !== self)
return;
element.focus();
// Select the text if the textfield became first responder through keyboard interaction
if (!_willBecomeFirstResponderByClick)
[self _selectText:self immediately:YES];
_willBecomeFirstResponderByClick = NO;
[self textDidFocus:[CPNotification notificationWithName:CPTextFieldDidFocusNotification object:self userInfo:nil]];
}, 0.0);
#endif
}
/* @ignore */
- (BOOL)resignFirstResponder
{
[self unsetThemeState:CPThemeStateEditing];
#if PLATFORM(DOM)
var element = [self _inputElement],
newValue = element.value,
error = @"";
if (newValue !== _stringValue)
{
[self _setStringValue:newValue];
}
// If there is a formatter, always give it a chance to reject the resignation,
// even if the value has not changed.
if ([self _valueIsValid:element.value] === NO)
if ([self _valueIsValid:newValue] === NO)
{
[self setThemeState:CPThemeStateEditing];
element.focus();
return NO;
}
#endif
// When we are no longer the first responder we don't worry about the key status of our window anymore.
[self _setObserveWindowKeyNotifications:NO];
[self _resignFirstKeyResponder];
_isEditing = NO;
[self textDidEndEditing:[CPNotification notificationWithName:CPControlTextDidEndEditingNotification object:self userInfo:nil]];
if ([self sendsActionOnEndEditing])
[self sendAction:[self action] to:[self target]];
[self textDidBlur:[CPNotification notificationWithName:CPTextFieldDidBlurNotification object:self userInfo:nil]];
return YES;
}
- (void)_resignFirstKeyResponder
{
[self unsetThemeState:CPThemeStateEditing];
// Cache the formatted string
_stringValue = [self stringValue];
_willBecomeFirstResponderByClick = NO;
[self _updatePlaceholderState];
[self setNeedsLayout];
#if PLATFORM(DOM)
var element = [self _inputElement];
CPTextFieldInputResigning = YES;
if (CPTextFieldInputIsActive)
element.blur();
if (!CPTextFieldInputDidBlur)
CPTextFieldBlurFunction();
CPTextFieldBlurHandler();
CPTextFieldInputDidBlur = NO;
CPTextFieldInputResigning = NO;
@@ -624,20 +731,32 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
}
#endif
}
// post CPControlTextDidEndEditingNotification
if (_isEditing)
- (void)_setObserveWindowKeyNotifications:(BOOL)shouldObserve
{
if (shouldObserve)
{
_isEditing = NO;
[self textDidEndEditing:[CPNotification notificationWithName:CPControlTextDidEndEditingNotification object:self userInfo:nil]];
if ([self sendsActionOnEndEditing])
[self sendAction:[self action] to:[self target]];
[[CPNotificationCenter defaultCenter] addObserver:self selector:@selector(_windowDidResignKey:) name:CPWindowDidResignKeyNotification object:[self window]];
[[CPNotificationCenter defaultCenter] addObserver:self selector:@selector(_windowDidBecomeKey:) name:CPWindowDidBecomeKeyNotification object:[self window]];
}
else
{
[[CPNotificationCenter defaultCenter] removeObserver:self name:CPWindowDidResignKeyNotification object:[self window]];
[[CPNotificationCenter defaultCenter] removeObserver:self name:CPWindowDidBecomeKeyNotification object:[self window]];
}
}
[self textDidBlur:[CPNotification notificationWithName:CPTextFieldDidBlurNotification object:self userInfo:nil]];
- (void)_windowDidResignKey:(CPNotification)aNotification
{
if (![[self window] isKeyWindow])
[self _resignFirstKeyResponder];
}
return YES;
- (void)_windowDidBecomeKey:(CPNotification)aNotification
{
if ([[self window] isKeyWindow] && [[self window] firstResponder] === self)
[self _becomeFirstKeyResponder];
}
- (BOOL)_valueIsValid:(CPString)aValue
@@ -651,7 +770,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
var acceptInvalidValue = NO;
if ([_delegate respondsToSelector:@selector(control:didFailToFormatString:errorDescription:)])
acceptInvalidValue = [_delegate control:self didFailToFormatString:[self _inputElement] errorDescription:error];
acceptInvalidValue = [_delegate control:self didFailToFormatString:aValue errorDescription:error];
if (acceptInvalidValue === NO)
return NO;
@@ -663,11 +782,20 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
}
/*!
Text fields require panels to become key window, so this returns \c YES.
Text fields require panels to become key window, so this returns \c YES
if the text field is ready to become the first responder as well.
*/
- (BOOL)needsPanelToBecomeKey
{
return YES;
return [self acceptsFirstResponder];
}
/*!
Only text fields that can become first responder accepts first mouse.
*/
- (BOOL)acceptsFirstMouse:(CPEvent)anEvent
{
return [self acceptsFirstResponder];
}
- (void)mouseDown:(CPEvent)anEvent
@@ -774,6 +902,13 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
- (void)insertNewline:(id)sender
{
var newValue = [self _inputElement].value;
if (newValue !== _stringValue)
{
[self _setStringValue:newValue];
}
if ([self _valueIsValid:_stringValue])
{
// If _isEditing == YES then the target action can also be called via
@@ -1010,7 +1145,6 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
However, since you don't know how tall it needs to be if you change the font, sizeToFit will still be
useful for making the textfield an appropriate height.
*/
- (void)sizeToFit
{
[self setFrameSize:[self _minimumFrameSize]];
@@ -1037,8 +1171,16 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
textSize = [text sizeWithFont:font inWidth:textSize.width];
}
else
{
textSize = [text sizeWithFont:font];
// Account for possible fractional pixels at right edge
textSize.width += 1;
}
// Account for possible fractional pixels at bottom edge
textSize.height += 1;
frameSize.height = textSize.height + contentInset.top + contentInset.bottom;
if ([self isBezeled])
@@ -1064,24 +1206,36 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
*/
- (void)selectText:(id)sender
{
// FIXME Should this really make the text field the first responder?
[self _selectText:sender immediately:NO];
}
- (void)_selectText:(id)sender immediately:(BOOL)immediately
{
// Selecting the text in a field makes it the first responder
if (([self isEditable] || [self isSelectable]))
{
var wind = [self window];
#if PLATFORM(DOM)
var element = [self _inputElement];
if ([[self window] firstResponder] === self)
window.setTimeout(function() { element.select(); }, 0);
else if ([self window] !== nil && [[self window] makeFirstResponder:self])
window.setTimeout(function() {[self selectText:sender];}, 0);
if ([wind firstResponder] === self)
{
if (immediately)
element.select();
else
window.setTimeout(function() { element.select(); }, 0);
}
else if (wind !== nil && [wind makeFirstResponder:self])
[self _selectText:sender immediately:immediately];
#else
// Even if we can't actually select the text we need to preserve the first
// responder side effect.
if ([self window] !== nil && [[self window] firstResponder] !== self)
[[self window] makeFirstResponder:self];
if (wind !== nil && [wind firstResponder] !== self)
[wind makeFirstResponder:self];
#endif
}
}
- (void)copy:(id)sender
@@ -1108,7 +1262,8 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
[self copy:sender];
[self deleteBackward:sender];
}
else
// If we don't have an oninput listener, we won't detect the change made by the cut and need to fake a key up "soon".
else if (!CPFeatureIsCompatible(CPInputOnInputEventFeature))
[CPTimer scheduledTimerWithTimeInterval:0.0 target:self selector:@selector(keyUp:) userInfo:nil repeats:NO];
}
@@ -1130,7 +1285,8 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
[self setStringValue:newValue];
[self setSelectedRange:CPMakeRange(selectedRange.location + pasteString.length, 0)];
}
else
// If we don't have an oninput listener, we won't detect the change made by the cut and need to fake a key up "soon".
else if (!CPFeatureIsCompatible(CPInputOnInputEventFeature))
[CPTimer scheduledTimerWithTimeInterval:0.0 target:self selector:@selector(keyUp:) userInfo:nil repeats:NO];
}
@@ -1296,30 +1452,14 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
{
var contentInset = [self currentValueForThemeAttribute:@"content-inset"];
if (!contentInset)
return bounds;
bounds.origin.x += contentInset.left;
bounds.origin.y += contentInset.top;
bounds.size.width -= contentInset.left + contentInset.right;
bounds.size.height -= contentInset.top + contentInset.bottom;
return bounds;
return _CGRectInsetByInset(bounds, contentInset);
}
- (CGRect)bezelRectForBounds:(CGRect)bounds
{
var bezelInset = [self currentValueForThemeAttribute:@"bezel-inset"];
if (_CGInsetIsEmpty(bezelInset))
return bounds;
bounds.origin.x += bezelInset.left;
bounds.origin.y += bezelInset.top;
bounds.size.width -= bezelInset.left + bezelInset.right;
bounds.size.height -= bezelInset.top + bezelInset.bottom;
return bounds;
return _CGRectInsetByInset(bounds, bezelInset);
}
- (CGRect)rectForEphemeralSubviewNamed:(CPString)aName
@@ -1346,7 +1486,6 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
else
{
var view = [[_CPImageAndTextView alloc] initWithFrame:_CGRectMakeZero()];
//[view setImagePosition:CPNoImage];
[view setHitTests:NO];
@@ -1422,7 +1561,7 @@ var secureStringForString = function(aString)
return "";
return Array(aString.length + 1).join(CPSecureTextFieldCharacter);
}
};
var CPTextFieldIsEditableKey = "CPTextFieldIsEditableKey",
@@ -1492,47 +1631,25 @@ var CPTextFieldIsEditableKey = "CPTextFieldIsEditableKey",
{
}
- (void)setValueFor:(CPString)theBinding
- (void)_updatePlaceholdersWithOptions:(CPDictionary)options
{
var destination = [_info objectForKey:CPObservedObjectKey],
keyPath = [_info objectForKey:CPObservedKeyPathKey],
options = [_info objectForKey:CPOptionsKey],
newValue = [destination valueForKeyPath:keyPath],
isPlaceholder = CPIsControllerMarker(newValue);
[super _updatePlaceholdersWithOptions:options];
if (isPlaceholder)
{
switch (newValue)
{
case CPMultipleValuesMarker:
newValue = [options objectForKey:CPMultipleValuesPlaceholderBindingOption] || @"Multiple Values";
break;
[self _setPlaceholder:@"Multiple Values" forMarker:CPMultipleValuesMarker isDefault:YES];
[self _setPlaceholder:@"No Selection" forMarker:CPNoSelectionMarker isDefault:YES];
[self _setPlaceholder:@"Not Applicable" forMarker:CPNotApplicableMarker isDefault:YES];
[self _setPlaceholder:@"" forMarker:CPNullMarker isDefault:YES];
}
case CPNoSelectionMarker:
newValue = [options objectForKey:CPNoSelectionPlaceholderBindingOption] || @"No Selection";
break;
- (void)setPlaceholderValue:(id)aValue withMarker:(CPString)aMarker forBinding:(CPString)aBinding
{
[_source setPlaceholderString:aValue];
[_source setObjectValue:nil];
}
case CPNotApplicableMarker:
if ([options objectForKey:CPRaisesForNotApplicableKeysBindingOption])
[CPException raise:CPGenericException
reason:@"can't transform non applicable key on: "+_source+" value: "+newValue];
newValue = [options objectForKey:CPNotApplicablePlaceholderBindingOption] || @"Not Applicable";
break;
case CPNullMarker:
newValue = [options objectForKey:CPNullPlaceholderBindingOption] || @"";
break;
}
[_source setPlaceholderString:newValue];
[_source setObjectValue:nil];
}
else
{
newValue = [self transformValue:newValue withOptions:options];
[_source setObjectValue:newValue];
}
- (void)setValue:(id)aValue forBinding:(CPString)aBinding
{
[_source setObjectValue:aValue];
}
@end
+10 -3
View File
@@ -21,9 +21,11 @@
*/
@import <Foundation/CPObject.j>
@import <Foundation/CPMutableArray.j>
@import <Foundation/CPString.j>
@import <Foundation/CPKeyedUnarchiver.j>
@class CPView
var CPThemesByName = { },
CPThemeDefaultTheme = nil,
@@ -145,7 +147,7 @@ var CPThemesByName = { },
className = [aClass defaultThemeClass];
else if ([aClass respondsToSelector:@selector(themeClass)])
{
CPLog.warn(@"%@ themeClass is deprecated in favor of defaultThemeClass",CPStringFromClass([anObject class]));
CPLog.warn(@"%@ themeClass is deprecated in favor of defaultThemeClass", CPStringFromClass(aClass));
className = [aClass themeClass];
}
else
@@ -255,7 +257,7 @@ var CPThemesByName = { },
attributeNames = [attributes keyEnumerator],
objectThemeClass = [anObject themeClass];
while (attributeName = [attributeNames nextObject])
while ((attributeName = [attributeNames nextObject]) !== nil)
[self _recordAttribute:[attributes objectForKey:attributeName] forClass:objectThemeClass];
}
@@ -418,6 +420,9 @@ CPThemeStateEditing = CPThemeState("editing");
CPThemeStateVertical = CPThemeState("vertical");
CPThemeStateDefault = CPThemeState("default");
CPThemeStateCircular = CPThemeState("circular");
CPThemeStateAutocompleting = CPThemeState("autocompleting");
CPThemeStateMainWindow = CPThemeState("mainWindow");
CPThemeStateKeyWindow = CPThemeState("keyWindow");
@implementation _CPThemeAttribute : CPObject
{
@@ -579,6 +584,7 @@ CPThemeStateCircular = CPThemeState("circular");
_cache = {};
_name = [aCoder decodeObjectForKey:@"name"];
_defaultValue = [aCoder decodeObjectForKey:@"defaultValue"];
_values = [CPDictionary dictionary];
if ([aCoder containsValueForKey:@"value"])
@@ -611,6 +617,7 @@ CPThemeStateCircular = CPThemeState("circular");
- (void)encodeWithCoder:(CPCoder)aCoder
{
[aCoder encodeObject:_name forKey:@"name"];
[aCoder encodeObject:_defaultValue forKey:@"defaultValue"];
var keys = [_values allKeys],
count = keys.length;
@@ -666,7 +673,7 @@ var numberOfOnes = function(aNumber)
cachedNumberOfOnes[slot] = count;
return count;
}
};
numberOfOnes.displayName = "numberOfOnes";
+1 -1
View File
@@ -33,7 +33,7 @@
@implementation CPThemeBlend : CPObject
{
CPBundle _bundle;
CPBundle _bundle @accessors(getter=bundle);
CPArray _themes;
id _loadDelegate;
}
+641 -515
View File
File diff suppressed because it is too large Load Diff
+171 -61
View File
@@ -28,6 +28,7 @@
@import "CPPopUpButton.j"
@import "CPToolbarItem.j"
@global CPApp
/*
@global
@@ -50,6 +51,11 @@ CPToolbarDisplayModeIconOnly = 2;
*/
CPToolbarDisplayModeLabelOnly = 3;
CPToolbarSizeModeDefault = 0;
CPToolbarSizeModeRegular = 1;
CPToolbarSizeModeSmall = 2;
var CPToolbarsByIdentifier = nil,
CPToolbarConfigurationsByIdentifier = nil;
@@ -83,10 +89,12 @@ var CPToolbarsByIdentifier = nil,
@implementation CPToolbar : CPObject
{
CPString _identifier;
CPToolbarDisplayMode _displayMode;
CPToolbarDisplayMode _displayMode @accessors(property=displayMode);
BOOL _showsBaselineSeparator;
BOOL _allowsUserCustomization;
BOOL _isVisible;
int _sizeMode @accessors(property=sizeMode);
int _desiredHeight;
id _delegate;
@@ -107,7 +115,7 @@ var CPToolbarsByIdentifier = nil,
/* @ignore */
+ (void)initialize
{
if (self != [CPToolbar class])
if (self !== [CPToolbar class])
return;
CPToolbarsByIdentifier = [CPDictionary dictionary];
@@ -148,6 +156,8 @@ var CPToolbarsByIdentifier = nil,
_identifier = anIdentifier;
_isVisible = YES;
_sizeMode = CPToolbarSizeModeDefault;
_desiredHeight = 0;
[CPToolbar _addToolbar:self forIdentifier:_identifier];
}
@@ -202,6 +212,16 @@ var CPToolbarsByIdentifier = nil,
[_window _noteToolbarChanged];
}
- (void)setSizeMode:(CPToolbarSizeMode)aSize
{
if (aSize === _sizeMode)
return;
_sizeMode = aSize;
[[self _toolbarView] setFrame:[self _toolbarViewFrame]];
[_window _noteToolbarChanged];
}
- (CPWindow)_window
{
return _window;
@@ -209,7 +229,13 @@ var CPToolbarsByIdentifier = nil,
- (void)_setWindow:(CPWindow)aWindow
{
if (_window)
[[CPNotificationCenter defaultCenter] removeObserver:self object:_window];
_window = aWindow;
if (_window)
[[CPNotificationCenter defaultCenter] addObserver:self selector:@selector(_autoValidateVisibleItems) name:_CPWindowDidChangeFirstResponderNotification object:aWindow];
}
/*!
@@ -226,18 +252,33 @@ var CPToolbarsByIdentifier = nil,
[self _reloadToolbarItems];
}
- (void)setDisplayMode:(CPToolbarDisplayMode)aDisplayMode
{
if (_displayMode === aDisplayMode)
return;
_displayMode = aDisplayMode;
[self _reloadToolbarItems];
}
/* @ignore */
- (void)_loadConfiguration
{
}
- (CGRect)_toolbarViewFrame
{
var height = _desiredHeight || (_sizeMode != CPToolbarSizeModeSmall ? [_toolbarView valueForThemeAttribute:@"regular-size-height"] : [_toolbarView valueForThemeAttribute:@"small-size-height"]);
return CGRectMake(0.0, 0.0, 1200.0, height);
}
/* @ignore */
- (CPView)_toolbarView
{
if (!_toolbarView)
{
_toolbarView = [[_CPToolbarView alloc] initWithFrame:CPRectMake(0.0, 0.0, 1200.0, 59.0)];
_toolbarView = [[_CPToolbarView alloc] initWithFrame:[self _toolbarViewFrame]];
[_toolbarView setToolbar:self];
[_toolbarView setAutoresizingMask:CPViewWidthSizable];
@@ -257,13 +298,17 @@ var CPToolbarsByIdentifier = nil,
// _defaultItems may have been loaded from Cib
_itemIdentifiers = [_defaultItems valueForKey:@"itemIdentifier"] || [];
if (_delegate)
if ([_delegate respondsToSelector:@selector(toolbarDefaultItemIdentifiers:)])
{
var itemIdentifiersFromDelegate = [[_delegate toolbarDefaultItemIdentifiers:self] mutableCopy];
var itemIdentifiersFromDelegate = [_delegate toolbarDefaultItemIdentifiers:self];
// If we get items both from the Cib and from the delegate method, put the delegate items before the
// Cib ones.
if (itemIdentifiersFromDelegate)
_itemIdentifiers = [_itemIdentifiers arrayByAddingObjectsFromArray:itemIdentifiersFromDelegate];
_itemIdentifiers = [itemIdentifiersFromDelegate arrayByAddingObjectsFromArray:_itemIdentifiers];
}
// If we didn't load from a cib and the delegate hasn't been set yet, we'll just work with an empty list
// at this point.
var index = 0,
count = [_itemIdentifiers count];
@@ -332,12 +377,26 @@ var CPToolbarsByIdentifier = nil,
each visible toolbar item.
*/
- (void)validateVisibleItems
{
[self _validateVisibleItems:NO]
}
- (void)_autoValidateVisibleItems
{
[self _validateVisibleItems:YES]
}
- (void)_validateVisibleItems:(BOOL)isAutovalidation
{
var toolbarItems = [self visibleItems],
count = [toolbarItems count];
while (count--)
[toolbarItems[count] validate];
{
var item = [toolbarItems objectAtIndex:count];
if (!isAutovalidation || [item autovalidates])
[item validate];
}
}
/* @ignore */
@@ -427,7 +486,8 @@ var CPToolbarIdentifierKey = @"CPToolbarIdentifierKey",
CPToolbarIdentifiedItemsKey = @"CPToolbarIdentifiedItemsKey",
CPToolbarDefaultItemsKey = @"CPToolbarDefaultItemsKey",
CPToolbarAllowedItemsKey = @"CPToolbarAllowedItemsKey",
CPToolbarSelectableItemsKey = @"CPToolbarSelectableItemsKey";
CPToolbarSelectableItemsKey = @"CPToolbarSelectableItemsKey",
CPToolbarSizeModeKey = @"CPToolbarSizeModeKey";
@implementation CPToolbar (CPCoding)
@@ -446,6 +506,7 @@ var CPToolbarIdentifierKey = @"CPToolbarIdentifierKey",
_showsBaselineSeparator = [aCoder decodeBoolForKey:CPToolbarShowsBaselineSeparatorKey];
_allowsUserCustomization = [aCoder decodeBoolForKey:CPToolbarAllowsUserCustomizationKey];
_isVisible = [aCoder decodeBoolForKey:CPToolbarIsVisibleKey];
_sizeMode = [aCoder decodeIntForKey:CPToolbarSizeModeKey];
_identifiedItems = [aCoder decodeObjectForKey:CPToolbarIdentifiedItemsKey];
_defaultItems = [aCoder decodeObjectForKey:CPToolbarDefaultItemsKey];
@@ -492,6 +553,7 @@ var CPToolbarIdentifierKey = @"CPToolbarIdentifierKey",
[aCoder encodeBool:_showsBaselineSeparator forKey:CPToolbarShowsBaselineSeparatorKey];
[aCoder encodeBool:_allowsUserCustomization forKey:CPToolbarAllowsUserCustomizationKey];
[aCoder encodeBool:_isVisible forKey:CPToolbarIsVisibleKey];
[aCoder encodeInt:_sizeMode forKey:CPToolbarSizeModeKey]
[aCoder encodeObject:_identifiedItems forKey:CPToolbarIdentifiedItemsKey];
[aCoder encodeObject:_defaultItems forKey:CPToolbarDefaultItemsKey];
@@ -508,14 +570,10 @@ var _CPToolbarViewBackgroundColor = nil,
_CPToolbarViewExtraItemsImage = nil,
_CPToolbarViewExtraItemsAlternateImage = nil;
var TOOLBAR_TOP_MARGIN = 5.0,
TOOLBAR_ITEM_MARGIN = 10.0,
TOOLBAR_EXTRA_ITEMS_WIDTH = 20.0;
var _CPToolbarItemInfoMake = function(anIndex, aView, aLabel, aMinWidth)
{
return { index:anIndex, view:aView, label:aLabel, minWidth:aMinWidth };
}
};
/* @ignore */
@implementation _CPToolbarView : CPView
@@ -540,16 +598,32 @@ var _CPToolbarItemInfoMake = function(anIndex, aView, aLabel, aMinWidth)
BOOL _FIXME_isHUD;
}
+ (void)initialize
+ (CPString)defaultThemeClass
{
if (self !== [_CPToolbarView class])
return;
return @"toolbar-view";
}
var bundle = [CPBundle bundleForClass:self];
_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)];
+ (id)themeAttributes
{
return [CPDictionary dictionaryWithObjects:[10.0,
20.0,
[CPNull null],
[CPNull null],
_CGInsetMake(4.0, 4.0, 4.0, 10),
59.0,
46.0,
[CPNull null],
CGRectMake(0.0, 0.0, 2.0, 32.0)]
forKeys:[
@"item-margin",
@"extra-item-width",
@"extra-item-extra-image",
@"extra-item-extra-alternate-image",
@"content-inset",
@"regular-size-height",
@"small-size-height",
@"image-item-separator-color",
@"image-item-separator-size"]];
}
- (id)initWithFrame:(CGRect)aFrame
@@ -563,14 +637,12 @@ var _CPToolbarItemInfoMake = function(anIndex, aView, aLabel, aMinWidth)
_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 = [[CPPopUpButton alloc] initWithFrame:_CGRectMake(0.0, 0.0, 10.0, 15.0) pullsDown:YES];
[_additionalItemsButton setBordered:NO];
[_additionalItemsButton setImagePosition:CPImageOnly];
[[_additionalItemsButton menu] setShowsStateColumn:NO];
[[_additionalItemsButton menu] setAutoenablesItems:NO];
[_additionalItemsButton setAlternateImage:_CPToolbarViewExtraItemsAlternateImage];
}
return self;
@@ -615,7 +687,7 @@ var _CPToolbarItemInfoMake = function(anIndex, aView, aLabel, aMinWidth)
{
// We begin by recalculating the visible items.
var items = [_toolbar items],
itemsWidth = CGRectGetWidth([self bounds]),
itemsWidth = _CGRectGetWidth([self bounds]),
minWidth = _minWidth,
// FIXME: This should be a CPSet.
invisibleItemsSortedByPriority = [];
@@ -626,7 +698,7 @@ var _CPToolbarItemInfoMake = function(anIndex, aView, aLabel, aMinWidth)
// minimum width for hiding items.
if (itemsWidth < minWidth)
{
itemsWidth -= TOOLBAR_EXTRA_ITEMS_WIDTH;
itemsWidth -= [self valueForThemeAttribute:@"extra-item-width"];
_visibleItems = [_visibleItems copy];
@@ -642,7 +714,7 @@ var _CPToolbarItemInfoMake = function(anIndex, aView, aLabel, aMinWidth)
var item = itemsSortedByVisibilityPriority[--count],
view = [self viewForItem:item];
minWidth -= [view minSize].width + TOOLBAR_ITEM_MARGIN;
minWidth -= [view minSize].width + [self valueForThemeAttribute:@"item-margin"];
[_visibleItems removeObjectIdenticalTo:item];
[invisibleItemsSortedByPriority addObject:item];
@@ -665,6 +737,24 @@ var _CPToolbarItemInfoMake = function(anIndex, aView, aLabel, aMinWidth)
height = minSize.height;
}
// We'll figure out the proper height for the toolbar depending on its items.
// If nothing has a minimum size we'll use the standard toolbar size for the
// sizeMode, indicated by a 0 _desiredHeight.
var contentInset = [self valueForThemeAttribute:@"content-inset"],
newDesiredHeight = height ? height + contentInset.top + contentInset.bottom : 0;
if (newDesiredHeight != _toolbar._desiredHeight)
{
// FIXME Probably the toolbar view shouldn't be telling the toolbar which height it should be. Maybe refactor
// to just have the toolbar scan the toolbar items whenever the items change.
_toolbar._desiredHeight = newDesiredHeight;
[self setFrame:[_toolbar _toolbarViewFrame]];
[_toolbar._window _noteToolbarChanged];
// The above will cause tile to be called again.
return;
}
// Determine all the items that have flexible width.
// Also determine the height of the toolbar.
var count = _visibleItems.length,
@@ -684,7 +774,7 @@ var _CPToolbarItemInfoMake = function(anIndex, aView, aLabel, aMinWidth)
// static width (min==max). This handles the case where the user did setView:
// with a view of a different size than minSize/maxSize
else
[view setFrameSize:CGSizeMake(minSize.width, height)];
[view setFrameSize:_CGSizeMake(minSize.width, height)];
[view setHidden:NO];
}
@@ -719,23 +809,25 @@ var _CPToolbarItemInfoMake = function(anIndex, aView, aLabel, aMinWidth)
remainingSpace += proposedWidth - constrainedWidth;
}
[view setFrameSize:CGSizeMake(constrainedWidth, height)];
[view setFrameSize:_CGSizeMake(constrainedWidth, height)];
}
}
// Now that all the visible items are the correct width, give them their final frames.
var index = 0,
count = _visibleItems.length,
x = TOOLBAR_ITEM_MARGIN;
x = contentInset.left,
contentInset = [self valueForThemeAttribute:@"content-inset"],
y = contentInset.top;
for (; index < count; ++index)
{
var view = [self viewForItem:_visibleItems[index]],
viewWidth = CGRectGetWidth([view frame]);
viewWidth = _CGRectGetWidth([view frame]);
[view setFrame:CGRectMake(x, 0.0, viewWidth, height)];
[view setFrame:_CGRectMake(x, y, viewWidth, height)];
x += viewWidth + TOOLBAR_ITEM_MARGIN;
x += viewWidth + [self valueForThemeAttribute:@"item-margin"];
}
var needsAdditionalItemsButton = NO;
@@ -767,14 +859,14 @@ var _CPToolbarItemInfoMake = function(anIndex, aView, aLabel, aMinWidth)
if (needsAdditionalItemsButton)
{
[_additionalItemsButton setFrameOrigin:CGPointMake(itemsWidth + 5.0, (CGRectGetHeight([self bounds]) - CGRectGetHeight([_additionalItemsButton frame])) / 2.0)];
[_additionalItemsButton setFrameOrigin:_CGPointMake(itemsWidth + 5.0, (_CGRectGetHeight([self bounds]) - _CGRectGetHeight([_additionalItemsButton frame])) / 2.0)];
[self addSubview:_additionalItemsButton];
[_additionalItemsButton removeAllItems];
[_additionalItemsButton addItemWithTitle:@"Additional Items"];
[[_additionalItemsButton itemArray][0] setImage:_CPToolbarViewExtraItemsImage];
[[_additionalItemsButton itemArray][0] setImage:[self valueForThemeAttribute:@"extra-item-extra-image"]];
var index = 0,
count = [_invisibleItems count],
@@ -840,7 +932,7 @@ var _CPToolbarItemInfoMake = function(anIndex, aView, aLabel, aMinWidth)
count = items.length;
_minWidth = TOOLBAR_ITEM_MARGIN;
_minWidth = [self valueForThemeAttribute:@"item-margin"];
_viewsForToolbarItems = { };
for (; index < count; ++index)
@@ -855,12 +947,17 @@ var _CPToolbarItemInfoMake = function(anIndex, aView, aLabel, aMinWidth)
[self addSubview:view];
_minWidth += [view minSize].width + TOOLBAR_ITEM_MARGIN;
_minWidth += [view minSize].width + [self valueForThemeAttribute:@"item-margin"];
}
[self tile];
}
- (void)layoutSubviews
{
[_additionalItemsButton setAlternateImage:[self valueForThemeAttribute:@"extra-item-extra-alternate-image"]];
}
@end
/* @ignore */
@@ -876,10 +973,9 @@ var _CPToolbarItemVisibilityPriorityCompare = function(lhs, rhs)
return CPOrderedAscending;
return CPOrderedDescending;
}
};
var TOP_MARGIN = 5.0,
LABEL_MARGIN = 2.0;
var LABEL_MARGIN = 2.0;
@implementation _CPToolbarItemView : CPControl
{
@@ -906,12 +1002,12 @@ var TOP_MARGIN = 5.0,
{
_toolbarItem = aToolbarItem;
_labelField = [[CPTextField alloc] initWithFrame:CGRectMakeZero()];
_labelField = [[CPTextField alloc] initWithFrame:_CGRectMakeZero()];
[_labelField setFont:[CPFont systemFontOfSize:11.0]];
[_labelField setTextColor:[self FIXME_labelColor]];
[_labelField setTextShadowColor:[self FIXME_labelShadowColor]];
[_labelField setTextShadowOffset:CGSizeMake(0.0, 1.0)];
[_labelField setTextShadowOffset:_CGSizeMake(0.0, 1.0)];
[_labelField setAutoresizingMask:CPViewWidthSizable | CPViewMinXMargin];
[self addSubview:_labelField];
@@ -958,13 +1054,7 @@ var TOP_MARGIN = 5.0,
if (identifier === CPToolbarSeparatorItemIdentifier)
{
_view = [[CPView alloc] initWithFrame:CGRectMake(0.0, 0.0, 2.0, 32.0)];
// FIXME: Get rid of this old API!!!
sizes = {};
sizes[@"CPToolbarItemSeparator"] = [CGSizeMake(2.0, 26.0), CGSizeMake(2.0, 1.0), CGSizeMake(2.0, 26.0)];
[_view setBackgroundColor:_CPControlThreePartImagePattern(YES, sizes, @"CPToolbarItem", @"Separator")];
_view = [[CPView alloc] initWithFrame:CGRectMakeZero()];
[self addSubview:_view];
}
@@ -996,7 +1086,7 @@ var TOP_MARGIN = 5.0,
{
_imageView = [[CPImageView alloc] initWithFrame:[self bounds]];
[_imageView setImageScaling:CPScaleProportionally];
[_imageView setImageScaling:CPImageScaleProportionallyDown];
[self addSubview:_imageView];
}
@@ -1014,8 +1104,13 @@ var TOP_MARGIN = 5.0,
_labelSize = [_labelField frame].size;
_minSize = CGSizeMake(MAX(_labelSize.width, minSize.width), _labelSize.height + minSize.height + LABEL_MARGIN + TOP_MARGIN);
_maxSize = CGSizeMake(MAX(_labelSize.width, maxSize.width), 100000000.0);
var iconOnly = [[_toolbarItem toolbar] displayMode] === CPToolbarDisplayModeIconOnly,
labelOnly = [[_toolbarItem toolbar] displayMode] === CPToolbarDisplayModeLabelOnly;
[_labelField setHidden:iconOnly];
[_view setHidden:labelOnly];
_minSize = _CGSizeMake(MAX(_labelSize.width, minSize.width), (labelOnly ? 0 : minSize.height) + (iconOnly ? 0 : _labelSize.height + LABEL_MARGIN));
_maxSize = _CGSizeMake(MAX(_labelSize.width, maxSize.width), 100000000.0);
[_toolbar tile];
}
@@ -1032,20 +1127,31 @@ var TOP_MARGIN = 5.0,
width = _CGRectGetWidth(bounds);
if (identifier === CPToolbarSeparatorItemIdentifier)
return [_view setFrame:CGRectMake(ROUND((width - 2.0) / 2.0), 0.0, 2.0, _CGRectGetHeight(bounds))];
{
var itemSeparatorColor = [_toolbar valueForThemeAttribute:@"image-item-separator-color"],
itemSeparatorSize = [_toolbar valueForThemeAttribute:@"image-item-separator-size"];
[_view setFrame:_CGRectMake(ROUND((width - itemSeparatorSize.size.width) / 2.0), 0.0, itemSeparatorSize.size.width, _CGRectGetHeight(bounds))];
[_view setBackgroundColor:itemSeparatorColor];
return;
}
// The view is centred in the available space above the label.
var view = _view || _imageView,
itemMaxSize = [_toolbarItem maxSize],
height = _CGRectGetHeight(bounds) - _labelSize.height - LABEL_MARGIN - TOP_MARGIN,
iconOnly = [[_toolbarItem toolbar] displayMode] === CPToolbarDisplayModeIconOnly,
height = _CGRectGetHeight(bounds) - (iconOnly ? 0 : _labelSize.height),
viewWidth = MIN(itemMaxSize.width, width),
viewHeight = MIN(itemMaxSize.height, height);
[view setFrame:CGRectMake( ROUND((width - viewWidth) / 2.0),
TOP_MARGIN + ROUND((height - viewHeight) / 2.0),
viewWidth,
viewHeight)];
[view setFrame:_CGRectMake(ROUND((width - viewWidth) / 2.0),
ROUND((height - viewHeight) / 2.0),
viewWidth,
viewHeight)];
[_labelField setFrameOrigin:CGPointMake(ROUND((width - _labelSize.width) / 2.0), TOP_MARGIN + height + LABEL_MARGIN)];
// Label is always drawn at the bottom of the view. So if the view is really tall but the icon is tiny, the icon is centred above the label while the label remains on the bottom.
[_labelField setFrameOrigin:_CGPointMake(ROUND((width - _labelSize.width) / 2.0), _CGRectGetHeight(bounds) - _labelSize.height)];
}
- (void)mouseDown:(CPEvent)anEvent
@@ -1065,6 +1171,10 @@ var TOP_MARGIN = 5.0,
- (void)setEnabled:(BOOL)shouldBeEnabled
{
// Tiling is very expensive so try to avoid it. The CPToolbarItem should already be careful to not notifying about its enabled state needlessly.
if ([self isEnabled] === shouldBeEnabled)
return;
[super setEnabled:shouldBeEnabled];
if (shouldBeEnabled)
@@ -1108,7 +1218,7 @@ var TOP_MARGIN = 5.0,
if (alternateImage)
[_imageView setImage:alternateImage];
[_labelField setTextShadowOffset:CGSizeMakeZero()];
[_labelField setTextShadowOffset:_CGSizeMakeZero()];
}
else
{
@@ -1117,7 +1227,7 @@ var TOP_MARGIN = 5.0,
if (image)
[_imageView setImage:image];
[_labelField setTextShadowOffset:CGSizeMake(0.0, 1.0)];
[_labelField setTextShadowOffset:_CGSizeMake(0.0, 1.0)];
}
[_labelField setTextShadowColor:[self FIXME_labelShadowColor]];
+1 -608
View File
@@ -20,615 +20,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import <Foundation/CPObject.j>
@import <Foundation/CPString.j>
@import "CPImage.j"
@import "CPView.j"
CPToolbarItemVisibilityPriorityStandard = 0;
CPToolbarItemVisibilityPriorityLow = -1000;
CPToolbarItemVisibilityPriorityHigh = 1000;
CPToolbarItemVisibilityPriorityUser = 2000;
CPToolbarSeparatorItemIdentifier = @"CPToolbarSeparatorItem";
CPToolbarSpaceItemIdentifier = @"CPToolbarSpaceItem";
CPToolbarFlexibleSpaceItemIdentifier = @"CPToolbarFlexibleSpaceItem";
CPToolbarShowColorsItemIdentifier = @"CPToolbarShowColorsItem";
CPToolbarShowFontsItemIdentifier = @"CPToolbarShowFontsItem";
CPToolbarCustomizeToolbarItemIdentifier = @"CPToolbarCustomizeToolbarItem";
CPToolbarPrintItemIdentifier = @"CPToolbarPrintItem";
/*!
@ingroup appkit
@class CPToolbarItem
A representation of an item in a CPToolbar.
*/
@implementation CPToolbarItem : CPObject
{
CPString _itemIdentifier;
CPToolbar _toolbar;
CPString _label;
CPString _paletteLabel;
CPString _toolTip;
int _tag;
id _target;
SEL _action;
BOOL _isEnabled;
CPImage _image;
CPImage _alternateImage;
CPView _view;
CGSize _minSize;
CGSize _maxSize;
int _visibilityPriority;
BOOL _autovalidates;
}
- (id)init
{
return [self initWithItemIdentifier:@""];
}
// Creating a Toolbar Item
/*!
Initializes the toolbar item with a specified identifier.
@param anItemIdentifier the item's identifier
@return the initialized toolbar item
*/
- (id)initWithItemIdentifier:(CPString)anItemIdentifier
{
self = [super init];
if (self)
{
_itemIdentifier = anItemIdentifier;
_tag = 0;
_isEnabled = YES;
_minSize = CGSizeMakeZero();
_maxSize = CGSizeMakeZero();
_visibilityPriority = CPToolbarItemVisibilityPriorityStandard;
_autovalidates = YES;
}
return self;
}
// Managing Attributes
/*!
Returns the item's identifier.
*/
- (CPString)itemIdentifier
{
return _itemIdentifier;
}
/*!
Returns the toolbar of which this item is a part.
*/
- (CPToolbar)toolbar
{
return _toolbar;
}
/* @ignore */
- (void)_setToolbar:(CPToolbar)aToolbar
{
_toolbar = aToolbar;
}
/*!
Returns the item's label
*/
- (CPString)label
{
return _label;
}
/*!
Sets the item's label.
@param aLabel the new label for the item
*/
- (void)setLabel:(CPString)aLabel
{
_label = aLabel;
}
/*!
Returns the palette label.
*/
- (CPString)paletteLabel
{
return _paletteLabel;
}
/*!
Sets the palette label
@param aPaletteLabel the new palette label
*/
- (void)setPaletteLabel:(CPString)aPaletteLabel
{
_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. \c nil will cause
the action to be passed on to the first responder.
@param aTarget the new target
*/
- (void)setTarget:(id)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
{
if (!_view)
_action = anAction;
else if ([_view respondsToSelector:@selector(setAction:)])
[_view setAction:anAction];
}
/*!
Returns \c YES 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 \c YES enables the item
*/
- (void)setEnabled:(BOOL)shouldBeEnabled
{
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;
if (!_image)
return;
if (_minSize.width === 0 && _minSize.height === 0 &&
_maxSize.width === 0 && _maxSize.height === 0)
{
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
{
if ([_view respondsToSelector:@selector(setAlternateImage:)])
[_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
{
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
{
return _minSize;
}
/*!
Sets the item's minimum size.
@param aMinSize the new minimum size
*/
- (void)setMinSize:(CGSize)aMinSize
{
if (!aMinSize.height || !aMinSize.width)
return;
_minSize = CGSizeMakeCopy(aMinSize);
// Try to provide some sanity: Make maxSize >= minSize
_maxSize = CGSizeMake(MAX(_minSize.width, _maxSize.width), MAX(_minSize.height, _maxSize.height));
}
/*!
Returns the item's maximum size.
*/
- (CGSize)maxSize
{
return _maxSize;
}
/*!
Sets the item's new maximum size.
@param aMaxSize the new maximum size
*/
- (void)setMaxSize:(CGSize)aMaxSize
{
if (!aMaxSize.height || !aMaxSize.width)
return;
_maxSize = CGSizeMakeCopy(aMaxSize);
// Try to provide some sanity: Make minSize <= maxSize
_minSize = CGSizeMake(MIN(_minSize.width, _maxSize.width), MIN(_minSize.height, _maxSize.height));
}
// Visibility Priority
/*!
Returns the item's visibility priority. The value will be one of:
<pre>
CPToolbarItemVisibilityPriorityStandard
CPToolbarItemVisibilityPriorityLow
CPToolbarItemVisibilityPriorityHigh
CPToolbarItemVisibilityPriorityUser
</pre>
*/
- (int)visibilityPriority
{
return _visibilityPriority;
}
/*!
Sets the item's visibility priority. The value must be one of:
<pre>
CPToolbarItemVisibilityPriorityStandard
CPToolbarItemVisibilityPriorityLow
CPToolbarItemVisibilityPriorityHigh
CPToolbarItemVisibilityPriorityUser
</pre>
@param aVisiblityPriority the priority
*/
- (void)setVisibilityPriority:(int)aVisibilityPriority
{
_visibilityPriority = aVisibilityPriority;
}
- (void)validate
{
var action = [self action],
target = [self target];
// View items do not do any target-action analysis.
if (_view)
{
if ([target respondsToSelector:@selector(validateToolbarItem:)])
[self setEnabled:[target validateToolbarItem:self]];
return;
}
if (!action)
return [self setEnabled:NO];
if (target && ![target respondsToSelector:action])
return [self setEnabled:NO];
target = [CPApp targetForAction:action to:target from:self];
if (!target)
return [self setEnabled:NO];
if ([target respondsToSelector:@selector(validateToolbarItem:)])
[self setEnabled:[target validateToolbarItem:self]];
else
[self setEnabled:YES];
}
- (BOOL)autovalidates
{
return _autovalidates;
}
- (void)setAutovalidates:(BOOL)shouldAutovalidate
{
_autovalidates = !!shouldAutovalidate;
}
@end
var CPToolbarItemItemIdentifierKey = @"CPToolbarItemItemIdentifierKey",
CPToolbarItemLabelKey = @"CPToolbarItemLabelKey",
CPToolbarItemPaletteLabelKey = @"CPToolbarItemPaletteLabelKey",
CPToolbarItemToolTipKey = @"CPToolbarItemToolTipKey",
CPToolbarItemTagKey = @"CPToolbarItemTagKey",
CPToolbarItemTargetKey = @"CPToolbarItemTargetKey",
CPToolbarItemActionKey = @"CPToolbarItemActionKey",
CPToolbarItemEnabledKey = @"CPToolbarItemEnabledKey",
CPToolbarItemImageKey = @"CPToolbarItemImageKey",
CPToolbarItemAlternateImageKey = @"CPToolbarItemAlternateImageKey",
CPToolbarItemViewKey = @"CPToolbarItemViewKey",
CPToolbarItemMinSizeKey = @"CPToolbarItemMinSizeKey",
CPToolbarItemMaxSizeKey = @"CPToolbarItemMaxSizeKey",
CPToolbarItemVisibilityPriorityKey = @"CPToolbarItemVisibilityPriorityKey",
CPToolbarItemAutovalidatesKey = @"CPToolbarItemAutovalidatesKey";
@implementation CPToolbarItem (CPCoding)
- (id)initWithCoder:(CPCoder)aCoder
{
self = [super init];
if (self)
{
_itemIdentifier = [aCoder decodeObjectForKey:CPToolbarItemItemIdentifierKey];
_minSize = [aCoder decodeSizeForKey:CPToolbarItemMinSizeKey];
_maxSize = [aCoder decodeSizeForKey:CPToolbarItemMaxSizeKey];
[self setLabel:[aCoder decodeObjectForKey:CPToolbarItemLabelKey]];
[self setPaletteLabel:[aCoder decodeObjectForKey:CPToolbarItemPaletteLabelKey]];
[self setToolTip:[aCoder decodeObjectForKey:CPToolbarItemToolTipKey]];
[self setTag:[aCoder decodeObjectForKey:CPToolbarItemTagKey]];
[self setTarget:[aCoder decodeObjectForKey:CPToolbarItemTargetKey]];
[self setAction:CPSelectorFromString([aCoder decodeObjectForKey:CPToolbarItemActionKey])];
[self setEnabled:[aCoder decodeBoolForKey:CPToolbarItemEnabledKey]];
[self setImage:[aCoder decodeObjectForKey:CPToolbarItemImageKey]];
[self setAlternateImage:[aCoder decodeObjectForKey:CPToolbarItemAlternateImageKey]];
[self setView:[aCoder decodeObjectForKey:CPToolbarItemViewKey]];
[self setVisibilityPriority:[aCoder decodeIntForKey:CPToolbarItemVisibilityPriorityKey]];
[self setAutovalidates:[aCoder decodeBoolForKey:CPToolbarItemAutovalidatesKey]];
}
return self;
}
- (void)encodeWithCoder:(CPCoder)aCoder
{
[aCoder encodeObject:_itemIdentifier forKey:CPToolbarItemItemIdentifierKey];
[aCoder encodeObject:[self label] forKey:CPToolbarItemLabelKey];
[aCoder encodeObject:[self paletteLabel] forKey:CPToolbarItemPaletteLabelKey];
[aCoder encodeObject:[self toolTip] forKey:CPToolbarItemToolTipKey];
[aCoder encodeObject:[self tag] forKey:CPToolbarItemTagKey];
[aCoder encodeObject:[self target] forKey:CPToolbarItemTargetKey];
[aCoder encodeObject:[self action] forKey:CPToolbarItemActionKey];
[aCoder encodeObject:[self isEnabled] forKey:CPToolbarItemEnabledKey];
[aCoder encodeObject:[self image] forKey:CPToolbarItemImageKey];
[aCoder encodeObject:[self alternateImage] forKey:CPToolbarItemAlternateImageKey];
[aCoder encodeObject:[self view] forKey:CPToolbarItemViewKey];
[aCoder encodeSize:[self minSize] forKey:CPToolbarItemMinSizeKey];
[aCoder encodeSize:[self maxSize] forKey:CPToolbarItemMaxSizeKey];
[aCoder encodeObject:[self visibilityPriority] forKey:CPToolbarItemVisibilityPriorityKey];
[aCoder encodeBool:[self autovalidates] forKey:CPToolbarItemAutovalidatesKey];
}
@end
@implementation CPToolbarItem (CPCopying)
- (id)copy
{
var copy = [[[self class] alloc] initWithItemIdentifier:_itemIdentifier];
if (_view)
[copy setView:[CPKeyedUnarchiver unarchiveObjectWithData:[CPKeyedArchiver archivedDataWithRootObject:_view]]];
[copy _setToolbar:_toolbar];
[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];
[copy setVisibilityPriority:[self visibilityPriority]];
[copy setAutovalidates:[self autovalidates]];
return copy;
}
@end
// Standard toolbar identifiers
@implementation CPToolbarItem (Standard)
/* @ignore */
+ (CPToolbarItem)_standardItemWithItemIdentifier:(CPString)anItemIdentifier
{
switch (anItemIdentifier)
{
case CPToolbarSeparatorItemIdentifier: return [_CPToolbarSeparatorItem new];
case CPToolbarSpaceItemIdentifier: return [_CPToolbarSpaceItem new];
case CPToolbarFlexibleSpaceItemIdentifier: return [_CPToolbarFlexibleSpaceItem new];
case CPToolbarShowColorsItemIdentifier: return [_CPToolbarShowColorsItem new];
case CPToolbarShowFontsItemIdentifier: return nil;
case CPToolbarCustomizeToolbarItemIdentifier: return nil;
case CPToolbarPrintItemIdentifier: return nil;
}
return nil;
}
@end
@import "_CPToolbarItem.j"
@import "_CPToolbarFlexibleSpaceItem.j"
@import "_CPToolbarShowColorsItem.j"
@import "_CPToolbarSeparatorItem.j"
+21
View File
@@ -1,3 +1,24 @@
/*
* CPTreeNode.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/CPIndexPath.j>
+14 -7
View File
@@ -23,9 +23,15 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import <Foundation/CPDictionary.j>
@import <Foundation/CPNotificationCenter.j>
@import <Foundation/CPString.j>
@import <AppKit/CPController.j>
@import <Foundation/CPUserDefaults.j>
@import "CPController.j"
@global CPUserDefaultsDidChangeNotification
var SharedUserDefaultsController = nil;
@@ -34,6 +40,7 @@ var SharedUserDefaultsController = nil;
CPUserDefaults _defaults @accessors(readonly, property=defaults);
CPDictionary _initialValues @accessors(property=initialValues);
BOOL _appliesImmediately @accessors(property=appliesImmediately);
id _valueProxy;
}
+ (id)sharedUserDefaultsController
@@ -180,7 +187,7 @@ var CPUserDefaultsControllerSharedKey = "CPUserDefaultsControllerSharedKey";
var keys = [_cachedValues allKeys],
keysCount = [keys count];
while(keysCount--)
while (keysCount--)
{
var key = keys[keysCount];
[self willChangeValueForKey:key];
@@ -194,7 +201,7 @@ var CPUserDefaultsControllerSharedKey = "CPUserDefaultsControllerSharedKey";
var keys = [_cachedValues allKeys],
keysCount = [keys count];
while(keysCount--)
while (keysCount--)
{
var key = keys[keysCount];
[[_controller defaults] setObject:[_cachedValues objectForKey:key] forKey:key];
@@ -207,7 +214,7 @@ var CPUserDefaultsControllerSharedKey = "CPUserDefaultsControllerSharedKey";
keys = [_cachedValues allKeys],
keysCount = [keys count];
while(keysCount--)
while (keysCount--)
{
var key = keys[keysCount];
[self willChangeValueForKey:key];
@@ -229,7 +236,7 @@ var CPUserDefaultsControllerSharedKey = "CPUserDefaultsControllerSharedKey";
keys = [_cachedValues allKeys],
keysCount = [keys count];
while(keysCount--)
while (keysCount--)
{
var key = keys[keysCount],
value = [_cachedValues objectForKey:key],
@@ -250,7 +257,7 @@ var CPUserDefaultsControllerSharedKey = "CPUserDefaultsControllerSharedKey";
keys = [_cachedValues allKeys],
keysCount = [keys count];
while(keysCount--)
while (keysCount--)
{
var key = keys[keysCount],
value = [_cachedValues objectForKey:key],
+450 -77
View File
@@ -26,14 +26,24 @@
@import "CGAffineTransform.j"
@import "CGGeometry.j"
@import "CPColor.j"
@import "CPGeometry.j"
@import "CPGraphicsContext.j"
@import "CPResponder.j"
@import "CPTheme.j"
@import "_CPDisplayServer.j"
@class _CPToolTip
@class CPWindow
@class _CPMenuItemView
@class CPPlatformWindow
@class CPMenu
@class CPClipView
@class CPScrollView
@global appkit_tag_dom_elements
@global CPWindowAbove
@global CPBorderlessWindowMask
@global CPScreenSaverWindowLevel
/*
@global
@@ -98,6 +108,7 @@ var CPViewFlags = { },
CPViewHasCustomDrawRect = 1 << 0,
CPViewHasCustomLayoutSubviews = 1 << 1;
/*!
@ingroup appkit
@class CPView
@@ -141,6 +152,7 @@ var CPViewFlags = { },
BOOL _postsFrameChangedNotifications;
BOOL _postsBoundsChangedNotifications;
BOOL _inhibitFrameAndBoundsChangedNotifications;
BOOL _inLiveResize;
#if PLATFORM(DOM)
DOMElement _DOMElement;
@@ -188,7 +200,10 @@ var CPViewFlags = { },
unsigned _viewClassFlags;
// ToolTips
CPString _toolTip @accessors(property=toolTip);
CPString _toolTip @accessors(getter=toolTip);
Function _toolTipFunctionIn;
Function _toolTipFunctionOut;
BOOL _toolTipInstalled;
}
/*
@@ -214,7 +229,7 @@ var CPViewFlags = { },
CachedNotificationCenter = [CPNotificationCenter defaultCenter];
}
- (void)setupViewFlags
- (void)_setupViewFlags
{
var theClass = [self class],
classUID = [theClass UID];
@@ -235,6 +250,13 @@ var CPViewFlags = { },
_viewClassFlags = CPViewFlags[classUID];
}
- (void)_setupToolTipHandlers
{
_toolTipInstalled = NO;
_toolTipFunctionIn = function(e) { [_CPToolTip scheduleToolTipForView:self]; }
_toolTipFunctionOut = function(e) { [_CPToolTip invalidateCurrentToolTipIfNeeded]; };
}
+ (CPSet)keyPathsForValuesAffectingFrame
{
return [CPSet setWithObjects:@"frameOrigin", @"frameSize"];
@@ -291,6 +313,9 @@ var CPViewFlags = { },
CPDOMDisplayServerSetStyleLeftTop(_DOMElement, NULL, _CGRectGetMinX(aFrame), _CGRectGetMinY(aFrame));
CPDOMDisplayServerSetStyleSize(_DOMElement, width, height);
if (typeof(appkit_tag_dom_elements) !== "undefined" && !!appkit_tag_dom_elements)
_DOMElement.setAttribute("data-cappuccino-view", [self className]);
_DOMImageParts = [];
_DOMImageSizes = [];
#endif
@@ -298,7 +323,8 @@ var CPViewFlags = { },
_theme = [CPTheme defaultTheme];
_themeState = CPThemeStateNormal;
[self setupViewFlags];
[self _setupToolTipHandlers];
[self _setupViewFlags];
[self _loadThemeAttributes];
}
@@ -306,6 +332,82 @@ var CPViewFlags = { },
return self;
}
/*!
Sets the tooltip for the receiver.
@param aToolTip the tooltip
*/
- (void)setToolTip:(CPString)aToolTip
{
if (_toolTip == aToolTip)
return;
if (aToolTip && ![aToolTip isKindOfClass:CPString])
aToolTip = [aToolTip description];
_toolTip = aToolTip;
if (_toolTip)
[self _installToolTipEventHandlers];
else
[self _uninstallToolTipEventHandlers];
}
/*! @ignore
Install the handlers for the tooltip
*/
- (void)_installToolTipEventHandlers
{
if (_toolTipInstalled)
return;
#if PLATFORM(DOM)
if (_DOMElement.addEventListener)
{
_DOMElement.addEventListener("mouseover", _toolTipFunctionIn, NO);
_DOMElement.addEventListener("keypress", _toolTipFunctionOut, NO);
_DOMElement.addEventListener("mouseout", _toolTipFunctionOut, NO);
}
else if (_DOMElement.attachEvent)
{
_DOMElement.attachEvent("onmouseover", _toolTipFunctionIn);
_DOMElement.attachEvent("onkeypress", _toolTipFunctionOut);
_DOMElement.attachEvent("onmouseout", _toolTipFunctionOut);
}
#endif
_toolTipInstalled = YES;
}
/*! @ignore
Uninstall the handlers for the tooltip
*/
- (void)_uninstallToolTipEventHandlers
{
if (!_toolTipInstalled)
return;
#if PLATFORM(DOM)
if (_DOMElement.removeEventListener)
{
_DOMElement.removeEventListener("mouseover", _toolTipFunctionIn, NO);
_DOMElement.removeEventListener("keypress", _toolTipFunctionOut, NO);
_DOMElement.removeEventListener("mouseout", _toolTipFunctionOut, NO);
}
else if (_DOMElement.detachEvent)
{
_DOMElement.detachEvent("onmouseover", _toolTipFunctionIn);
_DOMElement.detachEvent("onkeypress", _toolTipFunctionOut);
_DOMElement.detachEvent("onmouseout", _toolTipFunctionOut);
}
#endif
_toolTipInstalled = NO;
}
/*!
Returns the container view of the receiver
@return the receiver's containing view
@@ -365,10 +467,13 @@ var CPViewFlags = { },
/* @ignore */
- (void)_insertSubview:(CPView)aSubview atIndex:(int)anIndex
{
if (aSubview === self)
[CPException raise:CPInvalidArgumentException reason:"can't add a view as a subview of itself"];
// We will have to adjust the z-index of all views starting at this index.
var count = _subviews.length;
// dirty the key view loop, in case the window wants to auto recalculate it
// Dirty the key view loop, in case the window wants to auto recalculate it
[[self window] _dirtyKeyViewLoop];
// If this is already one of our subviews, remove it.
@@ -449,7 +554,7 @@ var CPViewFlags = { },
if (!_superview)
return;
// dirty the key view loop, in case the window wants to auto recalculate it
// Dirty the key view loop, in case the window wants to auto recalculate it
[[self window] _dirtyKeyViewLoop];
[_superview willRemoveSubview:self];
@@ -471,7 +576,7 @@ var CPViewFlags = { },
*/
- (void)replaceSubview:(CPView)aSubview with:(CPView)aView
{
if (aSubview._superview != self)
if (aSubview._superview !== self)
return;
var index = [_subviews indexOfObjectIdenticalTo:aSubview];
@@ -527,7 +632,7 @@ var CPViewFlags = { },
var addedSubview = nil,
addedSubviewEnumerator = [addedSubviews objectEnumerator];
while (addedSubview = [addedSubviewEnumerator nextObject])
while ((addedSubview = [addedSubviewEnumerator nextObject]) !== nil)
[self addSubview:addedSubview];
// If the order is fine, no need to reorder.
@@ -635,7 +740,7 @@ var CPViewFlags = { },
}
/*!
Called when the receiver is about to be remove one of its subviews.
Called when the receiver is about to remove one of its subviews.
@param aView the view that will be removed
*/
- (void)willRemoveSubview:(CPView)aView
@@ -706,7 +811,7 @@ var CPViewFlags = { },
/*!
Sets the frame size of the receiver to the dimensions and origin of the provided rectangle in the coordinate system
of the superview. The method also posts an CPViewFrameDidChangeNotification to the notification
of the superview. The method also posts a CPViewFrameDidChangeNotification to the notification
center if the receiver is configured to do so. If the frame is the same as the current frame, the method simply
returns (and no notification is posted).
@param aFrame the rectangle specifying the new origin and size of the receiver
@@ -759,7 +864,7 @@ var CPViewFlags = { },
}
/*!
Returns the center of the receiver's frame to the provided point. The point is defined in the superview's coordinate system.
Returns the center of the receiver's frame in the superview's coordinate system.
@return CGPoint the center point of the receiver's frame
*/
- (CGPoint)center
@@ -844,26 +949,90 @@ var CPViewFlags = { },
}
else
{
var images = [[_backgroundColor patternImage] imageSlices];
var images = [[_backgroundColor patternImage] imageSlices],
partIndex = 0;
if (_backgroundType === BackgroundVerticalThreePartImage)
{
CPDOMDisplayServerSetStyleSize(_DOMImageParts[1], size.width, size.height - _DOMImageSizes[0].height - _DOMImageSizes[2].height);
var top = _DOMImageSizes[0] ? _DOMImageSizes[0].height : 0,
bottom = _DOMImageSizes[2] ? _DOMImageSizes[2].height : 0;
// Make sure to repeat the top and bottom pieces horizontally if they're not the exact width needed.
if (top)
{
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], size.width, top);
partIndex++;
}
if (_DOMImageSizes[1])
{
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], size.width, size.height - top - bottom);
partIndex++;
}
if (bottom)
{
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], size.width, bottom);
}
}
else if (_backgroundType === BackgroundHorizontalThreePartImage)
{
CPDOMDisplayServerSetStyleSize(_DOMImageParts[1], size.width - _DOMImageSizes[0].width - _DOMImageSizes[2].width, size.height);
var left = _DOMImageSizes[0] ? _DOMImageSizes[0].width : 0,
right = _DOMImageSizes[2] ? _DOMImageSizes[2].width : 0;
// Make sure to repeat the left and right pieces vertically if they're not the exact height needed.
if (left)
{
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], left, size.height);
partIndex++;
}
if (_DOMImageSizes[1])
{
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], size.width - left - right, size.height);
partIndex++;
}
if (right)
{
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], right, size.height);
}
}
else if (_backgroundType === BackgroundNinePartImage)
{
var width = size.width - _DOMImageSizes[0].width - _DOMImageSizes[2].width,
height = size.height - _DOMImageSizes[0].height - _DOMImageSizes[6].height;
var left = _DOMImageSizes[0] ? _DOMImageSizes[0].width : 0,
right = _DOMImageSizes[2] ? _DOMImageSizes[2].width : 0,
top = _DOMImageSizes[0] ? _DOMImageSizes[0].height : 0,
bottom = _DOMImageSizes[6] ? _DOMImageSizes[6].height : 0,
width = size.width - left - right,
height = size.height - top - bottom;
CPDOMDisplayServerSetStyleSize(_DOMImageParts[1], width, _DOMImageSizes[0].height);
CPDOMDisplayServerSetStyleSize(_DOMImageParts[3], _DOMImageSizes[3].width, height);
CPDOMDisplayServerSetStyleSize(_DOMImageParts[4], width, height);
CPDOMDisplayServerSetStyleSize(_DOMImageParts[5], _DOMImageSizes[5].width, height);
CPDOMDisplayServerSetStyleSize(_DOMImageParts[7], width, _DOMImageSizes[7].height);
if (_DOMImageSizes[0])
partIndex++;
if (_DOMImageSizes[1])
{
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], width, top);
partIndex++;
}
if (_DOMImageSizes[2])
partIndex++;
if (_DOMImageSizes[3])
{
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], _DOMImageSizes[3].width, height);
partIndex++;
}
if (_DOMImageSizes[4])
{
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], width, height);
partIndex++;
}
if (_DOMImageSizes[5])
{
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], _DOMImageSizes[5].width, height);
partIndex++;
}
if (_DOMImageSizes[6])
partIndex++;
if (_DOMImageSizes[7])
{
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], width, _DOMImageSizes[7].height);
}
}
}
}
@@ -1328,10 +1497,9 @@ var CPViewFlags = { },
Returns \c YES by default.
@return \c YES, if the view object accepts first mouse-down event. \c NO, otherwise.
*/
//FIXME: should be NO by default?
- (BOOL)acceptsFirstMouse:(CPEvent)anEvent
{
return YES;
return NO;
}
/*!
@@ -1357,9 +1525,9 @@ var CPViewFlags = { },
@param aPoint the point to test
@return returns the containing view, or nil if the point is not contained
*/
- (CPView)hitTest:(CPPoint)aPoint
- (CPView)hitTest:(CGPoint)aPoint
{
if (_isHidden || !_hitTests || !CPRectContainsPoint(_frame, aPoint))
if (_isHidden || !_hitTests || !_CGRectContainsPoint(_frame, aPoint))
return nil;
var view = nil,
@@ -1435,17 +1603,18 @@ var CPViewFlags = { },
colorHasAlpha = colorExists && [_backgroundColor alphaComponent] < 1.0,
supportsRGBA = CPFeatureIsCompatible(CPCSSRGBAFeature),
colorNeedsDOMElement = colorHasAlpha && !supportsRGBA,
amount = 0;
amount = 0,
slices;
if ([patternImage isThreePartImage])
{
_backgroundType = [patternImage isVertical] ? BackgroundVerticalThreePartImage : BackgroundHorizontalThreePartImage;
amount = 3 - _DOMImageParts.length;
amount = 3;
}
else if ([patternImage isNinePartImage])
{
_backgroundType = BackgroundNinePartImage;
amount = 9 - _DOMImageParts.length;
amount = 9;
}
else
{
@@ -1453,6 +1622,34 @@ var CPViewFlags = { },
amount = (colorNeedsDOMElement ? 1 : 0) - _DOMImageParts.length;
}
// Prepare multipart image data and reduce number of required DOM parts by number of empty slices in the multipart image to save needless DOM elements.
if (_backgroundType === BackgroundVerticalThreePartImage || _backgroundType === BackgroundHorizontalThreePartImage || _backgroundType === BackgroundNinePartImage)
{
slices = [patternImage imageSlices];
// We won't need more divs than there are slices.
amount = MIN(amount, slices.length);
for (var i = 0, count = slices.length; i < count; i++)
{
var image = slices[i],
size = [image size];
if (!size || (size.width == 0 && size.height == 0))
size = nil;
_DOMImageSizes[i] = size;
// If there's a nil slice or a slice with no size, it won't need a div.
if (!size)
amount--;
}
// Now that we know how many divs we really need, compare that to number we actually have.
amount -= _DOMImageParts.length;
}
// Make sure the number of divs we have match our needs.
if (amount > 0)
{
while (amount--)
@@ -1494,64 +1691,148 @@ var CPViewFlags = { },
}
else
{
var slices = [patternImage imageSlices],
count = MIN(_DOMImageParts.length, slices.length),
frameSize = _frame.size;
var frameSize = _frame.size,
partIndex = 0;
while (count--)
for (var i = 0; i < slices.length; i++)
{
var image = slices[count],
size = _DOMImageSizes[count] = image ? [image size] : _CGSizeMakeZero();
var size = _DOMImageSizes[i];
CPDOMDisplayServerSetStyleSize(_DOMImageParts[count], size.width, size.height);
if (!size)
continue;
_DOMImageParts[count].style.background = image ? "url(\"" + [image filename] + "\")" : "";
var image = slices[i];
// // If image was nil, size should have been nil too.
// assert(image != nil);
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], size.width, size.height);
_DOMImageParts[partIndex].style.background = "url(\"" + [image filename] + "\")";
if (!supportsRGBA)
{
if (CPFeatureIsCompatible(CPOpacityRequiresFilterFeature))
try { _DOMImageParts[count].style.removeAttribute("filter") } catch (anException) { }
try { _DOMImageParts[partIndex].style.removeAttribute("filter") } catch (anException) { }
else
_DOMImageParts[count].style.opacity = 1.0;
_DOMImageParts[partIndex].style.opacity = 1.0;
}
partIndex++;
}
if (_backgroundType == BackgroundNinePartImage)
{
var width = frameSize.width - _DOMImageSizes[0].width - _DOMImageSizes[2].width,
height = frameSize.height - _DOMImageSizes[0].height - _DOMImageSizes[6].height;
var left = _DOMImageSizes[0] ? _DOMImageSizes[0].width : 0,
right = _DOMImageSizes[2] ? _DOMImageSizes[2].width : 0,
top = _DOMImageSizes[0] ? _DOMImageSizes[0].height : 0,
bottom = _DOMImageSizes[6] ? _DOMImageSizes[6].height : 0,
width = frameSize.width - left - right,
height = frameSize.height - top - bottom;
CPDOMDisplayServerSetStyleSize(_DOMImageParts[1], width, _DOMImageSizes[0].height);
CPDOMDisplayServerSetStyleSize(_DOMImageParts[3], _DOMImageSizes[3].width, height);
CPDOMDisplayServerSetStyleSize(_DOMImageParts[4], width, height);
CPDOMDisplayServerSetStyleSize(_DOMImageParts[5], _DOMImageSizes[5].width, height);
CPDOMDisplayServerSetStyleSize(_DOMImageParts[7], width, _DOMImageSizes[7].height);
partIndex = 0;
CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[0], NULL, 0.0, 0.0);
CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[1], NULL, _DOMImageSizes[0].width, 0.0);
CPDOMDisplayServerSetStyleRightTop(_DOMImageParts[2], NULL, 0.0, 0.0);
CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[3], NULL, 0.0, _DOMImageSizes[1].height);
CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[4], NULL, _DOMImageSizes[0].width, _DOMImageSizes[0].height);
CPDOMDisplayServerSetStyleRightTop(_DOMImageParts[5], NULL, 0.0, _DOMImageSizes[1].height);
CPDOMDisplayServerSetStyleLeftBottom(_DOMImageParts[6], NULL, 0.0, 0.0);
CPDOMDisplayServerSetStyleLeftBottom(_DOMImageParts[7], NULL, _DOMImageSizes[6].width, 0.0);
CPDOMDisplayServerSetStyleRightBottom(_DOMImageParts[8], NULL, 0.0, 0.0);
if (_DOMImageSizes[0])
{
CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[partIndex], NULL, 0.0, 0.0);
partIndex++;
}
if (_DOMImageSizes[1])
{
CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[partIndex], NULL, left, 0.0);
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], width, _DOMImageSizes[1].height);
partIndex++;
}
if (_DOMImageSizes[2])
{
CPDOMDisplayServerSetStyleRightTop(_DOMImageParts[partIndex], NULL, 0.0, 0.0);
partIndex++;
}
if (_DOMImageSizes[3])
{
CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[partIndex], NULL, 0.0, top);
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], _DOMImageSizes[3].width, height);
partIndex++;
}
if (_DOMImageSizes[4])
{
CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[partIndex], NULL, left, top);
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], width, height);
partIndex++;
}
if (_DOMImageSizes[5])
{
CPDOMDisplayServerSetStyleRightTop(_DOMImageParts[partIndex], NULL, 0.0, top);
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], _DOMImageSizes[5].width, height);
partIndex++;
}
if (_DOMImageSizes[6])
{
CPDOMDisplayServerSetStyleLeftBottom(_DOMImageParts[partIndex], NULL, 0.0, 0.0);
partIndex++;
}
if (_DOMImageSizes[7])
{
CPDOMDisplayServerSetStyleLeftBottom(_DOMImageParts[partIndex], NULL, left, 0.0);
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], width, _DOMImageSizes[7].height);
partIndex++;
}
if (_DOMImageSizes[8])
{
CPDOMDisplayServerSetStyleRightBottom(_DOMImageParts[partIndex], NULL, 0.0, 0.0);
}
}
else if (_backgroundType == BackgroundVerticalThreePartImage)
{
CPDOMDisplayServerSetStyleSize(_DOMImageParts[1], frameSize.width, frameSize.height - _DOMImageSizes[0].height - _DOMImageSizes[2].height);
var top = _DOMImageSizes[0] ? _DOMImageSizes[0].height : 0,
bottom = _DOMImageSizes[2] ? _DOMImageSizes[2].height : 0;
CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[0], NULL, 0.0, 0.0);
CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[1], NULL, 0.0, _DOMImageSizes[0].height);
CPDOMDisplayServerSetStyleLeftBottom(_DOMImageParts[2], NULL, 0.0, 0.0);
partIndex = 0;
// Make sure to repeat the top and bottom pieces horizontally if they're not the exact width needed.
if (top)
{
CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[partIndex], NULL, 0.0, 0.0);
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], frameSize.width, top);
partIndex++;
}
if (_DOMImageSizes[1])
{
CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[partIndex], NULL, 0.0, top);
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], frameSize.width, frameSize.height - top - bottom);
partIndex++;
}
if (bottom)
{
CPDOMDisplayServerSetStyleLeftBottom(_DOMImageParts[partIndex], NULL, 0.0, 0.0);
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], frameSize.width, bottom);
}
}
else if (_backgroundType == BackgroundHorizontalThreePartImage)
{
CPDOMDisplayServerSetStyleSize(_DOMImageParts[1], frameSize.width - _DOMImageSizes[0].width - _DOMImageSizes[2].width, frameSize.height);
var left = _DOMImageSizes[0] ? _DOMImageSizes[0].width : 0,
right = _DOMImageSizes[2] ? _DOMImageSizes[2].width : 0;
CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[0], NULL, 0.0, 0.0);
CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[1], NULL, _DOMImageSizes[0].width, 0.0);
CPDOMDisplayServerSetStyleRightTop(_DOMImageParts[2], NULL, 0.0, 0.0);
partIndex = 0;
// Make sure to repeat the left and right pieces vertically if they're not the exact height needed.
if (left)
{
CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[partIndex], NULL, 0.0, 0.0);
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], left, frameSize.height);
partIndex++;
}
if (_DOMImageSizes[1])
{
CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[partIndex], NULL, left, 0.0);
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], frameSize.width - left - right, frameSize.height);
partIndex++;
}
if (right)
{
CPDOMDisplayServerSetStyleRightTop(_DOMImageParts[partIndex], NULL, 0.0, 0.0);
CPDOMDisplayServerSetStyleSize(_DOMImageParts[partIndex], right, frameSize.height);
}
}
}
#endif
@@ -1765,7 +2046,7 @@ setBoundsOrigin:
@param aSourceObject the drag operation controller
@param slideBack Whether the view should 'slide back' if the drag is rejected
*/
- (void)dragView:(CPView)aView at:(CPPoint)aLocation offset:(CPSize)mouseOffset event:(CPEvent)anEvent pasteboard:(CPPasteboard)aPasteboard source:(id)aSourceObject slideBack:(BOOL)slideBack
- (void)dragView:(CPView)aView at:(CGPoint)aLocation offset:(CGSize)mouseOffset event:(CPEvent)anEvent pasteboard:(CPPasteboard)aPasteboard source:(id)aSourceObject slideBack:(BOOL)slideBack
{
[_window dragView:aView at:[self convertPoint:aLocation toView:nil] offset:mouseOffset event:anEvent pasteboard:aPasteboard source:aSourceObject slideBack:slideBack];
}
@@ -1815,7 +2096,7 @@ setBoundsOrigin:
Draws the receiver into \c aRect. This method should be overridden by subclasses.
@param aRect the area that should be drawn into
*/
- (void)drawRect:(CPRect)aRect
- (void)drawRect:(CGRect)aRect
{
}
@@ -1835,7 +2116,7 @@ setBoundsOrigin:
Marks the area denoted by \c aRect as dirty, and initiates a redraw on it.
@param aRect the area that needs to be redrawn
*/
- (void)setNeedsDisplayInRect:(CPRect)aRect
- (void)setNeedsDisplayInRect:(CGRect)aRect
{
if (!(_viewClassFlags & CPViewHasCustomDrawRect))
return;
@@ -1883,7 +2164,7 @@ setBoundsOrigin:
Draws the receiver into the area defined by \c aRect.
@param aRect the area to be drawn
*/
- (void)displayRect:(CPRect)aRect
- (void)displayRect:(CGRect)aRect
{
[self viewWillDraw];
@@ -1920,6 +2201,7 @@ setBoundsOrigin:
{
var graphicsPort = CGBitmapGraphicsContextCreate();
#if PLATFORM(DOM)
_DOMContentsElement = graphicsPort.DOMElement;
_DOMContentsElement.style.zIndex = -100;
@@ -1936,7 +2218,11 @@ setBoundsOrigin:
_DOMContentsElement.style.width = ROUND(_CGRectGetWidth(_frame)) + "px";
_DOMContentsElement.style.height = ROUND(_CGRectGetHeight(_frame)) + "px";
#if PLATFORM(DOM)
// The performance implications of this aren't clear, but without this subviews might not be redrawn when this
// view moves.
if (CPPlatformHasBug(CPCanvasParentDrawErrorsOnMovementBug))
_DOMElement.style.webkitTransform = 'translateX(0)';
CPDOMDisplayServerAppendChild(_DOMElement, _DOMContentsElement);
#endif
_graphicsContext = [CPGraphicsContext graphicsContextWithGraphicsPort:graphicsPort flipped:YES];
@@ -2128,6 +2414,43 @@ setBoundsOrigin:
{
}
/*!
Return yes if the receiver is in a live-resize operation.
*/
- (BOOL)inLiveResize
{
return _inLiveResize;
}
/*!
Not implemented.
A view will be sent this message before a window begins a resize operation. The
receiver might choose to simplify its drawing operations during a live resize
for speed.
Subclasses should call super.
*/
- (void)viewWillStartLiveResize
{
_inLiveResize = YES;
}
/*!
Not implemented.
A view will be sent this message after a window finishes a resize operation. The
receiver which simplified its drawing operations in viewWillStartLiveResize might
stop doing so now. Note the view might no longer be in a window, so use
[self setNeedsDisplay:YES] if a final non-simplified redraw is required.
Subclasses should call super.
*/
- (void)viewDidEndLiveResize
{
_inLiveResize = NO;
}
@end
@implementation CPView (KeyView)
@@ -2543,6 +2866,50 @@ setBoundsOrigin:
return (_themeAttributes && _themeAttributes[aName] !== undefined);
}
/*!
Registers theme values encoded in an array at runtime. The format of the data in the array
is the same as that used by ThemeDescriptors.j, with the exception that you need to use
CPColorWithImages() in place of PatternColor(). For more information see the comments
at the top of ThemeDescriptors.j.
@param themeValues array of theme values
*/
- (void)registerThemeValues:(CPArray)themeValues
{
for (var i = 0; i < themeValues.length; ++i)
{
var attributeValueState = themeValues[i],
attribute = attributeValueState[0],
value = attributeValueState[1],
state = attributeValueState[2];
if (state)
[self setValue:value forThemeAttribute:attribute inState:state];
else
[self setValue:value forThemeAttribute:attribute];
}
}
/*!
Registers theme values encoded in an array at runtime. The format of the data in the array
is the same as that used by ThemeDescriptors.j, with the exception that you need to use
CPColorWithImages() in place of PatternColor(). The values in \c inheritedValues are
registered first, then those in \c themeValues override/augment the inherited values.
For more information see the comments at the top of ThemeDescriptors.j.
@param themeValues array of base theme values
@param inheritedValues array of overridden/additional theme values
*/
- (void)registerThemeValues:(CPArray)themeValues inherit:(CPArray)inheritedValues
{
// Register inherited values first, then override those with the subtheme values.
if (inheritedValues)
[self registerThemeValues:inheritedValues];
if (themeValues)
[self registerThemeValues:themeValues];
}
- (CPView)createEphemeralSubviewNamed:(CPString)aViewName
{
return nil;
@@ -2607,6 +2974,7 @@ var CPViewAutoresizingMaskKey = @"CPViewAutoresizingMask",
CPViewBoundsKey = @"CPViewBoundsKey",
CPViewFrameKey = @"CPViewFrameKey",
CPViewHitTestsKey = @"CPViewHitTestsKey",
CPViewToolTipKey = @"CPViewToolTipKey",
CPViewIsHiddenKey = @"CPViewIsHiddenKey",
CPViewOpacityKey = @"CPViewOpacityKey",
CPViewSubviewsKey = @"CPViewSubviewsKey",
@@ -2661,7 +3029,13 @@ var CPViewAutoresizingMaskKey = @"CPViewAutoresizingMask",
_autoresizesSubviews = ![aCoder containsValueForKey:CPViewAutoresizesSubviewsKey] || [aCoder decodeBoolForKey:CPViewAutoresizesSubviewsKey];
_hitTests = ![aCoder containsValueForKey:CPViewHitTestsKey] || [aCoder decodeObjectForKey:CPViewHitTestsKey];
_hitTests = ![aCoder containsValueForKey:CPViewHitTestsKey] || [aCoder decodeBoolForKey:CPViewHitTestsKey];
[self _setupToolTipHandlers];
_toolTip = [aCoder decodeObjectForKey:CPViewToolTipKey];
if (_toolTip)
[self _installToolTipEventHandlers];
// DOM SETUP
#if PLATFORM(DOM)
@@ -2681,10 +3055,7 @@ var CPViewAutoresizingMaskKey = @"CPViewAutoresizingMask",
}
#endif
if ([aCoder containsValueForKey:CPViewIsHiddenKey])
[self setHidden:[aCoder decodeBoolForKey:CPViewIsHiddenKey]];
else
_isHidden = NO;
[self setHidden:[aCoder decodeBoolForKey:CPViewIsHiddenKey]];
if ([aCoder containsValueForKey:CPViewOpacityKey])
[self setAlphaValue:[aCoder decodeIntForKey:CPViewOpacityKey]];
@@ -2692,8 +3063,7 @@ var CPViewAutoresizingMaskKey = @"CPViewAutoresizingMask",
_opacity = 1.0;
[self setBackgroundColor:[aCoder decodeObjectForKey:CPViewBackgroundColorKey]];
[self setupViewFlags];
[self _setupViewFlags];
_theme = [CPTheme defaultTheme];
_themeClass = [aCoder decodeObjectForKey:CPViewThemeClassKey];
@@ -2774,6 +3144,9 @@ var CPViewAutoresizingMaskKey = @"CPViewAutoresizingMask",
if (_isHidden)
[aCoder encodeBool:_isHidden forKey:CPViewIsHiddenKey];
if (_toolTip)
[aCoder encodeObject:_toolTip forKey:CPViewToolTipKey];
var nextKeyView = [self nextKeyView];
if (nextKeyView !== nil && ![nextKeyView isEqual:self])
@@ -2799,7 +3172,7 @@ var _CPViewFullScreenModeStateMake = function(aView)
var superview = aView._superview;
return { autoresizingMask:aView._autoresizingMask, frame:CGRectMakeCopy(aView._frame), index:(superview ? [superview._subviews indexOfObjectIdenticalTo:aView] : 0), superview:superview };
}
};
var _CPViewGetTransform = function(/*CPView*/ fromView, /*CPView */ toView)
{
@@ -2896,4 +3269,4 @@ var _CPViewGetTransform = function(/*CPView*/ fromView, /*CPView */ toView)
}*/
return transform;
}
};
+1
View File
@@ -22,6 +22,7 @@
@import "CPAnimation.j"
@class CPWindow
CPViewAnimationTargetKey = @"CPViewAnimationTargetKey";
CPViewAnimationStartFrameKey = @"CPViewAnimationStartFrameKey";

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