Compare commits

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Two class methods have been added:

CPWindow +setConstrainWindowsToUsableScreen:
CPWindow +constrainWindowsToUsableScreen

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

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

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

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

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

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

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

setDidEndSelector:
runModalWithDidEndBlock:
beginSheetModalForWindow:didEndBlock:

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

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

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

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

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

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

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

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

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

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

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

This fix makes the same true in Objective-J.

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

Now xibs and images may be anywhere under Resources.

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

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

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

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

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

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

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

This fix makes CPCibWindowTemplate act similar to CPCibCustomView when the referenced class can't be found: it instantiates a regular CPWindow. This is sufficient for flatten's purposes.
2013-07-02 17:16:55 +01:00
Antoine Mercadal 93c27625b9 NEW: Added some themable attributes for CPPopover
The following theme attributes has been added
 - border-radius
 - stroke-width
 - shadow-size
 - shadow-blur
2013-06-28 17:48:32 -07:00
Alexander Ljungberg 6ef776e488 Fixed: - CPView nextValidKeyView infinite loop.
Previously, certain situations could easily lead to an infinite loop in - CPView nextValidKeyView. For instance, opening a sheet view with no responder returning YES for canBecomeKeyView would freeze Cappuccino.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Fixes #1913

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

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

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

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

Now all output from nib2cib is correctly captured.

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

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

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

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

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

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

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

This fix uses the browser provided language string fully to select the appropriate locale.
2013-05-14 13:03:31 -07:00
Alexander Ljungberg 2a9f3deb0e Merge pull request #1930 from mrcarlberg/cplocal_cant_handle_unknown_country_codes
Fixed: CPLocal can't handle unknown language codes
2013-05-14 12:00:39 -07:00
Alexander Ljungberg 89e81e97d1 Merge branch 'master' of github.com:cappuccino/cappuccino 2013-05-14 11:59:29 -07:00
Alexander Ljungberg b4fb4ba941 Formatting: CPLocale.
Tabs to spaces and other whitespace changes.
2013-05-14 11:59:17 -07:00
Aparajita Fishman eb859d42a4 Fixed: framework image names without @framework would cause nib2cib to fail.
I wasn't properly handling the case where _resourcePathForName would be called with a nil framework.
2013-05-14 07:54:08 -04:00
Martin Carlberg 9d86391bdb Fixed: CPLocal can't handle unknown language codes
When the language code is not known it still sets the current language code
to the unknown code instead of the defualt 'en_US' code.
This makes the test cases for CPDateFormatter fail when run on a foreign system.
2013-05-14 13:30:30 +02:00
Martin Carlberg 9b709b85a9 New: Added test cases for some preprocess directives in OutputTest.j
Also fixed so OutputTest.j now uses the new compiler instead of the old.
2013-05-14 10:31:29 +02:00
Alexander Ljungberg 9bde63923c Formatting: CPPredicateTest.
Refs #1914.
2013-05-13 22:27:39 -07:00
Alexander Ljungberg d7c676893d Merge pull request #1914 from mrcarlberg/predicate_expression_equals_nil
CPExpression and CPPredicate can't handle nil as argument in method isEqual:
2013-05-13 22:21:05 -07:00
Alexander Ljungberg 8bc8ae4e3b Merge pull request #1928 from mrcarlberg/ie_negative_width_height_crash
Fixed: IE8/9 (maybe 10 too) can't handle negative width or height.
2013-05-13 22:17:18 -07:00
Alexander Ljungberg 35b4e8f653 Merge pull request #1915 from Dogild/PopUpListComboBox
Fixed: CPComboBox popupList should close if mouse is clicked outside
2013-05-13 21:56:28 -07:00
Martin Carlberg 7837277cbe Merge branch 'master' of https://github.com/cappuccino/cappuccino into preprocess 2013-05-13 16:38:39 +02:00
Martin Carlberg 8145df9613 Fixed: Removed all uses of preprocess macros in the compiler 2013-05-13 16:23:12 +02:00
Martin Carlberg 9ffa184056 Fixed: IE8/9 can't handle negative style width or height.
Functions are used everywhere to set width or height in the DOM except in the method lockFocus. This will cause IE8/9 to report error if the width or height is negative in this method.
2013-05-13 15:12:59 +02:00
Martin Carlberg ee9b04944a Merge branch 'master' of https://github.com/cappuccino/cappuccino into preprocess 2013-05-06 16:24:54 +02:00
Martin Carlberg e9ca7c7395 Fixed: IE8 Browser support.
The compiler can now run in IE8. Also found the use of the function .indexOf on Arrays in CPView.j.
It is not supported in IE8.

Added a new file (OldBrowserCompatibility.js) in the Objective-J framework that will add functions if they are not supported in the javascript runtime.
2013-05-06 16:17:09 +02:00
Alexandre Wilhelm 736dffa334 capp_lint 2013-04-25 17:06:52 -07:00
Alexandre Wilhelm afdad97aad Added CPComboBox Aristo2 style 2013-04-24 17:47:30 -07:00
Alexandre Wilhelm 7e27de8a1e Updated slices 2013-04-24 17:46:53 -07:00
Martin Carlberg 14ee789df4 Fixed: Mark correct column position in 'Expected a Semicolon' errors in the parser. 2013-04-24 10:12:42 +02:00
Martin Carlberg b6fd6a15f0 Fixed: Removed extra spaces in code generation between 'else' and 'if' in 'else if' statements 2013-04-23 17:07:26 +02:00
Martin Carlberg e35bfaf96c Fixed: Better looking code generation with correct indentation for 'if' - 'else if' statements 2013-04-23 15:48:25 +02:00
Martin Carlberg ffdee8c3d7 Fixed: Method isEqual: can handle nil as an argument for CPExpression and CPPredicate including sub classes. 2013-04-23 12:58:07 +02:00
Martin Carlberg 8a94c33a64 New: Added test cases checking that a CPObject, CPExpression and CPPredicate is not equal nil.
CPExpression and CPPredicate can't handle nil as an argument to method isEqual:. These test cases checks that this is working.
2013-04-23 12:54:26 +02:00
Martin Carlberg 689ab09555 New: Now supports 'defined' operator, which lets you check whether macros are defined in the middle of an ‘#if’.
Also the evaluation of expressions are now lazy.
2013-04-11 09:37:40 +02:00
Martin Carlberg 30ee1ad8cd New: Handles line continue token '\' on lines starting with '#'
We now support lines like this:
#define StopButtonTitle() \
        CPLocalizedString(@"Stop", @"Stop button title")
2013-04-11 09:32:41 +02:00
Andrew Hankinson 6ef5b46dd6 Fixed: CPTokenField sends focus and blur notifications
This commit adds notifications for focus and blur on CPTokenField.

Attached is a modified Manual CPTokenFieldTest that observes these notifications.

Fixes #1396
2013-04-07 20:50:50 -04:00
Martin Carlberg 84df301f3e New: #if macro statement works for simple literals but not for macro identifiers and defined keyword 2013-03-28 22:43:26 +01:00
Andrew Hankinson 792a72af74 Fixed: Themed text values set via a single variable
Previously, the themed text values for controls were set directly on the control, which made modifying the theme values for text consistently across the controls difficult.

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

This commit negates the text-shadow offset so that the text appears correctly.
2013-03-26 23:17:23 -04:00
Andrew Hankinson bf29a4faa9 Defined file-level variables for text colors
This commit defines file-level variables for the disabled text colour, the disabled text shadow colour, and the placeholder text colour. It also adds or replaces these values in the controls where appropriate.
2013-03-26 23:14:57 -04:00
Andrew Hankinson 615380a70c Standardizing disabled text theming for popup and pulldown buttons 2013-03-26 22:46:49 -04:00
Andrew Hankinson 20a2b2d330 Fixed: circular slider disabled image uses CSS opacity 2013-03-26 20:23:38 -04:00
Andrew Hankinson d50439161a Fixed: Combo box disabled state dims text
Previously, setting a CPComboBox to disabled would not dim the text. This commit fixes the theme state to include a setting for the text colour and text shadow colour.
2013-03-26 19:19:03 -04:00
Andrew Hankinson 7d6cdf1b7b Updated pulldown button disabled images
These updated images have an outer stroke opacity of 20%, compared to 35% for the active images
2013-03-26 19:01:08 -04:00
Andrew Hankinson abcb60ed4c Updated popup button disabled images
These updated images have an outer stroke opacity of 20%, compared to 35% for the active images
2013-03-26 19:00:52 -04:00
Andrew Hankinson 443b6ff4f9 Updated combo box disabled images
These updated images have an outer stroke opacity of 20%, compared to 35% for the active images
2013-03-26 19:00:14 -04:00
Andrew Hankinson de89eadcf2 Formatting and whitespace 2013-03-26 18:40:22 -04:00
Andrew Hankinson 4956218b10 Fixed: Change default disabled opacity
Previously some disabled controls would be set with an opacity of 0.35, which resulted in controls that were visually too light.

This commit changes the default disabled opacity to 0.5.

Refs #1788
2013-03-26 17:44:57 -04:00
Andrew Hankinson bcfaf3a37e Fix Pulldown Button disabled images
The new images are set at full opacity with the blue highlight colour removed
2013-03-26 17:43:02 -04:00
Andrew Hankinson b1c45e579a Fix CPPopupButton disabled images
The new images are set at full opacity with the blue highlight colour removed
2013-03-26 17:42:41 -04:00
Andrew Hankinson e627f60b16 Fix CPComboBox disabled images
The new images are set at full opacity with the blue highlight colour removed
2013-03-26 17:42:05 -04:00
Andrew Hankinson a368fe5825 Fix disabled theme for Aristo2 segmented controls
Disabled state is now set via CSS opacity alone
2013-03-26 13:39:46 -04:00
Andrew Hankinson 895a128ff7 Fix disabled theme for Aristo2 radio buttons
Disabled state is now set via CSS opacity alone
2013-03-26 13:33:55 -04:00
Andrew Hankinson 792a4dda7f Merge branch 'fix-theme-disabled-controls' of github.com:ahankinson/cappuccino into fix-theme-disabled-controls 2013-03-26 13:29:56 -04:00
Andrew Hankinson 4d828a01aa Fix disabled theme for Aristo2 checkboxes
Previously the Aristo2 checkboxes used dedicated images for disabled controls.

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

This commit removes the disabled controls and allows the disabled state to be set via CSS opacity on the "regular" checkbox controls.
2013-03-26 13:23:11 -04:00
Blair Duncan 5868a4cefb added missing methods to CPDocumentController
documentForWindow
hasEditedDocuments

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

Also removed the firstEligibleExistingWindowController method from CPDocument
It did nothing but add confusion as it was not used anywhere else in the frameworks.
And it is not in cocoa.
2013-03-21 10:38:06 -04:00
Martin Carlberg 89457845f9 Fixed: Made some smaller code generation changes to get better formatted compiled code 2013-03-21 14:32:21 +01:00
Martin Carlberg 53e98521f3 Merge branch 'master' of https://github.com/cappuccino/cappuccino into preprocess 2013-03-21 12:25:47 +01:00
Martin Carlberg 1842d7127a New: The generated code will now have correct indentation. 2013-03-21 11:33:13 +01:00
Martin Carlberg ecc1e774b9 New: Added macro/identifier concatenation with the '##' operator
Example:
#define first Martin
#define second Carlberg
var first##second = 13;

Compiles to:
var MartinCarlberg = 13;

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

Compiles to:
function CGPointMake (x, y) {
  return {x: x, y: y};
}
2013-03-20 21:00:36 +01:00
Martin Carlberg fa18095538 Fixed: Does not add extra parentheses for expression operators with the same precedence 2013-03-20 20:47:27 +01:00
Martin Carlberg 92ac8569b3 New: Full support for generate code instead of copy
The new compiler can now generate code. The old way of copy and alter the source
code is still supported.
2013-03-17 21:00:24 +01:00
Martin Carlberg 0c982b0999 Fixed: An ExpressionStatement with a Send message expression can be parsed wrongly
When a statement ends without a semicolon and a Send message expression is on the next line it was wrongly parsed as a single Send message expression. It should be an ExpressionStatement with a Send message expression inside.
2013-03-17 20:52:21 +01:00
Martin Carlberg bef0ca18c6 New: New option to generate code for the objjc tool
A new option flag '-G' can be added to let the compiler generate the code instead of copy and alter it from the source code
2013-03-17 20:45:34 +01:00
Martin Carlberg 22cdbd7ec7 Merge branch 'master' of https://github.com/cappuccino/cappuccino into preprocess
Conflicts:
	Objective-J/ObjJAcornCompiler.js
	Objective-J/acorn.js
2013-03-12 11:20:56 +01:00
Martin Carlberg 362f3b890e Added first try for compiler to generate code 2013-03-12 09:22:26 +01:00
Martin Carlberg c17053f71a Removed test line 2013-02-26 08:53:12 +01:00
Martin Carlberg e8e87b3b83 Added recursive token transformer and preprocessor tokenizer 2013-02-24 22:26:27 +01:00
Martin Carlberg 340f1e3258 Made the acorn parser able to run outside of the Cappuccino world 2013-02-24 22:25:00 +01:00
Martin Carlberg 529e703ddd Merge branch 'master' of https://github.com/cappuccino/cappuccino into objj_compiler2 2013-02-24 15:45:56 +01:00
Martin Carlberg 699ef14b4e Merge with latest acorn compiler 2013-02-21 12:57:19 +01:00
Martin Carlberg 8c68854d1d Fixed local variable that is declared as a global 2013-02-19 20:25:57 +01:00
Martin Carlberg 64a38a2aef Refactored how maybe warnings is handled and prepared for new "local variable hides global variable" warning. The warning is disabled because there are to many warning in the Cappuccino frameworks right now. 2013-02-19 20:22:42 +01:00
Martin Carlberg cccfe7268b Fixed better comment 2013-02-19 17:48:16 +01:00
Martin Carlberg c03697c0a6 Fixed support for IE8 2013-02-19 17:47:34 +01:00
Martin Carlberg 32bf87c0c3 Fixed typo 2013-02-19 17:46:24 +01:00
362 changed files with 18085 additions and 4205 deletions
+1
View File
@@ -12,5 +12,6 @@ xcuserdata/
*.xCodeSupport/
*.XcodeSupport/
*XcodeSupport/
Tests/Manual/**/*.xcodeproj
*.sublime-project
*.sublime-workspace
+65 -24
View File
@@ -96,7 +96,8 @@ var bottomHeight = 71;
id _delegate @accessors(property=delegate);
id _modalDelegate;
SEL _didEndSelector;
SEL _didEndSelector @accessors(property=didEndSelector);
Function _didEndBlock;
_CPAlertThemeView _themeView @accessors(property=themeView, readonly);
CPWindow _window @accessors(property=window, readonly);
@@ -224,16 +225,15 @@ var bottomHeight = 71;
}
/*! @deprecated
*/
- (void)setWindowStyle:(int)aStyle
/*! @deprecated */
- (void)setWindowStyle:(int)style
{
CPLog.warn("DEPRECATED: setWindowStyle: is deprecated. use setTheme: instead");
[self setTheme:(aStyle === CPHUDBackgroundWindowMask) ? [CPTheme defaultHudTheme] : [CPTheme defaultTheme]];
[self setTheme:(style === CPHUDBackgroundWindowMask) ? [CPTheme defaultHudTheme] : [CPTheme defaultTheme]];
}
/*! @deprecated
*/
/*! @deprecated */
- (int)windowStyle
{
CPLog.warn("DEPRECATED: windowStyle: is deprecated. use theme instead");
@@ -242,18 +242,19 @@ var bottomHeight = 71;
/*!
set the text of the alert's message
Set the text of the alert's message.
@param aText CPString containing the text
*/
- (void)setMessageText:(CPString)aText
- (void)setMessageText:(CPString)text
{
[_messageLabel setStringValue:aText];
[_messageLabel setStringValue:text];
_needsLayout = YES;
}
/*!
return the content of the message text
Return the content of the message text.
@return CPString containing the message text
*/
- (CPString)messageText
@@ -262,13 +263,13 @@ var bottomHeight = 71;
}
/*!
set the text of the alert's informative text
Set the text of the alert's informative text.
@param aText CPString containing the informative text
*/
- (void)setInformativeText:(CPString)aText
- (void)setInformativeText:(CPString)text
{
[_informativeLabel setStringValue:aText];
[_informativeLabel setStringValue:text];
_needsLayout = YES;
}
@@ -285,6 +286,7 @@ var bottomHeight = 71;
/*!
Sets the title of the alert window.
This API is not present in Cocoa.
@param aTitle CPString containing the window title
*/
- (void)setTitle:(CPString)aTitle
@@ -294,7 +296,7 @@ var bottomHeight = 71;
}
/*!
set the accessory view
Set the accessory view.
@param aView the accessory view
*/
@@ -305,7 +307,7 @@ var bottomHeight = 71;
}
/*!
set if alert shows the suppression button
Set if the alert shows the suppression button.
@param shouldShowSuppressionButton YES or NO
*/
@@ -596,6 +598,17 @@ var bottomHeight = 71;
[CPApp runModalForWindow:_window];
}
/*!
The same as \c runModal, but executes the code in \c block when the
alert is dismissed.
*/
- (void)runModalWithDidEndBlock:(Function /*(CPAlert alert, int returnCode)*/)block
{
_didEndBlock = block;
[self runModal];
}
/*!
Runs the receiver modally as an alert sheet attached to a specified window.
@@ -630,6 +643,20 @@ var bottomHeight = 71;
[self beginSheetModalForWindow:aWindow modalDelegate:nil didEndSelector:nil contextInfo:nil];
}
/*!
Runs the receiver modally as an alert sheet attached to a specified window.
Executes the code in \c block when the alert is dismissed.
@param window The parent window for the sheet.
@param block Code block to execute on dismissal
*/
- (void)beginSheetModalForWindow:(CPWindow)aWindow didEndBlock:(Function /*(CPAlert alert, int returnCode)*/)block
{
_didEndBlock = block;
[self beginSheetModalForWindow:aWindow modalDelegate:nil didEndSelector:nil contextInfo:nil];
}
#pragma mark Private
/*!
@@ -697,14 +724,28 @@ var bottomHeight = 71;
*/
- (void)_alertDidEnd:(CPWindow)aWindow returnCode:(int)returnCode contextInfo:(id)contextInfo
{
if (_didEndSelector)
objj_msgSend(_modalDelegate, _didEndSelector, self, returnCode, contextInfo);
if (_didEndBlock)
{
if (typeof(_didEndBlock) === "function")
_didEndBlock(self, returnCode);
else
CPLog.warn("%s: didEnd block is not a function", [self description]);
_modalDelegate = nil;
_didEndSelector = nil;
if ([_delegate respondsToSelector:@selector(alertDidEnd:returnCode:)])
[_delegate alertDidEnd:self returnCode:returnCode];
// didEnd blocks are transient
_didEndBlock = nil;
}
else if (_modalDelegate)
{
if (_didEndSelector)
objj_msgSend(_modalDelegate, _didEndSelector, self, returnCode, contextInfo);
}
else if (_delegate)
{
if (_didEndSelector)
objj_msgSend(_delegate, _didEndSelector, self, returnCode);
else if ([_delegate respondsToSelector:@selector(alertDidEnd:returnCode:)])
[_delegate alertDidEnd:self returnCode:returnCode];
}
}
@end
@@ -716,7 +757,7 @@ var bottomHeight = 71;
return @"alert";
}
+ (id)themeAttributes
+ (CPDictionary)themeAttributes
{
return @{
@"size": CGSizeMake(400.0, 110.0),
+3 -1
View File
@@ -236,7 +236,9 @@ ACTUAL_FRAME_RATE = 0;
ACTUAL_FRAME_RATE = 0;
_lastTime = new Date();
_timer = [CPTimer scheduledTimerWithTimeInterval:0.0 target:self selector:@selector(animationTimerDidFire:) userInfo:nil repeats:YES];
var timerInterval = _frameRate <= 0.0 ? 0.0001 : 1.0/_frameRate;
_timer = [CPTimer scheduledTimerWithTimeInterval:timerInterval target:self selector:@selector(animationTimerDidFire:) userInfo:nil repeats:YES];
}
/*
+9 -48
View File
@@ -22,6 +22,7 @@
@import <Foundation/CPBundle.j>
@import "CPApplication_Constants.j"
@import "CPCompatibility.j"
@import "CPColorPanel.j"
@import "CPCursor.j"
@@ -40,24 +41,6 @@ var CPMainCibFile = @"CPMainCibFile",
CPMainCibFileHumanFriendly = @"Main cib file base name",
CPEventModifierFlags = 0;
CPApp = nil;
CPApplicationWillFinishLaunchingNotification = @"CPApplicationWillFinishLaunchingNotification";
CPApplicationDidFinishLaunchingNotification = @"CPApplicationDidFinishLaunchingNotification";
CPApplicationWillTerminateNotification = @"CPApplicationWillTerminateNotification";
CPApplicationWillBecomeActiveNotification = @"CPApplicationWillBecomeActiveNotification";
CPApplicationDidBecomeActiveNotification = @"CPApplicationDidBecomeActiveNotification";
CPApplicationWillResignActiveNotification = @"CPApplicationWillResignActiveNotification";
CPApplicationDidResignActiveNotification = @"CPApplicationDidResignActiveNotification";
CPTerminateNow = YES;
CPTerminateCancel = NO;
CPTerminateLater = -1; // not currently supported
CPRunStoppedResponse = -1000;
CPRunAbortedResponse = -1001;
CPRunContinuesResponse = -1002;
/*!
@ingroup appkit
@class CPApplication
@@ -174,7 +157,8 @@ CPRunContinuesResponse = -1002;
CPApplicationDidBecomeActiveNotification, @selector(applicationDidBecomeActive:),
CPApplicationWillResignActiveNotification, @selector(applicationWillResignActive:),
CPApplicationDidResignActiveNotification, @selector(applicationDidResignActive:),
CPApplicationWillTerminateNotification, @selector(applicationWillTerminate:)
CPApplicationWillTerminateNotification, @selector(applicationWillTerminate:),
CPApplicationDidChangeScreenParametersNotification, @selector(applicationDidChangeScreenParameters:)
],
count = [delegateNotifications count];
@@ -587,8 +571,8 @@ CPRunContinuesResponse = -1002;
/* @ignore */
- (BOOL)_handleKeyEquivalent:(CPEvent)anEvent
{
return [[self keyWindow] performKeyEquivalent:anEvent] ||
[[self mainMenu] performKeyEquivalent:anEvent];
return [[self keyWindow] performKeyEquivalent:anEvent] ||
[[self mainMenu] performKeyEquivalent:anEvent];
}
/*!
@@ -602,33 +586,10 @@ CPRunContinuesResponse = -1002;
var theWindow = [anEvent window];
#if PLATFORM(DOM)
var willPropagate = [[theWindow platformWindow] _willPropagateCurrentDOMEvent];
// temporarily pretend we won't propagate the event. we'll restore the saved value later
// we do this outside the if so that changes user code might make in _handleKeyEquiv. are preserved
[[theWindow platformWindow] _propagateCurrentDOMEvent:NO];
#endif
// Check if this is a candidate for key equivalent...
if ([anEvent _couldBeKeyEquivalent] && [self _handleKeyEquivalent:anEvent])
{
#if PLATFORM(DOM)
var characters = [anEvent characters],
modifierFlags = [anEvent modifierFlags];
// Unconditionally propagate on these keys to solve browser copy paste bugs
if ((characters == "c" || characters == "x" || characters == "v") && (modifierFlags & CPPlatformActionKeyMask))
[[theWindow platformWindow] _propagateCurrentDOMEvent:YES];
#endif
// The key equivalent was handled.
return;
}
#if PLATFORM(DOM)
// if we make it this far, then restore the original willPropagate value
[[theWindow platformWindow] _propagateCurrentDOMEvent:willPropagate];
#endif
if ([anEvent type] == CPMouseMoved)
{
@@ -1381,8 +1342,8 @@ var _CPAppBootstrapperActions = nil;
if (mainCibFile)
{
[mainBundle loadCibFile:mainCibFile
externalNameTable:@{ CPCibOwner: CPApp }
loadDelegate:self];
externalNameTable:@{ CPCibOwner: CPApp }
loadDelegate:self];
return YES;
}
@@ -1459,7 +1420,7 @@ var _CPAppBootstrapperActions = nil;
+ (void)cibDidFailToLoad:(CPCib)aCib
{
throw new Error("Could not load main cib file (Did you forget to nib2cib it?).");
throw new Error("Could not load main cib file. Did you forget to nib2cib it?");
}
+ (void)reset
+40
View File
@@ -0,0 +1,40 @@
/*
* CPApplication_Constants.j
* AppKit
*
* Created by Aparajita Fishman.
* Copyright 2013 The Cappuccino Project
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
CPApp = nil;
CPApplicationWillFinishLaunchingNotification = @"CPApplicationWillFinishLaunchingNotification";
CPApplicationDidFinishLaunchingNotification = @"CPApplicationDidFinishLaunchingNotification";
CPApplicationWillTerminateNotification = @"CPApplicationWillTerminateNotification";
CPApplicationWillBecomeActiveNotification = @"CPApplicationWillBecomeActiveNotification";
CPApplicationDidBecomeActiveNotification = @"CPApplicationDidBecomeActiveNotification";
CPApplicationWillResignActiveNotification = @"CPApplicationWillResignActiveNotification";
CPApplicationDidResignActiveNotification = @"CPApplicationDidResignActiveNotification";
CPApplicationDidChangeScreenParametersNotification = @"CPApplicationDidChangeScreenParametersNotification";
CPTerminateNow = YES;
CPTerminateCancel = NO;
CPTerminateLater = -1; // not currently supported
CPRunStoppedResponse = -1000;
CPRunAbortedResponse = -1001;
CPRunContinuesResponse = -1002;
+2
View File
@@ -147,6 +147,8 @@ var DefaultLineWidth = 1.0;
{
_path = CGPathCreateMutable();
_lineWidth = [[self class] defaultLineWidth];
_lineDashesPhase = 0;
_lineDashes = [];
}
return self;
+1 -1
View File
@@ -76,7 +76,7 @@ CPBelowBottom = 6;
return @"box";
}
+ (id)themeAttributes
+ (CPDictionary)themeAttributes
{
return @{
@"background-color": [CPNull null],
+14 -14
View File
@@ -71,7 +71,7 @@
return "browser";
}
+ (id)themeAttributes
+ (CPDictionary)themeAttributes
{
return @{
@"image-control-resize": [CPNull null],
@@ -171,7 +171,7 @@
[self addColumn];
}
- (void)setLastColumn:(int)columnIndex
- (void)setLastColumn:(CPInteger)columnIndex
{
if (columnIndex >= _tableViews.length)
return;
@@ -181,7 +181,7 @@
if (columnIndex > 0)
[_tableViews[columnIndex - 1] setNeedsDisplay:YES];
[_tableViews[columnIndex] setNeedsDisplay:YES];
[[_tableViews.slice(indexPlusOne) valueForKey:"enclosingScrollView"]
@@ -291,7 +291,7 @@
[aTableView addTableColumn:column];
}
- (void)reloadColumn:(int)column
- (void)reloadColumn:(CPInteger)column
{
[[self tableViewInColumn:column] reloadData];
}
@@ -359,7 +359,7 @@
// ITEMS
- (id)itemAtRow:(int)row inColumn:(int)column
- (id)itemAtRow:(CPInteger)row inColumn:(CPInteger)column
{
return [_tableDelegates[column] childAtIndex:row];
}
@@ -369,7 +369,7 @@
return [_delegate respondsToSelector:@selector(browser:isLeafItem:)] && [_delegate browser:self isLeafItem:item];
}
- (id)parentForItemsInColumn:(int)column
- (id)parentForItemsInColumn:(CPInteger)column
{
return [_tableDelegates[column] _item];
}
@@ -652,7 +652,7 @@
[_tableViews makeObjectsPerformSelector:@selector(registerForDraggedTypes:) withObject:types];
}
- (BOOL)canDragRowsWithIndexes:(CPIndexSet)rowIndexes inColumn:(int)columnIndex withEvent:(CPEvent)dragEvent
- (BOOL)canDragRowsWithIndexes:(CPIndexSet)rowIndexes inColumn:(CPInteger)columnIndex withEvent:(CPEvent)dragEvent
{
if ([_delegate respondsToSelector:@selector(browser:canDragRowsWithIndexes:inColumn:withEvent:)])
return [_delegate browser:self canDragRowsWithIndexes:rowIndexes inColumn:columnIndex withEvent:dragEvent];
@@ -660,7 +660,7 @@
return YES;
}
- (CPImage)draggingImageForRowsWithIndexes:(CPIndexSet)rowIndexes inColumn:(int)columnIndex withEvent:(CPEvent)dragEvent offset:(CGPoint)dragImageOffset
- (CPImage)draggingImageForRowsWithIndexes:(CPIndexSet)rowIndexes inColumn:(CPInteger)columnIndex withEvent:(CPEvent)dragEvent offset:(CGPoint)dragImageOffset
{
if ([_delegate respondsToSelector:@selector(browser:draggingImageForRowsWithIndexes:inColumn:withEvent:offset:)])
return [_delegate browser:self draggingImageForRowsWithIndexes:rowIndexes inColumn:columnIndex withEvent:dragEvent offset:dragImageOffset];
@@ -668,7 +668,7 @@
return nil;
}
- (CPView)draggingViewForRowsWithIndexes:(CPIndexSet)rowIndexes inColumn:(int)columnIndex withEvent:(CPEvent)dragEvent offset:(CGPoint)dragImageOffset
- (CPView)draggingViewForRowsWithIndexes:(CPIndexSet)rowIndexes inColumn:(CPInteger)columnIndex withEvent:(CPEvent)dragEvent offset:(CGPoint)dragImageOffset
{
if ([_delegate respondsToSelector:@selector(browser:draggingViewForRowsWithIndexes:inColumn:withEvent:offset:)])
return [_delegate browser:self draggingViewForRowsWithIndexes:rowIndexes inColumn:columnIndex withEvent:dragEvent offset:dragImageOffset];
@@ -771,7 +771,7 @@
CPBrowser _browser @accessors;
}
- (void)initWithFrame:(CGRect)aFrame
- (id)initWithFrame:(CGRect)aFrame
{
if (self = [super initWithFrame:aFrame])
{
@@ -902,12 +902,12 @@
[_browser selectRowIndexes:selectedIndexes inColumn:_index];
}
- (id)childAtIndex:(unsigned)index
- (id)childAtIndex:(CPUInteger)index
{
return [_delegate browser:_browser child:index ofItem:_item];
}
- (BOOL)tableView:(CPTableView)aTableView acceptDrop:(id)info row:(int)row dropOperation:(CPTableViewDropOperation)operation
- (BOOL)tableView:(CPTableView)aTableView acceptDrop:(id)info row:(CPInteger)row dropOperation:(CPTableViewDropOperation)operation
{
if ([_delegate respondsToSelector:@selector(browser:acceptDrop:atRow:column:dropOperation:)])
return [_delegate browser:_browser acceptDrop:info atRow:row column:_index dropOperation:operation];
@@ -915,7 +915,7 @@
return NO;
}
- (CPDragOperation)tableView:(CPTableView)aTableView validateDrop:(id)info proposedRow:(int)row proposedDropOperation:(CPTableViewDropOperation)operation
- (CPDragOperation)tableView:(CPTableView)aTableView validateDrop:(id)info proposedRow:(CPInteger)row proposedDropOperation:(CPTableViewDropOperation)operation
{
if ([_delegate respondsToSelector:@selector(browser:validateDrop:proposedRow:column:dropOperation:)])
return [_delegate browser:_browser validateDrop:info proposedRow:row column:_index dropOperation:operation];
@@ -995,7 +995,7 @@
[aCoder encodeObject:_highlightedBranchImage forKey:"_CPBrowserLeafViewHighlightedBranchImageKey"];
}
- (void)initWithCoder:(CPCoder)aCoder
- (id)initWithCoder:(CPCoder)aCoder
{
if (self = [super initWithCoder:aCoder])
{
+35 -26
View File
@@ -149,7 +149,7 @@ CPButtonImageOffset = 3.0;
return @"button";
}
+ (id)themeAttributes
+ (CPDictionary)themeAttributes
{
return @{
@"image": [CPNull null],
@@ -292,7 +292,7 @@ CPButtonImageOffset = 3.0;
}
/*!
Sets the button's next state to \c aState.
Sets the button's state to the next available state.
@param aState Possible states are any of the CPButton globals:
\c CPOffState, \c CPOnState, \c CPMixedState
*/
@@ -448,38 +448,47 @@ CPButtonImageOffset = 3.0;
{
switch (aButtonType)
{
case CPMomentaryLightButton: [self setHighlightsBy:CPChangeGrayCellMask | CPChangeBackgroundCellMask];
[self setShowsStateBy:CPNoCellMask];
break;
case CPMomentaryLightButton:
[self setHighlightsBy:CPChangeGrayCellMask | CPChangeBackgroundCellMask];
[self setShowsStateBy:CPNoCellMask];
break;
case CPMomentaryPushInButton: [self setHighlightsBy:CPPushInCellMask | CPChangeGrayCellMask | CPChangeBackgroundCellMask];
[self setShowsStateBy:CPNoCellMask];
break;
case CPMomentaryPushInButton:
[self setHighlightsBy:CPPushInCellMask | CPChangeGrayCellMask | CPChangeBackgroundCellMask];
[self setShowsStateBy:CPNoCellMask];
break;
case CPMomentaryChangeButton: [self setHighlightsBy:CPContentsCellMask];
[self setShowsStateBy:CPNoCellMask];
break;
case CPMomentaryChangeButton:
[self setHighlightsBy:CPContentsCellMask];
[self setShowsStateBy:CPNoCellMask];
break;
case CPPushOnPushOffButton: [self setHighlightsBy:CPPushInCellMask | CPChangeGrayCellMask | CPChangeBackgroundCellMask];
[self setShowsStateBy:CPChangeBackgroundCellMask | CPChangeGrayCellMask];
break;
case CPPushOnPushOffButton:
[self setHighlightsBy:CPPushInCellMask | CPChangeGrayCellMask | CPChangeBackgroundCellMask];
[self setShowsStateBy:CPChangeBackgroundCellMask | CPChangeGrayCellMask];
break;
case CPOnOffButton: [self setHighlightsBy:CPChangeGrayCellMask | CPChangeBackgroundCellMask];
[self setShowsStateBy:CPChangeGrayCellMask | CPChangeBackgroundCellMask];
break;
case CPOnOffButton:
[self setHighlightsBy:CPChangeGrayCellMask | CPChangeBackgroundCellMask];
[self setShowsStateBy:CPChangeGrayCellMask | CPChangeBackgroundCellMask];
break;
case CPToggleButton: [self setHighlightsBy:CPPushInCellMask | CPContentsCellMask];
[self setShowsStateBy:CPContentsCellMask];
break;
case CPToggleButton:
[self setHighlightsBy:CPPushInCellMask | CPContentsCellMask];
[self setShowsStateBy:CPContentsCellMask];
break;
case CPSwitchButton: [CPException raise:CPInvalidArgumentException
reason:"The CPSwitchButton type is not supported in Cappuccino, use the CPCheckBox class instead."];
case CPSwitchButton:
[CPException raise:CPInvalidArgumentException
reason:"The CPSwitchButton type is not supported in Cappuccino, use the CPCheckBox class instead."];
case CPRadioButton: [CPException raise:CPInvalidArgumentException
reason:"The CPRadioButton type is not supported in Cappuccino, use the CPRadio class instead."];
case CPRadioButton:
[CPException raise:CPInvalidArgumentException
reason:"The CPRadioButton type is not supported in Cappuccino, use the CPRadio class instead."];
default: [CPException raise:CPInvalidArgumentException
reason:"Unknown button type."];
default:
[CPException raise:CPInvalidArgumentException
reason:"Unknown button type."];
}
[self setImageDimsWhenDisabled:YES];
+1 -1
View File
@@ -79,7 +79,7 @@
return @"button-bar";
}
+ (id)themeAttributes
+ (CPDictionary)themeAttributes
{
return @{
@"resize-control-inset": CGInsetMake(0.0, 0.0, 0.0, 0.0),
+10 -6
View File
@@ -455,12 +455,12 @@ var HORIZONTAL_MARGIN = 2;
[self tileIfNeeded:NO];
}
- (void)resizeSubviewsWithOldSize:(CPSize)oldBoundsSize
- (void)resizeSubviewsWithOldSize:(CGSize)oldBoundsSize
{
// Desactivate subviews autoresizing
}
- (void)resizeWithOldSuperviewSize:(CPSize)oldBoundsSize
- (void)resizeWithOldSuperviewSize:(CGSize)oldBoundsSize
{
if (_lockResizing)
return;
@@ -784,6 +784,10 @@ var HORIZONTAL_MARGIN = 2;
var firstSelectedIndex = [[self selectionIndexes] firstIndex],
newSelectedRange = nil;
// This catches the case where the shift key is held down for the first selection.
if (firstSelectedIndex === CPNotFound)
firstSelectedIndex = index;
if (index < firstSelectedIndex)
newSelectedRange = CPMakeRange(index, (firstSelectedIndex - index) + 1);
else
@@ -826,7 +830,7 @@ var HORIZONTAL_MARGIN = 2;
[self tile];
}
- (void)setUniformSubviewsResizing:(float)flag
- (void)setUniformSubviewsResizing:(BOOL)flag
{
_uniformSubviewsResizing = flag;
[self tileIfNeeded:NO];
@@ -888,12 +892,12 @@ var HORIZONTAL_MARGIN = 2;
return CPNotFound;
}
- (CPCollectionViewItem)itemAtIndex:(unsigned)anIndex
- (CPCollectionViewItem)itemAtIndex:(CPUInteger)anIndex
{
return [_items objectAtIndex:anIndex];
}
- (CGRect)frameForItemAtIndex:(unsigned)anIndex
- (CGRect)frameForItemAtIndex:(CPUInteger)anIndex
{
return [[[self itemAtIndex:anIndex] view] frame];
}
@@ -1318,7 +1322,7 @@ Not supported. Use -collectionView:dataForItemsAtIndexes:fortype:
[self interpretKeyEvents:[anEvent]];
}
- (void)setAutoresizingMask:(int)aMask
- (void)setAutoresizingMask:(unsigned)aMask
{
[super setAutoresizingMask:0];
}
+2 -2
View File
@@ -576,7 +576,7 @@ var CPColorPanelSwatchesCookie = "CPColorPanelSwatchesCookie";
[aPasteboard setData:[CPKeyedArchiver archivedDataWithRootObject:_dragColor] forType:aType];
}
- (void)performDragOperation:(id <CPDraggingInfo>)aSender
- (void)performDragOperation:(id /*<CPDraggingInfo>*/)aSender
{
var location = [self convertPoint:[aSender draggingLocation] fromView:nil],
pasteboard = [aSender draggingPasteboard],
@@ -615,7 +615,7 @@ var CPColorPanelSwatchesCookie = "CPColorPanelSwatchesCookie";
return _colorPanel;
}
- (void)performDragOperation:(id <CPDraggingInfo>)aSender
- (void)performDragOperation:(id /*<CPDraggingInfo>*/)aSender
{
var pasteboard = [aSender draggingPasteboard];
+1 -1
View File
@@ -58,7 +58,7 @@ var _CPColorWellDidBecomeExclusiveNotification = @"_CPColorWellDidBecomeExclusiv
return @"colorwell";
}
+ (id)themeAttributes
+ (CPDictionary)themeAttributes
{
return @{
@"bezel-inset": CGInsetMakeZero(),
+5 -5
View File
@@ -58,7 +58,7 @@ var CPComboBoxTextSubview = @"text",
return "combobox";
}
+ (id)themeAttributes
+ (CPDictionary)themeAttributes
{
return @{
@"popup-button-size": CGSizeMake(21.0, 29.0),
@@ -171,7 +171,7 @@ var CPComboBoxTextSubview = @"text",
#pragma mark Setting a Delegate
- (id < CPComboBoxDelegate >)delegate
- (id /*< CPComboBoxDelegate >*/)delegate
{
return [super delegate];
}
@@ -182,7 +182,7 @@ var CPComboBoxTextSubview = @"text",
protocol, in actual fact it doesn't. Also note that the same
delegate may conform to the NSTextFieldDelegate protocol.
*/
- (void)setDelegate:(id < CPComboBoxDelegate >)aDelegate
- (void)setDelegate:(id /*< CPComboBoxDelegate >*/)aDelegate
{
var delegate = [self delegate];
@@ -231,7 +231,7 @@ var CPComboBoxTextSubview = @"text",
#pragma mark Setting a Data Source
- (id < CPComboBoxDataSource >)dataSource
- (id /*< CPComboBoxDataSource >*/)dataSource
{
if (!_usesDataSource)
[self _dataSourceWarningForMethod:_cmd condition:NO];
@@ -239,7 +239,7 @@ var CPComboBoxTextSubview = @"text",
return _dataSource;
}
- (void)setDataSource:(id < CPComboBoxDataSource >)aSource
- (void)setDataSource:(id /*< CPComboBoxDataSource >*/)aSource
{
if (!_usesDataSource)
[self _dataSourceWarningForMethod:_cmd condition:NO];
+46 -4
View File
@@ -46,7 +46,9 @@ CPHTMLDragAndDropFeature = 8;
CPJavaScriptInnerTextFeature = 9;
CPJavaScriptTextContentFeature = 10;
// In onpaste, oncopy and oncut events, the event has an event.clipboardData from which the current pasteboard contents can be read with event.clipboardData.getData.
CPJavaScriptClipboardEventsFeature = 11;
// window.clipboardData exists and can be read and written to at any time using window.clipboardData.getData/setData.
CPJavaScriptClipboardAccessFeature = 12;
CPJavaScriptCanvasDrawFeature = 13;
CPJavaScriptCanvasTransformFeature = 14;
@@ -76,11 +78,19 @@ CPInputOnInputEventFeature = 30;
CPFileAPIFeature = 31;
/*
When an absolutely positioned div (CPView) with an absolutely positioned canvas in it (CPView with drawRect:) moves things on top of the canvas (subviews) don't redraw correctly. E.g. if you have a bunch of text fields in a CPBox in a sheet which animates in, some of the text fields might not be visible because the CPBox has a canvas at the bottom and the box moved form offscreen to onscreen. This bug is probably very related: https://bugs.webkit.org/show_bug.cgi?id=67203
*/
CPCanvasParentDrawErrorsOnMovementBug = 1 << 0;
// The paste event is only sent if an input or textarea has focus.
CPJavaScriptPasteRequiresEditableTarget = 1 << 1;
// Redirecting the focus of the browser on keydown to an input for Cmd-V or Ctrl-V makes the paste fail.
CPJavaScriptPasteCantRefocus = 1 << 2;
var USER_AGENT = "",
PLATFORM_ENGINE = CPUnknownBrowserEngine,
PLATFORM_FEATURES = [],
@@ -118,6 +128,9 @@ else if (typeof window !== "undefined" && window.attachEvent) // Must follow Ope
// Tested in Internet Explore 8 and 9.
PLATFORM_FEATURES[CPInputSetFontOutsideOfDOM] = NO;
// IE allows free clipboard access.
PLATFORM_FEATURES[CPJavaScriptClipboardAccessFeature] = YES;
}
// WebKit
@@ -129,11 +142,8 @@ else if (USER_AGENT.indexOf("AppleWebKit/") != -1)
PLATFORM_FEATURES[CPCSSRGBAFeature] = YES;
PLATFORM_FEATURES[CPHTMLContentEditableFeature] = YES;
if (USER_AGENT.indexOf("Chrome") === -1)
PLATFORM_FEATURES[CPHTMLDragAndDropFeature] = YES;
PLATFORM_FEATURES[CPJavaScriptClipboardEventsFeature] = YES;
PLATFORM_FEATURES[CPJavaScriptClipboardAccessFeature] = YES;
PLATFORM_FEATURES[CPJavaScriptClipboardAccessFeature] = NO;
PLATFORM_FEATURES[CPJavaScriptShadowFeature] = YES;
var versionStart = USER_AGENT.indexOf("AppleWebKit/") + "AppleWebKit/".length,
@@ -159,7 +169,14 @@ else if (USER_AGENT.indexOf("AppleWebKit/") != -1)
PLATFORM_FEATURES[CPInput1PxLeftPadding] = YES;
if (USER_AGENT.indexOf("Chrome") === CPNotFound)
{
PLATFORM_FEATURES[CPSOPDisabledFromFileURLs] = YES;
PLATFORM_FEATURES[CPHTMLDragAndDropFeature] = YES;
// https://bugs.webkit.org/show_bug.cgi?id=75891
PLATFORM_BUGS |= CPJavaScriptPasteRequiresEditableTarget;
// https://bugs.webkit.org/show_bug.cgi?id=39689
PLATFORM_BUGS |= CPJavaScriptPasteCantRefocus;
}
// Assume this bug was introduced around Safari 5.1/Chrome 16. This could probably be tighter.
if (majorVersion > 533)
@@ -190,6 +207,17 @@ else if (USER_AGENT.indexOf("Gecko") !== -1) // Must follow KHTML check.
// Some day this might be fixed and should be version prefixed. No known fixed version yet.
PLATFORM_FEATURES[CPInput1PxLeftPadding] = YES;
// This was supposed to be added in Firefox 22, but when testing with the latest beta as of 2013-06-14
// it does not seem to work. It seems to exhibit the CPJavaScriptPasteRequiresEditableTarget problem,
// and in addition doesn't seem to work with our native copy code either.
/*if (version >= 22.0)
{
PLATFORM_FEATURES[CPJavaScriptClipboardEventsFeature] = YES;
// TODO File a bug at https://bugzilla.mozilla.org/. In other browsers, one can return "false" from the
// beforepaste event to indicate a paste should be enabled even that the DOMEvent.target is not editable.
PLATFORM_BUGS |= CPJavaScriptPasteRequiresEditableTarget;
}*/
}
// Feature-specific checks
@@ -323,6 +351,20 @@ function CPBrowserStyleProperty(aProperty)
r = candidates[PLATFORM_STYLE_JS_PROPERTIES['transition']] || nil;
break;
case 'transformorigin':
var candidates = {
'WebkitTransform' : 'WebkitTransformOrigin',
'MozTransform' : 'MozTransformOrigin',
'OTransform' : 'OTransformOrigin',
'msTransform' : 'MSTransformOrigin',
'transform' : 'transformOrigin'
};
r = candidates[PLATFORM_STYLE_JS_PROPERTIES['transform']] || nil;
break;
default:
var prefixes = ["Webkit", "Moz", "O", "ms"],
strippedProperty = aProperty.split('-').join(' '),
+49 -7
View File
@@ -322,11 +322,11 @@ var CPControlBlackColor = [CPColor blackColor];
_previousTrackingLocation = currentLocation;
}
- (void)setState:(int)state
- (void)setState:(CPInteger)state
{
}
- (int)nextState
- (CPInteger)nextState
{
return 0;
}
@@ -530,7 +530,7 @@ var CPControlBlackColor = [CPColor blackColor];
return formattedValue;
}
return (_value === undefined || _value === nil) ? "" : String(_value);
return (_value === undefined || _value === nil) ? @"" : String(_value);
}
/*!
@@ -607,7 +607,7 @@ var CPControlBlackColor = [CPColor blackColor];
if ([note object] != self)
return;
[[CPNotificationCenter defaultCenter] postNotificationName:CPControlTextDidBeginEditingNotification object:self userInfo:@{ "CPFieldEditor": [note object] }];
[[CPNotificationCenter defaultCenter] postNotificationName:CPControlTextDidBeginEditingNotification object:self userInfo:@{"CPFieldEditor": [note object]}];
}
- (void)textDidChange:(CPNotification)note
@@ -616,7 +616,7 @@ var CPControlBlackColor = [CPColor blackColor];
if ([note object] != self)
return;
[[CPNotificationCenter defaultCenter] postNotificationName:CPControlTextDidChangeNotification object:self userInfo:@{ "CPFieldEditor": [note object] }];
[[CPNotificationCenter defaultCenter] postNotificationName:CPControlTextDidChangeNotification object:self userInfo:@{"CPFieldEditor": [note object]}];
}
- (void)textDidEndEditing:(CPNotification)note
@@ -627,7 +627,49 @@ var CPControlBlackColor = [CPColor blackColor];
[self _reverseSetBinding];
[[CPNotificationCenter defaultCenter] postNotificationName:CPControlTextDidEndEditingNotification object:self userInfo:@{ "CPFieldEditor": [note object] }];
[[CPNotificationCenter defaultCenter] postNotificationName:CPControlTextDidEndEditingNotification object:self userInfo:[note userInfo]];
}
/*!
@ignore
Return the currentTextMovement needed by the delegate textDidEndEditing
This is going to check the currentEvent of the CPApp
*/
- (unsigned)_currentTextMovement
{
var currentEvent = [CPApp currentEvent],
keyCode = [currentEvent keyCode],
modifierFlags = [currentEvent modifierFlags];
switch (keyCode)
{
case CPEscapeKeyCode:
return CPCancelTextMovement;
case CPLeftArrowKeyCode:
return CPLeftTextMovement;
case CPRightArrowKeyCode:
return CPRightTextMovement;
case CPUpArrowKeyCode:
return CPUpTextMovement;
case CPDownArrowKeyCode:
return CPDownTextMovement;
case CPReturnKeyCode:
return CPReturnTextMovement;
case CPTabKeyCode:
if (modifierFlags & CPShiftKeyMask)
return CPBacktabTextMovement;
return CPTabTextMovement;
default:
return CPOtherTextMovement;
}
}
/*!
@@ -813,7 +855,7 @@ var CPControlBlackColor = [CPColor blackColor];
/*!
Returns the image scaling of the control.
*/
- (CPImageScaling)imageScaling
- (CPUInteger)imageScaling
{
return [self valueForThemeAttribute:@"image-scaling"];
}
+2 -1
View File
@@ -116,7 +116,8 @@ var currentCursor = nil,
- (void)push
{
currentCursor = cursorStack.push(self);
cursorStack.push(self);
currentCursor = self;
}
- (void)set
+12 -12
View File
@@ -71,7 +71,7 @@ CPEraDatePickerElementFlag = 0x0100;
//CPCalendar _calendar @accessors(property=calendar);
CPTimeZone _timeZone @accessors(property=timeZone);
id _delegate @accessors(property=delegate);
unsigned _datePickerElements @accessors(property=datePickerElements);
CPInteger _datePickerElements @accessors(property=datePickerElements);
CPInteger _datePickerMode @accessors(property=datePickerMode);
CPInteger _datePickerStyle @accessors(property=datePickerStyle);
CPInteger _timeInterval @accessors(property=timeInterval);
@@ -90,7 +90,7 @@ CPEraDatePickerElementFlag = 0x0100;
return @"datePicker";
}
+ (id)themeAttributes
+ (CPDictionary)themeAttributes
{
return @{
@"bezel-color": [CPColor clearColor],
@@ -135,10 +135,10 @@ CPEraDatePickerElementFlag = 0x0100;
@"clock-text-shadow-color": [CPColor clearColor],
@"clock-text-shadow-offset": CGSizeMakeZero(),
@"clock-font": [CPNull null],
@"second-hand-color": [CPColor clearColor],
@"hour-hand-color": [CPColor clearColor],
@"middle-hand-color": [CPColor clearColor],
@"minute-hand-color": [CPColor clearColor],
@"second-hand-image": [CPNull null],
@"hour-hand-image": [CPNull null],
@"middle-hand-image": [CPNull null],
@"minute-hand-image": [CPNull null],
@"size-clock": CGSizeMakeZero(),
@"second-hand-size": CGSizeMakeZero(),
@"hour-hand-size": CGSizeMakeZero(),
@@ -159,7 +159,7 @@ CPEraDatePickerElementFlag = 0x0100;
return [super _binderClassForBinding:theBinding];
}
- (id)_replacementKeyPathForBinding:(CPString)aBinding
- (CPString)_replacementKeyPathForBinding:(CPString)aBinding
{
if (aBinding == CPValueBinding)
return @"dateValue";
@@ -269,7 +269,7 @@ CPEraDatePickerElementFlag = 0x0100;
/*! Return the objectValue of the datePicker. The objectValue should take the timeZoneEffect
*/
- (void)objectValue
- (id)objectValue
{
// TODO : add timeZone effect. How to do it because js ???
return _dateValue
@@ -366,7 +366,7 @@ CPEraDatePickerElementFlag = 0x0100;
/*! Set the syle of the datePicker
@param aDatePickerStyle the datePicker style
*/
- (void)setDatePickerStyle:(CPDate)aDatePickerStyle
- (void)setDatePickerStyle:(CPInteger)aDatePickerStyle
{
_datePickerStyle = aDatePickerStyle;
@@ -377,7 +377,7 @@ CPEraDatePickerElementFlag = 0x0100;
/*! Set the elements of the datePicker
@param aDatePickerElements the datePicker elements
*/
- (void)setDatePickerElements:(CPDate)aDatePickerElements
- (void)setDatePickerElements:(CPInteger)aDatePickerElements
{
_datePickerElements = aDatePickerElements;
@@ -388,7 +388,7 @@ CPEraDatePickerElementFlag = 0x0100;
/*! Set the mode of the datePicker
@param aDatePickerMode the datePicker mode
*/
- (void)setDatePickerMode:(CPDate)aDatePickerMode
- (void)setDatePickerMode:(CPInteger)aDatePickerMode
{
_datePickerMode = aDatePickerMode;
@@ -688,4 +688,4 @@ var CPDatePickerModeKey = @"CPDatePickerModeKey",
self.setMilliseconds(99);
}
@end
@end
+14 -2
View File
@@ -445,6 +445,9 @@ var CPShortWeekDayNameArrayEn = [@"Mo", @"Tu", @"We", @"Th", @"Fr", @"Sa", @"Su"
*/
- (void)layoutSubviews
{
if ([_datePicker datePickerStyle] == CPTextFieldAndStepperDatePickerStyle || [_datePicker datePickerStyle] == CPTextFieldDatePickerStyle)
return;
var bounds = [self bounds],
dayNames = [self _dayNames],
width = CGRectGetWidth(bounds),
@@ -753,6 +756,9 @@ var CPShortWeekDayNameArrayEn = [@"Mo", @"Tu", @"We", @"Th", @"Fr", @"Sa", @"Su"
*/
- (void)layoutSubviews
{
if ([_datePicker datePickerStyle] == CPTextFieldAndStepperDatePickerStyle || [_datePicker datePickerStyle] == CPTextFieldDatePickerStyle)
return;
[super layoutSubviews];
[self tile];
@@ -1053,7 +1059,7 @@ var CPShortWeekDayNameArrayEn = [@"Mo", @"Tu", @"We", @"Th", @"Fr", @"Sa", @"Su"
/*! Set a theme
*/
- (void)setThemeState:(CPThemeState)aState
- (BOOL)setThemeState:(CPThemeState)aState
{
[_textField setThemeState:aState];
[super setThemeState:aState];
@@ -1061,7 +1067,7 @@ var CPShortWeekDayNameArrayEn = [@"Mo", @"Tu", @"We", @"Th", @"Fr", @"Sa", @"Su"
/*! Unset a theme
*/
- (void)unsetThemeState:(CPThemeState)aState
- (BOOL)unsetThemeState:(CPThemeState)aState
{
[_textField unsetThemeState:aState];
[super unsetThemeState:aState];
@@ -1133,6 +1139,9 @@ var CPShortWeekDayNameArrayEn = [@"Mo", @"Tu", @"We", @"Th", @"Fr", @"Sa", @"Su"
*/
- (void)layoutSubviews
{
if ([_datePicker datePickerStyle] == CPTextFieldAndStepperDatePickerStyle || [_datePicker datePickerStyle] == CPTextFieldDatePickerStyle)
return;
var bounds = [self bounds];
[_textField sizeToFit];
[_textField setFrameOrigin:CGPointMake(bounds.size.width / 2 - [_textField frameSize].width / 2 + [_datePicker valueForThemeAttribute:@"border-width"], bounds.size.height / 2 - [_textField frameSize].height / 2)];
@@ -1205,6 +1214,9 @@ var CPShortWeekDayNameArrayEn = [@"Mo", @"Tu", @"We", @"Th", @"Fr", @"Sa", @"Su"
- (void)layoutSubviews
{
if ([_datePicker datePickerStyle] == CPTextFieldAndStepperDatePickerStyle || [_datePicker datePickerStyle] == CPTextFieldDatePickerStyle)
return;
if ([_datePicker drawsBackground])
[self setBackgroundColor:[_datePicker backgroundColor]];
else
+76 -49
View File
@@ -1,4 +1,5 @@
/* _CPDatePickerClock.j
/*
* _CPDatePickerClock.j
* AppKit
*
* Created by Alexandre Wilhelm
@@ -24,9 +25,16 @@
@import "CPImageView.j"
@import "CALayer.j"
@class _CPCibCustomResource
@class CPDatePicker
@global CPHourMinuteSecondDatePickerElementFlag
@global CPTextFieldAndStepperDatePickerStyle
@global CPTextFieldDatePickerStyle
var RADIANS = Math.PI / 180;
@implementation _CPDatePickerClock : CPView
{
@@ -44,11 +52,6 @@
#pragma mark -
#pragma mark Init methods
/*! Init a new _CPDatePickerClock
@param aFrame
@param aDatePicker
@return a new instance of _CPDatePickerClock
*/
- (id)initWithFrame:(CGRect)aFrame datePicker:(CPDatePicker)aDatePicker
{
if (self = [super initWithFrame:aFrame])
@@ -110,8 +113,8 @@
[_rootLayer addSublayer:_middleHandLayer];
[_rootLayer setNeedsDisplay];
}
return self;
}
@@ -119,10 +122,11 @@
#pragma mark -
#pragma mark Layout methods
/*! Layout the subviews
*/
- (void)layoutSubviews
{
if ([_datePicker datePickerStyle] == CPTextFieldAndStepperDatePickerStyle || [_datePicker datePickerStyle] == CPTextFieldDatePickerStyle)
return;
[super layoutSubviews];
var bounds = [self bounds],
@@ -130,11 +134,11 @@
[dateValue _dateWithTimeZone:[_datePicker timeZone]];
[self setBackgroundColor:[_datePicker valueForThemeAttribute:@"bezel-color-clock" inState:[_datePicker themeState]]];
[_middleHandLayer setBackgroundHandColor:[_datePicker valueForThemeAttribute:@"middle-hand-color" inState:[_datePicker themeState]]];
[_hourHandLayer setBackgroundHandColor:[_datePicker valueForThemeAttribute:@"hour-hand-color" inState:[_datePicker themeState]]];
[_minuteHandLayer setBackgroundHandColor:[_datePicker valueForThemeAttribute:@"minute-hand-color" inState:[_datePicker themeState]]];
[_secondHandLayer setBackgroundHandColor:[_datePicker valueForThemeAttribute:@"second-hand-color" inState:[_datePicker themeState]]];
[self setBackgroundColor:[_datePicker currentValueForThemeAttribute:@"bezel-color-clock"]];
[_middleHandLayer setImage:[_datePicker currentValueForThemeAttribute:@"middle-hand-image"]];
[_hourHandLayer setImage:[_datePicker currentValueForThemeAttribute:@"hour-hand-image"]];
[_minuteHandLayer setImage:[_datePicker currentValueForThemeAttribute:@"minute-hand-image"]];
[_secondHandLayer setImage:[_datePicker currentValueForThemeAttribute:@"second-hand-image"]];
if ([_datePicker _isEnglishFormat])
{
@@ -156,6 +160,12 @@
[_minuteHandLayer setRotationRadians:[self _minutePositionRadianForDate:dateValue]];
[_secondHandLayer setRotationRadians:[self _secondPositionRadianForDate:dateValue]];
[_PMAMTextField setEnabled:_isEnabled];
[_hourHandLayer setEnabled:_isEnabled];
[_middleHandLayer setEnabled:_isEnabled];
[_secondHandLayer setEnabled:_isEnabled];
[_minuteHandLayer setEnabled:_isEnabled];
// Check if we have to display the hand second
if (([_datePicker datePickerElements] & CPHourMinuteSecondDatePickerElementFlag) == CPHourMinuteSecondDatePickerElementFlag)
[_secondHandLayer setHidden:NO];
@@ -167,46 +177,41 @@
#pragma mark -
#pragma mark Getter Setter methods
#pragma mark Accessors
/*! Return the radian position of the hour
*/
- (float)_hourPositionRadianForDate:(CPDate)aDate
{
var hours = aDate.getHours() + aDate.getMinutes() / 60;
return (360 * hours / 12) * (Math.PI / 180)
return (360 * hours / 12) * RADIANS;
}
/*! Return the radian position of the second
*/
- (float)_secondPositionRadianForDate:(CPDate)aDate
{
return (360 * aDate.getSeconds() / 60) * (Math.PI / 180)
return (360 * aDate.getSeconds() / 60) * RADIANS;
}
/*! Return the radian position of the minute
*/
- (float)_minutePositionRadianForDate:(CPDate)aDate
{
var minutes = aDate.getMinutes() + aDate.getSeconds() / 60;
return (360 * minutes / 60) * (Math.PI / 180)
return (360 * minutes / 60) * RADIANS;
}
/*! Set enabled
@param aBoolean
*/
- (void)setEnabled:(BOOL)aBoolean
- (void)setEnabled:(BOOL)shouldEnable
{
_isEnabled = aBoolean;
[_PMAMTextField setEnabled:aBoolean];
[_hourHandLayer setEnabled:aBoolean];
[_middleHandLayer setEnabled:aBoolean];
[_secondHandLayer setEnabled:aBoolean];
[_minuteHandLayer setEnabled:aBoolean];
shouldEnable = !!shouldEnable;
if (shouldEnable === _isEnabled)
return;
_isEnabled = shouldEnable;
[self setNeedsLayout];
// FIXME: This is a workaround for an apparent bug in CALayer.
// Without pumping the event loop, the sublayers of _rootLayer
// (the hands) are not redrawn until an event occurs.
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
}
@end
@@ -216,6 +221,7 @@
{
BOOL _isEnabled @accessors(setter=setEnabled:, getter=isEnabled);
CPImage _image;
CALayer _imageLayer;
float _rotationRadians;
}
@@ -224,10 +230,6 @@
#pragma mark -
#pragma mark Init methods
/*! Init a new hand layer with an image. The image will be draw in a ImageLayer
@param anImage
@return a new instance of handLayer
*/
- (id)initWithSize:(CGSize)aSize
{
if (self = [super init])
@@ -241,6 +243,7 @@
[self addSublayer:_imageLayer];
}
return self;
}
@@ -248,8 +251,8 @@
#pragma mark -
#pragma mark Setter Getter methods
/*! Set the bounds of the layer. The imageLayer will be at the center of this bounds
@param aRect
/*!
Set the bounds of the layer. The imageLayer will be at the center of this bounds.
*/
- (void)setBounds:(CGRect)aRect
{
@@ -258,12 +261,22 @@
[_imageLayer setPosition:CGPointMake(CGRectGetMidX(aRect), CGRectGetMidY(aRect))];
}
/*! Set the rotation of the imageLayer
@param radians
*/
- (void)setImage:(CPImage)anImage
{
if (_image === anImage)
return;
if ([anImage isKindOfClass:[_CPCibCustomResource class]])
_image = [anImage imageFromCoder:nil];
else
_image = anImage;
[_imageLayer setNeedsDisplay];
}
- (void)setRotationRadians:(float)radians
{
if (_rotationRadians == radians)
if (_rotationRadians === radians)
return;
_rotationRadians = radians;
@@ -273,15 +286,29 @@
1.0, 1.0)];
}
- (void)setBackgroundHandColor:(CPColor)aColor
- (void)setEnabled:(BOOL)shouldEnable
{
[_imageLayer setBackgroundColor:aColor];
shouldEnable = !!shouldEnable;
if (_isEnabled === shouldEnable)
return;
_isEnabled = shouldEnable;
[self setNeedsDisplay];
[_imageLayer setNeedsDisplay];
}
- (void)setEnabled:(BOOL)aBoolean
- (void)imageDidLoad:(CPImage)anImage
{
_isEnabled = aBoolean;
[self setNeedsDisplay];
[_imageLayer setNeedsDisplay];
}
- (void)drawLayer:(CALayer)aLayer inContext:(CGContext)aContext
{
if ([_image loadStatus] != CPImageLoadStatusCompleted)
[_image setDelegate:self];
else
CGContextDrawImage(aContext, [aLayer bounds], _image);
}
@end
+5 -2
View File
@@ -676,6 +676,9 @@ var CPZeroKeyCode = 48,
- (void)layoutSubviews
{
if ([_datePicker datePickerStyle] == CPClockAndCalendarDatePickerStyle)
return;
[super layoutSubviews];
var themeState = [_datePicker themeState];
@@ -1353,7 +1356,7 @@ var CPMonthDateType = 0,
/*! Set the stringValue of the TextField. Add some zeros of there isn't 2/4 letters in the value. It's called at the end of the editing process
@param aStringValue a CPString
*/
- (void)setStringValue:(id)aStringValue
- (void)setStringValue:(CPString)aStringValue
{
if (_dateType == CPYearDateType)
{
@@ -1434,7 +1437,7 @@ var CPMonthDateType = 0,
/*! Return the objectValue of the textField. Needed for the binding.
This returns the objectValue relative to the dateValue
*/
- (void)objectValue
- (id)objectValue
{
var dateValue = [[_datePicker dateValue] copy];
+11 -25
View File
@@ -244,11 +244,6 @@ var CPDocumentUntitledCount = 0;
{
}
- (CPWindowController)firstEligibleExistingWindowController
{
return nil;
}
// Creating and managing window controllers
/*!
Creates the window controller for this document.
@@ -261,6 +256,7 @@ var CPDocumentUntitledCount = 0;
- (void)makeViewAndWindowControllers
{
var viewCibName = [self viewCibName],
windowCibName = [self windowCibName],
viewController = nil,
windowController = nil;
@@ -268,31 +264,21 @@ var CPDocumentUntitledCount = 0;
if ([viewCibName length])
viewController = [[CPViewController alloc] initWithCibName:viewCibName bundle:nil owner:self];
// If we have a view controller, check if we have a free window for it.
if (viewController)
windowController = [self firstEligibleExistingWindowController];
// From a cib if we have one.
if ([windowCibName length])
windowController = [[CPWindowController alloc] initWithWindowCibName:windowCibName owner:self];
// If not, create one.
if (!windowController)
// If not you get a standard window capable of displaying multiple documents and view
else if (viewController)
{
var windowCibName = [self windowCibName];
var view = [viewController view],
viewFrame = [view frame];
// From a cib if we have one.
if ([windowCibName length])
windowController = [[CPWindowController alloc] initWithWindowCibName:windowCibName owner:self];
viewFrame.origin = CGPointMake(50, 50);
// If not you get a standard window capable of displaying multiple documents and view
else if (viewController)
{
var view = [viewController view],
viewFrame = [view frame];
var theWindow = [[CPWindow alloc] initWithContentRect:viewFrame styleMask:CPTitledWindowMask | CPClosableWindowMask | CPMiniaturizableWindowMask | CPResizableWindowMask];
viewFrame.origin = CGPointMake(50, 50);
var theWindow = [[CPWindow alloc] initWithContentRect:viewFrame styleMask:CPTitledWindowMask | CPClosableWindowMask | CPMiniaturizableWindowMask | CPResizableWindowMask];
windowController = [[CPWindowController alloc] initWithWindow:theWindow];
}
windowController = [[CPWindowController alloc] initWithWindow:theWindow];
}
if (windowController && viewController)
+35
View File
@@ -253,6 +253,14 @@ var CPSharedDocumentController = nil;
return _documents;
}
/*!
Returns the CPDocument object associated with the main window.
*/
- (CPDocument)currentDocument
{
return [[[CPApp mainWindow] windowController] document];
}
/*!
Adds \c aDocument under the control of the receiver.
@param aDocument the document to add
@@ -271,6 +279,33 @@ var CPSharedDocumentController = nil;
[_documents removeObjectIdenticalTo:aDocument];
}
/*!
Returns the document object whose window controller
owns a specified window.
*/
- (CPDocument)documentForWindow:(CPWindow)aWindow
{
return [[aWindow windowController] document];
}
/*!
Returns a Boolean value that indicates whether the receiver
has any documents with unsaved changes.
*/
- (BOOL)hasEditedDocuments
{
var iter = [_documents objectEnumerator],
obj;
while ((obj = [iter nextObject]) !== nil)
{
if ([obj isDocumentEdited])
return YES;
}
return NO;
}
- (CPString)defaultType
{
return [_documentTypes[0] objectForKey:@"CPBundleTypeName"];
+23
View File
@@ -68,6 +68,11 @@ var _CPEventPeriodicEventPeriod = 0,
float _deltaX;
float _deltaY;
float _deltaZ;
#if PLATFORM(DOM)
BOOL _suppressCappuccinoCut;
BOOL _suppressCappuccinoPaste;
#endif
}
/*!
@@ -473,6 +478,24 @@ var _CPEventPeriodicEventPeriod = 0,
return !firstResponderIsText;
}
/*!
Return YES if this event is a part of processing a browser controlled cut or paste event
where the browser will go ahead and do the work of cutting or pasting within the input
element after processing of this event. The implication is that it should not be done by
the CPTextField (or whatever else is controlling the input) since this would result in
nothing being cut (because the field already cut the text out), or a double paste
(because the field pasted as well as the browser).
*/
- (BOOL)_platformIsEffectingCutOrPaste
{
#if PLATFORM(DOM)
return _suppressCappuccinoCut || _suppressCappuccinoPaste;
#else
return NO;
#endif
}
/*!
Generates periodic events every \c aPeriod seconds.
+1 -1
View File
@@ -189,7 +189,7 @@ var IEFlashCLSID = "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000";
return @"CPFV_" + [self UID];
}
- (void)mouseMoved:(id)sommit
- (void)mouseMoved:(CPEvent)sommit
{
[[[self window] platformWindow] _propagateCurrentDOMEvent:YES];
}
+1 -1
View File
@@ -208,7 +208,7 @@ following:
var systemSize = String(_CPFontSystemFontSize),
currentSize = String(CPFontCurrentSystemSize);
for (key in _CPSystemFontCache)
for (var key in _CPSystemFontCache)
{
if (_CPSystemFontCache.hasOwnProperty(key) &&
(key.indexOf(systemSize) === 0 || key.indexOf(currentSize) === 0))
+7 -2
View File
@@ -136,14 +136,19 @@ function CPAppKitImage(aFilename, aSize)
/*!
Initializes the image, by associating it with a filename. The image
denoted in \c aFilename is not actually loaded. It will
be loaded once needed.
denoted in \c aFilename is not actually loaded. It will be loaded
once needed.
@param aFilename the file containing the image
@param aSize the image's size
@return the initialized image
*/
- (id)initByReferencingFile:(CPString)aFilename size:(CGSize)aSize
{
// Quietly return nil like in Cocoa, rather than crashing later.
if (aFilename === undefined || aFilename === nil)
return nil;
self = [super init];
if (self)
+33 -40
View File
@@ -87,26 +87,37 @@ var CPImageViewEmptyPlaceholderImage = nil;
if (self)
{
#if PLATFORM(DOM)
_DOMImageElement = document.createElement("img");
_DOMImageElement.style.position = "absolute";
_DOMImageElement.style.left = "0px";
_DOMImageElement.style.top = "0px";
if ([CPPlatform supportsDragAndDrop])
{
_DOMImageElement.setAttribute("draggable", "true");
_DOMImageElement.style["-khtml-user-drag"] = "element";
}
CPDOMDisplayServerAppendChild(_DOMElement, _DOMImageElement);
_DOMImageElement.style.visibility = "hidden";
[self _createDOMImageElement];
#endif
}
return self;
}
- (void)_createDOMImageElement
{
#if PLATFORM(DOM)
if (_DOMImageElement)
return;
_DOMImageElement = document.createElement("img");
_DOMImageElement.style.position = "absolute";
_DOMImageElement.style.left = "0px";
_DOMImageElement.style.top = "0px";
if ([CPPlatform supportsDragAndDrop])
{
_DOMImageElement.setAttribute("draggable", "true");
_DOMImageElement.style["-khtml-user-drag"] = "element";
}
_DOMImageElement.style.visibility = "hidden";
AppKitTagDOMElement(self, _DOMImageElement);
CPDOMDisplayServerAppendChild(_DOMElement, _DOMImageElement);
#endif
}
/*!
Returns the view's image.
*/
@@ -138,6 +149,9 @@ var CPImageViewEmptyPlaceholderImage = nil;
var newImage = [self objectValue];
#if PLATFORM(DOM)
if (!_DOMImageElement)
[self _createDOMImageElement];
_DOMImageElement.src = newImage ? [newImage filename] : [CPImageViewEmptyPlaceholderImage filename];
#endif
@@ -253,7 +267,7 @@ var CPImageViewEmptyPlaceholderImage = nil;
[self setNeedsDisplay:YES];
}
- (unsigned)imageScaling
- (CPUInteger)imageScaling
{
return [self currentValueForThemeAttribute:@"image-scaling"];
}
@@ -488,7 +502,7 @@ var CPImageViewEmptyPlaceholderImage = nil;
[_source setImage:image];
}
- (void)valueForBinding:(CPString)aBinding
- (id)valueForBinding:(CPString)aBinding
{
var image = [_source image];
@@ -517,28 +531,12 @@ var CPImageViewImageKey = @"CPImageViewImageKey",
*/
- (id)initWithCoder:(CPCoder)aCoder
{
#if PLATFORM(DOM)
_DOMImageElement = document.createElement("img");
_DOMImageElement.style.position = "absolute";
_DOMImageElement.style.left = "0px";
_DOMImageElement.style.top = "0px";
_DOMImageElement.style.visibility = "hidden";
if ([CPPlatform supportsDragAndDrop])
{
_DOMImageElement.setAttribute("draggable", "true");
_DOMImageElement.style["-khtml-user-drag"] = "element";
}
if (typeof(appkit_tag_dom_elements) !== "undefined" && !!appkit_tag_dom_elements)
_DOMImageElement.setAttribute("data-cappuccino-view", [self className]);
#endif
self = [super initWithCoder:aCoder];
if (self)
{
#if PLATFORM(DOM)
_DOMElement.appendChild(_DOMImageElement);
[self _createDOMImageElement];
#endif
[self setHasShadow:[aCoder decodeBoolForKey:CPImageViewHasShadowKey]];
@@ -564,17 +562,12 @@ var CPImageViewImageKey = @"CPImageViewImageKey",
// We do this in order to avoid encoding the _shadowView, which
// should just automatically be created programmatically as needed.
if (_shadowView)
{
var actualSubviews = _subviews;
_subviews = [_subviews copy];
[_subviews removeObjectIdenticalTo:_shadowView];
}
[_shadowView removeFromSuperview];
[super encodeWithCoder:aCoder];
if (_shadowView)
_subviews = actualSubviews;
[self addSubview:_shadowView];
[aCoder encodeBool:_hasShadow forKey:CPImageViewHasShadowKey];
[aCoder encodeInt:_imageAlignment forKey:CPImageViewImageAlignmentKey];
+1 -1
View File
@@ -62,7 +62,7 @@ CPRatingLevelIndicatorStyle = 3;
return "level-indicator";
}
+ (id)themeAttributes
+ (CPDictionary)themeAttributes
{
return @{
@"bezel-color": [CPNull null],
+32 -15
View File
@@ -278,7 +278,7 @@ var _CPMenuBarVisible = NO,
@param aMenuItem the item to insert
@param anIndex the index in the menu to insert the item.
*/
- (void)insertItem:(CPMenuItem)aMenuItem atIndex:(unsigned)anIndex
- (void)insertItem:(CPMenuItem)aMenuItem atIndex:(CPUInteger)anIndex
{
[self insertObject:aMenuItem inItemsAtIndex:anIndex];
}
@@ -291,7 +291,7 @@ var _CPMenuBarVisible = NO,
@param anIndex the index location in the menu for the new item
@return the new menu item
*/
- (CPMenuItem)insertItemWithTitle:(CPString)aTitle action:(SEL)anAction keyEquivalent:(CPString)aKeyEquivalent atIndex:(unsigned)anIndex
- (CPMenuItem)insertItemWithTitle:(CPString)aTitle action:(SEL)anAction keyEquivalent:(CPString)aKeyEquivalent atIndex:(CPUInteger)anIndex
{
var item = [[CPMenuItem alloc] initWithTitle:aTitle action:anAction keyEquivalent:aKeyEquivalent];
@@ -335,7 +335,7 @@ var _CPMenuBarVisible = NO,
Removes the item at the specified index from the menu
@param anIndex the index of the item to remove
*/
- (void)removeItemAtIndex:(unsigned)anIndex
- (void)removeItemAtIndex:(CPUInteger)anIndex
{
[self removeObjectFromItemsAtIndex:anIndex];
}
@@ -621,7 +621,7 @@ var _CPMenuBarVisible = NO,
*/
- (void)update
{
if (![self autoenablesItems])
if (!_autoenablesItems)
return;
var items = [self itemArray];
@@ -633,14 +633,24 @@ var _CPMenuBarVisible = NO,
if ([item hasSubmenu])
continue;
var validator = [CPApp targetForAction:[item action] to:[item target] from:item];
// If there are enabled bindings for the item, they override anything else
var binder = [CPBinder getBinding:CPEnabledBinding forObject:item];
if (binder)
{
[binder setValueFor:CPEnabledBinding];
return;
}
var validator = [CPApp targetForAction:[item action] to:[item target] from:item],
shouldBeEnabled = YES;
if (!validator)
{
// If targetForAction: returns nil, it could be that there is no action.
// If there is an action and nil is returned, no valid target could be found.
if ([item action] || [item target])
[item setEnabled:NO];
shouldBeEnabled = NO;
else
{
// Check to see if there is a target binding with an invalid selector
@@ -655,16 +665,18 @@ var _CPMenuBarVisible = NO,
selector = [options valueForKey:CPSelectorNameBindingOption];
if (target && selector && ![target respondsToSelector:CPSelectorFromString(selector)])
[item setEnabled:NO];
shouldBeEnabled = NO;
}
}
}
else if (![validator respondsToSelector:[item action]])
[item setEnabled:NO];
shouldBeEnabled = NO;
else if ([validator respondsToSelector:@selector(validateMenuItem:)])
[item setEnabled:[validator validateMenuItem:item]];
shouldBeEnabled = [validator validateMenuItem:item];
else if ([validator respondsToSelector:@selector(validateUserInterfaceItem:)])
[item setEnabled:[validator validateUserInterfaceItem:item]];
shouldBeEnabled = [validator validateUserInterfaceItem:item];
[item setEnabled:shouldBeEnabled];
}
[[_menuWindow _menuView] tile];
@@ -843,6 +855,9 @@ var _CPMenuBarVisible = NO,
+ (void)popUpContextMenu:(CPMenu)aMenu withEvent:(CPEvent)anEvent forView:(CPView)aView withFont:(CPFont)aFont
{
// This is needed when we are making several rights click
[[_CPMenuManager sharedMenuManager] cancelActiveMenu];
[aMenu _menuWillOpen];
if (!aFont)
@@ -851,8 +866,6 @@ var _CPMenuBarVisible = NO,
var theWindow = [aView window],
menuWindow = [_CPMenuWindow menuWindowWithMenu:aMenu font:aFont];
[_CPMenuWindow poolMenuWindow:menuWindow];
[menuWindow setBackgroundStyle:_CPMenuWindowPopUpBackgroundStyle];
var constraintRect = [CPMenu _constraintRectForView:aView],
@@ -1048,7 +1061,7 @@ var _CPMenuBarVisible = NO,
Sends the action of the menu item at the specified index.
@param anIndex the index of the item
*/
- (void)performActionForItemAtIndex:(unsigned)anIndex
- (void)performActionForItemAtIndex:(CPUInteger)anIndex
{
var item = _items[anIndex];
@@ -1180,7 +1193,8 @@ var _CPMenuBarVisible = NO,
var CPMenuTitleKey = @"CPMenuTitleKey",
CPMenuNameKey = @"CPMenuNameKey",
CPMenuItemsKey = @"CPMenuItemsKey",
CPMenuShowsStateColumnKey = @"CPMenuShowsStateColumnKey";
CPMenuShowsStateColumnKey = @"CPMenuShowsStateColumnKey",
CPMenuAutoEnablesItemsKey = @"CPMenuAutoEnablesItemsKey";
@implementation CPMenu (CPCoding)
@@ -1202,7 +1216,7 @@ var CPMenuTitleKey = @"CPMenuTitleKey",
_showsStateColumn = ![aCoder containsValueForKey:CPMenuShowsStateColumnKey] || [aCoder decodeBoolForKey:CPMenuShowsStateColumnKey];
_autoenablesItems = YES;
_autoenablesItems = ![aCoder containsValueForKey:CPMenuAutoEnablesItemsKey] || [aCoder decodeBoolForKey:CPMenuAutoEnablesItemsKey];
[self setMinimumWidth:0];
}
@@ -1225,6 +1239,9 @@ var CPMenuTitleKey = @"CPMenuTitleKey",
if (!_showsStateColumn)
[aCoder encodeBool:_showsStateColumn forKey:CPMenuShowsStateColumnKey];
if (!_autoenablesItems)
[aCoder encodeBool:_autoenablesItems forKey:CPMenuAutoEnablesItemsKey];
}
@end
+9
View File
@@ -407,6 +407,15 @@ var STICKY_TIME_INTERVAL = 0.4,
[menu cancelTracking];
}
- (void)cancelActiveMenu
{
if (CPApp._activeMenu)
{
[self completeTracking];
_menuContainerStack = [];
}
}
- (void)completeTracking
{
var trackingMenu = [self trackingMenu];
+3 -2
View File
@@ -72,7 +72,8 @@ _CPMenuWindowAttachedMenuBackgroundStyle = 2;
+ (void)poolMenuWindow:(_CPMenuWindow)aMenuWindow
{
if (!aMenuWindow || _CPMenuWindowPool.length >= _CPMenuWindowPoolCapacity)
// FIXME :the poolMenuWindow is called too many times somewhere....
if (!aMenuWindow || _CPMenuWindowPool.length >= _CPMenuWindowPoolCapacity || [_CPMenuWindowPool containsObject:aMenuWindow])
return;
_CPMenuWindowPool.push(aMenuWindow);
@@ -434,7 +435,7 @@ _CPMenuWindowAttachedMenuBackgroundStyle = 2;
return "menu-view";
}
+ (id)themeAttributes
+ (CPDictionary)themeAttributes
{
return @{
@"menu-window-more-above-image": [CPNull null],
+3
View File
@@ -166,6 +166,9 @@ var CPMenuItemStringRepresentationDictionary = @{
if (_isEnabled === isEnabled)
return;
if (!isEnabled && [self isHighlighted])
[_menu _highlightItemAtIndex:CPNotFound];
_isEnabled = !!isEnabled;
[_menuItemView setDirty];
+5 -5
View File
@@ -49,7 +49,7 @@
return "menu-item-bar-view";
}
+ (id)themeAttributes
+ (CPDictionary)themeAttributes
{
return @{
@"horizontal-margin": 9.0,
@@ -84,25 +84,25 @@
return self;
}
- (CPColor)setTextColor:(CPColor)aColor
- (void)setTextColor:(CPColor)aColor
{
_textColor = aColor;
[self setNeedsLayout];
}
- (CPColor)setTextShadowColor:(CPColor)aColor
- (void)setTextShadowColor:(CPColor)aColor
{
_textShadowColor = aColor;
[self setNeedsLayout];
}
- (CPColor)setHighlightTextColor:(CPColor)aColor
- (void)setHighlightTextColor:(CPColor)aColor
{
_highlightTextColor = aColor;
[self setNeedsLayout];
}
- (CPColor)setHighlightTextShadowColor:(CPColor)aColor
- (void)setHighlightTextShadowColor:(CPColor)aColor
{
_highlightTextShadowColor = aColor;
[self setNeedsLayout];
+1 -1
View File
@@ -45,7 +45,7 @@
return "menu-item-standard-view";
}
+ (id)themeAttributes
+ (CPDictionary)themeAttributes
{
return @{
@"submenu-indicator-color": [CPNull null],
+1 -2
View File
@@ -53,7 +53,7 @@
return "menu-item-view";
}
+ (id)themeAttributes
+ (CPDictionary)themeAttributes
{
return @{};
}
@@ -112,7 +112,6 @@
_view = menuItemView;
}
}
else if ([_menuItem menu] == [CPApp mainMenu])
{
if (![_view isKindOfClass:[_CPMenuItemMenuBarView class]])
+5 -5
View File
@@ -51,7 +51,7 @@
CPCountedSet _observedKeys;
}
+ (id)initialize
+ (void)initialize
{
if (self !== [CPObjectController class])
return;
@@ -572,7 +572,7 @@ var CPObjectControllerContentKey = @"CPObjectControllerCo
}
}
- (void)insertObject:(id)anObject atIndex:(unsigned)anIndex
- (void)insertObject:(id)anObject atIndex:(CPUInteger)anIndex
{
for (var i = 0, count = [_observationProxies count]; i < count; i++)
{
@@ -592,7 +592,7 @@ var CPObjectControllerContentKey = @"CPObjectControllerCo
[super insertObject:anObject atIndex:anIndex];
}
- (void)removeObjectAtIndex:(unsigned)anIndex
- (void)removeObjectAtIndex:(CPUInteger)anIndex
{
var currentObject = [self objectAtIndex:anIndex];
@@ -614,7 +614,7 @@ var CPObjectControllerContentKey = @"CPObjectControllerCo
[super removeObjectAtIndex:anIndex];
}
- (_CPObservableArray)objectsAtIndexes:(CPIndexSet)theIndexes
- (CPArray)objectsAtIndexes:(CPIndexSet)theIndexes
{
return [_CPObservableArray arrayWithArray:[super objectsAtIndexes:theIndexes]];
}
@@ -629,7 +629,7 @@ var CPObjectControllerContentKey = @"CPObjectControllerCo
[self removeObjectAtIndex:[self count]];
}
- (void)replaceObjectAtIndex:(unsigned)anIndex withObject:(id)anObject
- (void)replaceObjectAtIndex:(CPUInteger)anIndex withObject:(id)anObject
{
var currentObject = [self objectAtIndex:anIndex];
+69 -17
View File
@@ -352,6 +352,10 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
*/
- (void)expandItem:(id)anItem expandChildren:(BOOL)shouldExpandChildren
{
if ([self _delegateRespondsToShouldExpandItem])
if ([_outlineViewDelegate outlineView:self shouldExpandItem:anItem] == NO)
return;
var itemInfo = null;
if (!anItem)
@@ -427,6 +431,10 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
if (!anItem)
return;
if ([self _delegateRespondsToShouldCollapseItem])
if ([_outlineViewDelegate outlineView:self shouldCollapseItem:anItem] == NO)
return;
var itemInfo = _itemInfosForItems[[anItem UID]];
if (!itemInfo)
@@ -1070,7 +1078,7 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
@ignore
We need to offset the dataview and add the disclosure triangle.
*/
- (CPView)_dragViewForColumn:(int)theColumnIndex event:(CPEvent)theDragEvent offset:(CGPoint)theDragViewOffset
- (CPView)_dragViewForColumn:(CPInteger)theColumnIndex event:(CPEvent)theDragEvent offset:(CGPoint)theDragViewOffset
{
var dragView = [[_CPColumnDragView alloc] initWithLineColor:[self gridColor]],
tableColumn = [[self tableColumns] objectAtIndex:theColumnIndex],
@@ -1203,7 +1211,7 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
/*!
@ignore
*/
- (id)_parentItemForUpperRow:(int)theUpperRowIndex andLowerRow:(int)theLowerRowIndex atMouseOffset:(CGPoint)theOffset
- (id)_parentItemForUpperRow:(CPInteger)theUpperRowIndex andLowerRow:(CPInteger)theLowerRowIndex atMouseOffset:(CGPoint)theOffset
{
if (_shouldRetargetItem)
return _retargetedItem;
@@ -1233,7 +1241,7 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
/*!
@ignore
*/
- (CGRect)_rectForDropHighlightViewBetweenUpperRow:(int)theUpperRowIndex andLowerRow:(int)theLowerRowIndex offset:(CGPoint)theOffset
- (CGRect)_rectForDropHighlightViewBetweenUpperRow:(CPInteger)theUpperRowIndex andLowerRow:(CPInteger)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],
@@ -1549,12 +1557,12 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
[super keyDown:anEvent];
}
- (CPView)_viewForTableColumn:(CPTableColumn)aTableColumn row:(CPInteger)aRow
- (CPView)_sendDelegateViewForTableColumn:(CPTableColumn)aTableColumn row:(CPInteger)aRow
{
return [_outlineViewDelegate outlineView:self viewForTableColumn:aTableColumn item:[self itemAtRow:aRow]];
}
- (CPView)_dataViewForTableColumn:(CPTableColumn)aTableColumn row:(CPInteger)aRow
- (CPView)_sendDelegateDataViewForTableColumn:(CPTableColumn)aTableColumn row:(CPInteger)aRow
{
return [_outlineViewDelegate outlineView:self dataViewForTableColumn:aTableColumn item:[self itemAtRow:aRow]];
}
@@ -1574,6 +1582,34 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
return _implementedOutlineViewDelegateMethods & CPOutlineViewDelegate_outlineView_dataViewForTableColumn_item_;
}
- (BOOL)_delegateRespondsToShouldExpandItem
{
return _implementedOutlineViewDelegateMethods & CPOutlineViewDelegate_outlineView_shouldExpandItem_;
}
- (BOOL)_delegateRespondsToShouldCollapseItem
{
return _implementedOutlineViewDelegateMethods & CPOutlineViewDelegate_outlineView_shouldCollapseItem_;
}
/*!
@ignore
Return YES if the delegate implements outlineView:selectionIndexesForProposedSelection
*/
- (BOOL)_delegateRespondsToSelectionIndexesForProposedSelection
{
return _implementedOutlineViewDelegateMethods & CPOutlineViewDelegate_outlineView_selectionIndexesForProposedSelection_;
}
/*!
@ignore
Return YES if the delegate implements outlineView:shouldSelectItem:
*/
- (BOOL)_delegateRespondsToShouldSelectRow
{
return _implementedOutlineViewDelegateMethods & CPOutlineViewDelegate_outlineView_shouldSelectItem_;
}
@end
// FIX ME: We're using with() here because Safari fails if we use anOutlineView._itemInfosForItems or whatever...
@@ -1771,7 +1807,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:(CGPoint)theOffset
- (int)_childIndexForDropOperation:(CPTableViewDropOperation)theDropOperation row:(CPInteger)theRow offset:(CGPoint)theOffset
{
if (_outlineView._shouldRetargetChildIndex)
return _outlineView._retargedChildIndex;
@@ -1795,7 +1831,7 @@ var _loadItemInfoForItem = function(/*CPOutlineView*/ anOutlineView, /*id*/ anIt
return childIndex;
}
- (void)_parentItemForDropOperation:(CPTableViewDropOperation)theDropOperation row:(int)theRow offset:(CGPoint)theOffset
- (void)_parentItemForDropOperation:(CPTableViewDropOperation)theDropOperation row:(CPInteger)theRow offset:(CGPoint)theOffset
{
if (theDropOperation === CPTableViewDropAbove)
return [_outlineView _parentItemForUpperRow:theRow - 1 andLowerRow:theRow atMouseOffset:theOffset]
@@ -1803,8 +1839,8 @@ var _loadItemInfoForItem = function(/*CPOutlineView*/ anOutlineView, /*id*/ anIt
return [_outlineView itemAtRow:theRow];
}
- (CPDragOperation)tableView:(CPTableView)aTableView validateDrop:(id < CPDraggingInfo >)theInfo
proposedRow:(int)theRow proposedDropOperation:(CPTableViewDropOperation)theOperation
- (CPDragOperation)tableView:(CPTableView)aTableView validateDrop:(id /*< CPDraggingInfo >*/)theInfo
proposedRow:(CPInteger)theRow proposedDropOperation:(CPTableViewDropOperation)theOperation
{
if (!(_outlineView._implementedOutlineViewDataSourceMethods & CPOutlineViewDataSource_outlineView_validateDrop_proposedItem_proposedChildIndex_))
return CPDragOperationNone;
@@ -1823,7 +1859,7 @@ var _loadItemInfoForItem = function(/*CPOutlineView*/ anOutlineView, /*id*/ anIt
return [_outlineView._outlineViewDataSource outlineView:_outlineView validateDrop:theInfo proposedItem:parentItem proposedChildIndex:childIndex];
}
- (BOOL)tableView:(CPTableView)aTableView acceptDrop:(id <CPDraggingInfo>)theInfo row:(int)theRow dropOperation:(CPTableViewDropOperation)theOperation
- (BOOL)tableView:(CPTableView)aTableView acceptDrop:(id /*<CPDraggingInfo>*/)theInfo row:(CPInteger)theRow dropOperation:(CPTableViewDropOperation)theOperation
{
if (!(_outlineView._implementedOutlineViewDataSourceMethods & CPOutlineViewDataSource_outlineView_acceptDrop_item_childIndex_))
return NO;
@@ -1867,7 +1903,7 @@ var _loadItemInfoForItem = function(/*CPOutlineView*/ anOutlineView, /*id*/ anIt
return self;
}
- (BOOL)tableView:(CPTableView)theTableView shouldSelectRow:(int)theRow
- (BOOL)tableView:(CPTableView)theTableView shouldSelectRow:(CPInteger)theRow
{
return SHOULD_SELECT_ITEM(_outlineView, [_outlineView itemAtRow:theRow]);
}
@@ -1877,7 +1913,7 @@ var _loadItemInfoForItem = function(/*CPOutlineView*/ anOutlineView, /*id*/ anIt
return SELECTION_SHOULD_CHANGE(_outlineView);
}
- (BOOL)tableView:(CPTableView)aTableView shouldEditTableColumn:(CPTableColumn)aColumn row:(int)aRow
- (BOOL)tableView:(CPTableView)aTableView shouldEditTableColumn:(CPTableColumn)aColumn row:(CPInteger)aRow
{
if ((_outlineView._implementedOutlineViewDelegateMethods & CPOutlineViewDelegate_outlineView_shouldEditTableColumn_item_))
return [_outlineView._outlineViewDelegate outlineView:_outlineView shouldEditTableColumn:aColumn item:[_outlineView itemAtRow:aRow]];
@@ -1885,7 +1921,7 @@ var _loadItemInfoForItem = function(/*CPOutlineView*/ anOutlineView, /*id*/ anIt
return NO;
}
- (float)tableView:(CPTableView)theTableView heightOfRow:(int)theRow
- (float)tableView:(CPTableView)theTableView heightOfRow:(CPInteger)theRow
{
if ((_outlineView._implementedOutlineViewDelegateMethods & CPOutlineViewDelegate_outlineView_heightOfRowByItem_))
return [_outlineView._outlineViewDelegate outlineView:_outlineView heightOfRowByItem:[_outlineView itemAtRow:theRow]];
@@ -1893,7 +1929,7 @@ var _loadItemInfoForItem = function(/*CPOutlineView*/ anOutlineView, /*id*/ anIt
return [theTableView rowHeight];
}
- (void)tableView:(CPTableView)aTableView willDisplayView:(id)aView forTableColumn:(CPTableColumn)aTableColumn row:(int)aRowIndex
- (void)tableView:(CPTableView)aTableView willDisplayView:(id)aView forTableColumn:(CPTableColumn)aTableColumn row:(CPInteger)aRowIndex
{
if ((_outlineView._implementedOutlineViewDelegateMethods & CPOutlineViewDelegate_outlineView_willDisplayView_forTableColumn_item_))
{
@@ -1902,7 +1938,7 @@ var _loadItemInfoForItem = function(/*CPOutlineView*/ anOutlineView, /*id*/ anIt
}
}
- (BOOL)tableView:(CPTableView)aTableView isGroupRow:(int)aRow
- (BOOL)tableView:(CPTableView)aTableView isGroupRow:(CPInteger)aRow
{
if ((_outlineView._implementedOutlineViewDelegateMethods & CPOutlineViewDelegate_outlineView_isGroupItem_))
return [_outlineView._outlineViewDelegate outlineView:_outlineView isGroupItem:[_outlineView itemAtRow:aRow]];
@@ -1910,7 +1946,7 @@ var _loadItemInfoForItem = function(/*CPOutlineView*/ anOutlineView, /*id*/ anIt
return NO;
}
- (CPMenu)tableView:(CPTableView)aTableView menuForTableColumn:(CPTableColumn)aTableColumn row:(int)aRow
- (CPMenu)tableView:(CPTableView)aTableView menuForTableColumn:(CPTableColumn)aTableColumn row:(CPInteger)aRow
{
if ((_outlineView._implementedOutlineViewDelegateMethods & CPOutlineViewDelegate_outlineView_menuForTableColumn_item_))
{
@@ -1923,6 +1959,22 @@ var _loadItemInfoForItem = function(/*CPOutlineView*/ anOutlineView, /*id*/ anIt
return [_outlineView menu] || [[_outlineView class] defaultMenu];
}
- (CPIndexSet)tableView:(CPTableView)aTableView selectionIndexesForProposedSelection:(CPIndexSet)anIndexSet
{
if ((_outlineView._implementedOutlineViewDelegateMethods & CPOutlineViewDelegate_outlineView_selectionIndexesForProposedSelection_))
return [_outlineView._outlineViewDelegate outlineView:_outlineView selectionIndexesForProposedSelection:anIndexSet];
return anIndexSet;
}
- (BOOL)tableView:(CPTableView)aTableView shouldSelectTableColumn:(CPTableColumn)aTableColumn
{
if ((_outlineView._implementedOutlineViewDelegateMethods & CPOutlineViewDelegate_outlineView_shouldSelectTableColumn_))
return [_outlineView._outlineViewDelegate outlineView:_outlineView shouldSelectTableColumn:aTableColumn];
return YES;
}
@end
@implementation CPDisclosureButton : CPButton
@@ -1940,7 +1992,7 @@ var _loadItemInfoForItem = function(/*CPOutlineView*/ anOutlineView, /*id*/ anIt
return self;
}
- (void)setState:(CPState)aState
- (void)setState:(CPInteger)aState
{
[super setState:aState];
+11 -4
View File
@@ -191,10 +191,12 @@ var CPPasteboards = nil,
_owners = @{};
_provided = @{};
var count = _types.length;
while (count--)
[_owners setObject:anOwner forKey:_types[count]];
if (anOwner)
{
var count = _types.length;
while (count--)
[_owners setObject:anOwner forKey:_types[count]];
}
if (_nativePasteboard && shouldUpdate)
{
@@ -205,6 +207,7 @@ var CPPasteboards = nil,
_nativePasteboard.declareTypes_(nativeTypes);
_changeCount = _nativePasteboard.changeCount();
}
return ++_changeCount;
}
@@ -243,6 +246,10 @@ var CPPasteboards = nil,
*/
- (void)setString:(CPString)aString forType:(CPString)aType
{
// Putting a non-string on the string pasteboard can lead to strange crashes.
if (aString && aString.isa && ![aString isKindOfClass:CPString])
[CPException raise:CPInvalidArgumentException reason:"CPPasteboard setString:forType: must be called with a string."];
[self setPropertyList:aString forType:aType];
}
+5 -5
View File
@@ -279,7 +279,7 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
Selects the item at the specified index
@param anIndex the index of the item to select
*/
- (void)setObjectValue:(int)anIndex
- (void)setObjectValue:(id)anIndex
{
var indexOfSelectedItem = [self objectValue];
@@ -344,7 +344,7 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
Returns the item at the specified index or \c nil if the item does not exist.
@param anIndex the index of the item to obtain
*/
- (CPMenuItem)itemAtIndex:(unsigned)anIndex
- (CPMenuItem)itemAtIndex:(CPUInteger)anIndex
{
return [[self menu] itemAtIndex:anIndex];
}
@@ -353,7 +353,7 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
Returns the title of the item at the specified index or \c nil if no item exists.
@param anIndex the index of the item
*/
- (CPString)itemTitleAtIndex:(unsigned)anIndex
- (CPString)itemTitleAtIndex:(CPUInteger)anIndex
{
return [[[self menu] itemAtIndex:anIndex] title];
}
@@ -838,7 +838,7 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
[self _setContentValuesIfNeeded:contentArray];
}
- (void)valueForBinding:(CPString)aBinding
- (id)valueForBinding:(CPString)aBinding
{
return [self _content];
}
@@ -910,7 +910,7 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
{
}
- (void)setValue:(id)aValue forBinding:(CPString)aBinding
- (void)setValue:(CPArray)aValue forBinding:(CPString)aBinding
{
[super _setContent:aValue];
}
+1 -1
View File
@@ -152,7 +152,7 @@ CPRadioImageOffset = 4.0;
[_radioGroup _setSelectedRadio:self];
}
- (void)sendAction:(SEL)anAction to:(id)anObject
- (BOOL)sendAction:(SEL)anAction to:(id)anObject
{
[super sendAction:anAction to:anObject];
+1 -1
View File
@@ -356,7 +356,7 @@ CPDeleteForwardKeyCode = 46;
var CPResponderNextResponderKey = @"CPResponderNextResponderKey",
CPResponderMenuKey = @"CPResponderMenuKey";
@implementation CPResponder (CPCoding)
@implementation CPResponder (CPCoding) <CPCoding>
/*!
Initializes the responder with data from a coder.
+5 -5
View File
@@ -484,7 +484,7 @@
#pragma mark RuleEditor delegate methods
- (int)_queryNumberOfChildrenOfItem:(id)rowItem withRowType:(int)type
- (int)_queryNumberOfChildrenOfItem:(id)rowItem withRowType:(CPRuleEditorRowType)type
{
if (rowItem == nil)
{
@@ -494,7 +494,7 @@
return [[rowItem children] count];
}
- (id)_queryChild:(int)childIndex ofItem:(id)rowItem withRowType:(int)type
- (id)_queryChild:(int)childIndex ofItem:(id)rowItem withRowType:(CPRuleEditorRowType)type
{
if (rowItem == nil)
{
@@ -505,7 +505,7 @@
return [[rowItem children] objectAtIndex:childIndex];
}
- (id)_queryValueForItem:(id)rowItem inRow:(int)rowIndex
- (id)_queryValueForItem:(id)rowItem inRow:(CPInteger)rowIndex
{
return [rowItem displayValue];
}
@@ -516,7 +516,7 @@ var CPPredicateTemplatesKey = @"CPPredicateTemplates";
@implementation CPPredicateEditor (CPCoding)
- (id)initWithCoder:(id)aCoder
- (id)initWithCoder:(CPCoder)aCoder
{
self = [super initWithCoder:aCoder];
@@ -531,7 +531,7 @@ var CPPredicateTemplatesKey = @"CPPredicateTemplates";
return self;
}
- (void)encodeWithCoder:(id)aCoder
- (void)encodeWithCoder:(CPCoder)aCoder
{
[super encodeWithCoder:aCoder];
[aCoder encodeObject:_allTemplates forKey:CPPredicateTemplatesKey];
@@ -702,12 +702,12 @@ CPTransformableAttributeType = 1800;
return textField;
}
- (void)_setOptions:(unsigned int)options
- (void)_setOptions:(unsigned)options
{
_predicateOptions = options;
}
- (void)_setModifier:(unsigned int)modifier
- (void)_setModifier:(unsigned)modifier
{
_predicateModifier = modifier;
}
+26 -26
View File
@@ -122,7 +122,7 @@ var CPRuleEditorItemPBoardType = @"CPRuleEditorItemPBoardType",
return @"rule-editor";
}
+ (id)themeAttributes
+ (CPDictionary)themeAttributes
{
return @{
@"alternating-row-colors": [CPNull null],
@@ -461,7 +461,7 @@ var CPRuleEditorItemPBoardType = @"CPRuleEditorItemPBoardType",
@param row The index of a row in the receiver.
@return The currently chosen items for row @a row.
*/
- (id)criteriaForRow:(int)row
- (id)criteriaForRow:(CPInteger)row
{
var rowcache = [self _rowCacheForIndex:row];
if (rowcache)
@@ -480,7 +480,7 @@ var CPRuleEditorItemPBoardType = @"CPRuleEditorItemPBoardType",
@return The chosen values (strings, views, or menu items) for row row.
@discussion The values returned are the same as those returned from the delegate method -#ruleEditor:displayValueForCriterion:inRow:
*/
- (CPMutableArray)displayValuesForRow:(int)row
- (CPMutableArray)displayValuesForRow:(CPInteger)row
{
var rowcache = [self _rowCacheForIndex:row];
if (rowcache)
@@ -503,7 +503,7 @@ var CPRuleEditorItemPBoardType = @"CPRuleEditorItemPBoardType",
@param rowIndex The index of a row in the receiver.
@return The index of the parent of the row at @a rowIndex. If the row at @a rowIndex is a root row, returns @c -1.
*/
- (int)parentRowForRow:(int)rowIndex
- (int)parentRowForRow:(CPInteger)rowIndex
{
if (rowIndex < 0 || rowIndex >= [self numberOfRows])
[CPException raise:CPRangeException reason:_cmd + @" row " + rowIndex + " is out of range"];
@@ -544,7 +544,7 @@ TODO: implement
@return The type of the row at @a rowIndex.
@warning Raises a @c CPRangeException if rowIndex is less than @c 0 or greater than or equal to the number of rows.
*/
- (CPRuleEditorRowType)rowTypeForRow:(int)rowIndex
- (CPRuleEditorRowType)rowTypeForRow:(CPInteger)rowIndex
{
if (rowIndex < 0 || rowIndex > [self numberOfRows])
[CPException raise:CPRangeException reason:_cmd + @"row " + rowIndex + " is out of range"];
@@ -565,7 +565,7 @@ TODO: implement
@return The immediate subrows of the row at @a rowIndex.
@discussion Rows are numbered starting at @c 0.
*/
- (CPIndexSet)subrowIndexesForRow:(int)rowIndex
- (CPIndexSet)subrowIndexesForRow:(CPInteger)rowIndex
{
var object;
@@ -691,7 +691,7 @@ TODO: implement
@note Currently, @a shouldAnimate has no effect, rows are always animated when calling this method.
@see addRow:
*/
- (void)insertRowAtIndex:(int)rowIndex withType:(unsigned int)rowType asSubrowOfRow:(int)parentRow animate:(BOOL)shouldAnimate
- (void)insertRowAtIndex:(int)rowIndex withType:(unsigned int)rowType asSubrowOfRow:(CPInteger)parentRow animate:(BOOL)shouldAnimate
{
/*
TODO: raise exceptions if parentRow is greater than or equal to rowIndex, or if rowIndex would fall amongst the children of some other parent, or if the nesting mode forbids this configuration.
@@ -1313,7 +1313,7 @@ TODO: implement
return [_boundArrayOwner mutableArrayValueForKey:_boundArrayKeyPath];
}
- (BOOL)_nextUnusedItems:(CPArray)items andValues:(CPArray)values forRow:(int)rowIndex forRowType:(unsigned int)type
- (BOOL)_nextUnusedItems:(CPArray)items andValues:(CPArray)values forRow:(CPInteger)rowIndex forRowType:(unsigned int)type
{
var parentItem = [items lastObject], // if empty items array, this is NULL aka the root item;
childrenCount = [self _queryNumberOfChildrenOfItem:parentItem withRowType:type],
@@ -1375,7 +1375,7 @@ TODO: implement
return YES;
}
- (CPMutableArray)_getItemsAndValuesToAddForRow:(int)rowIndex ofType:(CPRuleEditorRowType)type
- (CPMutableArray)_getItemsAndValuesToAddForRow:(CPInteger)rowIndex ofType:(CPRuleEditorRowType)type
{
//var cachedItemsAndValues = _itemsAndValuesToAddForRowType[type];
//if (cachedItemsAndValues)
@@ -1418,7 +1418,7 @@ TODO: implement
[self insertRowAtIndex:insertIndex withType:type asSubrowOfRow:parentRowIndex animate:YES];
}
- (id)_insertNewRowAtIndex:(int)insertIndex ofType:(CPRuleEditorRowType)rowtype withParentRow:(int)parentRowIndex
- (id)_insertNewRowAtIndex:(int)insertIndex ofType:(CPRuleEditorRowType)rowtype withParentRow:(CPInteger)parentRowIndex
{
var row = [[[self rowClass] alloc] init],
itemsandvalues = [self _getItemsAndValuesToAddForRow:insertIndex ofType:rowtype],
@@ -1520,7 +1520,7 @@ TODO: implement
}
}
- (void)_changedItem:(id)fromItem toItem:(id)toItem inRow:(int)aRow atCriteriaIndex:(int)fromItemIndex
- (void)_changedItem:(id)fromItem toItem:(id)toItem inRow:(CPInteger)aRow atCriteriaIndex:(int)fromItemIndex
{
var criteria = [self criteriaForRow:aRow],
displayValues = [self displayValuesForRow:aRow],
@@ -1684,7 +1684,7 @@ TODO: implement
[super bind:aBinding toObject:observableController withKeyPath:aKeyPath options:options];
}
- (void)unbind:(id)object
- (void)unbind:(CPString)object
{
_rowClass = [_CPRuleEditorRowObject class];
[super unbind:object];
@@ -2005,7 +2005,7 @@ TODO: implement
return [_ruleDelegate ruleEditor:self child:childIndex forCriterion:item withRowType:type];
}
- (id)_queryValueForItem:(id)item inRow:(int)row
- (id)_queryValueForItem:(id)item inRow:(CPInteger)row
{
return [_ruleDelegate ruleEditor:self displayValueForCriterion:item inRow:row];
}
@@ -2026,12 +2026,12 @@ TODO: implement
_alignmentGridWidth = width;
}
- (BOOL)_validateItem:(id)item value:(id)value inRow:(int)row
- (BOOL)_validateItem:(id)item value:(id)value inRow:(CPInteger)row
{
return [self _queryCanSelectItem:item displayValue:value inRow:row];
}
- (BOOL)_queryCanSelectItem:(id)item displayValue:(id)value inRow:(int)row
- (BOOL)_queryCanSelectItem:(id)item displayValue:(id)value inRow:(CPInteger)row
{
return YES;
}
@@ -2128,7 +2128,7 @@ TODO: implement
return YES;
}
- (CPDragOperation)draggingEntered:(id < CPDraggingInfo >)sender
- (CPDragOperation)draggingEntered:(id /*< CPDraggingInfo >*/)sender
{
if ([sender draggingSource] === self)
{
@@ -2158,7 +2158,7 @@ TODO: implement
_subviewIndexOfDropLine = CPNotFound;
}
- (CPDragOperation)draggingUpdated:(id <CPDraggingInfo>)sender
- (CPDragOperation)draggingUpdated:(id /*<CPDraggingInfo>*/)sender
{
var point = [self convertPoint:[sender draggingLocation] fromView:nil],
y = point.y + _sliceHeight / 2,
@@ -2195,12 +2195,12 @@ TODO: implement
return CPDragOperationMove;
}
- (BOOL)prepareForDragOperation:(id < CPDraggingInfo >)sender
- (BOOL)prepareForDragOperation:(id /*< CPDraggingInfo >*/)sender
{
return (_subviewIndexOfDropLine !== CPNotFound);
}
- (BOOL)performDragOperation:(id < CPDraggingInfo >)info
- (BOOL)performDragOperation:(id /*< CPDraggingInfo >*/)info
{
var aboveInsertIndexCount = 0,
object,
@@ -2262,7 +2262,7 @@ TODO: implement
{
}
- (void)_setWindow:(id)window
- (void)_setWindow:(CPWindow)window
{
[super _setWindow:window];
}
@@ -2325,7 +2325,7 @@ TODO: implement
return YES;
}
- (void)_getAllAvailableItems:(id)items values:(id)values asChildrenOfItem:(id)parentItem inRow:(int)aRow
- (void)_getAllAvailableItems:(id)items values:(id)values asChildrenOfItem:(id)parentItem inRow:(CPInteger)aRow
{
var type,
indexofCriterion,
@@ -2426,7 +2426,7 @@ var CPRuleEditorAlignmentGridWidthKey = @"CPRuleEditorAlignmentGridWidth",
return self;
}
- (void)encodeWithCoder:(id)coder
- (void)encodeWithCoder:(CPCoder)coder
{
[super encodeWithCoder:coder];
@@ -2481,7 +2481,7 @@ var CriteriaKey = @"criteria",
return "<" + [self className] + ">\nsubrows = " + [subrows description] + "\ncriteria = " + [criteria description] + "\ndisplayValues = " + [displayValues description];
}
- (id)initWithCoder:(id)coder
- (id)initWithCoder:(CPCoder)coder
{
self = [super init];
if (self !== nil)
@@ -2495,7 +2495,7 @@ var CriteriaKey = @"criteria",
return self;
}
- (void)encodeWithCoder:(id)coder
- (void)encodeWithCoder:(CPCoder)coder
{
[coder encodeObject:subrows forKey:SubrowsKey];
[coder encodeObject:criteria forKey:CriteriaKey];
@@ -2534,7 +2534,7 @@ var CPBoundArrayKey = @"CPBoundArray";
return self;
}
- (id)initWithCoder:(id)coder
- (id)initWithCoder:(CPCoder)coder
{
if (self = [super init])
boundArray = [coder decodeObjectForKey:CPBoundArrayKey];
@@ -2542,7 +2542,7 @@ var CPBoundArrayKey = @"CPBoundArray";
return self;
}
- (void)encodeWithCoder:(id)coder
- (void)encodeWithCoder:(CPCoder)coder
{
[coder encodeObject:boundArray forKey:CPBoundArrayKey];
}
@@ -86,7 +86,7 @@ else if (CPBrowserIsEngine(CPInternetExplorerBrowserEngine))
return self;
}
- (id)hitTest:(CGPoint)point
- (CPView)hitTest:(CGPoint)point
{
if (!CGRectContainsPoint([self frame], point) || ![self sliceIsEditable])
return nil;
@@ -100,12 +100,12 @@ else if (CPBrowserIsEngine(CPInternetExplorerBrowserEngine))
return ![superview isKindOfClass:[_CPRuleEditorViewSlice]] || [superview isEditable];
}
- (BOOL)trackMouse:(CPEvent)theEvent
- (void)trackMouse:(CPEvent)theEvent
{
if (![self sliceIsEditable])
return NO;
return;
return [super trackMouse:theEvent];
[super trackMouse:theEvent];
}
- (CGRect)contentRectForBounds:(CGRect)bounds
@@ -522,7 +522,7 @@ var CONTROL_HEIGHT = 16.,
return self;
}
- (id)hitTest:(CGPoint)point
- (CPView)hitTest:(CGPoint)point
{
if (!CGRectContainsPoint([self frame], point))
return nil;
+27 -17
View File
@@ -34,34 +34,44 @@
/*! @ignore */
var _isSystemUsingOverlayScrollers = function()
var _isBrowserUsingOverlayScrollers = function()
{
#if PLATFORM(DOM)
var inner = document.createElement('p'),
outer = document.createElement('div');
/*
Even if the system supports overlay (Lion) scrollers,
the browser (e.g. FireFox *cough*) may not.
inner.style.width = "100%";
inner.style.height = "200px";
To determine if the browser is using overlay scrollbars,
we put a <p> element inside a shorter <div> and set its
overflow to scroll. If the browser is using visible scrollers,
the outer div's clientWidth will less than the offsetWidth, because
clientWidth does not include scrollbars, whereas offsetWidth does.
So if clientWidth === offsetWidth, the scrollers must be overlay.
Even IE gets this right.
*/
var outer = document.createElement('div'),
inner = document.createElement('p');
// position it absolute so it doesn't affect existing DOM elements
outer.style.position = "absolute";
outer.style.top = "0px";
outer.style.left = "0px";
outer.style.visibility = "hidden";
outer.style.width = "200px";
outer.style.height = "150px";
outer.style.overflow = "hidden";
outer.appendChild (inner);
outer.style.overflow = "scroll";
document.body.appendChild (outer);
var w1 = inner.offsetWidth;
outer.style.overflow = 'scroll';
var w2 = inner.offsetWidth;
if (w1 == w2)
w2 = outer.clientWidth;
inner.style.width = "100%";
inner.style.height = "200px";
outer.appendChild(inner);
document.body.removeChild (outer);
document.body.appendChild(outer);
return (w1 - w2 == 0);
var usingOverlayScrollers = outer.clientWidth === outer.offsetWidth;
document.body.removeChild(outer);
return usingOverlayScrollers;
#else
return NO;
#endif
@@ -130,8 +140,8 @@ var CPScrollerStyleGlobal = CPScrollerStyleOverlay,
var globalValue = [[CPBundle mainBundle] objectForInfoDictionaryKey:@"CPScrollersGlobalStyle"];
if (globalValue == nil || globalValue == -1)
CPScrollerStyleGlobal = _isSystemUsingOverlayScrollers() ? CPScrollerStyleOverlay : CPScrollerStyleLegacy
if (globalValue === nil || globalValue === -1)
CPScrollerStyleGlobal = _isBrowserUsingOverlayScrollers() ? CPScrollerStyleOverlay : CPScrollerStyleLegacy
else
CPScrollerStyleGlobal = globalValue;
}
+2 -1
View File
@@ -108,7 +108,7 @@ CPThemeStateScrollerKnobDark = CPThemeState("scroller-knob-dark");
return "scroller";
}
+ (id)themeAttributes
+ (CPDictionary)themeAttributes
{
return @{
@"scroller-width": 7.0,
@@ -182,6 +182,7 @@ CPThemeStateScrollerKnobDark = CPThemeState("scroller-knob-dark");
_allowFadingOut = YES;
_isMouseOver = NO;
_style = CPScrollerStyleOverlay;
var paramAnimFadeOut = @{
CPViewAnimationTargetKey: self,
CPViewAnimationEffectKey: CPViewAnimationFadeOutEffect,
+1 -1
View File
@@ -458,7 +458,7 @@ var RECENT_SEARCH_PREFIX = @" ";
[self sendAction:[self action] to:[self target]];
}
- (void)sendAction:(SEL)anAction to:(id)anObject
- (BOOL)sendAction:(SEL)anAction to:(id)anObject
{
[super sendAction:anAction to:anObject];
+1 -1
View File
@@ -56,7 +56,7 @@ CPSegmentSwitchTrackingMomentary = 2;
return "segmented-control";
}
+ (id)themeAttributes
+ (CPDictionary)themeAttributes
{
return @{
@"alignment": CPCenterTextAlignment,
+1 -1
View File
@@ -47,7 +47,7 @@ CPThemeStateShadowViewHeavy = CPThemeState("shadowview-style-heavy");
return "shadow-view";
}
+ (id)themeAttributes
+ (CPDictionary)themeAttributes
{
return @{
@"bezel-color": [CPNull null],
+1 -1
View File
@@ -49,7 +49,7 @@ CPCircularSlider = 1;
return "slider";
}
+ (id)themeAttributes
+ (CPDictionary)themeAttributes
{
return @{
@"knob-color": [CPNull null],
-1
View File
@@ -55,7 +55,6 @@
CPTextField _hexLabel;
CPTextField _hexValue;
CPTextField _hexValue;
CPTextField _redValue;
CPTextField _greenValue;
CPTextField _blueValue;
+2 -2
View File
@@ -103,7 +103,7 @@ var ShouldSuppressResizeNotifications = 1,
return @"splitview";
}
+ (id)themeAttributes
+ (CPDictionary)themeAttributes
{
return @{
@"divider-thickness": 1.0,
@@ -995,7 +995,7 @@ The sum of the views and the sum of the dividers should be equal to the size of
@param unsigned int - The divider index the button bar will be assigned to.
*/
// FIXME Should be renamed to setButtonBar:ofDividerAtIndex:.
- (void)setButtonBar:(CPButtonBar)aButtonBar forDividerAtIndex:(unsigned)dividerIndex
- (void)setButtonBar:(CPButtonBar)aButtonBar forDividerAtIndex:(CPUInteger)dividerIndex
{
if (!aButtonBar)
{
+2 -2
View File
@@ -213,7 +213,7 @@
Set the current value of the stepper.
@param aValue a float containing the value
*/
- (void)setDoubleValue:(float)aValue
- (void)setDoubleValue:(double)aValue
{
if (aValue > _maxValue)
[super setDoubleValue:_valueWraps ? _minValue : _maxValue];
@@ -267,7 +267,7 @@
return @"stepper";
}
+ (id)themeAttributes
+ (CPDictionary)themeAttributes
{
return @{
@"bezel-color-up-button": [CPNull null],
+3 -3
View File
@@ -107,7 +107,7 @@ var CPTabViewDidSelectTabViewItemSelector = 1,
@param aTabViewItem the item to insert
@param anIndex the index for the item
*/
- (void)insertTabViewItem:(CPTabViewItem)aTabViewItem atIndex:(unsigned)anIndex
- (void)insertTabViewItem:(CPTabViewItem)aTabViewItem atIndex:(CPUInteger)anIndex
{
[_items insertObject:aTabViewItem atIndex:anIndex];
@@ -183,7 +183,7 @@ var CPTabViewDidSelectTabViewItemSelector = 1,
Returns the CPTabViewItem at the specified index.
@return a tab view item, or nil
*/
- (CPTabViewItem)tabViewItemAtIndex:(unsigned)anIndex
- (CPTabViewItem)tabViewItemAtIndex:(CPUInteger)anIndex
{
return [_items objectAtIndex:anIndex];
}
@@ -270,7 +270,7 @@ var CPTabViewDidSelectTabViewItemSelector = 1,
Selects the item at the specified index.
@param anIndex the index of the item to display.
*/
- (BOOL)selectTabViewItemAtIndex:(unsigned)anIndex
- (BOOL)selectTabViewItemAtIndex:(CPUInteger)anIndex
{
if (anIndex === _selectedIndex)
return;
+3 -3
View File
@@ -416,7 +416,7 @@ CPTableColumnUserResizingMask = 1 << 1;
to be invoked with row equal to -1 in cases where no actual row is involved but the table
view needs to get some generic cell info.
*/
- (id)dataViewForRow:(int)aRowIndex
- (id)dataViewForRow:(CPInteger)aRowIndex
{
return [self dataView];
}
@@ -595,7 +595,7 @@ CPTableColumnUserResizingMask = 1 << 1;
@implementation CPTableColumn (Bindings)
+ (id)_binderClassForBinding:(CPString)aBinding
+ (Class)_binderClassForBinding:(CPString)aBinding
{
if (aBinding == CPValueBinding)
return [CPTableColumnValueBinder class];
@@ -828,7 +828,7 @@ var CPTableColumnIdentifierKey = @"CPTableColumnIdentifierKey",
/*!
@ignore
*/
- (id)dataCellForRow:(int)row
- (id)dataCellForRow:(CPInteger)row
{
[CPException raise:CPUnsupportedMethodException
reason:@"dataCellForRow: is not supported. Use -dataViewForRow:row instead."];
+29 -26
View File
@@ -43,7 +43,7 @@
return @"columnHeader";
}
+ (id)themeAttributes
+ (CPDictionary)themeAttributes
{
return @{
@"background-color": [CPNull null],
@@ -53,11 +53,11 @@
@"text-color": [CPNull null],
@"font": [CPNull null],
@"text-shadow-color": [CPNull null],
@"text-shadow-offset": CGSizeMakeZero(),
@"text-shadow-offset": CGSizeMakeZero()
};
}
- (void)initWithFrame:(CGRect)frame
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
@@ -246,11 +246,12 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal
return @"tableHeaderRow";
}
+ (id)themeAttributes
+ (CPDictionary)themeAttributes
{
return @{
@"background-color": [CPNull null],
@"divider-color": [CPColor grayColor],
@"divider-thickness": 1.0
};
}
@@ -286,7 +287,7 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal
return [_tableView columnAtPoint:CGPointMake(aPoint.x, aPoint.y)];
}
- (CGRect)headerRectOfColumn:(int)aColumnIndex
- (CGRect)headerRectOfColumn:(CPInteger)aColumnIndex
{
var headerRect = CGRectMakeCopy([self bounds]),
columnRect = [_tableView rectOfColumn:aColumnIndex];
@@ -307,7 +308,7 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal
return _drawsColumnLines;
}
- (CGRect)_cursorRectForColumn:(int)column
- (CGRect)_cursorRectForColumn:(CPInteger)column
{
if (column == -1 || !([_tableView._tableColumns[column] resizingMask] & CPTableColumnUserResizingMask))
return CGRectMakeZero();
@@ -333,7 +334,7 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal
var headerView = [_tableView._tableColumns[column] headerView];
[headerView setThemeState:CPThemeStateHighlighted];
if (_tableView._editingColumn == column)
if (_tableView._editingCellIndex || _tableView._editingColumn == column)
[[self window] makeFirstResponder:_tableView];
}
@@ -382,7 +383,7 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal
_mouseDownLocation = currentLocation;
_activeColumn = columnIndex;
[_tableView _sendDelegateDidMouseDownInHeader:columnIndex];
[_tableView _sendDelegateMouseDownInHeaderOfTableColumn:columnIndex];
if (shouldResize)
[self startResizingTableColumn:columnIndex at:currentLocation];
@@ -416,13 +417,13 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal
[CPApp setTarget:self selector:@selector(trackMouse:) forNextEventMatchingMask:CPLeftMouseDraggedMask | CPLeftMouseUpMask untilDate:nil inMode:nil dequeue:YES];
}
- (void)startTrackingTableColumn:(int)aColumnIndex at:(CGPoint)aPoint
- (void)startTrackingTableColumn:(CPInteger)aColumnIndex at:(CGPoint)aPoint
{
_lastDragDestinationColumnIndex = -1;
[self _setPressedColumn:aColumnIndex];
}
- (BOOL)continueTrackingTableColumn:(int)aColumnIndex at:(CGPoint)aPoint
- (BOOL)continueTrackingTableColumn:(CPInteger)aColumnIndex at:(CGPoint)aPoint
{
if ([self _shouldDragTableColumn:aColumnIndex at:aPoint])
{
@@ -443,21 +444,21 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal
return YES;
}
- (BOOL)_shouldStopTrackingTableColumn:(int)aColumnIndex at:(CGPoint)aPoint
- (BOOL)_shouldStopTrackingTableColumn:(CPInteger)aColumnIndex at:(CGPoint)aPoint
{
return _isTrackingColumn && _activeColumn === aColumnIndex &&
CGRectContainsPoint([self headerRectOfColumn:aColumnIndex], aPoint);
}
- (void)stopTrackingTableColumn:(int)aColumnIndex at:(CGPoint)aPoint
- (void)stopTrackingTableColumn:(CPInteger)aColumnIndex at:(CGPoint)aPoint
{
[self _setPressedColumn:CPNotFound];
[self _updateResizeCursor:[CPApp currentEvent]];
}
- (BOOL)_shouldDragTableColumn:(int)aColumnIndex at:(CGPoint)aPoint
- (BOOL)_shouldDragTableColumn:(CPInteger)aColumnIndex at:(CGPoint)aPoint
{
return ABS(aPoint.x - _mouseDownLocation.x) >= 10.0 && [_tableView _shouldReorderColumn:aColumnIndex toColumn:-1];
return ABS(aPoint.x - _mouseDownLocation.x) >= 10.0 && [_tableView _sendDelegateShouldReorderColumn:aColumnIndex toColumn:-1];
}
- (CGRect)_headerRectOfLastVisibleColumn
@@ -503,9 +504,9 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal
[dragWindow setFrame:frame];
}
- (void)_moveColumn:(int)aFromIndex toColumn:(int)aToIndex
- (void)_moveColumn:(CPInteger)aFromIndex toColumn:(CPInteger)aToIndex
{
if ([_tableView _shouldReorderColumn:aFromIndex toColumn:aToIndex])
if ([_tableView _sendDelegateShouldReorderColumn:aFromIndex toColumn:aToIndex])
{
[_tableView moveColumn:aFromIndex toColumn:aToIndex];
_activeColumn = aToIndex;
@@ -580,7 +581,7 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal
[_tableView _enqueueDraggingViews];
}
- (BOOL)shouldResizeTableColumn:(int)aColumnIndex at:(CGPoint)aPoint
- (BOOL)shouldResizeTableColumn:(CPInteger)aColumnIndex at:(CGPoint)aPoint
{
if (_isResizing)
return YES;
@@ -591,7 +592,7 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal
return [_tableView allowsColumnResizing] && CGRectContainsPoint([self _cursorRectForColumn:aColumnIndex], aPoint);
}
- (void)startResizingTableColumn:(int)aColumnIndex at:(CGPoint)aPoint
- (void)startResizingTableColumn:(CPInteger)aColumnIndex at:(CGPoint)aPoint
{
_isResizing = YES;
@@ -601,7 +602,7 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal
[_tableView setDisableAutomaticResizing:YES];
}
- (void)continueResizingTableColumn:(int)aColumnIndex at:(CGPoint)aPoint
- (void)continueResizingTableColumn:(CPInteger)aColumnIndex at:(CGPoint)aPoint
{
var tableColumn = [[_tableView tableColumns] objectAtIndex:aColumnIndex],
newWidth = [tableColumn width] + aPoint.x - _previousTrackingLocation.x;
@@ -621,7 +622,7 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal
}
}
- (void)stopResizingTableColumn:(int)aColumnIndex at:(CGPoint)aPoint
- (void)stopResizingTableColumn:(CPInteger)aColumnIndex at:(CGPoint)aPoint
{
var tableColumn = [[_tableView tableColumns] objectAtIndex:aColumnIndex];
[tableColumn _postDidResizeNotificationWithOldWidth:_columnOldWidth];
@@ -679,7 +680,8 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal
- (void)layoutSubviews
{
var tableColumns = [_tableView tableColumns],
count = [tableColumns count];
count = [tableColumns count],
lineThickness = [self currentValueForThemeAttribute:@"divider-thickness"];
for (var i = 0; i < count; i++)
{
@@ -689,7 +691,7 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal
// Make space for the gridline on the right.
frame.origin.x -= 0.5;
frame.size.width -= 1.0;
frame.size.width -= lineThickness;
frame.size.height -= 0.5;
// Note: we're not adding in intercell spacing here. This setting only affects the regular
// table cell data views, not the header. Verified in Cocoa on March 29th, 2011.
@@ -714,9 +716,10 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal
tableColumns = [_tableView tableColumns],
exposedTableColumns = _tableView._exposedColumns,
firstIndex = [exposedTableColumns firstIndex],
exposedRange = CPMakeRange(firstIndex, [exposedTableColumns lastIndex] - firstIndex + 1);
exposedRange = CPMakeRange(firstIndex, [exposedTableColumns lastIndex] - firstIndex + 1),
lineThickness = [self currentValueForThemeAttribute:@"divider-thickness"];
CGContextSetLineWidth(context, 1);
CGContextSetLineWidth(context, lineThickness);
CGContextSetStrokeColor(context, [self currentValueForThemeAttribute:@"divider-color"]);
[exposedColumnIndexes getIndexes:columnsArray maxCount:-1 inIndexRange:exposedRange];
@@ -735,8 +738,8 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal
columnMaxX = CGRectGetMaxX(columnToStroke);
CGContextMoveToPoint(context, FLOOR(columnMaxX) - 0.5, ROUND(CGRectGetMinY(columnToStroke)));
CGContextAddLineToPoint(context, FLOOR(columnMaxX) - 0.5, ROUND(CGRectGetMaxY(columnToStroke)) - 1.0);
CGContextMoveToPoint(context, FLOOR(columnMaxX) - 0.5 * lineThickness, ROUND(CGRectGetMinY(columnToStroke)));
CGContextAddLineToPoint(context, FLOOR(columnMaxX) - 0.5 * lineThickness, ROUND(CGRectGetMaxY(columnToStroke)) - 1.0);
}
CGContextClosePath(context);
+853 -399
View File
File diff suppressed because it is too large Load Diff
+11
View File
@@ -28,3 +28,14 @@ CPFormFeedCharacter = "\u000c";
CPCarriageReturnCharacter = "\u000d";
CPBackTabCharacter = "\u0019";
CPDeleteCharacter = "\u007f";
CPIllegalTextMovement = 0;
CPOtherTextMovement = 0;
CPReturnTextMovement = 16;
CPTabTextMovement = 17;
CPBacktabTextMovement = 18;
CPLeftTextMovement = 19;
CPRightTextMovement = 20;
CPUpTextMovement = 21;
CPDownTextMovement = 22;
CPCancelTextMovement = 23;
+316 -110
View File
@@ -209,7 +209,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
return "textfield";
}
+ (id)themeAttributes
+ (CPDictionary)themeAttributes
{
return @{
@"bezel-inset": CGInsetMakeZero(),
@@ -218,7 +218,6 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
};
}
/* @ignore */
#if PLATFORM(DOM)
- (DOMElement)_inputElement
{
@@ -352,8 +351,8 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
else
[self unsetThemeState:CPThemeStateEditable];
// We only allow first responder status if the field is editable and enabled.
if (!shouldBeEditable && [[self window] firstResponder] === self)
// We only allow first responder status if the field is enable, and editable or selectable.
if (!(shouldBeEditable && ![self isSelectable]) && [[self window] firstResponder] === self)
[[self window] makeFirstResponder:nil];
if (shouldBeEditable)
@@ -378,7 +377,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
{
[super setEnabled:shouldBeEnabled];
// We only allow first responder status if the field is editable and enabled.
// We only allow first responder status if the field is enabled.
if (!shouldBeEnabled && [[self window] firstResponder] === self)
[[self window] makeFirstResponder:nil];
}
@@ -529,30 +528,36 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
return _textFieldBackgroundColor;
}
/* @ignore */
/*! @ignore */
- (BOOL)acceptsFirstResponder
{
return [self isEditable] && [self isEnabled] && [self _isWithinUsablePlatformRect];
return [self isEnabled] && ([self isEditable] || [self isSelectable]) && [self _isWithinUsablePlatformRect];
}
/* @ignore */
/*! @ignore */
- (BOOL)becomeFirstResponder
{
if (![self isEnabled])
return NO;
// 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])
if ([[self window] isKeyWindow] && [self isEditable])
return [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.)
It's also possible for a text field to be non-editable but selectable in which case it can also become the first responder -
this is what allows text to be copied from it.
*/
- (BOOL)_becomeFirstKeyResponder
{
@@ -561,6 +566,11 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
if (![self _isWithinUsablePlatformRect])
return NO;
// A selectable but non-editable text field may be the first responder, but never the
// first key responder (first key responder indicating editability.)
if (![self isEditable])
return NO;
[self setThemeState:CPThemeStateEditing];
[self _updatePlaceholderState];
@@ -677,28 +687,30 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
return YES;
}
/* @ignore */
/*! @ignore */
- (BOOL)resignFirstResponder
{
#if PLATFORM(DOM)
var element = [self _inputElement],
newValue = element.value,
error = @"";
if (newValue !== _stringValue)
// We might have been the first responder without actually editing.
if (_isEditing && CPTextFieldInputOwner === self)
{
[self _setStringValue:newValue];
}
var element = [self _inputElement],
newValue = element.value,
error = @"";
// If there is a formatter, always give it a chance to reject the resignation,
// even if the value has not changed.
if ([self _valueIsValid:newValue] === NO)
{
element.focus();
return NO;
}
if (newValue !== _stringValue)
{
[self _setStringValue:newValue];
}
// If there is a formatter, always give it a chance to reject the resignation,
// even if the value has not changed.
if ([self _valueIsValid:newValue] === NO)
{
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.
@@ -707,10 +719,13 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
[self _resignFirstKeyResponder];
_isEditing = NO;
[self textDidEndEditing:[CPNotification notificationWithName:CPControlTextDidEndEditingNotification object:self userInfo:nil]];
if ([self isEditable])
{
[self textDidEndEditing:[CPNotification notificationWithName:CPControlTextDidEndEditingNotification object:self userInfo:@{"CPTextMovement": [self _currentTextMovement]}]];
if ([self sendsActionOnEndEditing])
[self sendAction:[self action] to:[self target]];
if ([self sendsActionOnEndEditing])
[self sendAction:[self action] to:[self target]];
}
[self textDidBlur:[CPNotification notificationWithName:CPTextFieldDidBlurNotification object:self userInfo:nil]];
@@ -783,9 +798,14 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
- (void)_windowDidBecomeKey:(CPNotification)aNotification
{
if ([[self window] isKeyWindow] && [[self window] firstResponder] === self)
if (!([self isEnabled] && [self isEditable]))
return;
var wind = [self window];
if ([wind isKeyWindow] && [wind firstResponder] === self)
if (![self _becomeFirstKeyResponder])
[[self window] makeFirstResponder:nil];
[wind makeFirstResponder:nil];
}
- (BOOL)_valueIsValid:(CPString)aValue
@@ -820,13 +840,24 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
}
/*!
Only text fields that can become first responder accepts first mouse.
Only text fields that can become first responder accept first mouse.
*/
- (BOOL)acceptsFirstMouse:(CPEvent)anEvent
{
return [self acceptsFirstResponder];
}
- (void)_didEdit
{
if (!_isEditing)
{
_isEditing = YES;
[self textDidBeginEditing:[CPNotification notificationWithName:CPControlTextDidBeginEditingNotification object:self userInfo:nil]];
}
[self textDidChange:[CPNotification notificationWithName:CPControlTextDidChangeNotification object:self userInfo:nil]];
}
- (void)mouseDown:(CPEvent)anEvent
{
// Don't track! (ever?)
@@ -853,7 +884,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
- (void)mouseUp:(CPEvent)anEvent
{
if (![self isSelectable] && (![self isEditable] || ![self isEnabled]))
if (![self isEnabled] || !([self isSelectable] || [self isEditable]))
[[self nextResponder] mouseUp:anEvent];
else if ([self isSelectable])
{
@@ -865,13 +896,22 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
CPTextFieldCachedSelectStartFunction = nil
CPTextFieldCachedDragFunction = nil;
}
// TODO clickCount === 2 should select the clicked word.
if ([[CPApp currentEvent] clickCount] === 3)
{
[self selectText:nil];
return;
}
return [[[anEvent window] platformWindow] _propagateCurrentDOMEvent:YES];
}
}
- (void)mouseDragged:(CPEvent)anEvent
{
if (![self isSelectable] && (![self isEditable] || ![self isEnabled]))
if (![self isEnabled] || !([self isSelectable] || [self isEditable]))
[[self nextResponder] mouseDragged:anEvent];
else if ([self isSelectable])
return [[[anEvent window] platformWindow] _propagateCurrentDOMEvent:YES];
@@ -879,26 +919,21 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
- (void)keyUp:(CPEvent)anEvent
{
#if PLATFORM(DOM)
if (!([self isEnabled] && [self isEditable]))
return;
#if PLATFORM(DOM)
var newValue = [self _inputElement].value;
if (newValue !== _stringValue)
{
[self _setStringValue:newValue];
if (!_isEditing)
{
_isEditing = YES;
[self textDidBeginEditing:[CPNotification notificationWithName:CPControlTextDidBeginEditingNotification object:self userInfo:nil]];
}
[self textDidChange:[CPNotification notificationWithName:CPControlTextDidChangeNotification object:self userInfo:nil]];
[self _didEdit];
}
#endif
[[[self window] platformWindow] _propagateCurrentDOMEvent:YES];
#endif
}
- (void)keyDown:(CPEvent)anEvent
@@ -931,11 +966,15 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
- (void)insertNewline:(id)sender
{
if (!([self isEnabled] && [self isEditable]))
return;
var newValue = [self _inputElement].value;
if (newValue !== _stringValue)
{
[self _setStringValue:newValue];
[self _didEdit];
}
if ([self _valueIsValid:_stringValue])
@@ -948,7 +987,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
if (_isEditing)
{
_isEditing = NO;
[self textDidEndEditing:[CPNotification notificationWithName:CPControlTextDidEndEditingNotification object:self userInfo:nil]];
[self textDidEndEditing:[CPNotification notificationWithName:CPControlTextDidEndEditingNotification object:self userInfo:@{"CPTextMovement": [self _currentTextMovement]}]];
}
// If there is no target action, or the sendAction call returns
@@ -974,6 +1013,9 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
- (void)_insertCharacterIgnoringFieldEditor:(CPString)aCharacter
{
if (!([self isEnabled] && [self isEditable]))
return;
#if PLATFORM(DOM)
var oldValue = _stringValue,
@@ -986,13 +1028,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
// NOTE: _stringValue is now the current input element value
if (oldValue !== _stringValue)
{
if (!_isEditing)
{
_isEditing = YES;
[self textDidBeginEditing:[CPNotification notificationWithName:CPControlTextDidBeginEditingNotification object:self userInfo:nil]];
}
[self textDidChange:[CPNotification notificationWithName:CPControlTextDidChangeNotification object:self userInfo:nil]];
[self _didEdit];
}
#endif
@@ -1035,7 +1071,6 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
}
/*
@ignore
Sets the internal string value without updating the value in the input element.
This should only be invoked when the underlying text element's value has changed.
*/
@@ -1044,8 +1079,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
return [self _setStringValue:aValue isNewValue:YES errorDescription:nil];
}
/*
@ignore
/*!
Sets the internal string value without updating the value in the input element.
If there is a formatter and formatting fails, returns NO. Otherwise returns YES.
*/
@@ -1104,10 +1138,13 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
value = undefined;
[super setObjectValue:value];
_stringValue = (value === nil || value === undefined) ? @"" : String(value);
}
else
_stringValue = formattedString;
}
_stringValue = [self stringValue];
else
_stringValue = [self stringValue];
#if PLATFORM(DOM)
@@ -1241,22 +1278,29 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
- (void)_selectText:(id)sender immediately:(BOOL)immediately
{
// Selecting the text in a field makes it the first responder
if (([self isEditable] || [self isSelectable]))
if ([self isEditable] || [self isSelectable])
{
var wind = [self window];
#if PLATFORM(DOM)
var element = [self _inputElement];
if ([wind firstResponder] === self)
if ([self isEditable])
{
if (immediately)
element.select();
else
window.setTimeout(function() { element.select(); }, 0);
var element = [self _inputElement];
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
{
[self setSelectedRange:CPMakeRange(0, _stringValue.length)];
}
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.
@@ -1269,36 +1313,70 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
- (void)copy:(id)sender
{
if (![CPPlatform isBrowser])
// First write to the Cappuccino clipboard.
var stringToCopy = nil;
if ([self isEditable])
{
var selectedRange = [self selectedRange];
if (selectedRange.length < 1)
return;
var pasteboard = [CPPasteboard generalPasteboard],
stringForPasting = [_stringValue substringWithRange:selectedRange];
stringToCopy = [_stringValue substringWithRange:selectedRange];
}
else
{
// selectedRange won't work if we're displaying our text using a <div>. Instead we have to ask the browser
// what's selected and hope it's right in a Cappuccino context as well.
#if PLATFORM(DOM)
stringToCopy = [[[self window] platformWindow] _selectedText];
#endif
}
[pasteboard declareTypes:[CPStringPboardType] owner:nil];
[pasteboard setString:stringForPasting forType:CPStringPboardType];
var pasteboard = [CPPasteboard generalPasteboard];
[pasteboard declareTypes:[CPStringPboardType] owner:nil];
[pasteboard setString:stringToCopy forType:CPStringPboardType];
if ([CPPlatform isBrowser])
{
// Then also allow the browser to capture the copied text into the system clipboard.
[[[self window] platformWindow] _propagateCurrentDOMEvent:YES];
}
}
- (void)cut:(id)sender
{
if (![CPPlatform isBrowser])
if (![self isEnabled])
return;
[self copy:sender];
if (![self isEditable])
return;
if (![[CPApp currentEvent] _platformIsEffectingCutOrPaste])
{
[self copy:sender];
[self deleteBackward:sender];
}
// 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];
else
{
// Allow the browser's standard cut handling. This should also result in the deleteBackward: happening.
[[[self window] platformWindow] _propagateCurrentDOMEvent:YES];
// 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".
if (!CPFeatureIsCompatible(CPInputOnInputEventFeature))
[CPTimer scheduledTimerWithTimeInterval:0.0 target:self selector:@selector(keyUp:) userInfo:nil repeats:NO];
}
}
- (void)paste:(id)sender
{
if (![CPPlatform isBrowser])
if (!([self isEnabled] && [self isEditable]))
return;
if (![[CPApp currentEvent] _platformIsEffectingCutOrPaste])
{
var pasteboard = [CPPasteboard generalPasteboard];
@@ -1312,15 +1390,24 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
newValue = [_stringValue stringByReplacingCharactersInRange:selectedRange withString:pasteString];
[self setStringValue:newValue];
[self _didEdit];
[self setSelectedRange:CPMakeRange(selectedRange.location + pasteString.length, 0)];
}
// 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];
else
{
// Allow the browser's standard paste handling.
[[[self window] platformWindow] _propagateCurrentDOMEvent:YES];
if (!CPFeatureIsCompatible(CPInputOnInputEventFeature))
[CPTimer scheduledTimerWithTimeInterval:0.0 target:self selector:@selector(keyUp:) userInfo:nil repeats:NO];
}
}
- (CPRange)selectedRange
{
// TODO Need a way to figure out the selected range if we're not using an input. Need
// to get whole document selection and somehow see which part is inside of this text field.
if ([[self window] firstResponder] !== self)
return CPMakeRange(0, 0);
@@ -1364,35 +1451,48 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
#if PLATFORM(DOM)
var inputElement = [self _inputElement];
try
if (![self isEditable])
{
if ([inputElement.selectionStart isKindOfClass:CPNumber])
{
inputElement.selectionStart = aRange.location;
inputElement.selectionEnd = CPMaxRange(aRange);
}
else
{
// browsers which don't support selectionStart/selectionEnd (aka IE).
var theDocument = inputElement.ownerDocument || inputElement.document,
existingRange = theDocument.selection.createRange(),
range = inputElement.createTextRange();
// No input element - selectable text field only.
var contentView = [self layoutEphemeralSubviewNamed:@"content-view"
positioned:CPWindowAbove
relativeToEphemeralSubviewNamed:@"bezel-view"];
if (range.inRange(existingRange))
if (contentView)
[contentView setSelectedRange:aRange];
}
else
{
// Input element
var inputElement = [self _inputElement];
try
{
if ([inputElement.selectionStart isKindOfClass:CPNumber])
{
range.collapse(true);
range.move('character', aRange.location);
range.moveEnd('character', aRange.length);
range.select();
inputElement.selectionStart = aRange.location;
inputElement.selectionEnd = CPMaxRange(aRange);
}
else
{
// browsers which don't support selectionStart/selectionEnd (aka IE).
var theDocument = inputElement.ownerDocument || inputElement.document,
existingRange = theDocument.selection.createRange(),
range = inputElement.createTextRange();
if (range.inRange(existingRange))
{
range.collapse(true);
range.move('character', aRange.location);
range.moveEnd('character', aRange.length);
range.select();
}
}
}
catch (e)
{
}
}
catch (e)
{
}
#endif
}
@@ -1403,18 +1503,84 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
- (void)deleteBackward:(id)sender
{
if (!([self isEnabled] && [self isEditable]))
return;
var selectedRange = [self selectedRange];
if (selectedRange.length < 2)
return;
if (selectedRange.length < 1)
{
if (selectedRange.location < 1)
return;
selectedRange.location += 1;
selectedRange.length -= 1;
// Delete a single element backward from the insertion point if there's no selection.
selectedRange.location -= 1;
selectedRange.length += 1;
}
var newValue = [_stringValue stringByReplacingCharactersInRange:selectedRange withString:""];
[self setStringValue:newValue];
[self setSelectedRange:CPMakeRange(selectedRange.location, 0)];
[self _didEdit];
#if PLATFORM(DOM)
// Since we just performed the deletion manually, we don't need the browser to do anything else.
// (Previously we would allow the event to propagate for the browser to delete 1 character only,
// and we'd delete the rest manually. But this meant that if deleteBackward: was called without
// it being a browser backspace event, 1 character would be left behind.)
[[[self window] platformWindow] _propagateCurrentDOMEvent:NO];
#endif
}
- (void)delete:(id)sender
{
if (!([self isEnabled] && [self isEditable]))
return;
// delete: only works when there's a selection (as opposed to deleteForward: and deleteBackward:).
var selectedRange = [self selectedRange];
if (selectedRange.length < 1)
return;
var newValue = [_stringValue stringByReplacingCharactersInRange:selectedRange withString:""];
[self setStringValue:newValue];
[self setSelectedRange:CPMakeRange(selectedRange.location, 0)];
[self _didEdit];
#if PLATFORM(DOM)
// Since we just performed the deletion manually, we don't need the browser to do anything else.
[[[self window] platformWindow] _propagateCurrentDOMEvent:NO];
#endif
}
- (void)deleteForward:(id)sender
{
if (!([self isEnabled] && [self isEditable]))
return;
var selectedRange = [self selectedRange];
if (selectedRange.length < 1)
{
if (selectedRange.location + 1 >= _stringValue.length)
return;
selectedRange.length += 1;
}
var newValue = [_stringValue stringByReplacingCharactersInRange:selectedRange withString:""];
[self setStringValue:newValue];
[self setSelectedRange:CPMakeRange(selectedRange.location, 0)];
[self _didEdit];
#if PLATFORM(DOM)
// Since we just performed the deletion manually, we don't need the browser to do anything else.
[[[self window] platformWindow] _propagateCurrentDOMEvent:NO];
#endif
}
#pragma mark Setting the Delegate
@@ -1581,6 +1747,41 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
}
}
#pragma mark Overrides
- (void)viewDidHide
{
[super viewDidHide];
if ([[self window] firstResponder] === self)
[self _resignFirstKeyResponder];
}
- (void)viewDidUnhide
{
[super viewDidUnhide];
if ([self isEditable] && [[self window] firstResponder] === self)
[self _becomeFirstKeyResponder];
}
- (BOOL)validateUserInterfaceItem:(id /*<CPValidatedUserInterfaceItem>*/)anItem
{
var theAction = [anItem action];
if (![self isEditable] && (theAction == @selector(cut:) || theAction == @selector(paste:) || theAction == @selector(delete:)))
return NO;
// FIXME - [self selectedRange] is always empty if we're not an editable field, so we must assume yes here.
if (![self isEditable])
return YES;
if (theAction == @selector(copy:) || theAction == @selector(cut:) || theAction == @selector(delete:))
return [self selectedRange].length;
return YES;
}
#pragma mark Private
- (BOOL)_isWithinUsablePlatformRect
@@ -1588,8 +1789,13 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
// Make sure the text field is completely within the platform window
// so the browser will not scroll it into view.
var wind = [self window],
frame = [self convertRectToBase:[self bounds]],
var wind = [self window];
// If the field is not yet within a window, it can't be first responder
if (!wind)
return NO;
var frame = [self convertRectToBase:[self bounds]],
usableRect = [[wind platformWindow] usableContentFrame];
frame.origin = [wind convertBaseToGlobal:frame.origin];
@@ -1677,7 +1883,7 @@ var CPTextFieldIsEditableKey = "CPTextFieldIsEditableKey",
@implementation _CPTextFieldValueBinder : CPBinder
- (void)_updatePlaceholdersWithOptions:(CPDictionary)options forBinding:(CPBinder)aBinding
- (void)_updatePlaceholdersWithOptions:(CPDictionary)options forBinding:(CPString)aBinding
{
[super _updatePlaceholdersWithOptions:options];
Executable → Regular
+12 -6
View File
@@ -34,6 +34,8 @@
@import "CPWindow_Constants.j"
@global CPApp
@global CPTextFieldDidFocusNotification
@global CPTextFieldDidBlurNotification
#if PLATFORM(DOM)
@@ -96,7 +98,7 @@ CPTokenFieldDeleteButtonType = 1;
return "tokenfield";
}
+ (id)themeAttributes
+ (CPDictionary)themeAttributes
{
return @{ @"editor-inset": CGInsetMakeZero() };
}
@@ -392,6 +394,8 @@ CPTokenFieldDeleteButtonType = 1;
element.focus();
CPTokenFieldInputOwner = self;
}, 0.0);
[self textDidFocus:[CPNotification notificationWithName:CPTextFieldDidFocusNotification object:self userInfo:nil]];
}, 0.0);
[[[self window] platformWindow] _propagateCurrentDOMEvent:YES];
@@ -424,12 +428,14 @@ CPTokenFieldDeleteButtonType = 1;
if (_shouldNotifyTarget)
{
_shouldNotifyTarget = NO;
[self textDidEndEditing:[CPNotification notificationWithName:CPControlTextDidEndEditingNotification object:self userInfo:nil]];
[self textDidEndEditing:[CPNotification notificationWithName:CPControlTextDidEndEditingNotification object:self userInfo:@{"CPTextMovement": [self _currentTextMovement]}]];
if ([self sendsActionOnEndEditing])
[self sendAction:[self action] to:[self target]];
}
[self textDidBlur:[CPNotification notificationWithName:CPTextFieldDidBlurNotification object:self userInfo:nil]];
return YES;
}
@@ -639,7 +645,7 @@ CPTokenFieldDeleteButtonType = 1;
[[self _tokens] makeObjectsPerformSelector:@selector(setEditable:) withObject:shouldBeEditable];
}
- (void)sendAction:(SEL)anAction to:(id)anObject
- (BOOL)sendAction:(SEL)anAction to:(id)anObject
{
_shouldNotifyTarget = NO;
[super sendAction:anAction to:anObject];
@@ -647,7 +653,7 @@ CPTokenFieldDeleteButtonType = 1;
// Incredible hack to disable supers implementation
// so it cannot change our object value and break the tokenfield
- (void)_setStringValue:(id)aValue
- (BOOL)_setStringValue:(CPString)aValue
{
}
@@ -1535,7 +1541,7 @@ CPTokenFieldDeleteButtonType = 1;
{
}
+ (id)themeAttributes
+ (CPDictionary)themeAttributes
{
var attributes = [CPButton themeAttributes];
@@ -1565,7 +1571,7 @@ CPTokenFieldDeleteButtonType = 1;
{
}
+ (id)themeAttributes
+ (CPDictionary)themeAttributes
{
var attributes = [CPButton themeAttributes];
+3 -12
View File
@@ -93,7 +93,7 @@ var CPToolbarsByIdentifier = nil,
BOOL _showsBaselineSeparator;
BOOL _allowsUserCustomization;
BOOL _isVisible;
int _sizeMode @accessors(property=sizeMode);
CPToolbarSizeMode _sizeMode @accessors(property=sizeMode);
int _desiredHeight;
id _delegate;
@@ -165,15 +165,6 @@ var CPToolbarsByIdentifier = nil,
return self;
}
/*!
Sets the toolbar's display mode. NOT YET IMPLEMENTED.
*/
- (void)setDisplayMode:(CPToolbarDisplayMode)aDisplayMode
{
}
/*!
Returns the toolbar's identifier
*/
@@ -603,7 +594,7 @@ var _CPToolbarItemInfoMake = function(anIndex, aView, aLabel, aMinWidth)
return @"toolbar-view";
}
+ (id)themeAttributes
+ (CPDictionary)themeAttributes
{
return @{
@"item-margin": 10.0,
@@ -1225,7 +1216,7 @@ var LABEL_MARGIN = 2.0;
[_labelField setTextShadowColor:[self FIXME_labelShadowColor]];
}
- (void)sendAction:(SEL)anAction to:(id)aSender
- (BOOL)sendAction:(SEL)anAction to:(id)aSender
{
[CPApp sendAction:anAction to:aSender from:_toolbarItem];
}
+309 -44
View File
@@ -43,6 +43,26 @@
@global appkit_tag_dom_elements
#if PLATFORM(DOM)
if (typeof(appkit_tag_dom_elements) !== "undefined" && appkit_tag_dom_elements)
{
AppKitTagDOMElement = function(owner, element)
{
element.setAttribute("data-cappuccino-view", [owner className]);
element.setAttribute("data-cappuccino-uid", [owner UID]);
}
}
else
{
AppKitTagDOMElement = function(owner, element)
{
// By default, do nothing.
}
}
#endif
/*
@global
@group CPViewAutoresizingMasks
@@ -179,6 +199,11 @@ var CPViewFlags = { },
_CPViewFullScreenModeState _fullScreenModeState;
// Zoom Support
BOOL _isScaled;
CGSize _hierarchyScaleSize;
CGSize _scaleSize;
// Layout Support
BOOL _needsLayout;
JSObject _ephemeralSubviews;
@@ -314,15 +339,17 @@ var CPViewFlags = { },
_isHidden = NO;
_hitTests = YES;
_hierarchyScaleSize = CGSizeMake(1.0 , 1.0);
_scaleSize = CGSizeMake(1.0, 1.0);
_isScaled = NO;
#if PLATFORM(DOM)
_DOMElement = DOMElementPrototype.cloneNode(false);
AppKitTagDOMElement(self, _DOMElement);
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
@@ -543,6 +570,13 @@ var CPViewFlags = { },
}
[aSubview setNextResponder:self];
[aSubview _scaleSizeUnitSquareToSize:[self _hierarchyScaleSize]];
// If the subview is not hidden and one of its ancestors is hidden,
// notify the subview that it is now hidden.
if (![aSubview isHidden] && [self isHiddenOrHasHiddenAncestor])
[aSubview _notifyViewDidHide];
[aSubview viewDidMoveToSuperview];
[self didAddSubview:aSubview];
@@ -575,6 +609,12 @@ var CPViewFlags = { },
#if PLATFORM(DOM)
CPDOMDisplayServerRemoveChild(_superview._DOMElement, _DOMElement);
#endif
// If the view is not hidden and one of its ancestors is hidden,
// notify the view that it is now unhidden.
if (!_isHidden && [_superview isHiddenOrHasHiddenAncestor])
[self _notifyViewDidUnhide];
_superview = nil;
[self _setWindow:nil];
@@ -930,8 +970,8 @@ var CPViewFlags = { },
if (YES)
{
_bounds.size.width = aSize.width;
_bounds.size.height = aSize.height;
_bounds.size.width = aSize.width * 1 / _scaleSize.width;
_bounds.size.height = aSize.height * 1 / _scaleSize.height;
}
if (_layer)
@@ -944,7 +984,7 @@ var CPViewFlags = { },
[self setNeedsDisplay:YES];
#if PLATFORM(DOM)
CPDOMDisplayServerSetStyleSize(_DOMElement, size.width, size.height);
[self _setDisplayServerSetStyleSize:size];
if (_DOMContentsElement)
{
@@ -1053,6 +1093,19 @@ var CPViewFlags = { },
[CachedNotificationCenter postNotificationName:CPViewFrameDidChangeNotification object:self];
}
/*!
This method is used to set the width and height of the _DOMElement. It cares about the scale of the view.
When scaling, for instance with a size (0.5, 0.5), the bounds of the view will be multiply by 2. It's why we multiply by the inverse of the scaling.
The view will finally keep the same proportion for the user on the screen.
*/
- (void)_setDisplayServerSetStyleSize:(CGSize)aSize
{
#if PLATFORM(DOM)
var scale = [self scaleSize];
CPDOMDisplayServerSetStyleSize(_DOMElement, aSize.width * 1 / scale.width, aSize.height * 1 / scale.height);
#endif
}
/*!
Sets the receiver's bounds. The bounds define the size and location of the receiver inside it's frame. Posts a
CPViewBoundsDidChangeNotification to the default notification center if the receiver is configured to do so.
@@ -1353,6 +1406,7 @@ var CPViewFlags = { },
// FIXME: Should we return to visibility? This breaks in FireFox, Opera, and IE.
// _DOMElement.style.visibility = (_isHidden = aFlag) ? "hidden" : "visible";
_isHidden = aFlag;
#if PLATFORM(DOM)
_DOMElement.style.display = _isHidden ? "none" : "block";
#endif
@@ -1388,6 +1442,7 @@ var CPViewFlags = { },
[self viewDidHide];
var count = [_subviews count];
while (count--)
[_subviews[count] _notifyViewDidHide];
}
@@ -1397,6 +1452,7 @@ var CPViewFlags = { },
[self viewDidUnhide];
var count = [_subviews count];
while (count--)
[_subviews[count] _notifyViewDidUnhide];
}
@@ -1547,15 +1603,42 @@ var CPViewFlags = { },
*/
- (CPView)hitTest:(CGPoint)aPoint
{
if (_isHidden || !_hitTests || !CGRectContainsPoint(_frame, aPoint))
if (_isHidden || !_hitTests)
return nil;
var frame = _frame,
sizeScale = [self _hierarchyScaleSize];
if (_isScaled)
frame = CGRectApplyAffineTransform(_frame, CGAffineTransformMakeScale([_superview _hierarchyScaleSize].width, [_superview _hierarchyScaleSize].height));
else
frame = CGRectApplyAffineTransform(_frame, CGAffineTransformMakeScale(sizeScale.width, sizeScale.height));
if (!CGRectContainsPoint(frame, aPoint))
return nil;
var view = nil,
i = _subviews.length,
adjustedPoint = CGPointMake(aPoint.x - CGRectGetMinX(_frame), aPoint.y - CGRectGetMinY(_frame));
adjustedPoint = CGPointMake(aPoint.x - CGRectGetMinX(frame), aPoint.y - CGRectGetMinY(frame));
if (_inverseBoundsTransform)
adjustedPoint = CGPointApplyAffineTransform(adjustedPoint, _inverseBoundsTransform);
{
var affineTransform = CGAffineTransformMakeCopy(_inverseBoundsTransform);
if (_isScaled)
{
affineTransform.tx *= [_superview _hierarchyScaleSize].width;
affineTransform.ty *= [_superview _hierarchyScaleSize].height;
}
else
{
affineTransform.tx *= sizeScale.width;
affineTransform.ty *= sizeScale.height;
}
adjustedPoint = CGPointApplyAffineTransform(adjustedPoint, affineTransform);
}
while (i--)
if (view = [_subviews[i] hitTest:adjustedPoint])
@@ -1876,6 +1959,9 @@ var CPViewFlags = { },
*/
- (CGPoint)convertPoint:(CGPoint)aPoint fromView:(CPView)aView
{
if (aView === self)
return aPoint;
return CGPointApplyAffineTransform(aPoint, _CPViewGetTransform(aView, self));
}
@@ -1886,7 +1972,7 @@ var CPViewFlags = { },
*/
- (CGPoint)convertPointFromBase:(CGPoint)aPoint
{
return CGPointApplyAffineTransform(aPoint, _CPViewGetTransform(nil, self));
return [self convertPoint:aPoint fromView:nil];
}
/*!
@@ -1897,9 +1983,13 @@ var CPViewFlags = { },
*/
- (CGPoint)convertPoint:(CGPoint)aPoint toView:(CPView)aView
{
if (aView === self)
return aPoint;
return CGPointApplyAffineTransform(aPoint, _CPViewGetTransform(self, aView));
}
/*!
Converts the point from the receivers coordinate system to the base coordinate system.
@param aPoint A point specifying a location in the coordinate system of the receiver
@@ -1907,7 +1997,7 @@ var CPViewFlags = { },
*/
- (CGPoint)convertPointToBase:(CGPoint)aPoint
{
return CGPointApplyAffineTransform(aPoint, _CPViewGetTransform(self, nil));
return [self convertPoint:aPoint toView:nil];
}
/*!
@@ -1918,6 +2008,9 @@ var CPViewFlags = { },
*/
- (CGSize)convertSize:(CGSize)aSize fromView:(CPView)aView
{
if (aView === self)
return aSize;
return CGSizeApplyAffineTransform(aSize, _CPViewGetTransform(aView, self));
}
@@ -1929,6 +2022,9 @@ var CPViewFlags = { },
*/
- (CGSize)convertSize:(CGSize)aSize toView:(CPView)aView
{
if (aView === self)
return aSize;
return CGSizeApplyAffineTransform(aSize, _CPViewGetTransform(self, aView));
}
@@ -1940,6 +2036,9 @@ var CPViewFlags = { },
*/
- (CGRect)convertRect:(CGRect)aRect fromView:(CPView)aView
{
if (self === aView)
return aRect;
return CGRectApplyAffineTransform(aRect, _CPViewGetTransform(aView, self));
}
@@ -1950,7 +2049,7 @@ var CPViewFlags = { },
*/
- (CGRect)convertRectFromBase:(CGRect)aRect
{
return CGRectApplyAffineTransform(aRect, _CPViewGetTransform(nil, self));
return [self convertRect:aRect fromView:nil];
}
/*!
@@ -1961,6 +2060,9 @@ var CPViewFlags = { },
*/
- (CGRect)convertRect:(CGRect)aRect toView:(CPView)aView
{
if (self === aView)
return aRect;
return CGRectApplyAffineTransform(aRect, _CPViewGetTransform(self, aView));
}
@@ -1971,7 +2073,7 @@ var CPViewFlags = { },
*/
- (CGRect)convertRectToBase:(CGRect)aRect
{
return CGRectApplyAffineTransform(aRect, _CPViewGetTransform(self, nil));
return [self convertRect:aRect toView:nil];
}
/*!
@@ -2116,6 +2218,88 @@ setBoundsOrigin:
}
// Scaling
/*!
Scales the receivers coordinate system so that the unit square scales to the specified dimensions.
The bounds of the receiver will change, for instance if the given size is (0.5, 0.5) the width and height of the bounds will be multiply by 2.
You must call setNeedsDisplay: to redraw the view.
@param aSize, the size corresponding the new unit scales
*/
- (void)scaleUnitSquareToSize:(CGSize)aSize
{
if (!aSize)
return;
// Reset the bounds
var bounds = CGRectMakeCopy([self bounds]);
bounds.size.width *= _scaleSize.width;
bounds.size.height *= _scaleSize.height;
[self willChangeValueForKey:@"scaleSize"];
_scaleSize = CGSizeMakeCopy([self scaleSize]);
_scaleSize.height *= aSize.height;
_scaleSize.width *= aSize.width;
[self didChangeValueForKey:@"scaleSize"];
_isScaled = YES;
_hierarchyScaleSize = CGSizeMakeCopy([self _hierarchyScaleSize]);
_hierarchyScaleSize.height *= aSize.height;
_hierarchyScaleSize.width *= aSize.width;
var scaleAffine = CGAffineTransformMakeScale(1.0 / _scaleSize.width, 1.0 / _scaleSize.height),
newBounds = CGRectApplyAffineTransform(CGRectMakeCopy(bounds), scaleAffine);
[self setBounds:newBounds];
[_subviews makeObjectsPerformSelector:@selector(_scaleSizeUnitSquareToSize:) withObject:aSize];
}
/*!
@ignore
Set the _hierarchyScaleSize and call all of the subviews to set their _hierarchyScaleSize
*/
- (void)_scaleSizeUnitSquareToSize:(CGSize)aSize
{
_hierarchyScaleSize = CGSizeMakeCopy([_superview _hierarchyScaleSize]);
if (_isScaled)
{
_hierarchyScaleSize.width *= _scaleSize.width;
_hierarchyScaleSize.height *= _scaleSize.height;
}
[_subviews makeObjectsPerformSelector:@selector(_scaleSizeUnitSquareToSize:) withObject:aSize];
}
/*!
Return the _hierarchyScaleSize, this is a CGSize with the real zoom of the view (depending with his parents)
*/
- (CGSize)_hierarchyScaleSize
{
return _hierarchyScaleSize || CGSizeMake(1.0, 1.0);
}
/*!
Make a zoom in css
*/
- (void)_applyCSSScalingTranformations
{
#if PLATFORM(DOM)
if (_isScaled)
{
var scale = [self scaleSize],
browserPropertyTransform = CPBrowserStyleProperty(@"transform"),
browserPropertyTransformOrigin = CPBrowserStyleProperty(@"transformOrigin");
self._DOMElement.style[browserPropertyTransform] = 'scale(' + scale.width + ', ' + scale.height + ')';
self._DOMElement.style[browserPropertyTransformOrigin] = '0 0';
[self _setDisplayServerSetStyleSize:[self frameSize]];
}
#endif
}
// Displaying
/*!
@@ -2124,7 +2308,10 @@ setBoundsOrigin:
- (void)setNeedsDisplay:(BOOL)aFlag
{
if (aFlag)
{
[self _applyCSSScalingTranformations];
[self setNeedsDisplayInRect:[self bounds]];
}
}
/*!
@@ -2217,6 +2404,9 @@ setBoundsOrigin:
var graphicsPort = CGBitmapGraphicsContextCreate();
#if PLATFORM(DOM)
var width = CGRectGetWidth(_frame),
height = CGRectGetHeight(_frame);
_DOMContentsElement = graphicsPort.DOMElement;
_DOMContentsElement.style.zIndex = -100;
@@ -2225,13 +2415,10 @@ setBoundsOrigin:
_DOMContentsElement.style.position = "absolute";
_DOMContentsElement.style.visibility = "visible";
_DOMContentsElement.width = ROUND(CGRectGetWidth(_frame));
_DOMContentsElement.height = ROUND(CGRectGetHeight(_frame));
CPDOMDisplayServerSetSize(_DOMContentsElement, width, height);
_DOMContentsElement.style.top = "0px";
_DOMContentsElement.style.left = "0px";
_DOMContentsElement.style.width = ROUND(CGRectGetWidth(_frame)) + "px";
_DOMContentsElement.style.height = ROUND(CGRectGetHeight(_frame)) + "px";
CPDOMDisplayServerSetStyleLeftTop(_DOMContentsElement, NULL, 0.0, 0.0);
CPDOMDisplayServerSetStyleSize(_DOMContentsElement, width, height);
// The performance implications of this aren't clear, but without this subviews might not be redrawn when this
// view moves.
@@ -2521,14 +2708,18 @@ setBoundsOrigin:
- (CPView)nextValidKeyView
{
var result = [self nextKeyView],
firstResult = result;
resultUID = [result UID],
unsuitableResults = {};
while (result && ![result canBecomeKeyView])
{
unsuitableResults[resultUID] = 1;
result = [result nextKeyView];
// Cycled.
if (result === firstResult)
resultUID = [result UID];
// Did we get back to a key view we already ruled out due to ![result canBecomeKeyView]?
if (unsuitableResults[resultUID])
return nil;
}
@@ -2654,6 +2845,40 @@ setBoundsOrigin:
@end
@implementation CPView (Scaling)
/*!
Set the zoom of the view. This will call scaleUnitSquareToSize: and setNeedsDisplay:
This method doesn't care about the last zoom you set in the view
@param aSize, the size corresponding the new unit scales
*/
- (void)setScaleSize:(CGSize)aSize
{
if (CGSizeEqualToSize(_scaleSize, aSize))
return;
var size = CGSizeMakeZero(),
scale = CGSizeMakeCopy([self scaleSize]);
size.height = aSize.height / scale.height;
size.width = aSize.width / scale.width;
[self scaleUnitSquareToSize:size];
[self setNeedsDisplay:YES];
}
/*!
Return the scaleSize of the view, this scaleSize is used to scale in css
*/
- (CGSize)scaleSize
{
return _scaleSize || CGSizeMake(1.0, 1.0);
}
@end
@implementation CPView (Theming)
#pragma mark Theme States
@@ -3032,7 +3257,10 @@ var CPViewAutoresizingMaskKey = @"CPViewAutoresizingMask",
CPViewWindowKey = @"CPViewWindowKey",
CPViewNextKeyViewKey = @"CPViewNextKeyViewKey",
CPViewPreviousKeyViewKey = @"CPViewPreviousKeyViewKey",
CPReuseIdentifierKey = @"CPReuseIdentifierKey";
CPReuseIdentifierKey = @"CPReuseIdentifierKey",
CPViewScaleKey = @"CPViewScaleKey",
CPViewSizeScaleKey = @"CPViewSizeScaleKey",
CPViewIsScaledKey = @"CPViewIsScaledKey";
@implementation CPView (CPCoding)
@@ -3049,6 +3277,7 @@ var CPViewAutoresizingMaskKey = @"CPViewAutoresizingMask",
// a more "elegant" way to do this...?
#if PLATFORM(DOM)
_DOMElement = DOMElementPrototype.cloneNode(false);
AppKitTagDOMElement(self, _DOMElement);
#endif
// Also decode these "early".
@@ -3098,13 +3327,17 @@ var CPViewAutoresizingMaskKey = @"CPViewAutoresizingMask",
if (_toolTip)
[self _installToolTipEventHandlers];
_scaleSize = [aCoder containsValueForKey:CPViewScaleKey] ? [aCoder decodeSizeForKey:CPViewScaleKey] : CGSizeMake(1.0, 1.0);
_hierarchyScaleSize = [aCoder containsValueForKey:CPViewSizeScaleKey] ? [aCoder decodeSizeForKey:CPViewSizeScaleKey] : CGSizeMake(1.0, 1.0);
_isScaled = [aCoder containsValueForKey:CPViewIsScaledKey] ? [aCoder decodeBoolForKey:CPViewIsScaledKey] : NO;
// DOM SETUP
#if PLATFORM(DOM)
_DOMImageParts = [];
_DOMImageSizes = [];
CPDOMDisplayServerSetStyleLeftTop(_DOMElement, NULL, CGRectGetMinX(_frame), CGRectGetMinY(_frame));
CPDOMDisplayServerSetStyleSize(_DOMElement, CGRectGetWidth(_frame), CGRectGetHeight(_frame));
[self _setDisplayServerSetStyleSize:_frame.size];
var index = 0,
count = _subviews.length;
@@ -3227,6 +3460,10 @@ var CPViewAutoresizingMaskKey = @"CPViewAutoresizingMask",
if (_identifier)
[aCoder encodeObject:_identifier forKey:CPReuseIdentifierKey];
[aCoder encodeSize:[self scaleSize] forKey:CPViewScaleKey];
[aCoder encodeSize:[self _hierarchyScaleSize] forKey:CPViewSizeScaleKey];
[aCoder encodeBool:_isScaled forKey:CPViewIsScaledKey];
}
@end
@@ -3256,12 +3493,26 @@ var _CPViewGetTransform = function(/*CPView*/ fromView, /*CPView */ toView)
{
var frame = view._frame;
if (view._isScaled)
{
var affineZoom = CGAffineTransformMakeScale(view._scaleSize.width, view._scaleSize.height);
CGAffineTransformConcatTo(transform, affineZoom, transform);
}
transform.tx += CGRectGetMinX(frame);
transform.ty += CGRectGetMinY(frame);
if (view._boundsTransform)
{
CGAffineTransformConcatTo(transform, view._boundsTransform, transform);
var inverseBoundsTransform = CGAffineTransformMakeCopy(view._boundsTransform);
if (view._isScaled)
{
var affineZoom = CGAffineTransformMakeScale(view._scaleSize.width, view._scaleSize.height);
CGAffineTransformConcatTo(inverseBoundsTransform, affineZoom, inverseBoundsTransform);
}
CGAffineTransformConcatTo(transform, inverseBoundsTransform, transform);
}
view = view._superview;
@@ -3269,50 +3520,64 @@ var _CPViewGetTransform = function(/*CPView*/ fromView, /*CPView */ toView)
// If we hit toView, then we're done.
if (view === toView)
{
return transform;
}
else if (fromView && toView)
{
fromWindow = [fromView window];
toWindow = [toView window];
if (fromWindow && toWindow && fromWindow !== toWindow)
{
sameWindow = NO;
var frame = [fromWindow frame];
transform.tx += CGRectGetMinX(frame);
transform.ty += CGRectGetMinY(frame);
}
}
}
// FIXME: For now we can do things this way, but eventually we need to do them the "hard" way.
var view = toView;
var view = toView,
transform2 = CGAffineTransformMakeIdentity();
while (view)
while (view && view != fromView)
{
var frame = view._frame;
var frame = CGRectMakeCopy(view._frame);
transform.tx -= CGRectGetMinX(frame);
transform.ty -= CGRectGetMinY(frame);
// FIXME : For now we don't care about rotate transform and so on
if (view._isScaled)
{
transform2.a *= 1 / view._scaleSize.width;
transform2.d *= 1 / view._scaleSize.height;
}
transform2.tx += CGRectGetMinX(frame) * transform2.a;
transform2.ty += CGRectGetMinY(frame) * transform2.d;
if (view._boundsTransform)
{
CGAffineTransformConcatTo(transform, view._inverseBoundsTransform, transform);
var inverseBoundsTransform = CGAffineTransformMakeIdentity();
inverseBoundsTransform.tx -= view._inverseBoundsTransform.tx * transform2.a;
inverseBoundsTransform.ty -= view._inverseBoundsTransform.ty * transform2.d;
CGAffineTransformConcatTo(transform2, inverseBoundsTransform, transform2);
}
view = view._superview;
}
if (!sameWindow)
{
var frame = [toWindow frame];
transform2.tx = -transform2.tx;
transform2.ty = -transform2.ty;
transform.tx -= CGRectGetMinX(frame);
transform.ty -= CGRectGetMinY(frame);
if (view === fromView)
{
// toView is inside of fromView
return transform2;
}
CGAffineTransformConcatTo(transform, transform2, transform);
return transform;
/* var views = [],
view = toView;
+1 -1
View File
@@ -105,7 +105,7 @@ CPViewAnimationFadeOutEffect = @"CPViewAnimationFadeOutEffect";
[super startAnimation];
}
- (void)setCurrentProgress:(CPAnimationProgress)progress
- (void)setCurrentProgress:(float)progress
{
[super setCurrentProgress:progress];
+51 -15
View File
@@ -248,7 +248,7 @@ CPTexturedBackgroundWindowMask
@param aStyleMask a style mask
@return the initialized window
*/
- (id)initWithContentRect:(CGRect)aContentRect styleMask:(unsigned int)aStyleMask
- (id)initWithContentRect:(CGRect)aContentRect styleMask:(unsigned)aStyleMask
{
self = [super init];
@@ -735,6 +735,10 @@ CPTexturedBackgroundWindowMask
}
}
/*
Constrain a frame so that the window remains at least partially visible on screen,
moving or resizing the frame as necessary.
*/
- (CGRect)_constrainFrame:(CGRect)aFrame toUsableScreenWidth:(BOOL)constrainWidth andHeight:(BOOL)constrainHeight
{
var frame = CGRectMakeCopy(aFrame);
@@ -759,7 +763,7 @@ CPTexturedBackgroundWindowMask
if (CGRectGetWidth(frame) > usableWidth)
{
frame.origin.x = CGRectGetMinX(usableRect);
frame.size.width = usableWidth;
frame.size.width = MAX(usableWidth, _minSize.width);
}
}
@@ -778,13 +782,20 @@ CPTexturedBackgroundWindowMask
if (CGRectGetHeight(frame) > usableHeight)
{
frame.origin.y = CGRectGetMinY(usableRect);
frame.size.height = usableHeight;
frame.size.height = MAX(usableHeight, _minSize.height);
}
}
return frame;
}
/*
Constrain the origin of a frame such that:
- The window view's minimum resize width is kept onscreen at the left/right of the window.
- The top of the window is kept below the top of the usable content.
- The top of the contentView + CPWindowMinVisibleVerticalMargin is kept above the bottom of the usable content.
*/
- (CGRect)_constrainOriginOfFrame:(CGRect)aFrame
{
var frame = CGRectMakeCopy(aFrame);
@@ -792,19 +803,20 @@ CPTexturedBackgroundWindowMask
if (!_constrainsToUsableScreen || !_isVisible)
return frame;
/*
- CPWindowMinVisibleHorizontalMargin is kept onscreen at the left/right of the window.
- The top of the window is kept below the top of the usable content.
- The top of the contentView + CPWindowMinVisibleVerticalMargin is kept above the bottom of the usable content.
*/
var usableRect = [_platformWindow usableContentFrame],
maxUsableY = CGRectGetMaxY(usableRect) - CGRectGetMinY([_contentView frame]) - CPWindowMinVisibleVerticalMargin;
minimumSize = [_windowView _minimumResizeSize];
frame.origin.x = MAX(frame.origin.x, CGRectGetMinX(usableRect) + CPWindowMinVisibleHorizontalMargin - CGRectGetWidth(frame));
frame.origin.x = MIN(frame.origin.x, CGRectGetMaxX(usableRect) - CPWindowMinVisibleHorizontalMargin);
// First constrain x so that at least CPWindowMinVisibleHorizontalMargin is visible on the right
frame.origin.x = MAX(frame.origin.x, CGRectGetMinX(usableRect) + minimumSize.width - CGRectGetWidth(frame));
// Now constrain x so that at least CPWindowMinVisibleHorizontalMargin is visible on the left
frame.origin.x = MIN(frame.origin.x, CGRectGetMaxX(usableRect) - minimumSize.width);
// Now constrain y so that it is below the top of the usable content
frame.origin.y = MAX(frame.origin.y, CGRectGetMinY(usableRect));
frame.origin.y = MIN(frame.origin.y, maxUsableY);
// Finally constrain y so that at least CPWindowMinVisibleHorizontalMargin is visible at the bottom
frame.origin.y = MIN(frame.origin.y, CGRectGetMaxY(usableRect) - CGRectGetMinY([_contentView frame]) - CPWindowMinVisibleVerticalMargin);
return frame;
}
@@ -1021,6 +1033,23 @@ CPTexturedBackgroundWindowMask
[[CPNotificationCenter defaultCenter] postNotificationName:CPWindowResizeStyleGlobalChangeNotification object:nil];
}
/*!
If set to NO, platform window (virtual screen) resizes will not attempt to move/resize user windows.
to the usable area.
*/
+ (void)setConstrainWindowsToUsableScreen:(BOOL)shouldConstrain
{
CPWindowConstrainToScreen = shouldConstrain;
}
/*!
Return whether platform window (virtual screen) resizes constrain user windows to the usable area.
*/
+ (BOOL)constrainWindowsToUsableScreen
{
return CPWindowConstrainToScreen;
}
- (void)_didReceiveResizeStyleChange:(CPNotification)aNotification
{
[_windowView setShowsResizeIndicator:_styleMask & CPResizableWindowMask];
@@ -1670,11 +1699,17 @@ CPTexturedBackgroundWindowMask
switch (type)
{
case CPLeftMouseDown:
// This is needed when a doubleClick occurs when the sheet is closing or opening
if (!_parentWindow)
return;
[_windowView mouseDown:anEvent];
// -dw- if the window is clicked, the sheet should come to front, and become key,
// and the window should be immediately behind
[sheet makeKeyAndOrderFront:self];
return;
case CPMouseMoved:
@@ -2466,7 +2501,7 @@ CPTexturedBackgroundWindowMask
// If this has an owner, dump it!
[[aToolbar _window] setToolbar:nil];
// This is no longer out toolbar.
// This is no longer our toolbar.
[_toolbar _setWindow:nil];
_toolbar = aToolbar;
@@ -3269,7 +3304,8 @@ var keyViewComparator = function(lhs, rhs, context)
if ([self isFullPlatformWindow])
return [self setFrame:[_platformWindow visibleFrame]];
if (_autoresizingMask === CPWindowNotSizable)
// If this window is constrainable and we are globally ignoring constraining, ignore the platform resize
if ((_constrainsToUsableScreen && !CPWindowConstrainToScreen) || _autoresizingMask === CPWindowNotSizable)
return;
var frame = [_platformWindow contentBounds],
@@ -3291,7 +3327,7 @@ var keyViewComparator = function(lhs, rhs, context)
if (_autoresizingMask & CPWindowHeightSizable)
newFrame.size.height += dY;
[self setFrame:newFrame];
[self _setFrame:newFrame display:YES animate:NO constrainWidth:YES constrainHeight:YES];
}
/*
+2
View File
@@ -194,3 +194,5 @@ CPStandardWindowShadowStyle = 0;
CPMenuWindowShadowStyle = 1;
CPPanelWindowShadowStyle = 2;
CPCustomWindowShadowStyle = 3;
CPWindowConstrainToScreen = YES;
@@ -32,7 +32,7 @@
return @"bordeless-bridge-window-view";
}
+ (id)themeAttributes
+ (CPDictionary)themeAttributes
{
return @{
@"toolbar-background-color": [CPColor grayColor],
+1 -1
View File
@@ -33,7 +33,7 @@
return @"doc-modal-window-view";
}
+ (id)themeAttributes
+ (CPDictionary)themeAttributes
{
return @{
@"body-color": [CPColor whiteColor],
+10 -10
View File
@@ -28,11 +28,7 @@
@global CPPopoverAppearanceMinimal
var _CPPopoverWindowViewDefaultCursorSize = CGSizeMake(16, 10),
_CPPopoverWindowViewRadius = 5.0,
_CPPopoverWindowViewStrokeWidth = 1.0,
_CPPopoverWindowViewShadowSize = CGSizeMake(0, 6),
_CPPopoverWindowViewShadowBlur = 15.0;
var _CPPopoverWindowViewDefaultCursorSize = CGSizeMake(16, 10);
/*!
@ignore
@@ -54,13 +50,17 @@ var _CPPopoverWindowViewDefaultCursorSize = CGSizeMake(16, 10),
return @"popover-window-view";
}
+ (id)themeAttributes
+ (CPDictionary)themeAttributes
{
return @{
@"background-gradient": [CPNull null],
@"background-gradient-hud": [CPNull null],
@"stroke-color": [CPNull null],
@"stroke-color-hud": [CPNull null],
@"border-radius": 5.0,
@"stroke-width": 1.0,
@"shadow-size": CGSizeMake(0, 6),
@"shadow-blur": 15.0
};
}
@@ -156,15 +156,15 @@ var _CPPopoverWindowViewDefaultCursorSize = CGSizeMake(16, 10),
[super drawRect:aRect];
var context = [[CPGraphicsContext currentContext] graphicsPort],
radius = _CPPopoverWindowViewRadius,
radius = [self valueForThemeAttribute:@"border-radius"],
arrowWidth = _cursorSize.width,
arrowHeight = _cursorSize.height,
strokeWidth = _CPPopoverWindowViewStrokeWidth,
strokeWidth = [self valueForThemeAttribute:@"stroke-width"],
halfStrokeWidth = strokeWidth / 2.0,
strokeColor,
shadowColor = [[CPColor blackColor] colorWithAlphaComponent:.2],
shadowSize = _CPPopoverWindowViewShadowSize,
shadowBlur = _CPPopoverWindowViewShadowBlur,
shadowSize = [self valueForThemeAttribute:@"shadow-size"],
shadowBlur = [self valueForThemeAttribute:@"shadow-blur"],
gradient,
frame = [self bounds];
+1 -1
View File
@@ -41,7 +41,7 @@
return @"shadow-window-view";
}
+ (id)themeAttributes
+ (CPDictionary)themeAttributes
{
return @{};
}
+2 -2
View File
@@ -41,7 +41,7 @@ var _CPStandardWindowViewDividerViewHeight = 1.0;
return @"textured-window-head-view";
}
+ (id)themeAttributes
+ (CPDictionary)themeAttributes
{
return @{};
}
@@ -108,7 +108,7 @@ var _CPStandardWindowViewDividerViewHeight = 1.0;
return @"standard-window-view";
}
+ (id)themeAttributes
+ (CPDictionary)themeAttributes
{
return @{
@"gradient-height": [CPNull null],
+1 -1
View File
@@ -38,7 +38,7 @@
return @"tooltip";
}
+ (id)themeAttributes
+ (CPDictionary)themeAttributes
{
return @{
@"stroke-color": [CPColor colorWithHexString:@"E3E3E3"],
+36 -4
View File
@@ -81,7 +81,7 @@ _CPWindowViewResizeSlop = 3;
return "window";
}
+ (id)themeAttributes
+ (CPDictionary)themeAttributes
{
return @{
@"title-bar-height": 25,
@@ -631,7 +631,38 @@ _CPWindowViewResizeSlop = 3;
newHeight = startHeight;
}
[theWindow _setFrame:CGRectMake(newX, newY, newWidth, newHeight) display:YES animate:NO constrainWidth:NO constrainHeight:NO];
// When resizing, we always constrain to the usable screen.
frame = CGRectMake(newX, newY, newWidth, newHeight);
var constrainedFrame = [theWindow _constrainOriginOfFrame:frame],
dx = constrainedFrame.origin.x - frame.origin.x,
dy = constrainedFrame.origin.y - frame.origin.y;
// When resizing from the left or top, we adjust the origin and size.
switch (_resizeRegion)
{
case _CPWindowViewResizeRegionBottomLeft:
case _CPWindowViewResizeRegionLeft:
case _CPWindowViewResizeRegionTopLeft:
case _CPWindowViewResizeRegionTop:
case _CPWindowViewResizeRegionTopRight:
frame.origin = constrainedFrame.origin;
frame.size.width -= dx;
frame.size.height -= dy;
}
// When resizing from the right or bottom, we only adjust the size.
switch (_resizeRegion)
{
case _CPWindowViewResizeRegionTopRight:
case _CPWindowViewResizeRegionRight:
case _CPWindowViewResizeRegionBottomRight:
case _CPWindowViewResizeRegionBottom:
frame.size.width += dx;
frame.size.height += dy;
}
[theWindow _setFrame:frame display:YES animate:NO constrainWidth:NO constrainHeight:NO];
[self setCursorForLocation:location resizing:YES];
}
@@ -683,7 +714,7 @@ _CPWindowViewResizeSlop = 3;
[theWindow _setAttachedSheetFrameOrigin];
[sheet._windowView _adjustShadowViewSize];
}
else if (theWindow._isSheet)
else if (theWindow && theWindow._isSheet)
[self _adjustShadowViewSize];
}
@@ -928,7 +959,8 @@ _CPWindowViewResizeSlop = 3;
- (CGSize)_minimumResizeSize
{
return CGSizeMake(0, _CPWindowViewMinContentHeight);
// Leave at least 4px so there is something visible.
return CGSizeMake(4, _CPWindowViewMinContentHeight);
}
- (int)bodyOffset
+5 -5
View File
@@ -63,8 +63,8 @@ var CPCibOwner = @"CPCibOwner";
+ (CPCib)loadCibFile:(CPString)anAbsolutePath externalNameTable:(CPDictionary)aNameTable loadDelegate:aDelegate
{
return ([[CPCib alloc]
initWithContentsOfURL:anAbsolutePath
loadDelegate:[[_CPCibLoadDelegate alloc]
initWithContentsOfURL:anAbsolutePath
loadDelegate:[[_CPCibLoadDelegate alloc]
initWithLoadDelegate:aDelegate
externalNameTable:aNameTable]]);
}
@@ -84,9 +84,9 @@ var CPCibOwner = @"CPCibOwner";
- (CPCib)loadCibFile:(CPString)aFileName externalNameTable:(CPDictionary)aNameTable loadDelegate:(id)aDelegate
{
return ([[CPCib alloc]
initWithCibNamed:aFileName
bundle:self
loadDelegate:[[_CPCibLoadDelegate alloc]
initWithCibNamed:aFileName
bundle:self
loadDelegate:[[_CPCibLoadDelegate alloc]
initWithLoadDelegate:aDelegate
externalNameTable:aNameTable]]);
}
+24 -6
View File
@@ -35,7 +35,10 @@
var _CPCibCustomResourceClassNameKey = @"_CPCibCustomResourceClassNameKey",
_CPCibCustomResourceResourceNameKey = @"_CPCibCustomResourceResourceNameKey",
_CPCibCustomResourcePropertiesKey = @"_CPCibCustomResourcePropertiesKey";
_CPCibCustomResourcePropertiesKey = @"_CPCibCustomResourcePropertiesKey",
_CPCibCustomResourceTemplateImageMap = nil;
@implementation _CPCibCustomResource : CPObject
{
@@ -45,6 +48,16 @@ var _CPCibCustomResourceClassNameKey = @"_CPCibCustomResourceClassNameKey",
CPBundle _bundle;
}
+ (void)initialize
{
if (self !== [_CPCibCustomResource class])
return;
_CPCibCustomResourceTemplateImageMap = @{
"CPAddTemplate": "button-image-plus",
"CPRemoveTemplate": "button-image-minus"
};
}
+ (id)imageResourceWithName:(CPString)aResourceName size:(CGSize)aSize
{
return [[self alloc] initWithClassName:@"CPImage" resourceName:aResourceName properties:@{ @"size": aSize }];
@@ -98,12 +111,12 @@ var _CPCibCustomResourceClassNameKey = @"_CPCibCustomResourceClassNameKey",
(![aCoder respondsToSelector:@selector(awakenCustomResources)] || [aCoder awakenCustomResources]))
if (_className === @"CPImage")
{
if (_resourceName == "CPAddTemplate")
return [[CPTheme defaultTheme] valueForAttributeWithName:@"button-image-plus" forClass:[CPButtonBar class]];
else if (_resourceName == "CPRemoveTemplate")
return [[CPTheme defaultTheme] valueForAttributeWithName:@"button-image-minus" forClass:[CPButtonBar class]];
var templateImage = [_CPCibCustomResourceTemplateImageMap objectForKey:_resourceName];
return [self imageFromCoder:aCoder];
if (templateImage)
return [[CPTheme defaultTheme] valueForAttributeWithName:templateImage forClass:[CPButtonBar class]];
else
return [self imageFromCoder:aCoder];
}
return self;
@@ -176,6 +189,11 @@ var _CPCibCustomResourceClassNameKey = @"_CPCibCustomResourceClassNameKey",
return [_properties objectForKey:@"size"];
}
- (BOOL)isSingleImage
{
return YES;
}
- (BOOL)isThreePartImage
{
return NO;
+1 -1
View File
@@ -48,7 +48,7 @@
@end
var _CPCibCustomViewClassNameKey = @"_CPCibCustomViewClassNameKey";
var _CPCibCustomViewClassNameKey = @"_CPCibCustomViewClassNameKey";
@implementation _CPCibCustomView (CPCoding)
+13 -9
View File
@@ -87,12 +87,17 @@
- (id)_cibInstantiate
{
var windowClass = CPClassFromString([self windowClass]),
theWindow = [[windowClass alloc] initWithContentRect:_windowRect styleMask:_windowStyleMask];
var windowClass = CPClassFromString([self windowClass]);
/* if (!windowClass)
[NSException raise:NSInvalidArgumentException format:@"Unable to locate NSWindow class %@, using NSWindow",_windowClass];
class=[NSWindow class];*/
if (!windowClass)
{
#if DEBUG
CPLog.warn("Unknown class \"%@\" in cib file, using CPWindow instead.", [self windowClass]);
#endif
windowClass = [CPWindow class];
}
var theWindow = [[windowClass alloc] initWithContentRect:_windowRect styleMask:_windowStyleMask];
if (_minSize)
[theWindow setMinSize:_minSize];
@@ -103,12 +108,11 @@
//[result setHidesOnDeactivate:(_wtFlags&0x80000000)?YES:NO];
[theWindow setTitle:_windowTitle];
// FIXME: we can't autoresize yet...
var contentViewAutoresizesSubviews = [_windowView autoresizesSubviews];
[_windowView setAutoresizesSubviews:NO];
[theWindow setContentView:_windowView];
[_windowView setAutoresizesSubviews:YES];
[_windowView setAutoresizesSubviews:contentViewAutoresizesSubviews];
if ([_viewClass isKindOfClass:[CPToolbar class]])
[theWindow setToolbar:_viewClass];
+1 -1
View File
@@ -687,7 +687,7 @@ if (_DOMContentsElement && aLayer._zPosition > _DOMContentsElement.style.zIndex)
@param aLayer the layer to insert
@param anIndex the index to insert the layer at
*/
- (void)insertSublayer:(CALayer)aLayer atIndex:(unsigned)anIndex
- (void)insertSublayer:(CALayer)aLayer atIndex:(CPUInteger)anIndex
{
if (!aLayer)
return;
+1 -1
View File
@@ -75,7 +75,7 @@ var CAMediaNamedTimingFunctions = nil;
return self;
}
- (void)getControlPointAtIndex:(unsigned)anIndex values:(float/*[2]*/)reference
- (void)getControlPointAtIndex:(CPUInteger)anIndex values:(float/*[2]*/)reference
{
if (anIndex == 0)
{
+19 -6
View File
@@ -43,7 +43,7 @@ var CANVAS_LINECAP_TABLE = [ "butt", "round", "square" ],
#define _CGContextFillRectCanvas(aContext, aRect) aContext.fillRect(CGRectGetMinX(aRect), CGRectGetMinY(aRect), CGRectGetWidth(aRect), CGRectGetHeight(aRect))
#define _CGContextClipCanvas(aContext) aContext.clip()
// In Cocoa, all primitives excepts rects cannot be added to the context's path
// In Cocoa, all primitives excepts rects and arcs cannot be added to the context's path
// until a move to point has been done, because an empty path has no current point.
var hasPath = function(aContext, methodName)
{
@@ -113,12 +113,12 @@ function CGContextSetBlendMode(aContext, aBlendMode)
function CGContextAddArc(aContext, x, y, radius, startAngle, endAngle, clockwise)
{
if (!hasPath(aContext, "CGContextAddArc"))
return;
// Despite the documentation saying otherwise, the last parameter is anti-clockwise not clockwise.
// http://developer.mozilla.org/en/docs/Canvas_tutorial:Drawing_shapes#Arcs
_CGContextAddArcCanvas(aContext, x, y, radius, startAngle, endAngle, !clockwise);
// AddArc implicitly starts a path
aContext.hasPath = YES;
}
function CGContextAddArcToPoint(aContext, x1, y1, x2, y2, radius)
@@ -470,7 +470,7 @@ var scale_rotate = function(a, b, c, d)
var rotate_scale = function(a, b, c, d)
{
var sign = (a * d < 0.0 || b * c > 0.0) ? -1.0 : 1.0;
var sign = (a * d < 0.0 || b * c > 0.0) ? -1.0 : 1.0,
a1 = (ATAN2(sign * b, sign * a) + ATAN2(-c, d)) / 2.0,
cos = COS(a1),
sin = SIN(a1);
@@ -596,7 +596,6 @@ function CGContextDrawLinearGradient(aContext, aGradient, aStartPoint, anEndPoin
{
var colors = aGradient.colors,
count = colors.length,
linearGradient = aContext.createLinearGradient(aStartPoint.x, aStartPoint.y, anEndPoint.x, anEndPoint.y);
while (count--)
@@ -607,6 +606,20 @@ function CGContextDrawLinearGradient(aContext, aGradient, aStartPoint, anEndPoin
aContext.hasPath = NO;
}
function CGContextDrawRadialGradient(aContext, aGradient, aStartCenter, aStartRadius, anEndCenter, anEndRadius, options)
{
var colors = aGradient.colors,
count = colors.length,
linearGradient = aContext.createRadialGradient(aStartCenter.x, aStartCenter.y, aStartRadius, anEndCenter.x, anEndCenter.y, anEndRadius);
while (count--)
linearGradient.addColorStop(aGradient.locations[count], to_string(colors[count]));
aContext.fillStyle = linearGradient;
aContext.fill();
aContext.hasPath = NO;
}
function CGBitmapGraphicsContextCreate()
{
var DOMElement = document.createElement("canvas"),
+26 -8
View File
@@ -120,12 +120,14 @@ function CGPathAddArc(aPath, aTransform, x, y, aRadius, aStartAngle, anEndAngle,
The ending point of the arc becomes the new current point of the path.
*/
var arcEndX = x + aRadius * COS(anEndAngle),
arcEndY = y + aRadius * SIN(anEndAngle);
arcEndY = y + aRadius * SIN(anEndAngle),
arcStartX = x + aRadius * COS(aStartAngle),
arcStartY = y + aRadius * SIN(aStartAngle);
if (aPath.count)
{
if (aPath.current.x !== arcEndX || aPath.current.y !== arcEndY)
CGPathAddLineToPoint(aPath, aTransform, arcEndX, arcEndY);
if (aPath.current.x !== x || aPath.current.y !== y)
CGPathAddLineToPoint(aPath, aTransform, arcStartX, arcStartY);
}
else
{
@@ -136,7 +138,7 @@ function CGPathAddArc(aPath, aTransform, x, y, aRadius, aStartAngle, anEndAngle,
}
aPath.current = CGPointMake(arcEndX, arcEndY);
aPath.elements[aPath.count++] = { type:kCGPathElementAddArc, x:x, y:y, radius:aRadius, startAngle:aStartAngle, endAngle:anEndAngle, clockwise:isClockwise };
aPath.elements[aPath.count++] = { type:kCGPathElementAddArc, x:x, y:y, radius:aRadius, startAngle:aStartAngle, endAngle:anEndAngle, isClockwise:isClockwise };
}
function CGPathAddArcToPoint(aPath, aTransform, x1, y1, x2, y2, aRadius)
@@ -233,7 +235,7 @@ function CGPathAddPath(aPath, aTransform, anotherPath)
case kCGPathElementAddArc:
CGPathAddArc(aPath, aTransform, element.x, element.y,
element.radius, element.startAngle,
element.endAngle, element.clockwise);
element.endAngle, element.isClockwise);
break;
case kCGPathElementAddArcToPoint:
@@ -438,7 +440,7 @@ function CGPathEqualToPath(aPath, anotherPath)
element.radius !== anotherElement.radius ||
element.startAngle !== anotherElement.startAngle ||
element.endAngle !== anotherElement.endAngle ||
element.clockwise !== anotherElement.clockwise)
element.isClockwise !== anotherElement.isClockwise)
{
return NO;
}
@@ -608,7 +610,23 @@ function CGPathGetBoundingBox(aPath)
return CGRectMake(ox, oy, rx - ox, ry - oy);
}
function CGPathContainsPoint(aPath, aTransform, point, eoFill)
{
if (!aPath.count)
return NO;
if (aTransform)
point = CGPointApplyAffineTransform(point, aTransform);
var context = CGBitmapGraphicsContextCreate();
CGContextBeginPath(context);
CGContextAddPath(context, aPath);
CGContextClosePath(context);
return context.isPointInPath(point.x, point.y);
}
/*!
@}
*/
*/
+27 -30
View File
@@ -26,6 +26,7 @@
@import "CPPlatform.j"
@class CPMenu
@class CPPlatformPasteboard
@global CPApp
@@ -33,46 +34,42 @@ var PrimaryPlatformWindow = NULL;
@implementation CPPlatformWindow : CPObject
{
CGRect _contentRect;
CGRect _contentRect;
CPInteger _level;
BOOL _hasShadow;
unsigned _shadowStyle;
CPString _title;
CPInteger _level;
BOOL _hasShadow;
unsigned _shadowStyle;
CPString _title;
#if PLATFORM(DOM)
DOMWindow _DOMWindow;
DOMWindow _DOMWindow;
DOMElement _DOMBodyElement;
DOMElement _DOMFocusElement;
DOMElement _DOMEventGuard;
DOMElement _DOMScrollingElement;
id _hideDOMScrollingElementTimeout;
DOMElement _DOMBodyElement;
DOMElement _DOMFocusElement;
DOMElement _DOMEventGuard;
DOMElement _DOMScrollingElement;
id _hideDOMScrollingElementTimeout;
CPArray _windowLevels;
CPDictionary _windowLayers;
CPArray _windowLevels;
CPDictionary _windowLayers;
BOOL _mouseIsDown;
BOOL _mouseDownIsRightClick;
CGPoint _lastMouseEventLocation;
CPWindow _mouseDownWindow;
CPTimeInterval _lastMouseUp;
CPTimeInterval _lastMouseDown;
BOOL _mouseIsDown;
BOOL _mouseDownIsRightClick;
CGPoint _lastMouseEventLocation;
CPWindow _mouseDownWindow;
CPTimeInterval _lastMouseUp;
CPTimeInterval _lastMouseDown;
Object _charCodes;
unsigned _keyCode;
unsigned _lastKey;
BOOL _capsLockActive;
BOOL _ignoreNativeCopyOrCutEvent;
BOOL _ignoreNativePastePreparation;
Object _charCodes;
unsigned _keyCode;
unsigned _lastKey;
BOOL _capsLockActive;
BOOL _DOMEventMode;
BOOL _DOMEventMode;
// Native Pasteboard Support
DOMElement _DOMPasteboardElement;
CPEvent _pasteboardKeyDownEvent;
CPPlatformPasteboard _platformPasteboard;
CPString _overriddenEventType;
CPString _overriddenEventType;
#endif
}
+2 -1
View File
@@ -23,6 +23,7 @@
@import <Foundation/CPArray.j>
@import <Foundation/CPObject.j>
@import "CGGeometry.j"
@implementation CPDOMWindowLayer : CPObject
{
@@ -78,7 +79,7 @@
aWindow._isVisible = NO;
}
- (void)insertWindow:(CPWindow)aWindow atIndex:(unsigned)anIndex
- (void)insertWindow:(CPWindow)aWindow atIndex:(CPUInteger)anIndex
{
// We will have to adjust the z-index of all windows starting at this index.
var count = [_windows count],
+528
View File
@@ -0,0 +1,528 @@
/*
* CPPlatformPasteboard.j
* AppKit
*
* Created by Alexander Ljungberg.
* Copyright 2013, 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/CPRunLoop.j>
@import "CPCompatibility.j"
@import "CPEvent.j"
@import "CPPasteboard.j"
@import "CPPlatform.j"
@import "CPPlatformWindow+DOMKeys.j"
@global CPApp
@global CPPlatformWindow
// From CPPlatformWindow+DOM.j
@global _CPDOMEventStop
#if PLATFORM(DOM)
#define SUPPRESS_CAPPUCCINO_CUT_FOR_EVENT(anEvent) anEvent._suppressCappuccinoCut = YES
#define SUPPRESS_CAPPUCCINO_PASTE_FOR_EVENT(anEvent) anEvent._suppressCappuccinoPaste = YES
var hasEditableTarget = function(aDOMEvent)
{
var target = aDOMEvent.target || aDOMEvent.srcElement;
if (!target)
return NO;
if (target.contentEditable == "true")
return YES;
var nodeName = target.nodeName.toUpperCase();
return nodeName === "INPUT" || nodeName == "TEXTAREA";
}
/*
* This class encapsulates copy and paste related functionality for the
* DOM environment. While originally all of this code was apread out in a
* dozen places in CPPlatformWindow+DOM.j, this class serves to collect
* and isolate that code for easier testing and maintenance.
*/
@implementation CPPlatformPasteboard : CPObject
{
DOMWindow _DOMWindow;
DOMElement _DOMPasteboardElement;
BOOL supportsNativeCopyAndPaste;
BOOL hasBugWhichPreventsNonEditablePaste;
BOOL hasBugWhichPreventsNonEditablePasteRedirect;
CPEvent _lastKeyDownEvent;
BOOL currentEventIsNativePasteEvent;
BOOL currentEventIsNativeCopyOrCutEvent;
BOOL currentEventShouldBeSuppressed;
BOOL currentEventShouldDefinitelyBubble;
BOOL currentEventShouldDefinitelyNotBubble;
BOOL _ignoreNativeCopyOrCutEvent;
BOOL _ignoreNativePastePreparation;
}
- (id)init
{
if (self = [super init])
{
supportsNativeCopyAndPaste = CPFeatureIsCompatible(CPJavaScriptClipboardEventsFeature);
hasBugWhichPreventsNonEditablePaste = CPPlatformHasBug(CPJavaScriptPasteRequiresEditableTarget);
hasBugWhichPreventsNonEditablePasteRedirect = CPPlatformHasBug(CPJavaScriptPasteCantRefocus);
}
return self;
}
- (void)setDOMWindow:(DOMWindow)aDOMWindow
{
if (_DOMWindow === aDOMWindow)
return;
if (_DOMWindow)
[self destroyDOMElements];
_DOMWindow = aDOMWindow;
if (_DOMWindow)
[self createDOMElements];
}
- (void)createDOMElements
{
var theDocument = _DOMWindow.document,
_DOMBodyElement = theDocument.getElementById("cappuccino-body") || theDocument.body;
// Create Native Pasteboard handler.
_DOMPasteboardElement = theDocument.createElement("textarea");
_DOMPasteboardElement.style.position = "absolute";
_DOMPasteboardElement.style.top = "-10000px";
_DOMPasteboardElement.style.zIndex = "999";
_DOMPasteboardElement.className = "cpdontremove";
_DOMBodyElement.appendChild(_DOMPasteboardElement);
_DOMPasteboardElement.blur();
var copyEventCallback = function (anEvent) { return [self beforeCopyEvent:anEvent]; },
nativeBeforeClipboardEventCallback = function (anEvent) { return [self nativeBeforeClipboardEvent:anEvent]; },
nativeCopyOrCutEventCallback = function (anEvent) { return [self nativeCopyOrCutEvent:anEvent]; },
pasteEventCallback = function (anEvent) { return [self beforePasteEvent:anEvent]; },
nativePasteEventCallback = function (anEvent) { return [self nativePasteEvent:anEvent]; };
if (theDocument.addEventListener)
{
if (supportsNativeCopyAndPaste)
{
_DOMWindow.addEventListener("beforecopy", nativeBeforeClipboardEventCallback, NO);
_DOMWindow.addEventListener("beforecut", nativeBeforeClipboardEventCallback, NO);
_DOMWindow.addEventListener("beforepaste", nativeBeforeClipboardEventCallback, NO);
_DOMWindow.addEventListener("copy", nativeCopyOrCutEventCallback, NO);
_DOMWindow.addEventListener("cut", nativeCopyOrCutEventCallback, NO);
_DOMWindow.addEventListener("paste", nativePasteEventCallback, NO);
}
else
{
theDocument.addEventListener("beforepaste", pasteEventCallback, NO);
theDocument.addEventListener("beforecopy", copyEventCallback, NO);
theDocument.addEventListener("beforecut", copyEventCallback, NO);
}
_DOMWindow.addEventListener("unload", function()
{
if (supportsNativeCopyAndPaste)
{
_DOMWindow.removeEventListener("beforecopy", nativeBeforeClipboardEventCallback, NO);
_DOMWindow.removeEventListener("beforecut", nativeBeforeClipboardEventCallback, NO);
_DOMWindow.removeEventListener("beforepaste", nativeBeforeClipboardEventCallback, NO);
_DOMWindow.removeEventListener("copy", nativeCopyOrCutEventCallback, NO);
_DOMWindow.removeEventListener("cut", nativeCopyOrCutEventCallback, NO);
_DOMWindow.removeEventListener("paste", nativePasteEventCallback, NO);
}
else
{
theDocument.removeEventListener("beforepaste", pasteEventCallback, NO);
theDocument.removeEventListener("beforecopy", copyEventCallback, NO);
theDocument.removeEventListener("beforecut", copyEventCallback, NO);
}
}, NO);
}
else
{
// TODO If we wanted IE 8 and lower copy and paste it'd go here.
}
}
- (void)destroyDOMElements
{
var theDocument = _DOMWindow.document,
_DOMBodyElement = theDocument.getElementById("cappuccino-body") || theDocument.body;
_DOMBodyElement.removeChild(_DOMPasteboardElement);
_DOMPasteboardElement = nil;
}
- (void)windowMaySendKeyEvent:(CPEvent)anEvent
{
// Reset our opinions.
currentEventIsNativePasteEvent = NO;
currentEventIsNativeCopyOrCutEvent = NO;
currentEventShouldBeSuppressed = NO;
currentEventShouldDefinitelyNotBubble = NO;
currentEventShouldDefinitelyBubble = NO;
if (!anEvent)
return;
if ([anEvent type] !== CPKeyDown)
{
// Reset these flags on key up.
_ignoreNativePastePreparation = NO;
_ignoreNativeCopyOrCutEvent = NO;
return;
}
var modifierFlags = [anEvent modifierFlags];
if (!(modifierFlags & (CPControlKeyMask | CPCommandKeyMask)))
return;
_lastKeyDownEvent = anEvent;
var aDOMEvent = anEvent._DOMEvent,
characters = [anEvent characters],
mayRequireDOMPasteboardElement = [self _mayRequireDOMPasteboardElementHack:aDOMEvent flags:modifierFlags];
if (characters === "v" && mayRequireDOMPasteboardElement)
{
if (supportsNativeCopyAndPaste && hasBugWhichPreventsNonEditablePaste && hasBugWhichPreventsNonEditablePasteRedirect && !hasEditableTarget(aDOMEvent))
{
// You can't paste from the system clipboard into a non-editable area in Safari, neither using native
// copy and paste nor our _DOMPasteboardElement hack. We will paste from the Cappuccino pasteboard only
// and allow Safari to "beep" to indicate something went wrong.
// The key down will not result in a paste event being sent by Safari, so it's not a paste event.
currentEventIsNativePasteEvent = NO;
// Yes to get the beep.
currentEventShouldDefinitelyBubble = YES;
}
else if (!(supportsNativeCopyAndPaste || hasBugWhichPreventsNonEditablePaste) && !_ignoreNativePastePreparation)
{
// We don't support native copy and paste so we must focus the _DOMPasteboardElement to receive the
// paste content. This needs to be done at keyDown time (or in the case of modern Safari, before the keyDown,
// which unfortunately isn't possible. See above.)
_DOMPasteboardElement.focus();
_DOMPasteboardElement.select();
_DOMPasteboardElement.value = "";
_DOMWindow.setNativeTimeout(function () { [self _checkDOMPasteboardElement]; }, 0);
currentEventIsNativePasteEvent = YES;
}
else if (supportsNativeCopyAndPaste)
currentEventIsNativePasteEvent = YES;
if (currentEventIsNativePasteEvent)
{
// We need the event to propagate or nothing will be pasted.
currentEventShouldDefinitelyBubble = YES;
// And we don't send the keydown because either our native paste envent handler will send it,
// or the _checkDOMPasteboardElement check will.
currentEventShouldBeSuppressed = YES;
}
}
else if ((characters == "c" || characters == "x") && mayRequireDOMPasteboardElement)
{
currentEventIsNativeCopyOrCutEvent = YES;
// If _ignoreNativeCopyOrCutEvent, we already handled the copy/cut in beforeCopyEvent:.
// If supportsNativeCopyAndPaste, we will be handling it in the nativebeforeCopyEvent: handler.
// In both of those cases we don't want to send the event on keydown too, or we'll get 2X copy/cut operations.
if (supportsNativeCopyAndPaste || _ignoreNativeCopyOrCutEvent)
currentEventShouldBeSuppressed = YES;
}
if (!currentEventShouldBeSuppressed)
{
if (characters === "v")
SUPPRESS_CAPPUCCINO_PASTE_FOR_EVENT(anEvent);
else if (characters === "x")
SUPPRESS_CAPPUCCINO_CUT_FOR_EVENT(anEvent);
}
}
- (BOOL)windowShouldSuppressKeyEvent
{
return currentEventShouldBeSuppressed;
}
- (void)windowDidSendKeyEvent:(CPEvent)anEvent
{
// Now that the copy event has been sent through the Cappuccino event stack, we can load any Cappuccino
// pasteboard string into our DOMPasteboardElement hack, if necessary.
if (!supportsNativeCopyAndPaste && currentEventIsNativeCopyOrCutEvent)
[self _primeDOMPasteboardElement];
}
- (BOOL)windowShouldStopPropagation
{
return currentEventShouldDefinitelyNotBubble;
}
- (BOOL)windowShouldNotStopPropagation
{
return currentEventShouldDefinitelyBubble;
}
- (CPEvent)_fakeClipboardEvent:(DOMEvent)aDOMEvent type:(CPString)aType
{
var keyCode = aType === "x" ? CPKeyCodes.X : (aType === "c" ? CPKeyCodes.C : CPKeyCodes.V),
characters = aType,
timestamp = [CPEvent currentTimestamp], // fake event, might as well use current timestamp
windowNumber = [[CPApp keyWindow] windowNumber],
modifierFlags = CPPlatformActionKeyMask,
location = [_lastKeyDownEvent locationInWindow],
anEvent = [CPEvent keyEventWithType:CPKeyDown location:location modifierFlags:modifierFlags
timestamp:timestamp windowNumber:windowNumber context:nil
characters:characters charactersIgnoringModifiers:characters isARepeat:NO keyCode:keyCode];
anEvent._data1 = @{ "simulated": YES };
anEvent._DOMEvent = aDOMEvent;
return anEvent;
}
- (void)beforeCopyEvent:(DOMEvent)aDOMEvent
{
if ([self _mayRequireDOMPasteboardElementHack:aDOMEvent flags:CPPlatformActionKeyMask] && !_ignoreNativeCopyOrCutEvent)
{
// we have to send out a fake copy or cut event so that we can force the copy/cut mechanisms to take place
var anEvent = [self _fakeClipboardEvent:aDOMEvent type:(aDOMEvent.type === "beforecut" ? "x" : "c")];
[CPApp sendEvent:anEvent];
// Once we've sent it, we can load the copy information into the pasteboard hack.
[self _primeDOMPasteboardElement];
//then we have to IGNORE the real keyboard event to prevent a double copy
//safari also sends the beforecopy event twice, so we additionally check here and prevent two events
_ignoreNativeCopyOrCutEvent = YES;
}
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
}
- (boolean)beforePasteEvent:(DOMEvent)aDOMEvent
{
// Set up to capture the paste in a temporary input field. We'll send the event after capture.
if ([self _mayRequireDOMPasteboardElementHack:aDOMEvent flags:CPPlatformActionKeyMask])
{
_DOMPasteboardElement.focus();
_DOMPasteboardElement.select();
_DOMPasteboardElement.value = "";
_ignoreNativePastePreparation = YES;
}
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
}
/*
Return true if the event may be a copy and paste event, but the target is not an input or text area.
*/
- (void)_mayRequireDOMPasteboardElementHack:(DOMEvent)aDOMEvent flags:(unsigned)modifierFlags
{
return !hasEditableTarget(aDOMEvent) && (modifierFlags & CPPlatformActionKeyMask);
}
- (void)_primeDOMPasteboardElement
{
var pasteboard = [CPPasteboard generalPasteboard],
types = [pasteboard types];
if (types.length)
{
if ([types indexOfObjectIdenticalTo:CPStringPboardType] !== CPNotFound)
_DOMPasteboardElement.value = [pasteboard stringForType:CPStringPboardType];
else
_DOMPasteboardElement.value = [pasteboard _generateStateUID];
_DOMPasteboardElement.focus();
_DOMPasteboardElement.select();
window.setNativeTimeout(function() { [self _clearDOMPasteboardElement]; }, 0);
}
}
- (void)_checkDOMPasteboardElement
{
if (supportsNativeCopyAndPaste)
{
[self _clearDOMPasteboardElement];
return;
}
var value = _DOMPasteboardElement.value;
if ([value length])
{
var pasteboard = [CPPasteboard generalPasteboard];
if ([pasteboard _stateUID] != value)
{
[pasteboard declareTypes:[CPStringPboardType] owner:self];
[pasteboard setString:value forType:CPStringPboardType];
}
}
[self _clearDOMPasteboardElement];
[CPApp sendEvent:[self _fakeClipboardEvent:nil type:@"v"]];
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
}
- (void)_clearDOMPasteboardElement
{
_DOMPasteboardElement.value = "";
_DOMPasteboardElement.blur();
}
- (boolean)nativeBeforeClipboardEvent:(DOMEvent)aDOMEvent
{
// Our job here is to return "false" if the given clipboard operation should be enabled even in a situation where
// the browser might normally grey the option out.
// Allow these fields to do their own thing.
if (hasEditableTarget(aDOMEvent))
return true;
var returnValue = YES;
switch (aDOMEvent.type)
{
case "beforecopy":
returnValue = !([CPApp targetForAction:@selector(copy:)]);
break;
case "beforecut":
returnValue = !([CPApp targetForAction:@selector(cut:)]);
break;
case "beforepaste":
returnValue = !([CPApp targetForAction:@selector(paste:)]);
break;
}
if (!returnValue)
_CPDOMEventStop(aDOMEvent, self);
return returnValue;
}
- (boolean)nativePasteEvent:(DOMEvent)aDOMEvent
{
// This shouldn't happen.
if (!supportsNativeCopyAndPaste)
return;
var value;
if (aDOMEvent.clipboardData && aDOMEvent.clipboardData.setData)
value = aDOMEvent.clipboardData.getData('text/plain');
else
value = _DOMWindow.clipboardData.getData("Text");
if ([value length])
{
var pasteboard = [CPPasteboard generalPasteboard];
if ([pasteboard _stateUID] != value)
{
[pasteboard declareTypes:[CPStringPboardType] owner:self];
[pasteboard setString:value forType:CPStringPboardType];
}
}
var anEvent = [self _fakeClipboardEvent:aDOMEvent type:"v"],
platformWindow = [[anEvent window] platformWindow];
SUPPRESS_CAPPUCCINO_PASTE_FOR_EVENT(anEvent);
// By default we'll stop the native handling of the event since we're handling it ourselves. However, we need to
// stop it before we send the event so that the event can overrule our choice. CPTextField for instance wants the
// default handling when focused (which is to insert into the field).
[platformWindow _propagateCurrentDOMEvent:NO]
[CPApp sendEvent:anEvent];
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
if (![platformWindow _willPropagateCurrentDOMEvent])
_CPDOMEventStop(aDOMEvent, self);
return false;
}
- (boolean)nativeCopyOrCutEvent:(DOMEvent)aDOMEvent
{
// This shouldn't happen.
if (!supportsNativeCopyAndPaste)
return;
var anEvent = [self _fakeClipboardEvent:aDOMEvent type:(aDOMEvent.type.indexOf("cut") != CPNotFound ? "x" : "c")],
platformWindow = [[anEvent window] platformWindow];
SUPPRESS_CAPPUCCINO_CUT_FOR_EVENT(anEvent);
[platformWindow _propagateCurrentDOMEvent:NO]
// Let the app react through copy: and cut: actions.
[CPApp sendEvent:anEvent];
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
// If StopDOMEventPropagation was set to NO, we don't try to write to the system clipboard. The control that did this
// wants to use the default copy/cut functionality.
if (![platformWindow _willPropagateCurrentDOMEvent])
{
// Now the app should have written whatever it wants to have copied to the Cappuccino clipboard. So now we need
// to write it to the system board.
_CPDOMEventStop(aDOMEvent, self);
var pasteboard = [CPPasteboard generalPasteboard];
if ([[pasteboard types] containsObject:CPStringPboardType])
{
var stringValue = [pasteboard stringForType:CPStringPboardType];
if (aDOMEvent.clipboardData && aDOMEvent.clipboardData.setData)
aDOMEvent.clipboardData.setData('text/plain', stringValue);
else
_DOMWindow.clipboardData.setData('Text', stringValue);
}
}
return ![platformWindow _willPropagateCurrentDOMEvent];
}
@end
#endif
+2 -2
View File
@@ -53,7 +53,7 @@ var DOMFixedWidthSpanElement = nil,
style = DOMFlexibleWidthSpanElement.style;
style.position = "absolute";
style.left = "-100000px";
style.zIndex = -100000;
style.zIndex = -10000;
style.visibility = "visible";
style.padding = "0px";
style.margin = "0px";
@@ -99,7 +99,7 @@ var DOMFixedWidthSpanElement = nil,
DOMMetricsDivElement.className = "cpdontremove";
style = DOMMetricsDivElement.style;
style.position = "absolute";
style.left = "-10000px";
style.left = "-100000px";
style.zIndex = -10000;
style.width = "100000px";
style.whiteSpace = "nowrap";
+84 -189
View File
@@ -107,27 +107,29 @@
* P: undefined 80 undefined
*/
@import <Foundation/CPNotificationCenter.j>
@import <Foundation/CPObject.j>
@import <Foundation/CPRunLoop.j>
@import <Foundation/CPSet.j>
@import <Foundation/CPTimer.j>
@import "CPCursor.j"
@import "CPApplication_Constants.j"
@import "CPCompatibility.j"
@import "CPCursor.j"
@import "CPDOMWindowLayer.j"
@import "CPDragServer_Constants.j"
@import "CPEvent.j"
@import "CPPasteboard.j"
@import "CPPlatform.j"
@import "CPPlatformWindow.j"
@import "CPPlatformPasteboard.j"
@import "CPPlatformWindow+DOMKeys.j"
@import "CPPlatformWindow.j"
@import "CPText.j"
@import "CPWindow_Constants.j"
@class CPDragServer
@class _CPToolTip
@global CPApp
@global _CPRunModalLoop
// List of all open native windows
@@ -135,7 +137,6 @@ var PlatformWindows = [CPSet set];
// Define up here so compressor knows about them.
var CPDOMEventGetClickCount,
CPDOMEventStop,
StopDOMEventPropagation,
StopContextMenuDOMEventPropagation;
@@ -196,11 +197,13 @@ var ModifierKeyCodes = [
CPKeyCodes.ALT,
CPKeyCodes.SHIFT
],
supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
var resizeTimer = nil;
#if PLATFORM(DOM)
@implementation CPPlatformWindow (DOM)
- (id)_init
@@ -215,6 +218,8 @@ var resizeTimer = nil;
_windowLevels = [];
_windowLayers = @{};
_platformPasteboard = [CPPlatformPasteboard new];
[self registerDOMWindow];
[self updateFromNativeContentRect];
@@ -301,19 +306,6 @@ var resizeTimer = nil;
_DOMBodyElement.appendChild(_DOMFocusElement);
// Create Native Pasteboard handler.
_DOMPasteboardElement = theDocument.createElement("textarea");
_DOMPasteboardElement.style.position = "absolute";
_DOMPasteboardElement.style.top = "-10000px";
_DOMPasteboardElement.style.zIndex = "999";
_DOMPasteboardElement.className = "cpdontremove";
_DOMBodyElement.appendChild(_DOMPasteboardElement);
// Make sure the pastboard element is blurred.
_DOMPasteboardElement.blur();
// Create a full screen div to protect against iframes and other elements
// from consuming events during tracking
// FIXME: multiple windows
@@ -367,6 +359,8 @@ var resizeTimer = nil;
[self createDOMElements];
[self _addLayers];
[_platformPasteboard setDOMWindow:_DOMWindow];
var theClass = [self class],
dragEventImplementation = class_getMethodImplementation(theClass, @selector(dragEvent:)),
@@ -376,17 +370,9 @@ var resizeTimer = nil;
resizeEventImplementation = class_getMethodImplementation(theClass, resizeEventSelector),
resizeEventCallback = function (anEvent) { resizeEventImplementation(self, nil, anEvent); },
copyEventSelector = @selector(copyEvent:),
copyEventImplementation = class_getMethodImplementation(theClass, copyEventSelector),
copyEventCallback = function (anEvent) {copyEventImplementation(self, nil, anEvent); },
pasteEventSelector = @selector(pasteEvent:),
pasteEventImplementation = class_getMethodImplementation(theClass, pasteEventSelector),
pasteEventCallback = function (anEvent) {pasteEventImplementation(self, nil, anEvent); },
keyEventSelector = @selector(keyEvent:),
keyEventImplementation = class_getMethodImplementation(theClass, keyEventSelector),
keyEventCallback = function (anEvent) { keyEventImplementation(self, nil, anEvent); },
keyEventCallback = function (anEvent) { return keyEventImplementation(self, nil, anEvent); },
mouseEventSelector = @selector(mouseEvent:),
mouseEventImplementation = class_getMethodImplementation(theClass, mouseEventSelector),
@@ -421,10 +407,6 @@ var resizeTimer = nil;
theDocument.addEventListener("mousemove", mouseEventCallback, NO);
theDocument.addEventListener("contextmenu", contextMenuEventCallback, NO);
theDocument.addEventListener("beforecopy", copyEventCallback, NO);
theDocument.addEventListener("beforecut", copyEventCallback, NO);
theDocument.addEventListener("beforepaste", pasteEventCallback, NO);
theDocument.addEventListener("keyup", keyEventCallback, NO);
theDocument.addEventListener("keydown", keyEventCallback, NO);
theDocument.addEventListener("keypress", keyEventCallback, NO);
@@ -454,10 +436,6 @@ var resizeTimer = nil;
theDocument.removeEventListener("keydown", keyEventCallback, NO);
theDocument.removeEventListener("keypress", keyEventCallback, NO);
theDocument.removeEventListener("beforecopy", copyEventCallback, NO);
theDocument.removeEventListener("beforecut", copyEventCallback, NO);
theDocument.removeEventListener("beforepaste", pasteEventCallback, NO);
theDocument.removeEventListener("touchstart", touchEventCallback, NO);
theDocument.removeEventListener("touchend", touchEventCallback, NO);
theDocument.removeEventListener("touchmove", touchEventCallback, NO);
@@ -473,6 +451,8 @@ var resizeTimer = nil;
[PlatformWindows removeObject:self];
[_platformPasteboard setDOMWindow:nil];
self._DOMWindow = nil;
}, NO);
}
@@ -494,7 +474,7 @@ var resizeTimer = nil;
theDocument.onmousewheel = scrollEventCallback;
_DOMBodyElement.ondrag = function () { return NO; };
_DOMBodyElement.onselectstart = function () { return _DOMWindow.event.srcElement === _DOMPasteboardElement; };
_DOMBodyElement.onselectstart = function () { return _DOMWindow.event.srcElement === _platformPasteboard._DOMPasteboardElement; };
_DOMWindow.attachEvent("onunload", function()
{
@@ -523,6 +503,8 @@ var resizeTimer = nil;
[PlatformWindows removeObject:self];
[_platformPasteboard setDOMWindow:nil];
self._DOMWindow = nil;
}, NO);
}
@@ -709,9 +691,7 @@ var resizeTimer = nil;
StopDOMEventPropagation = NO;
}
var isNativePasteEvent = NO,
isNativeCopyOrCutEvent = NO,
overrideCharacters = nil,
var overrideCharacters = nil,
charactersIgnoringModifiers = @"";
switch (aDOMEvent.type)
@@ -753,31 +733,6 @@ var resizeTimer = nil;
//we are simply going to skip all keypress events that use cmd/ctrl key
//this lets us be consistent in all browsers and send on the keydown
//which means we can cancel the event early enough, but only if sendEvent needs to
var eligibleForCopyPaste = [self _validateCopyCutOrPasteEvent:aDOMEvent flags:modifierFlags];
// If this could be a native PASTE event, then we need to further examine it before
// sending a CPEvent. Select our element to see if anything gets pasted in it.
if (characters === "v" && eligibleForCopyPaste)
{
if (!_ignoreNativePastePreparation)
{
_DOMPasteboardElement.select();
_DOMPasteboardElement.value = "";
}
isNativePasteEvent = YES;
}
// However, of this could be a native COPY event, we need to let the normal event-process take place so it
// can capture our internal Cappuccino pasteboard.
else if ((characters == "c" || characters == "x") && eligibleForCopyPaste)
{
isNativeCopyOrCutEvent = YES;
if (_ignoreNativeCopyOrCutEvent)
break;
}
}
else if (CPKeyCodes.firesKeyPressEvent(_keyCode, _lastKey, aDOMEvent.shiftKey, aDOMEvent.ctrlKey, aDOMEvent.altKey))
{
@@ -823,12 +778,6 @@ var resizeTimer = nil;
timestamp:timestamp windowNumber:windowNumber context:nil
characters:characters charactersIgnoringModifiers:charactersIgnoringModifiers isARepeat:isARepeat keyCode:charCode];
if (isNativePasteEvent)
{
_pasteboardKeyDownEvent = event;
window.setNativeTimeout(function () { [self _checkPasteboardElement] }, 0);
}
break;
case "keyup":
@@ -838,8 +787,6 @@ var resizeTimer = nil;
_keyCode = -1;
_lastKey = -1;
_charCodes[keyCode] = nil;
_ignoreNativeCopyOrCutEvent = NO;
_ignoreNativePastePreparation = NO;
// check for caps lock state
if (keyCode === CPKeyCodes.CAPS_LOCK)
@@ -864,127 +811,33 @@ var resizeTimer = nil;
event = [CPEvent keyEventWithType:CPKeyUp location:location modifierFlags:modifierFlags
timestamp: timestamp windowNumber:windowNumber context:nil
characters:characters charactersIgnoringModifiers:charactersIgnoringModifiers isARepeat:NO keyCode:keyCode];
break;
}
if (event && !isNativePasteEvent)
{
if (event)
event._DOMEvent = aDOMEvent;
[_platformPasteboard windowMaySendKeyEvent:event];
if (event && ![_platformPasteboard windowShouldSuppressKeyEvent])
{
[CPApp sendEvent:event];
if (isNativeCopyOrCutEvent)
{
// If this is a native copy event, then check if the pasteboard has anything in it.
[self _primePasteboardElement];
}
[_platformPasteboard windowDidSendKeyEvent:event];
}
if (StopDOMEventPropagation)
CPDOMEventStop(aDOMEvent, self);
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
}
- (void)copyEvent:(DOMEvent)aDOMEvent
{
if ([self _validateCopyCutOrPasteEvent:aDOMEvent flags:CPPlatformActionKeyMask] && !_ignoreNativeCopyOrCutEvent)
var didStop = NO;
// Platform pasteboard can overrule the decision to stop propagation either way, or it might have no opinion.
if ([_platformPasteboard windowShouldStopPropagation] || (StopDOMEventPropagation && ![_platformPasteboard windowShouldNotStopPropagation]))
{
// we have to send out a fake copy or cut event so that we can force the copy/cut mechanisms to take place
var cut = aDOMEvent.type === "beforecut",
keyCode = cut ? CPKeyCodes.X : CPKeyCodes.C,
characters = cut ? "x" : "c",
timestamp = [CPEvent currentTimestamp], // fake event, might as well use current timestamp
windowNumber = [[CPApp keyWindow] windowNumber],
modifierFlags = CPPlatformActionKeyMask,
location = _lastMouseEventLocation || CGPointMakeZero(),
event = [CPEvent keyEventWithType:CPKeyDown location:location modifierFlags:modifierFlags
timestamp:timestamp windowNumber:windowNumber context:nil
characters:characters charactersIgnoringModifiers:characters isARepeat:NO keyCode:keyCode];
event._DOMEvent = aDOMEvent;
[CPApp sendEvent:event];
[self _primePasteboardElement];
//then we have to IGNORE the real keyboard event to prevent a double copy
//safari also sends the beforecopy event twice, so we additionally check here and prevent two events
_ignoreNativeCopyOrCutEvent = YES;
didStop = YES;
_CPDOMEventStop(aDOMEvent, self);
}
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
}
- (void)pasteEvent:(DOMEvent)aDOMEvent
{
if ([self _validateCopyCutOrPasteEvent:aDOMEvent flags:CPPlatformActionKeyMask])
{
_DOMPasteboardElement.focus();
_DOMPasteboardElement.select();
_DOMPasteboardElement.value = "";
_ignoreNativePastePreparation = YES;
}
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
}
- (void)_validateCopyCutOrPasteEvent:(DOMEvent)aDOMEvent flags:(unsigned)modifierFlags
{
return (
((aDOMEvent.target || aDOMEvent.srcElement).nodeName.toUpperCase() !== "INPUT" &&
(aDOMEvent.target || aDOMEvent.srcElement).nodeName.toUpperCase() !== "TEXTAREA"
) || aDOMEvent.target === _DOMPasteboardElement
) &&
(modifierFlags & CPPlatformActionKeyMask);
}
- (void)_primePasteboardElement
{
var pasteboard = [CPPasteboard generalPasteboard],
types = [pasteboard types];
if (types.length)
{
if ([types indexOfObjectIdenticalTo:CPStringPboardType] != CPNotFound)
_DOMPasteboardElement.value = [pasteboard stringForType:CPStringPboardType];
else
_DOMPasteboardElement.value = [pasteboard _generateStateUID];
_DOMPasteboardElement.focus();
_DOMPasteboardElement.select();
window.setNativeTimeout(function() { [self _clearPasteboardElement]; }, 0);
}
}
- (void)_checkPasteboardElement
{
var value = _DOMPasteboardElement.value;
if ([value length])
{
var pasteboard = [CPPasteboard generalPasteboard];
if ([pasteboard _stateUID] != value)
{
[pasteboard declareTypes:[CPStringPboardType] owner:self];
[pasteboard setString:value forType:CPStringPboardType];
}
}
[self _clearPasteboardElement];
[CPApp sendEvent:_pasteboardKeyDownEvent];
_pasteboardKeyDownEvent = nil;
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
}
- (void)_clearPasteboardElement
{
_DOMPasteboardElement.value = "";
_DOMPasteboardElement.blur();
return !didStop;
}
- (void)scrollEvent:(DOMEvent)aDOMEvent
@@ -1060,7 +913,7 @@ var resizeTimer = nil;
{
// Find the scroll delta
var deltaX = _DOMScrollingElement.scrollLeft - 150,
deltaY = (_DOMScrollingElement.scrollTop - 150) || (aDOMEvent.deltaY===undefined?0: aDOMEvent.deltaY);
deltaY = (_DOMScrollingElement.scrollTop - 150) || (aDOMEvent.deltaY === undefined ? 0 : aDOMEvent.deltaY);
// If we scroll super with momentum,
// there are so many events going off that
@@ -1081,7 +934,7 @@ var resizeTimer = nil;
// We set StopDOMEventPropagation = NO on line 1008
//if (StopDOMEventPropagation)
// CPDOMEventStop(aDOMEvent, self);
// _CPDOMEventStop(aDOMEvent, self);
// Reset the DOM elements scroll offset
_DOMScrollingElement.scrollLeft = 150;
@@ -1142,6 +995,10 @@ var resizeTimer = nil;
[windows[windowCount] resizeWithOldPlatformWindowSize:oldSize];
}
[[CPNotificationCenter defaultCenter] postNotificationName:CPApplicationDidChangeScreenParametersNotification
object:CPApp
userInfo:nil];
//window.liveResize = NO;
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
@@ -1322,8 +1179,12 @@ var resizeTimer = nil;
[CPApp sendEvent:event];
}
var didStop = NO;
if (StopDOMEventPropagation && (!supportsNativeDragAndDrop || type !== "mousedown" && !isDragging))
CPDOMEventStop(aDOMEvent, self);
{
didStop = YES;
_CPDOMEventStop(aDOMEvent, self);
}
// If there are any tracking event listeners (listening for CPLeftMouseDraggedMask)
// then show the event guard so we don't lose events to iframes
@@ -1345,12 +1206,13 @@ var resizeTimer = nil;
_DOMEventGuard.style.display = hasTrackingEventListener ? "" : "none";
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
return !didStop;
}
- (void)contextMenuEvent:(DOMEvent)aDOMEvent
{
if (StopContextMenuDOMEventPropagation)
CPDOMEventStop(aDOMEvent, self);
_CPDOMEventStop(aDOMEvent, self);
return !StopContextMenuDOMEventPropagation;
}
@@ -1646,6 +1508,44 @@ var resizeTimer = nil;
return theWindow;
}
/*! @ignore Return the selected text in the DOM window if known. */
- (CPString)_selectedText
{
if (_DOMWindow.getSelection)
return "" + _DOMWindow.getSelection();
else if (_DOMWindow.document.getSelection)
return "" + _DOMWindow.document.getSelection();
else if (_DOMWindow.selection)
return "" + _DOMWindow.selection.createRange().text;
else
return nil;
}
/*!
Set the text selection range to the given range within the given element, which must be a child of
this DOM window.
*/
- (void)setSelectedRange:(CPRange)aRange inElement:(DOMElement)anElement
{
if (_DOMWindow.getSelection())
{
var domRange = _DOMWindow.document.createRange();
domRange.setStart(anElement.childNodes[0], aRange.location);
domRange.setEnd(anElement.childNodes[0], CPMaxRange(aRange));
_DOMWindow.getSelection().removeAllRanges();
_DOMWindow.getSelection().addRange(domRange);
}
else if (_DOMWindow.document.selection)
{
var domRange = _DOMWindow.document.body.createTextRange();
domRange.moveToElementText(anElement);
domRange.collapse(true);
domRange.moveStart('character', aRange.location);
domRange.moveEnd('character', aRange.length);
domRange.select();
}
}
/*!
When using command (mac) or control (windows), keys are propagated to the browser by default.
To prevent a character key from propagating (to prevent its default action, and instead use it
@@ -1751,7 +1651,8 @@ var CPDOMEventGetClickCount = function(aComparisonEvent, aTimestamp, aLocation)
ABS(comparisonLocation.y - aLocation.y) < CLICK_SPACE_DELTA) ? [aComparisonEvent clickCount] + 1 : 1;
};
var CPDOMEventStop = function(aDOMEvent, aPlatformWindow)
// Global.
_CPDOMEventStop = function(aDOMEvent, aPlatformWindow)
{
// IE Model
aDOMEvent.cancelBubble = true;
@@ -1763,12 +1664,6 @@ var CPDOMEventStop = function(aDOMEvent, aPlatformWindow)
if (aDOMEvent.stopPropagation)
aDOMEvent.stopPropagation();
if (aDOMEvent.type === CPDOMEventMouseDown)
{
aPlatformWindow._DOMFocusElement.focus();
aPlatformWindow._DOMFocusElement.blur();
}
};
function CPWindowObjectList()
+69 -37
View File
@@ -375,7 +375,7 @@ var themedButtonValues = nil,
"themedMenuItemStandardView",
"themedMenuItemMenuBarView",
"themedToolbarView",
"themedBordelessBridgeWindowView",
"themedBorderlessBridgeWindowView",
"themedWindowView",
"themedBrowser",
"themedRuleEditor",
@@ -1097,7 +1097,7 @@ var themedButtonValues = nil,
+ (CPDatePicker)themedDatePicker
{
var datePicker = [[CPDatePicker alloc] initWithFrame:CGRectMake(40,140,300,29)],
var datePicker = [[CPDatePicker alloc] initWithFrame:CGRectMake(40.0, 40.0, 170.0, 29.0)],
bezelColor = PatternColor(
[
@@ -1166,6 +1166,7 @@ var themedButtonValues = nil,
[@"max-size", CGSizeMake(-1.0, 29.0)]
];
[datePicker setDatePickerStyle:CPTextFieldDatePickerStyle];
[self registerThemeValues:themeValues forView:datePicker];
return datePicker;
@@ -1173,7 +1174,7 @@ var themedButtonValues = nil,
+ (CPDatePicker)themedDatePickerCalendar
{
var datePicker = [[CPDatePicker alloc] initWithFrame:CGRectMake(40,140,300,29)],
var datePicker = [[CPDatePicker alloc] initWithFrame:CGRectMake(40.0, 140.0, 276.0, 148.0)],
arrowImageLeft = PatternImage("datepicker-calendar-arrow-left.png", 7.0, 10.0),
arrowImageRight = PatternImage("datepicker-calendar-arrow-right.png", 7.0, 10.0),
@@ -1183,17 +1184,26 @@ var themedButtonValues = nil,
arrowImageRightHighlighted = PatternImage("datepicker-calendar-arrow-right-highlighted.png", 7.0, 10.0),
circleImageHighlighted = PatternImage("datepicker-circle-image-highlighted.png", 9.0, 10.0),
secondHandColor = PatternColor("datepicker-clock-second-hand.png", 89.0, 89.0),
minuteHandColor = PatternColor("datepicker-clock-minute-hand.png", 85.0, 85.0),
hourHandColor = PatternColor("datepicker-clock-hour-hand.png", 47.0, 47.0),
middleHandColor = PatternColor("datepicker-clock-middle-hand.png", 13.0, 13.0),
clockImageColor = PatternColor("datepicker-clock.png", 122.0, 123.0),
secondHandSize = CGSizeMake(89.0, 89.0),
secondHandImage = PatternImage("datepicker-clock-second-hand.png", secondHandSize.width, secondHandSize.height),
secondHandColorDisabled = PatternColor("datepicker-clock-second-hand-disabled.png", 89.0, 89.0),
minuteHandColorDisabled = PatternColor("datepicker-clock-minute-hand-disabled.png", 85.0, 85.0),
hourHandColorDisabled = PatternColor("datepicker-clock-hour-hand-disabled.png", 47.0, 47.0),
middleHandColorDisabled = PatternColor("datepicker-clock-middle-hand-disabled.png", 13.0, 13.0),
clockImageColorDisabled = PatternColor("datepicker-clock-disabled.png", 122.0, 123.0),
minuteHandSize = CGSizeMake(85.0, 85.0),
minuteHandImage = PatternImage("datepicker-clock-minute-hand.png", minuteHandSize.width, minuteHandSize.height),
hourHandSize = CGSizeMake(47.0, 47.0),
hourHandImage = PatternImage("datepicker-clock-hour-hand.png", hourHandSize.width, hourHandSize.height),
middleHandSize = CGSizeMake(13.0, 13.0),
middleHandImage = PatternImage("datepicker-clock-middle-hand.png", middleHandSize.width, middleHandSize.height),
clockSize = CGSizeMake(122.0, 123.0),
clockImageColor = PatternColor("datepicker-clock.png", clockSize.width, clockSize.height),
secondHandImageDisabled = PatternImage("datepicker-clock-second-hand-disabled.png", secondHandSize.width, secondHandSize.height),
minuteHandImageDisabled = PatternImage("datepicker-clock-minute-hand-disabled.png", minuteHandSize.width, minuteHandSize.height),
hourHandImageDisabled = PatternImage("datepicker-clock-hour-hand-disabled.png", hourHandSize.width, hourHandSize.height),
middleHandImageDisabled = PatternImage("datepicker-clock-middle-hand-disabled.png", middleHandSize.width, middleHandSize.height),
clockImageColorDisabled = PatternColor("datepicker-clock-disabled.png", clockSize.width, clockSize.height),
themeValues =
[
@@ -1204,7 +1214,7 @@ var themedButtonValues = nil,
[@"bezel-color-calendar", [CPColor whiteColor]],
[@"bezel-color-calendar", [CPColor colorWithCalibratedRed:159.0 / 255.0 green:201.0 / 255.0 blue:225.0 / 255.0 alpha:1.0], CPThemeStateSelected],
[@"bezel-color-calendar", [CPColor colorWithCalibratedRed:159.0 / 255.0 green:201.0 / 255.0 blue:225.0 / 255.0 alpha:0.5], CPThemeStateSelected |CPThemeStateDisabled],
[@"bezel-color-calendar", [CPColor colorWithCalibratedRed:159.0 / 255.0 green:201.0 / 255.0 blue:225.0 / 255.0 alpha:0.5], CPThemeStateSelected | CPThemeStateDisabled],
[@"bezel-color-clock", clockImageColor],
[@"bezel-color-clock", clockImageColorDisabled, CPThemeStateDisabled],
@@ -1286,25 +1296,25 @@ var themedButtonValues = nil,
[@"circle-image-highlighted", circleImageHighlighted],
[@"arrow-inset", CGInsetMake(9.0, 4.0, 0.0, 0.0)],
[@"second-hand-color", secondHandColor],
[@"hour-hand-color", hourHandColor],
[@"middle-hand-color", middleHandColor],
[@"minute-hand-color", minuteHandColor],
[@"second-hand-image", secondHandImage],
[@"hour-hand-image", hourHandImage],
[@"middle-hand-image", middleHandImage],
[@"minute-hand-image", minuteHandImage],
[@"second-hand-color", secondHandColorDisabled, CPThemeStateDisabled],
[@"hour-hand-color", hourHandColorDisabled, CPThemeStateDisabled],
[@"middle-hand-color", middleHandColorDisabled, CPThemeStateDisabled],
[@"minute-hand-color", minuteHandColorDisabled, CPThemeStateDisabled],
[@"second-hand-image", secondHandImageDisabled, CPThemeStateDisabled],
[@"hour-hand-image", hourHandImageDisabled, CPThemeStateDisabled],
[@"middle-hand-image", middleHandImageDisabled, CPThemeStateDisabled],
[@"minute-hand-image", minuteHandImageDisabled, CPThemeStateDisabled],
[@"second-hand-size", CGSizeMake(89.0, 89.0)],
[@"hour-hand-size", CGSizeMake(47.0, 47.0)],
[@"middle-hand-size", CGSizeMake(13.0, 13.0)],
[@"minute-hand-size", CGSizeMake(85.0, 85.0)],
[@"second-hand-size", secondHandSize],
[@"hour-hand-size", hourHandSize],
[@"middle-hand-size", middleHandSize],
[@"minute-hand-size", minuteHandSize],
[@"border-width", 1.0],
[@"size-header", CGSizeMake(141.0, 39.0)],
[@"size-tile", CGSizeMake(20.0, 18.0)],
[@"size-clock", CGSizeMake(122.0, 123.0)],
[@"size-clock", clockSize],
[@"size-calendar", CGSizeMake(141.0, 109.0)],
[@"min-size-calendar", CGSizeMake(141.0, 148.0)],
[@"max-size-calendar", CGSizeMake(141.0, 148.0)]
@@ -1312,6 +1322,7 @@ var themedButtonValues = nil,
];
[datePicker setDatePickerStyle:CPClockAndCalendarDatePickerStyle];
[datePicker setBackgroundColor:[CPColor whiteColor]];
[self registerThemeValues:themeValues forView:datePicker];
return datePicker;
@@ -2071,15 +2082,32 @@ var themedButtonValues = nil,
themedTableViewValues =
[
[@"alternating-row-colors", alternatingRowColors],
[@"grid-color", gridColor],
[@"highlighted-grid-color", [CPColor whiteColor]],
[@"selection-color", selectionColor],
[@"sourcelist-selection-color", sourceListSelectionColor],
[@"sort-image", sortImage],
[@"sort-image-reversed", sortImageReversed],
[@"image-generic-file", imageGenericFile],
[@"default-row-height", 23.0],
[@"alternating-row-colors", alternatingRowColors],
[@"grid-color", gridColor],
[@"highlighted-grid-color", [CPColor whiteColor]],
[@"selection-color", selectionColor],
[@"sourcelist-selection-color", sourceListSelectionColor],
[@"sort-image", sortImage],
[@"sort-image-reversed", sortImageReversed],
[@"image-generic-file", imageGenericFile],
[@"default-row-height", 23.0],
[@"dropview-on-background-color", [CPColor colorWithRed:72 / 255 green:134 / 255 blue:202 / 255 alpha:0.25]],
[@"dropview-on-border-color", [CPColor colorWithHexString:@"4886ca"]],
[@"dropview-on-border-width", 3.0],
[@"dropview-on-border-radius", 8.0],
[@"dropview-on-selected-background-color", [CPColor clearColor]],
[@"dropview-on-selected-border-color", [CPColor whiteColor]],
[@"dropview-on-selected-border-width", 2.0],
[@"dropview-on-selected-border-radius", 8.0],
[@"dropview-above-border-color", [CPColor colorWithHexString:@"4886ca"]],
[@"dropview-above-border-width", 3.0],
[@"dropview-above-selected-border-color", [CPColor colorWithHexString:@"8BB6F0"]],
[@"dropview-above-selected-border-width", 2.0],
];
[self registerThemeValues:themedTableViewValues forView:tableview];
@@ -2751,7 +2779,7 @@ var themedButtonValues = nil,
return docModalWindowView;
}
+ (_CPBorderlessBridgeWindowView)themedBordelessBridgeWindowView
+ (_CPBorderlessBridgeWindowView)themedBorderlessBridgeWindowView
{
var bordelessBridgeWindowView = [[_CPBorderlessBridgeWindowView alloc] initWithFrame:CGRectMake(0,0,0,0)],
@@ -2969,6 +2997,10 @@ var themedButtonValues = nil,
themeValues =
[
[@"border-radius", 5.0],
[@"stroke-width", 1.0],
[@"shadow-size", CGSizeMake(0, 6)],
[@"shadow-blur", 15.0],
[@"background-gradient", gradient],
[@"background-gradient-hud", gradientHUD],
[@"stroke-color", strokeColor],
Binary file not shown.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 998 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 238 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 250 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 475 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 344 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 423 B

Before

Width:  |  Height:  |  Size: 88 B

After

Width:  |  Height:  |  Size: 88 B

Before

Width:  |  Height:  |  Size: 94 B

After

Width:  |  Height:  |  Size: 94 B

Before

Width:  |  Height:  |  Size: 144 B

After

Width:  |  Height:  |  Size: 144 B

Before

Width:  |  Height:  |  Size: 148 B

After

Width:  |  Height:  |  Size: 148 B

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