Compare commits

..
80 Commits
Author SHA1 Message Date
release 834d878a4d Changed version number to 1.0.0.004 2011-06-24 04:36:38 -05:00
release 4cb5ccbc3a Changed version number to 1.0.0.004-SNAPSHOT 2011-06-24 03:05:58 -05:00
release 929cd78bae Changed version number to 1.0.0.003 2011-06-24 03:05:51 -05:00
hmalphettes f5961b9e06 remove the web-fragment.xml. it is not used and could be harmful. 2011-06-15 14:42:01 +08:00
Pascal Belloncle 7fb17e9f41 added Gemfile 2011-06-14 14:55:18 -03:00
hmalphettes dd70bdc698 use '/' for development. use the BundleShape to be able to be published by the latest version of tycho eventually 2011-06-13 17:14:35 +08:00
release 59d619d190 Changed version number to 1.0.0.003-SNAPSHOT 2011-06-13 03:31:35 -05:00
release dd160d6bed Changed version number to 1.0.0.002 2011-06-13 03:31:30 -05:00
hmalphettes ae5a2c4164 CARBON-183 and remove harful servlet-3.0 web-fragment.xml. Remove the dependency on buildr4osgi 2011-06-13 16:15:15 +08:00
hmalphettes a939bed8e0 CORE-153 pad the buildnumber 2011-06-13 15:51:15 +08:00
release c686a4384b Changed version number to 1.0.0.2-SNAPSHOT 2011-06-11 13:19:43 -05:00
release 6bb2dd2a16 Changed version number to 1.0.0.1 2011-06-11 13:19:38 -05:00
Pascal Belloncle 2ec574173a correct path for patch in archive 2011-06-10 17:17:00 -07:00
Pascal Belloncle 743feb5360 stupid copy paste typo 2011-06-10 16:52:14 -07:00
Pascal Belloncle bc4dc041e5 Merge branch 'master' of github.com:intalio/cappuccino 2011-06-10 16:37:40 -07:00
Pascal Belloncle 8c8d1ae3d3 osgi build 2011-06-10 16:37:30 -07:00
Aparajita Fishman a9781016be Look for frameworks in the app/Frameworks directory before the install directory. Document framework search path and CPAuxiliaryThemes support in the man page. 2011-06-04 22:53:31 -07:00
Aparajita Fishman 4be0bb3a30 Load userland NS classes from the main bundle as well as frameworks, and temporarily change the class of NSSwapper classes to the target class when calling KVC methods. 2011-06-04 18:03:53 -07:00
Aparajita Fishman a74267e937 Merge remote branch 'refs/remotes/280north/master' 2011-06-04 16:20:50 -07:00
Alexander LjungbergandAparajita Fishman 6dea853ef3 Decode but mostly ignore NSImages in nib2cib. Fixed: radio groups in IB come with an NSImage and so would not nib2cib anymore after the recent addition of template image support in NSButton. 2011-06-04 16:19:59 -07:00
Aparajita Fishman 94df530580 Another overhaul of nib2cib.
- Added support for userland NS classes.
- Added support for auxiliary themes.
- NSView should be writing _themeClass, otherwise custom themed classes do not get the correct _themeClass when unarchived.
- Added support for stored options, this is critical. For example, if you are using custom frameworks, you have to ensure they are loaded during automatic nib2cib'ing that occurs when building an app or using xcodecapp. Stored options makes this easy to do.
- Finally did the right thing and made nib2cib into an Objective-J class.
2011-06-04 16:07:00 -07:00
Aparajita Fishman d038c50531 Added ability to specify bundle, which makes this usable with non-main bundle images. 2011-06-04 12:01:19 -07:00
Aparajita Fishman 83546d58db Tweak language of error message to be clearer, currently it sounds like it was searching in the cib file for the class, not the other way around. 2011-06-04 10:59:49 -07:00
Aparajita Fishman 8de587d4fc Only log the connection info if _source and _destination are defined. Runtime attribute connections do not have both. Correctly show boolean value types as BOOL, not CPNumber. 2011-06-04 10:58:38 -07:00
Aparajita Fishman bd9a6ea150 A few more fixes to support multiple themes. 2011-06-04 10:46:29 -07:00
Aparajita Fishman fe69142567 Merge remote branch 'refs/remotes/aparajita/runtime-attributes'
Conflicts:
	Tools/nib2cib/NSNibConnector.j
2011-06-04 10:39:50 -07:00
Aparajita Fishman 5f85f7bef1 Removed unused variable, fixed typo 2011-06-03 18:08:33 -07:00
Aparajita Fishman 397e314cc9 Use Menlo if Consolas is not available 2011-06-01 18:19:49 -07:00
Aparajita Fishman c87d96676c Merge remote branch 'refs/remotes/280north/master' 2011-06-01 12:21:27 -07:00
Aparajita Fishman 13d4e36d39 Lost this change in the merge 2011-05-30 23:39:44 -07:00
Aparajita Fishman a5c06c8f27 Merge remote branch 'refs/remotes/280north/master'
Conflicts:
	AppKit/CPTableView.j
2011-05-30 23:37:16 -07:00
Aparajita Fishman 76bdbb660e clickedRow should be -1 initially, remove leftover setTheme. 2011-05-30 23:31:28 -07:00
Aparajita Fishman a7929e6c1e Enable escape as key equivalent. 2011-05-30 23:18:43 -07:00
Aparajita Fishman b3cbc7e362 Test app and unit test to validate pinned ranges in beginsWith/endsWith predicate comparison. 2011-05-26 14:29:51 -07:00
Aparajita Fishman d6b3efaae8 Pin ranges to valid values. 2011-05-26 13:00:46 -07:00
Aparajita Fishman 33345f65ce Restored space, backspace and escape as key equivalents, but only if the first responder is not a CPTextField. Updated test app to show clearly the effect of this change. 2011-05-23 16:31:15 -07:00
Aparajita Fishman 3fe5ec5d6d Fixed set of keys that can be considered a key equivalent, removed redundant call to performKeyEquivalent, test app 2011-05-22 18:05:08 -07:00
Aparajita Fishman 142b982577 Documentation tweaks 2011-05-22 17:19:06 -07:00
Aparajita Fishman 147c65b962 On WebKit (at least on Mac), right Command key code is 93, not 91. This was not being interpreted correctly. 2011-05-22 17:06:25 -07:00
Aparajita Fishman 89dbccd74e Use CPLog instead of console.log 2011-05-20 08:01:22 -07:00
Aparajita Fishman a4647f2b82 CPColor and CPImage enhancements
- Enhanced -description method of CPImage and CPColor to show the exact content, especially for pattern colors.

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

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

- Sample app included.
2011-05-20 00:23:17 -07:00
Aparajita Fishman 94336ebcbb Merge remote branch 'refs/remotes/280north/master'
Conflicts:
	Tools/Documentation/preprocess/003.make_headers.rb
2011-05-19 23:19:08 -07:00
Aparajita Fishman 5dfa43ce5f Oops, accessor methods weren't being synthesized, removed some cruft 2011-05-19 17:10:26 -07:00
Aparajita Fishman ff7774976e Major fix to documentation generation:
- It turns out doxygen would not generate documentation for the first method in a file (or sometimes any methods at all) if there was no ivar block or an empty ivar block. Now a dummy __doxygen__ ivar is inserted in empty blocks to force correct behavior.

- Added a missing @endverbatim to CPExpression.j.

- Tweaked class documentation for CPPredicate.j.
2011-05-19 16:46:41 -07:00
Aparajita Fishman a435e54a67 Stupid Uber Glory bundle duplicated the file a few times when stripping whitespace. 2011-05-18 17:32:59 -07:00
Aparajita Fishman 852597f11d Fixed formatting of lists and code in class description. The code did not change, I don't know why git says it did. 2011-05-18 16:55:15 -07:00
Aparajita Fishman 806fea9222 Whitespace cleanup 2011-05-18 16:53:51 -07:00
Aparajita Fishman 972bb4100f If there is no header view, there should be no corner view. This is what Cocoa does. Also for correctness -enclosingScrollView should be used to get the table's scrollview. Test app included. 2011-05-18 10:29:54 -07:00
Aparajita Fishman 6a6b83635f More documentation enhancements...
- Changed to centered, fixed-width layout, it results in shorter line lengths which reads more easily.
- Moved support files to separate support directory.
- Removed blank lines at end of multi-parameter method prototypes.
2011-05-18 07:49:52 -07:00
Aparajita Fishman d8f202fc1f Missed a text substitution, darkened up the method header a bit 2011-05-17 21:11:31 -07:00
Aparajita Fishman 2322743252 Documentation tweak 2011-05-17 10:51:09 -07:00
Aparajita Fishman 8b3f9c5557 Merge remote branch 'refs/remotes/280north/master'
Conflicts:
	Tools/Documentation/doxygen.css
	Tools/Documentation/processor_setup.sh
2011-05-17 10:48:22 -07:00
Aparajita Fishman b573daf59b NSColorWell was not setting its enabled state 2011-05-16 11:12:48 -07:00
Aparajita Fishman 4f8fa778d5 Style cleanup 2011-05-14 14:03:51 -04:00
Aparajita Fishman 30d5a7f7a2 Tweak the class list page 2011-05-12 23:15:13 -04:00
Aparajita Fishman b01a4436b6 Lightened up box around method prototype 2011-05-12 16:55:32 -04:00
Aparajita Fishman 9ad8f75a08 Another overhaul of doc generation.
- Added generic facility for pre- and post-processor scripts to be run.
- Added support utility script for inclusion by processors.
- Totally overhauled css to make the pages more readable (I hope).
- Fixed some doc errors in CPTableView.
- Don't generate XML.
- Added colorize() and colorPrint() functions to common.jake.
- Added docs-no-frame task for generating docs without a sidebar frame.
2011-05-12 14:40:19 -04:00
Aparajita Fishman 2bf9afa97a Whitespace cleanup 2011-05-11 23:58:20 -04:00
Aparajita Fishman 9e892d4eea Added CPMenu -removeAll method, removed unused internal _itemIsHighlighted method, test app 2011-05-11 23:56:01 -04:00
Aparajita Fishman d2407d1c2a Don't generate XML for docs, updated ThemeDescriptor capp template 2011-05-11 12:18:21 -04:00
Aparajita Fishman 17dc96ad2f Merge remote branch 'refs/remotes/280north/master' 2011-05-11 08:13:33 -04:00
Aparajita Fishman b3a427ba18 Correct performKeyEquivalent documentation 2011-05-10 19:17:32 -04:00
Aparajita Fishman 4cdefcc2c7 Merge remote branch 'refs/remotes/280north/master' 2011-05-10 11:12:05 -04:00
Aparajita Fishman b7c0dcf050 Added textFrame method to locate the text within the view 2011-05-09 21:14:02 -04:00
Aparajita Fishman fe9573e5b8 Merge branch 'refs/heads/object-union-operators' 2011-05-09 17:12:54 -04:00
Aparajita Fishman 9fcf0258e0 Fix the content inset on CPTextField so there are 2 pixels below and 3 pixels above a text selection. 2011-05-09 17:12:27 -04:00
Aparajita Fishman e22faa0d79 Added distinctUnionOfObjects and unionOfObjects object operators. 2011-05-09 15:31:12 -04:00
Aparajita Fishman 175b204bb6 Improvements to the ThemeDescriptor capp template:
- New/improved jake tasks: debug, release, all, clean, clobber, test, test-release, help.
- help task shows comprehensive, formatted documentation for the available tasks.
- BlendKit is automatically symlinked into the Frameworks directory if necessary as part of the build process, so that the showcase will always work.
- User can easily change the build directory by changing one line.
- Fixed incorrect placeholders in main.j.
2011-05-07 13:10:33 -04:00
Aparajita Fishman b126b2946d Revert "Using objects to encapsulate a bit more"
This reverts commit f0a2a91837.
5c10615c9f fixes the root cause,
thus obviating the reverted commit.
2011-05-06 18:04:36 -04:00
Aparajita Fishman fec200c835 Merge remote branch 'refs/remotes/280north/master' 2011-05-06 17:56:00 -04:00
Aparajita Fishman ea0a47a845 _CPThemeAttribute -setValue should not blow away existing values. 2011-05-06 08:51:17 -04:00
Aparajita Fishman 835d89774a Merge remote branch 'refs/remotes/origin/nib2cib-fix-load-theme' 2011-05-05 15:00:01 -04:00
Aparajita Fishman f0a2a91837 Using objects to encapsulate a bit more 2011-05-05 14:40:19 -04:00
Aparajita Fishman 8614bab724 Merge branch 'master' of git://github.com/280north/cappuccino 2011-05-05 08:07:16 -04:00
Aparajita Fishman 9c181cc9c9 Allow class to be used with +themeForView, fix to image load notification 2011-05-05 08:06:31 -04:00
Aparajita Fishman a0a7b126ab When multiple _CPImageAndTextViews to share a common image, update them all when the image loads. 2011-05-04 10:59:23 -04:00
Aparajita Fishman 78ddc2db70 Automated support for multiple themes and simple theme inheritance 2011-04-29 16:45:00 -04:00
Aparajita Fishman e80cbc89b2 Added debug logging, some more samples in AppController 2011-03-28 19:24:13 -04:00
Aparajita Fishman c0f5ed1f87 Fixed the copyright 2011-03-28 07:50:15 -04:00
Aparajita Fishman 51a8975f0a Implement support for user defined runtime attributes in nib2cib 2011-03-27 22:14:43 -04:00
338 changed files with 4711 additions and 25783 deletions
+1 -1
View File
@@ -9,4 +9,4 @@ WebSite
*.xcodeproj/*.perspectivev3
xcuserdata/
!*.xcodeproj/project.pbxproj
*.xCodeSupport/
target
+2
View File
@@ -0,0 +1,2 @@
rvm_install_on_use_flag=1
rvm jruby-head@buildr
+1 -1
View File
@@ -37,6 +37,7 @@
@import "CPCibControlConnector.j"
@import "CPCibLoading.j"
@import "CPCibOutletConnector.j"
@import "CPCibRuntimeAttributesConnector.j"
@import "CPClipView.j"
@import "CPCollectionView.j"
@import "CPCollectionViewItem.j"
@@ -66,7 +67,6 @@
@import "CPOutlineView.j"
@import "CPPanel.j"
@import "CPPasteboard.j"
@import "CPPopover.j"
@import "CPPopUpButton.j"
@import "CPPredicateEditor.j"
@import "CPPredicateEditorRowTemplate.j"
+4 -4
View File
@@ -117,7 +117,7 @@ CPCriticalAlertStyle = 2;
*/
+ (CPAlert)alertWithMessageText:(CPString)aMessage defaultButton:(CPString)defaultButtonTitle alternateButton:(CPString)alternateButtonTitle otherButton:(CPString)otherButtonTitle informativeTextWithFormat:(CPString)informativeText
{
var alert = [[self alloc] init];
var alert = [[CPAlert alloc] init];
[alert setMessageText:aMessage];
[alert addButtonWithTitle:defaultButtonTitle];
@@ -142,7 +142,7 @@ CPCriticalAlertStyle = 2;
*/
+ (CPAlert)alertWithError:(CPString)anErrorMessage
{
var alert = [[self alloc] init];
var alert = [[CPAlert alloc] init];
[alert setMessageText:anErrorMessage];
[alert setAlertStyle:CPCriticalAlertStyle];
@@ -371,8 +371,8 @@ CPCriticalAlertStyle = 2;
[_informativeLabel setAlignment:[self currentValueForThemeAttribute:@"informative-text-alignment"]];
[_informativeLabel setLineBreakMode:CPLineBreakByWordWrapping];
informativeLabelWidth = CGRectGetWidth([[_window contentView] frame]) - inset.left - inset.right;
informativeLabelOriginY = [_messageLabel frameOrigin].y + [_messageLabel frameSize].height + defaultElementsMargin;
informativeLabelWidth = CGRectGetWidth([[_window contentView] frame]) - inset.left - inset.right,
informativeLabelOriginY = [_messageLabel frameOrigin].y + [_messageLabel frameSize].height + defaultElementsMargin,
informativeLabelTextSize = [[_informativeLabel stringValue] sizeWithFont:[_informativeLabel font] inWidth:informativeLabelWidth];
[_informativeLabel setFrame:CGRectMake(inset.left, informativeLabelOriginY, informativeLabelTextSize.width, informativeLabelTextSize.height + sizeWithFontCorrection)];
-3
View File
@@ -306,9 +306,6 @@ ACTUAL_FRAME_RATE = 0;
if ([_delegate respondsToSelector:@selector(animation:valueForProgress:)])
return [_delegate animation:self valueForProgress:t];
if (_animationCurve == CPAnimationLinear)
return t;
var c1 = [],
c2 = [];
+47 -16
View File
@@ -107,7 +107,7 @@ CPRunContinuesResponse = -1002;
CPPanel _aboutPanel;
CPThemeBlend _themeBlend @accessors(property=themeBlend);
CPArray _themeBlends @accessors(property=themeBlends);
}
/*!
@@ -141,6 +141,8 @@ CPRunContinuesResponse = -1002;
_windows = [];
[_windows addObject:nil];
_themeBlends = [];
}
return self;
@@ -1156,6 +1158,16 @@ CPRunContinuesResponse = -1002;
userInfo:nil];
}
- (CPThemeBlend)themeBlend
{
return (_themeBlends.length > 0 ? _themeBlends[0] : nil);
}
- (void)setThemeBlend:(CPThemeBlend)aThemeBlend
{
_themeBlends[0] = aThemeBlend;
}
+ (CPString)defaultThemeName
{
return ([[CPBundle mainBundle] objectForInfoDictionaryKey:"CPDefaultTheme"] || @"Aristo");
@@ -1218,15 +1230,14 @@ function CPApplicationMain(args, namedArgs)
[_CPAppBootstrapper performActions];
}
var _CPAppBootstrapperActions = nil;
var _CPAppBootstrapperActions = nil,
_CPAppThemeURLsToLoad = [];
@implementation _CPAppBootstrapper : CPObject
{
}
+ (CPArray)actions
{
return [@selector(bootstrapPlatform), @selector(loadDefaultTheme), @selector(loadMainCibFile)];
return [@selector(bootstrapPlatform), @selector(loadThemes), @selector(loadMainCibFile)];
}
+ (void)performActions
@@ -1250,17 +1261,30 @@ var _CPAppBootstrapperActions = nil;
return [CPPlatform bootstrap];
}
+ (BOOL)loadDefaultTheme
+ (BOOL)loadThemes
{
var defaultThemeName = [CPApplication defaultThemeName],
themeURL = nil;
_CPAppThemeURLsToLoad.push([CPApplication defaultThemeName]);
if (defaultThemeName === @"Aristo")
themeURL = [[CPBundle bundleForClass:[CPApplication class]] pathForResource:defaultThemeName + @".blend"];
var auxiliaryThemes = ([[CPBundle mainBundle] objectForInfoDictionaryKey:@"CPAuxiliaryThemes"] || []);
_CPAppThemeURLsToLoad = _CPAppThemeURLsToLoad.concat(auxiliaryThemes);
[self loadNextTheme];
return YES;
}
+ (BOOL)loadNextTheme
{
var themeName = _CPAppThemeURLsToLoad.shift();
if (themeName === @"Aristo")
themeURL = [[CPBundle bundleForClass:[CPApplication class]] pathForResource:themeName + @".blend"];
else
themeURL = [[CPBundle mainBundle] pathForResource:defaultThemeName + @".blend"];
themeURL = [[CPBundle mainBundle] pathForResource:themeName + @".blend"];
var blend = [[CPThemeBlend alloc] initWithContentsOfURL:themeURL];
[blend loadWithDelegate:self];
return YES;
@@ -1268,10 +1292,17 @@ var _CPAppBootstrapperActions = nil;
+ (void)blendDidFinishLoading:(CPThemeBlend)aThemeBlend
{
[[CPApplication sharedApplication] setThemeBlend:aThemeBlend];
[CPTheme setDefaultTheme:[CPTheme themeNamed:[CPApplication defaultThemeName]]];
var themeBlends = [CPApp themeBlends];
[self performActions];
[themeBlends addObject:aThemeBlend];
if ([themeBlends count] === 1)
[CPTheme setDefaultTheme:[CPTheme themeNamed:[CPApplication defaultThemeName]]];
if (_CPAppThemeURLsToLoad.length === 0)
[self performActions];
else
[self loadNextTheme];
}
+ (BOOL)loadMainCibFile
@@ -1340,8 +1371,8 @@ var _CPAppBootstrapperActions = nil;
[editMenu addItem:undoMenuItem];
[editMenu addItem:redoMenuItem];
[editMenu addItem:[[CPMenuItem alloc] initWithTitle:@"Cut" action:@selector(cut:) keyEquivalent:@"x"]];
[editMenu addItem:[[CPMenuItem alloc] initWithTitle:@"Copy" action:@selector(copy:) keyEquivalent:@"c"]];
[editMenu addItem:[[CPMenuItem alloc] initWithTitle:@"Cut" action:@selector(cut:) keyEquivalent:@"x"]],
[editMenu addItem:[[CPMenuItem alloc] initWithTitle:@"Copy" action:@selector(copy:) keyEquivalent:@"c"]],
[editMenu addItem:[[CPMenuItem alloc] initWithTitle:@"Paste" action:@selector(paste:) keyEquivalent:@"v"]];
[editMenuItem setSubmenu:editMenu];
+34 -156
View File
@@ -313,8 +313,6 @@
// Don't use [super setContent:] as that would fire the contentObject change.
// We need to be in control of when notifications fire.
// Note that if we have a contentArray binding, setting the content does /not/
// cause a reverse binding set.
_contentObject = value;
if (_clearsFilterPredicateOnInsertion && _filterPredicate != nil)
@@ -564,9 +562,8 @@
- (BOOL)setSelectionIndexes:(CPIndexSet)indexes
{
[self _selectionWillChange]
var r = [self __setSelectionIndexes:indexes];
[self __setSelectionIndexes:indexes];
[self _selectionDidChange];
return r;
}
/*
@@ -575,7 +572,7 @@
*/
- (BOOL)__setSelectionIndex:(int)theIndex
{
return [self __setSelectionIndexes:[CPIndexSet indexSetWithIndex:theIndex]];
[self __setSelectionIndexes:[CPIndexSet indexSetWithIndex:theIndex]];
}
/*
@@ -584,38 +581,28 @@
*/
- (BOOL)__setSelectionIndexes:(CPIndexSet)indexes
{
var newIndexes = indexes;
if (!indexes)
indexes = [CPIndexSet indexSet];
if (!newIndexes)
newIndexes = [CPIndexSet indexSet];
if (![newIndexes count])
if (![indexes count])
{
if (_avoidsEmptySelection && [[self arrangedObjects] count])
newIndexes = [CPIndexSet indexSetWithIndex:0];
indexes = [CPIndexSet indexSetWithIndex:0];
}
else
{
var objectsCount = [[self arrangedObjects] count];
// Don't trash the input - the caller might depend on it or we might have been
// given _selectionIndexes as the input in which case the equality test below
// would always succeed despite our change below.
newIndexes = [newIndexes copy];
// Remove out of bounds indexes.
[newIndexes removeIndexesInRange:CPMakeRange(objectsCount, [newIndexes lastIndex] + 1)];
[indexes removeIndexesInRange:CPMakeRange(objectsCount, [indexes lastIndex] + 1)];
// When avoiding empty selection and the deleted selection was at the bottom, select the last item.
if (![newIndexes count] && _avoidsEmptySelection && objectsCount)
newIndexes = [CPIndexSet indexSetWithIndex:objectsCount - 1];
if (![indexes count] && _avoidsEmptySelection && objectsCount)
indexes = [CPIndexSet indexSetWithIndex:objectsCount - 1];
}
if ([_selectionIndexes isEqualToIndexSet:newIndexes])
if ([_selectionIndexes isEqualToIndexSet:indexes])
return NO;
// If we haven't already created our own index instance, make sure to copy it here so that
// the copy the user sent in is decoupled from our internal copy.
_selectionIndexes = indexes === newIndexes ? [indexes copy] : newIndexes;
_selectionIndexes = [indexes copy];
// Push back the new selection to the model for selectionIndexes if we have one.
// There won't be an infinite loop because of the equality check above.
@@ -647,11 +634,10 @@
[self willChangeValueForKey:@"selectionIndexes"];
[self _selectionWillChange];
var r = [self __setSelectedObjects:objects];
[self __setSelectedObjects:objects];
[self didChangeValueForKey:@"selectionIndexes"];
[self _selectionDidChange];
return r;
}
/*
@@ -751,10 +737,6 @@
*/
_disableSetContent = YES;
[_contentObject addObject:object];
// Allow handlesContentAsCompoundValue reverse sets to trigger.
[[CPBinder getBinding:@"contentArray" forObject:self] _contentArrayDidChange];
_disableSetContent = NO;
if (willClearPredicate)
@@ -789,8 +771,7 @@
}
/*!
Adds an object at a given index in the receiver's arrangedObjects. Also add the object
to the content collection (although at the end rather than the given index).
Adds an object at a given index to the receiver's collection.
@param id anObject - The object to add to the collection.
@param int anIndex - The index to insert the object at.
@@ -800,12 +781,8 @@
if (![self canAdd])
return;
var willClearPredicate = NO;
if (_clearsFilterPredicateOnInsertion && _filterPredicate)
{
if (_clearsFilterPredicateOnInsertion)
[self willChangeValueForKey:@"filterPredicate"];
willClearPredicate = YES;
}
[self willChangeValueForKey:@"content"];
@@ -813,17 +790,10 @@
See _disableSetContent explanation in addObject:.
*/
_disableSetContent = YES;
// The atArrangedObjectIndex: part of this method's name only refers to where the
// object goes in arrangedObjects, not in the content array. So use addObject:,
// not insertObject:atIndex: here for speed.
[_contentObject addObject:anObject];
// Allow handlesContentAsCompoundValue reverse sets to trigger.
[[CPBinder getBinding:@"contentArray" forObject:self] _contentArrayDidChange];
[_contentObject insertObject:anObject atIndex:anIndex];
_disableSetContent = NO;
if (willClearPredicate)
if (_clearsFilterPredicateOnInsertion)
[self __setFilterPredicate:nil];
[[self arrangedObjects] insertObject:anObject atIndex:anIndex];
@@ -839,7 +809,7 @@
[self __setSelectionIndexes:[CPIndexSet indexSetWithIndex:0]];
[self didChangeValueForKey:@"content"];
if (willClearPredicate)
if (_clearsFilterPredicateOnInsertion)
[self didChangeValueForKey:@"filterPredicate"];
}
@@ -850,28 +820,26 @@
*/
- (void)removeObject:(id)object
{
[self willChangeValueForKey:@"content"];
[self willChangeValueForKey:@"content"];
// See _disableSetContent explanation in addObject:.
_disableSetContent = YES;
/*
See _disableSetContent explanation in addObject:.
*/
_disableSetContent = YES;
[_contentObject removeObject:object];
_disableSetContent = NO;
[_contentObject removeObject:object];
// Allow handlesContentAsCompoundValue reverse sets to trigger.
[[CPBinder getBinding:@"contentArray" forObject:self] _contentArrayDidChange];
_disableSetContent = NO;
if (_filterPredicate === nil || [_filterPredicate evaluateWithObject:object])
{
if (_filterPredicate === nil || [_filterPredicate evaluateWithObject:object])
{
// selectionIndexes change notification will be fired as a result of the
// content change. Don't fire manually.
var pos = [_arrangedObjects indexOfObject:object];
[_arrangedObjects removeObjectAtIndex:pos];
[_selectionIndexes shiftIndexesStartingAtIndex:pos by:-1];
}
}
[self didChangeValueForKey:@"content"];
[self didChangeValueForKey:@"content"];
}
/*!
@@ -907,61 +875,16 @@
*/
- (void)remove:(id)sender
{
[self removeObjectsAtArrangedObjectIndexes:_selectionIndexes];
[self removeObjects:[[self arrangedObjects] objectsAtIndexes:[self selectionIndexes]]];
}
/*!
Removes the objects at the specified indexes in the controller's arranged objects from the content array.
@param CPIndexSet indexes - indexes of the objects to remove.
*/
- (void)removeObjectsAtArrangedObjectIndexes:(CPIndexSet)anIndexSet
- (void)removeObjectsAtArrangedObjectIndexes:(CPIndexSet)indexes
{
[self willChangeValueForKey:@"content"];
/*
See _disableSetContent explanation in addObject:.
*/
_disableSetContent = YES;
var arrangedObjects = [self arrangedObjects],
index = [anIndexSet lastIndex],
position = CPNotFound,
newSelectionIndexes = [_selectionIndexes copy];
while (index !== CPNotFound)
{
var object = [arrangedObjects objectAtIndex:index];
// First try the simple case which should work if there are no sort descriptors.
if ([_contentObject objectAtIndex:index] === object)
[_contentObject removeObjectAtIndex:index];
else
{
// Since we don't have a reverse mapping between the sorted order and the
// unsorted one, we'll just simply have to remove an arbitrary pointer. It might
// be the 'wrong' one - as in not the one the user selected - but the wrong
// one is still just another pointer to the same object, so the user will not
// be able to see any difference.
contentIndex = [_contentObject indexOfObjectIdenticalTo:object];
[_contentObject removeObjectAtIndex:contentIndex];
}
[arrangedObjects removeObjectAtIndex:index];
// Deselect this row if it was selected, and either way shift all selection indexes
// following it up by 1.
[newSelectionIndexes removeIndex:index];
[newSelectionIndexes shiftIndexesStartingAtIndex:index by:-1];
index = [anIndexSet indexLessThanIndex:index];
}
// Allow handlesContentAsCompoundValue reverse sets to trigger.
[[CPBinder getBinding:@"contentArray" forObject:self] _contentArrayDidChange];
_disableSetContent = NO;
// This will automatically handle the avoidsEmptySelection case.
[self __setSelectionIndexes:newSelectionIndexes];
[self didChangeValueForKey:@"content"];
[self _removeObjects:[[self arrangedObjects] objectsAtIndexes:indexes]];
}
/*!
@@ -981,8 +904,6 @@
[contentArray addObject:[objects objectAtIndex:i]];
[self setContent:contentArray];
// Allow handlesContentAsCompoundValue reverse sets to trigger.
[[CPBinder getBinding:@"contentArray" forObject:self] _contentArrayDidChange];
}
/*!
@@ -1001,13 +922,11 @@
{
[self willChangeValueForKey:@"content"];
// See _disableSetContent explanation in addObject:.
/*
See _disableSetContent explanation in addObject:.
*/
_disableSetContent = YES;
[_contentObject removeObjectsInArray:objects];
// Allow handlesContentAsCompoundValue reverse sets to trigger.
[[CPBinder getBinding:@"contentArray" forObject:self] _contentArrayDidChange];
_disableSetContent = NO;
var arrangedObjects = [self arrangedObjects],
@@ -1066,53 +985,12 @@
var destination = [_info objectForKey:CPObservedObjectKey],
keyPath = [_info objectForKey:CPObservedKeyPathKey],
options = [_info objectForKey:CPOptionsKey],
isCompound = [self handlesContentAsCompoundValue];
if (!isCompound)
{
newValue = [destination mutableArrayValueForKeyPath:keyPath];
}
else
{
// handlesContentAsCompoundValue == YES so we cannot just set up a proxy.
// Every read and every write must go through transformValue and
// reverseTransformValue, and the resulting object cannot be described by
// a key path.
newValue = [destination valueForKeyPath:keyPath];
}
newValue = [self transformValue:newValue withOptions:options];
if (isCompound)
{
// Make sure we can edit our copy of the content. TODO In Cocoa, this copy
// appears to be deferred until the array actually needs to be edited.
newValue = [newValue mutableCopy];
}
[_source setValue:newValue forKey:aBinding];
}
- (void)_contentArrayDidChange
{
// When handlesContentAsCompoundValue == YES, it is not sufficient to modify the content object
// in place because what we are holding is an array 'unwrapped' from a compound value by
// a value transformer. So when we modify it we need a reverse set and transform to create
// a new compound value.
//
// (The Cocoa documentation on the subject is not very clear but after substantial
// experimentation this seems both reasonable and compliant.)
if ([self handlesContentAsCompoundValue])
{
var destination = [_info objectForKey:CPObservedObjectKey],
keyPath = [_info objectForKey:CPObservedKeyPathKey];
[self suppressSpecificNotificationFromObject:destination keyPath:keyPath];
[self reverseSetValueFor:@"contentArray"];
[self unsuppressSpecificNotificationFromObject:destination keyPath:keyPath];
}
}
@end
var CPArrayControllerAvoidsEmptySelection = @"CPArrayControllerAvoidsEmptySelection",
-1
View File
@@ -61,7 +61,6 @@ CPGrooveBorder = 3;
var box = [[self alloc] initWithFrame:CGRectMakeZero()],
enclosingView = [aView superview];
[box setAutoresizingMask:[aView autoresizingMask]];
[box setFrameFromContentFrame:[aView frame]];
[enclosingView replaceSubview:aView with:box];
+1 -1
View File
@@ -60,7 +60,7 @@ var cachedBlackColor,
/*!
Orientation to use with \c CPColorPattern for vertical patterns.
*/
CPColorPatternIsVertical = YES;
CPColorPatternIsVertical = YES,
/*!
Orientation to use with \c CPColorPattern for horizontal patterns.
+1 -1
View File
@@ -51,7 +51,7 @@ CPWheelColorPickerMode = 1;
*/
CPSliderColorPickerMode = 2;
CPColorPickerViewWidth = 265;
CPColorPickerViewWidth = 265,
CPColorPickerViewHeight = 370;
/*!
+8 -41
View File
@@ -20,9 +20,6 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#import "../Foundation/Ref.h"
@import "../Foundation/CPFormatter.j"
@import "CPFont.j"
@import "CPShadow.j"
@import "CPView.j"
@@ -85,7 +82,6 @@ var CPControlBlackColor = [CPColor blackColor];
@implementation CPControl : CPView
{
id _value;
CPFormatter _formatter @accessors(property=formatter);
// Target-Action Support
id _target;
@@ -225,11 +221,10 @@ var CPControlBlackColor = [CPColor blackColor];
@param anAction the action to send
@param anObject the object to which the action will be sent
*/
- (BOOL)sendAction:(SEL)anAction to:(id)anObject
- (void)sendAction:(SEL)anAction to:(id)anObject
{
[self _reverseSetBinding];
return [CPApp sendAction:anAction to:anObject from:self];
[CPApp sendAction:anAction to:anObject from:self];
}
- (int)sendActionOn:(int)mask
@@ -507,46 +502,15 @@ var CPControlBlackColor = [CPColor blackColor];
*/
- (CPString)stringValue
{
if (_formatter && _value !== undefined && _value !== nil)
{
var formattedValue = [self hasThemeState:CPThemeStateEditing] ? [_formatter editingStringForObjectValue:_value] : [_formatter stringForObjectValue:_value];
if (formattedValue !== nil && formattedValue !== undefined)
return formattedValue;
}
return (_value === undefined || _value === nil) ? "" : String(_value);
}
/*!
Sets the receiver's string value.
*/
- (void)setStringValue:(CPString)aString
- (void)setStringValue:(CPString)anObject
{
// Cocoa raises an invalid parameter assertion and returns if you pass nil.
if (aString === nil || aString === undefined)
{
CPLog.warn("nil sent to CPControl -setStringValue");
return;
}
var value;
if (_formatter)
{
value = nil;
if ([_formatter getObjectValue:AT_REF(value) forString:aString errorDescription:nil] === NO)
{
// If the given string is non-empty and doesn't work, Cocoa tries an empty string.
if (!aString || [_formatter getObjectValue:AT_REF(value) forString:@"" errorDescription:nil] === NO)
value = undefined; // Means the value is invalid
}
}
else
value = aString;
[self setObjectValue:value];
[self setObjectValue:anObject];
}
- (void)takeDoubleValueFrom:(id)sender
@@ -562,18 +526,21 @@ var CPControlBlackColor = [CPColor blackColor];
[self setFloatValue:[sender floatValue]];
}
- (void)takeIntegerValueFrom:(id)sender
{
if ([sender respondsToSelector:@selector(integerValue)])
[self setIntegerValue:[sender integerValue]];
}
- (void)takeIntValueFrom:(id)sender
{
if ([sender respondsToSelector:@selector(intValue)])
[self setIntValue:[sender intValue]];
}
- (void)takeObjectValueFrom:(id)sender
{
if ([sender respondsToSelector:@selector(objectValue)])
@@ -915,7 +882,7 @@ var __Deprecated__CPImageViewImageKey = @"CPImageViewImageKey";
if (_target !== nil)
[aCoder encodeConditionalObject:_target forKey:CPControlTargetKey];
if (_action !== nil)
if (_action !== NULL)
[aCoder encodeObject:_action forKey:CPControlActionKey];
[aCoder encodeInt:_sendActionOn forKey:CPControlSendActionOnKey];
+9 -6
View File
@@ -571,12 +571,10 @@ var _CPEventPeriodicEventPeriod = 0,
if (_modifierFlags & (CPCommandKeyMask | CPControlKeyMask))
return YES;
// Cocoa allows almost any key as a key equivalent unless the first responder is a
// text field (presumably a subclass of NSText.)
// Cocoa does not consider space, backspace, or escape a key equivalent
// if the first responder is a text field (presumably a subclass of NSText).
var firstResponderIsText = [[_window firstResponder] isKindOfClass:[CPTextField class]];
// Some keys are accepted as key equivalents even if the first responder is a text
// field.
for (var i = 0; i < characterCount; i++)
{
var c = _characters.charAt(i);
@@ -585,13 +583,18 @@ var _CPEventPeriodicEventPeriod = 0,
c === CPEnterCharacter ||
c === CPNewlineCharacter ||
c === CPCarriageReturnCharacter ||
c === CPEscapeFunctionKey)
c === CPEscapeFunctionKey ||
(!firstResponderIsText &&
(c === CPSpaceFunctionKey ||
c === CPDeleteCharacter ||
c === CPBackspaceCharacter)))
{
return YES;
}
}
return !firstResponderIsText;
// FIXME: More cases?
return NO;
}
/*!
+4 -48
View File
@@ -39,8 +39,6 @@ var CPBindingOperationAnd = 0,
{
CPDictionary _info;
id _source;
JSObject _suppressedNotifications;
}
+ (void)exposeBinding:(CPString)aBinding forClass:(Class)aClass
@@ -124,7 +122,6 @@ var CPBindingOperationAnd = 0,
{
_source = aSource;
_info = [CPDictionary dictionaryWithObjects:[aDestination, aKeyPath] forKeys:[CPObservedObjectKey, CPObservedKeyPathKey]];
_suppressedNotifications = {};
if (options)
[_info setObject:options forKey:CPOptionsKey];
@@ -172,10 +169,6 @@ var CPBindingOperationAnd = 0,
if (!changes)
return;
var objectSuppressions = _suppressedNotifications[[anObject UID]];
if (objectSuppressions && objectSuppressions[aKeyPath])
return;
[self setValueFor:context];
}
@@ -233,44 +226,6 @@ var CPBindingOperationAnd = 0,
return [[options objectForKey:CPContinuouslyUpdatesValueBindingOption] boolValue];
}
- (BOOL)handlesContentAsCompoundValue
{
var options = [_info objectForKey:CPOptionsKey];
return [[options objectForKey:CPHandlesContentAsCompoundValueBindingOption] boolValue];
}
/*!
Use this to avoid reacting to the notifications coming out of a reverseTransformedValue:.
*/
- (void)suppressSpecificNotificationFromObject:(id)anObject keyPath:(CPString)aKeyPath
{
if (!anObject)
return;
var uid = [anObject UID],
objectSuppressions = _suppressedNotifications[uid];
if (!objectSuppressions)
_suppressedNotifications[uid] = objectSuppressions = {};
objectSuppressions[aKeyPath] = YES;
}
/*!
Use this to cancel suppressSpecificNotificationFromObject:keyPath:.
*/
- (void)unsuppressSpecificNotificationFromObject:(id)anObject keyPath:(CPString)aKeyPath
{
if (!anObject)
return;
var uid = [anObject UID],
objectSuppressions = _suppressedNotifications[uid];
if (!objectSuppressions)
return;
delete objectSuppressions[aKeyPath];
}
@end
@implementation CPObject (KeyValueBindingCreation)
@@ -280,6 +235,7 @@ var CPBindingOperationAnd = 0,
[CPBinder exposeBinding:aBinding forClass:[self class]];
}
+ (Class)_binderClassForBinding:(CPString)theBinding
{
return [CPBinder class];
@@ -311,10 +267,10 @@ var CPBindingOperationAnd = 0,
- (void)bind:(CPString)aBinding toObject:(id)anObject withKeyPath:(CPString)aKeyPath options:(CPDictionary)options
{
if (!anObject || !aKeyPath)
return CPLog.error("Invalid object or path on " + self + " for " + aBinding);
return CPLog.error("Invalid object or path on "+self+" for "+aBinding);
//if (![[self exposedBindings] containsObject:aBinding])
// CPLog.warn("No binding exposed on " + self + " for " + aBinding);
// CPLog.warn("No binding exposed on "+self+" for "+aBinding);
var binderClass = [[self class] _binderClassForBinding:aBinding];
@@ -518,4 +474,4 @@ CPValueTransformerBindingOption = @"CPValueTransformer";
CPIsControllerMarker = function(/*id*/anObject)
{
return anObject === CPMultipleValuesMarker || anObject === CPNoSelectionMarker || anObject === CPNotApplicableMarker || anObject === CPNullMarker;
}
}
+2 -11
View File
@@ -149,9 +149,9 @@ var _CPLevelIndicatorBezelColor = nil,
var filledColor = _CPLevelIndicatorSegmentNormalColor,
value = [self doubleValue];
if (value <= _criticalValue)
if (value < _criticalValue)
filledColor = _CPLevelIndicatorSegmentCriticalColor;
else if (value <= _warningValue)
else if (value < _warningValue)
filledColor = _CPLevelIndicatorSegmentWarningColor;
for (var i = 0; i < segmentCount; i++)
@@ -223,15 +223,6 @@ var _CPLevelIndicatorBezelColor = nil,
return _isEditable;
}
- (CPView)hitTest:(CPPoint)aPoint
{
// Don't swallow clicks when displayed in a table.
if (![self isEditable])
return nil;
return [super hitTest:aPoint];
}
- (void)mouseDown:(CPEvent)anEvent
{
if (![self isEditable] || ![self isEnabled])
+13 -35
View File
@@ -352,12 +352,8 @@ var _CPMenuBarVisible = NO,
while (count--)
[_items[count] setMenu:nil];
_highlightedIndex = CPNotFound;
// Because we are changing _items directly, be sure to notify KVO
[self willChangeValueForKey:@"items"];
_items = [CPMutableArray array];
[self didChangeValueForKey:@"items"];
_highlightedIndex = CPNotFound;
}
/*!
@@ -626,11 +622,11 @@ var _CPMenuBarVisible = NO,
var validator = [CPApp targetForAction:[item action] to:[item target] from:item];
if (!validator || ![validator respondsToSelector:[item action]])
[item setEnabled:NO];
[item _setEnabled:NO];
else if ([validator respondsToSelector:@selector(validateMenuItem:)])
[item setEnabled:[validator validateMenuItem:item]];
[item _setEnabled:[validator validateMenuItem:item]];
else if ([validator respondsToSelector:@selector(validateUserInterfaceItem:)])
[item setEnabled:[validator validateUserInterfaceItem:item]];
[item _setEnabled:[validator validateUserInterfaceItem:item]];
}
[[_menuWindow _menuView] tile];
@@ -715,7 +711,10 @@ var _CPMenuBarVisible = NO,
if (aView && !theWindow)
throw "In call to popUpMenuPositioningItem:atLocation:inView:callback:, view is not in any window.";
[self _menuWillOpen];
var delegate = [self delegate];
if ([delegate respondsToSelector:@selector(menuWillOpen:)])
[delegate menuWillOpen:self];
// Convert location to global coordinates if not already in them.
if (aView)
@@ -803,7 +802,10 @@ var _CPMenuBarVisible = NO,
+ (void)popUpContextMenu:(CPMenu)aMenu withEvent:(CPEvent)anEvent forView:(CPView)aView withFont:(CPFont)aFont
{
[aMenu _menuWillOpen];
var delegate = [aMenu delegate];
if ([delegate respondsToSelector:@selector(menuWillOpen:)])
[delegate menuWillOpen:aMenu];
if (!aFont)
aFont = [CPFont systemFontOfSize:12.0];
@@ -873,15 +875,7 @@ var _CPMenuBarVisible = NO,
*/
- (CPMenuItem)highlightedItem
{
if (_highlightedIndex < 0)
return nil;
var highlightedItem = _items[_highlightedIndex];
if ([highlightedItem isSeparatorItem])
return nil;
return highlightedItem;
return _highlightedIndex >= 0 ? _items[_highlightedIndex] : nil;
}
// Managing the Delegate
@@ -896,22 +890,6 @@ var _CPMenuBarVisible = NO,
return _delegate;
}
- (void)_menuWillOpen
{
var delegate = [self delegate];
if ([delegate respondsToSelector:@selector(menuWillOpen:)])
[delegate menuWillOpen:self];
}
- (void)_menuDidClose
{
var delegate = [self delegate];
if ([delegate respondsToSelector:@selector(menuDidClose:)])
[delegate menuDidClose:self];
}
// Handling Tracking
/*!
Cancels tracking.
+10 -28
View File
@@ -1,8 +1,8 @@
@import <Foundation/CPObject.j>
_CPMenuManagerScrollingStateUp = -1;
_CPMenuManagerScrollingStateDown = 1;
_CPMenuManagerScrollingStateUp = -1,
_CPMenuManagerScrollingStateDown = 1,
_CPMenuManagerScrollingStateNone = 0;
var STICKY_TIME_INTERVAL = 500,
@@ -11,7 +11,6 @@ var STICKY_TIME_INTERVAL = 500,
@implementation _CPMenuManager: CPObject
{
CPTimeInterval _startTime;
BOOL _hasMouseGoneUpAfterStartedTracking;
int _scrollingState;
CGPoint _lastGlobalLocation;
@@ -61,9 +60,6 @@ var STICKY_TIME_INTERVAL = 500,
{
var menu = [aMenuContainer menu];
if ([menu numberOfItems] <= 0)
return;
CPApp._activeMenu = menu;
_startTime = [anEvent timestamp];//new Date();
@@ -91,8 +87,6 @@ var STICKY_TIME_INTERVAL = 500,
return [self trackMenuBarButtonEvent:anEvent];
}
_hasMouseGoneUpAfterStartedTracking = NO;
[self trackEvent:anEvent];
}
@@ -105,7 +99,7 @@ var STICKY_TIME_INTERVAL = 500,
if (type === CPAppKitDefined)
return [self completeTracking];
[CPApp setTarget:self selector:@selector(trackEvent:) forNextEventMatchingMask:CPKeyDownMask | CPPeriodicMask | CPMouseMovedMask | CPLeftMouseDraggedMask | CPLeftMouseUpMask | CPRightMouseUpMask | CPAppKitDefinedMask | CPScrollWheelMask untilDate:nil inMode:nil dequeue:YES];
[CPApp setTarget:self selector:@selector(trackEvent:) forNextEventMatchingMask:CPKeyDownMask | CPPeriodicMask | CPMouseMovedMask | CPLeftMouseDraggedMask | CPLeftMouseUpMask | CPAppKitDefinedMask | CPScrollWheelMask untilDate:nil inMode:nil dequeue:YES];
if (type === CPKeyDown)
{
@@ -227,20 +221,8 @@ var STICKY_TIME_INTERVAL = 500,
[CPEvent startPeriodicEventsAfterDelay:0.0 withPeriod:0.04];
}
}
else if (type === CPLeftMouseUp || type === CPRightMouseUp)
{
if (_hasMouseGoneUpAfterStartedTracking)
{
// Don't close the menu if the current item has a submenu
// and did not override it's default action
if ([activeItem action] === @selector(submenuAction:))
return;
[trackingMenu cancelTracking];
}
else
_hasMouseGoneUpAfterStartedTracking = YES;
}
else if (type === CPLeftMouseUp && ([anEvent timestamp] - _startTime > (STICKY_TIME_INTERVAL + [activeMenu numberOfItems] * 5)))
[trackingMenu cancelTracking];
}
// Prevent previous selected menu items from opening by stopping the timer if a
@@ -324,7 +306,11 @@ var STICKY_TIME_INTERVAL = 500,
// Hide all submenus.
[self showMenu:nil fromMenu:trackingMenu atPoint:nil];
[trackingMenu _menuDidClose];
var delegate = [trackingMenu delegate];
if ([delegate respondsToSelector:@selector(menuDidClose:)])
[delegate menuDidClose:trackingMenu];
if (_trackingCallback)
_trackingCallback([self trackingMenuContainer], trackingMenu);
@@ -393,8 +379,6 @@ var STICKY_TIME_INTERVAL = 500,
var count = _menuContainerStack.length,
index = count;
[newMenu _menuWillOpen];
// Hide all menus up to the base menu...
while (index--)
{
@@ -414,8 +398,6 @@ var STICKY_TIME_INTERVAL = 500,
[_CPMenuWindow poolMenuWindow:menuContainer];
[_menuContainerStack removeObjectAtIndex:index];
[menu _menuDidClose];
}
if (!newMenu)
+8 -1
View File
@@ -148,6 +148,14 @@ var CPMenuItemStringRepresentationDictionary = [CPDictionary dictionary];
@param isEnabled \c YES enables the item. \c NO disables it.
*/
- (void)setEnabled:(BOOL)isEnabled
{
if ([_menu autoenablesItems])
return;
[self _setEnabled:isEnabled];
}
- (void)_setEnabled:(BOOL)isEnabled
{
if (_isEnabled === isEnabled)
return;
@@ -488,7 +496,6 @@ CPOffState
if (_submenu)
{
[_submenu setSupermenu:_menu];
[_submenu setTitle:[self title]]
[self setTarget:_menu];
[self setAction:@selector(submenuAction:)];
+2 -13
View File
@@ -131,8 +131,8 @@
_contentObject = aContent;
[self _selectionDidChange];
[self didChangeValueForKey:@"contentObject"];
[self _selectionDidChange];
}
/*!
@@ -498,7 +498,7 @@ var CPObjectControllerContentKey = @"CPObjectControllerCo
- (CPString)description
{
return "<_CPObservableArray: " + [super description] + " >";
return "<_CPObservableArray: "+[super description]+" >";
}
- (id)initWithArray:(CPArray)anArray
@@ -710,17 +710,6 @@ var CPObjectControllerContentKey = @"CPObjectControllerCo
{
[[_controller selectedObjects] setValue:theValue forKeyPath:theKeyPath];
[_cachedValues removeObjectForKey:theKeyPath];
// Allow handlesContentAsCompoundValue to work, based on observation of Cocoa's
// NSArrayController - when handlesContentAsCompoundValue and setValue:forKey:@"selection.X"
// is called, the array controller causes the compound value to be rewritten if
// handlesContentAsCompoundValue == YES. Note that
// A) this doesn't use observation (observe: X is not visible in backtraces)
// B) it only happens through the selection proxy and not on arrangedObject.X, content.X
// or even selectedObjects.X.
// FIXME The main code for this should somehow be in CPArrayController and also work
// for table based row edits.
[[CPBinder getBinding:@"contentArray" forObject:_controller] _contentArrayDidChange];
}
- (void)setValue:(id)theValue forKey:(CPString)theKeyPath
-38
View File
@@ -1458,44 +1458,6 @@ var CPOutlineViewCoalesceSelectionNotificationStateOff = 0,
userInfo:[CPDictionary dictionaryWithObject:item forKey:"CPObject"]];
}
- (void)keyDown:(CPEvent)anEvent
{
var character = [anEvent charactersIgnoringModifiers],
modifierFlags = [anEvent modifierFlags];
// Check for the key events manually, as opposed to waiting for CPWindow to sent the actual action message
// in _processKeyboardUIKey:, because we might not want to handle the arrow events.
if (character !== CPRightArrowFunctionKey && character !== CPLeftArrowFunctionKey)
return [super keyDown:anEvent];
var rows = [self selectedRowIndexes],
indexes = [],
items = [];
[rows getIndexes:indexes maxCount:-1 inIndexRange:nil];
var i = 0,
c = [indexes count];
for (; i < c; i++)
items.push([self itemAtRow:indexes[i]]);
if (character === CPRightArrowFunctionKey)
{
for (var i = 0; i < c; i++)
[self expandItem:items[i]];
}
else if (character === CPLeftArrowFunctionKey)
{
for (var i = 0; i < c; i++)
[self collapseItem:items[i]];
}
[super keyDown:anEvent];
}
@end
// FIX ME: We're using with() here because Safari fails if we use anOutlineView._itemInfosForItems or whatever...
+1 -2
View File
@@ -86,7 +86,7 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
[self setPullsDown:shouldPullDown];
var options = CPKeyValueObservingOptionNew | CPKeyValueObservingOptionOld; // | CPKeyValueObservingOptionInitial;
var options = CPKeyValueObservingOptionNew |CPKeyValueObservingOptionOld;/* |CPKeyValueObservingOptionInitial;*/
[self addObserver:self forKeyPath:@"menu.items" options:options context:nil];
[self addObserver:self forKeyPath:@"_firstItem.changeCount" options:options context:nil];
[self addObserver:self forKeyPath:@"selectedItem.changeCount" options:options context:nil];
@@ -193,7 +193,6 @@ CPPopUpButtonStatePullsDown = CPThemeState("pulls-down");
- (void)removeAllItems
{
[[self menu] removeAllItems];
[self synchronizeTitleAndSelectedItem];
}
/*!
-325
View File
@@ -1,325 +0,0 @@
/*
* CPPopover.j
* AppKit
*
* Created by Antoine Mercadal.
* Copyright 2011 Antoine Mercadal.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import <Foundation/CPObject.j>
@import "CPButton.j"
@import "CPColor.j"
@import "CPImage.j"
@import "CPImageView.j"
@import "CPResponder.j"
@import "CPView.j"
@import "_CPAttachedWindow.j"
CPPopoverBehaviorApplicationDefined = 0;
CPPopoverBehaviorTransient = 1;
CPPopoverBehaviorSemitransient = 2;
var CPPopoverDelegate_popover_willShow_ = 1 << 0,
CPPopoverDelegate_popover_didShow_ = 1 << 1,
CPPopoverDelegate_popover_shouldClose_ = 1 << 2,
CPPopoverDelegate_popover_willClose_ = 1 << 3,
CPPopoverDelegate_popover_didClose_ = 1 << 4;
/*! @ingroup appkit
@class CPPopover
This class represent a widget that displays a attached
view relative to another one.
Delegate can implement:
popoverShouldClose:(CPPopover)aPopOver
popoverWillShow:(CPPopover)aPopOver
popoverDidShow:(CPPopover)aPopOver
popoverWillClose:(CPPopover)aPopOver
popoverDidClose:(CPPopover)aPopOver
*/
@implementation CPPopover : CPResponder
{
@outlet CPViewController _contentViewController @accessors(property=contentViewController);
@outlet id _delegate @accessors(getter=delegate);
BOOL _animates @accessors(property=animates);
BOOL _shown @accessors(getter=shown);
int _appearance @accessors(property=appearance);
int _behavior @accessors(getter=behavior);
BOOL _needsCompute;
_CPAttachedWindow _attachedWindow;
int _implementedDelegateMethods;
}
#pragma mark -
#pragma mark Initialization
/*!
Initialize the CPPopover witn default values
@returns anInitialized CPPopover
*/
- (CPPopover)init
{
if (self = [super init])
{
_animates = YES;
_appearance = CPPopoverAppearanceMinimal;
_behavior = CPPopoverBehaviorApplicationDefined;
_needsCompute = YES;
_shown = NO;
}
return self;
}
#pragma mark -
#pragma mark Getters / Setters
/*!
Returns the current rect of the popover
@return CPRect represeting the frame of the popover
*/
- (CPRect)positioningRect
{
if (!_attachedWindow || ![_attachedWindow isVisible])
return nil;
return [_attachedWindow frame];
}
/*! Sets the frame of the popover
@param aRect the desired frame
*/
- (void)setPositioningRect:(CPRect)aRect
{
if (!_attachedWindow || ![_attachedWindow isVisible])
return;
[_attachedWindow setFrame:aRect];
}
/*!
Returns the size of the popover's view
@return CPSize represeting the size of the popover's view
*/
- (CPRect)contentSize
{
if (!_attachedWindow || ![_attachedWindow isVisible])
return nil;
return [[_contentViewController view] frameSize];
}
/*!
Sets the size of of the popover's view
@param aSize the desired size
*/
- (void)setContentSize:(CPSize)aSize
{
[[_contentViewController view] setFrameSize:aSize];
}
/*!
Indicates if CPPopover is visible
@returns YES if visible
*/
- (BOOL)shown
{
if (!_attachedWindow)
return NO;
return [_attachedWindow isVisible];
}
/*!
Set the behaviour of the CPPopover. It can be
- CPPopoverBehaviorTransient: the popover will be close if another control outside the popover become the responder
- CPPopoverBehaviorApplicationDefined: (DEFAULT) the application is responsible for closing the popover
@param aBehaviour the desired behaviour
*/
- (void)setBehaviour:(int)aBehaviour
{
if (_behavior == aBehaviour)
return;
_behavior = aBehaviour;
_needsCompute = YES;
}
- (void)setDelegate:(id)aDelegate
{
if (_delegate === aDelegate)
return;
_delegate = aDelegate;
_implementedDelegateMethods = 0;
if ([_delegate respondsToSelector:@selector(popoverWillShow:)])
_implementedDelegateMethods |= CPPopoverDelegate_popover_willShow_;
if ([_delegate respondsToSelector:@selector(popoverDidShow:)])
_implementedDelegateMethods |= CPPopoverDelegate_popover_didShow_;
if ([_delegate respondsToSelector:@selector(popoverShouldClose:)])
_implementedDelegateMethods |= CPPopoverDelegate_popover_shouldClose_;
if ([_delegate respondsToSelector:@selector(popoverWillClose:)])
_implementedDelegateMethods |= CPPopoverDelegate_popover_willClose_;
if ([_delegate respondsToSelector:@selector(popoverDidClose:)])
_implementedDelegateMethods |= CPPopoverDelegate_popover_didClose_;
}
#pragma mark -
#pragma mark Positioning
/*!
Show the popover
@param positioningRect if set, the popover will be positionned to a random rect relative to the window
@param positioningView if set, the popover will be positioned relative to this view
@param preferredEdge: CPRectEdge representing the preferred positioning.
*/
- (void)showRelativeToRect:(CPRect)positioningRect ofView:(CPView)positioningView preferredEdge:(CPRectEdge)preferredEdge
{
if (_implementedDelegateMethods & CPPopoverDelegate_popover_willShow_)
[_delegate popoverWillShow:self];
if (!_contentViewController)
[CPException raise:CPInternalInconsistencyException reason:@"contentViewController must not be nil"];
if (_needsCompute || !_attachedWindow)
{
var styleMask = (_behavior == CPPopoverBehaviorTransient) ? CPClosableOnBlurWindowMask : nil;
_attachedWindow = [[_CPAttachedWindow alloc] initWithContentRect:CPRectMakeZero() styleMask:styleMask];
}
[_attachedWindow setAppearance:_appearance];
[_attachedWindow setAnimates:_animates];
[_attachedWindow setDelegate:self];
[_attachedWindow setMovableByWindowBackground:NO];
[_attachedWindow setFrame:[_attachedWindow frameRectForContentRect:[[_contentViewController view] frame]]];
[_attachedWindow setContentView:[_contentViewController view]];
if (positioningRect)
[_attachedWindow positionRelativeToRect:positioningRect preferredEdge:preferredEdge];
else if (positioningView)
[_attachedWindow positionRelativeToView:positioningView preferredEdge:preferredEdge];
else
[CPException raise:CPInvalidArgumentException reason:@"a value must be passed for positioningRect or positioningView"];
if (_implementedDelegateMethods & CPPopoverDelegate_popover_didShow_)
[_delegate popoverDidShow:self];
}
/*!
Closes the popover
*/
- (void)close
{
if (_implementedDelegateMethods & CPPopoverDelegate_popover_shouldClose_)
if (![_delegate popoverShouldClose:self])
return;
if (_implementedDelegateMethods & CPPopoverDelegate_popover_willClose_)
[_delegate popoverWillClose:self];
[_attachedWindow close];
if (_implementedDelegateMethods & CPPopoverDelegate_popover_didClose_)
[_delegate popoverDidClose:self];
}
#pragma mark -
#pragma mark Action
/*!
Close the popover
@param aSender the sender of the action
*/
- (IBAction)performClose:(id)aSender
{
[self close];
}
#pragma mark -
#pragma mark Delegates
/*! @ignore */
- (BOOL)attachedWindowShouldClose:(_CPAttachedWindow)anAttachedWindow
{
[self close];
// we return NO, because we want the CPPopover to compute
// if the attached can be close in order to send delegate messages
return NO;
}
@end
var CPPopoverNeedsComputeKey = @"CPPopoverNeedsComputeKey",
CPPopoverAppearanceKey = @"CPPopoverAppearanceKey",
CPPopoverAnimatesKey = @"CPPopoverAnimatesKey",
CPPopoverContentViewControllerKey = @"CPPopoverContentViewControllerKey",
CPPopoverDelegateKey = @"CPPopoverDelegateKey",
CPPopoverBehaviorKey = @"CPPopoverBehaviorKey";
@implementation CPPopover (CPCoding)
- (id)initWithCoder:(CPCoder)aCoder
{
self = [super initWithCoder:aCoder];
if (self)
{
_needsCompute = [aCoder decodeIntForKey:CPPopoverNeedsComputeKey];
_appearance = [aCoder decodeIntForKey:CPPopoverAppearanceKey];
_animates = [aCoder decodeBoolForKey:CPPopoverAnimatesKey];
_contentViewController = [aCoder decodeObjectForKey:CPPopoverContentViewControllerKey];
[self setDelegate:[aCoder decodeObjectForKey:CPPopoverDelegateKey]];
[self setBehaviour:[aCoder decodeIntForKey:CPPopoverBehaviorKey]];
}
return self;
}
- (void)encodeWithCoder:(CPCoder)aCoder
{
[super encodeWithCoder:aCoder];
[aCoder encodeBool:_needsCompute forKey:CPPopoverNeedsComputeKey];
[aCoder encodeInt:_appearance forKey:CPPopoverAppearanceKey];
[aCoder encodeObject:_animates forKey:CPPopoverAnimatesKey];
[aCoder encodeObject:_contentViewController forKey:CPPopoverContentViewControllerKey];
[aCoder encodeObject:_delegate forKey:CPPopoverDelegateKey];
[aCoder encodeInt:_behavior forKey:CPPopoverBehaviorKey];
}
@end
+2 -8
View File
@@ -150,14 +150,6 @@ CPRadioImageOffset = 4.0;
[_radioGroup _setSelectedRadio:self];
}
- (void)sendAction:(SEL)anAction to:(id)anObject
{
[super sendAction:anAction to:anObject];
if (_radioGroup)
[CPApp sendAction:[_radioGroup action] to:[_radioGroup target] from:_radioGroup];
}
@end
var CPRadioRadioGroupKey = @"CPRadioRadioGroupKey";
@@ -228,6 +220,8 @@ var CPRadioRadioGroupKey = @"CPRadioRadioGroupKey";
[_selectedRadio setState:CPOffState];
_selectedRadio = aRadio;
[CPApp sendAction:_action to:_target from:self];
}
- (CPRadio)selectedRadio
+2 -2
View File
@@ -200,7 +200,7 @@
if (isPopup)
{
itemArray = [[templateView itemArray] valueForKey:@"title"];
itemsCount = [itemArray count];
itemsCount = [itemArray count],
menuIndex = 0;
}
@@ -501,4 +501,4 @@ var CPPredicateTemplatesKey = @"CPPredicateTemplates";
@end
/*! @endcond */
/*! @endcond */
@@ -20,17 +20,17 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
CPUndefinedAttributeType = 0;
CPInteger16AttributeType = 100;
CPInteger32AttributeType = 200;
CPInteger64AttributeType = 300;
CPDecimalAttributeType = 400;
CPDoubleAttributeType = 500;
CPFloatAttributeType = 600;
CPStringAttributeType = 700;
CPBooleanAttributeType = 800;
CPDateAttributeType = 900;
CPBinaryDataAttributeType = 1000;
CPUndefinedAttributeType = 0,
CPInteger16AttributeType = 100,
CPInteger32AttributeType = 200,
CPInteger64AttributeType = 300,
CPDecimalAttributeType = 400,
CPDoubleAttributeType = 500,
CPFloatAttributeType = 600,
CPStringAttributeType = 700,
CPBooleanAttributeType = 800,
CPDateAttributeType = 900,
CPBinaryDataAttributeType = 1000,
CPTransformableAttributeType = 1800;
@implementation CPPredicateEditorRowTemplate : CPObject
@@ -785,4 +785,4 @@ var CPPredicateTemplateTypeKey = @"CPPredicateTemplateType",
}
@end
/*! @endcond */
/*! @endcond */
@@ -16,12 +16,12 @@ var GRADIENT_NORMAL,
{
if (CPBrowserIsEngine(CPWebKitBrowserEngine))
{
GRADIENT_NORMAL = "-webkit-gradient(linear, left top, left bottom, from(rgb(252, 252, 252)), to(rgb(223, 223, 223)))";
GRADIENT_NORMAL = "-webkit-gradient(linear, left top, left bottom, from(rgb(252, 252, 252)), to(rgb(223, 223, 223)))",
GRADIENT_HIGHLIGHTED = "-webkit-gradient(linear, left top, left bottom, from(rgb(223, 223, 223)), to(rgb(252, 252, 252)))";
}
else if (CPBrowserIsEngine(CPGeckoBrowserEngine))
{
GRADIENT_NORMAL = "-moz-linear-gradient(top, rgb(252, 252, 252), rgb(223, 223, 223))";
GRADIENT_NORMAL = "-moz-linear-gradient(top, rgb(252, 252, 252), rgb(223, 223, 223))",
GRADIENT_HIGHLIGHTED = "-moz-linear-gradient(top, rgb(223, 223, 223), rgb(252, 252, 252))";
}
}
@@ -35,7 +35,7 @@ var GRADIENT_NORMAL,
style.border = "1px solid rgb(189, 189, 189)";
style.filter = IE_FILTER;
[self setTextColor:[CPColor colorWithWhite:101 / 255 alpha:1]];
[self setTextColor:[CPColor colorWithWhite:101/255 alpha:1]];
[self setBordered:NO];
}
+536 -938
View File
File diff suppressed because it is too large Load Diff
+66 -261
View File
@@ -5,9 +5,6 @@
* Created by Francisco Tolmasky.
* Copyright 2008, 280 North, Inc.
*
* Modified to match Lion style by Antoine Mercadal 2011
* <antoine.mercadal@archipelproject.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
@@ -25,6 +22,7 @@
@import "CPControl.j"
// CPScroller Constants
CPScrollerNoPart = 0;
CPScrollerDecrementPage = 1;
@@ -56,17 +54,6 @@ NAMES_FOR_PARTS[CPScrollerKnobSlot] = @"knob-slot";
NAMES_FOR_PARTS[CPScrollerKnob] = @"knob";
CPScrollerStyleLegacy = 0;
CPScrollerStyleOverlay = 1;
CPScrollerKnobStyleDefault = 0;
CPScrollerKnobStyleDark = 1;
CPScrollerKnobStyleLight = 2;
CPThemeStateScrollViewLegacy = CPThemeState("scroller-style-legacy");
CPThemeStateScrollerKnobLight = CPThemeState("scroller-knob-light");
CPThemeStateScrollerKnobDark = CPThemeState("scroller-knob-dark");
@implementation CPScroller : CPControl
{
CPControlSize _controlSize;
@@ -81,19 +68,8 @@ CPThemeStateScrollerKnobDark = CPThemeState("scroller-knob-dark");
CPScrollerPart _trackingPart;
float _trackingFloatValue;
CGPoint _trackingStartPoint;
CPViewAnimation _animationScroller;
BOOL _allowFadingOut @accessors(getter=allowFadingOut);
int _style;
CPTimer _timerFadeOut;
BOOL _isMouseOver;
}
#pragma mark -
#pragma mark Class methods
+ (CPString)defaultThemeClass
{
return "scroller";
@@ -102,43 +78,49 @@ CPThemeStateScrollerKnobDark = CPThemeState("scroller-knob-dark");
+ (id)themeAttributes
{
return [CPDictionary dictionaryWithJSObject:{
@"scroller-width": 7.0,
@"knob-slot-color": [CPNull null],
@"scroller-width": 15.0,
@"knob-slot-color": [CPColor lightGrayColor],
@"decrement-line-color": [CPNull null],
@"increment-line-color": [CPNull null],
@"knob-color": [CPNull null],
@"knob-color": [CPColor grayColor],
@"decrement-line-size":_CGSizeMakeZero(),
@"increment-line-size":_CGSizeMakeZero(),
@"track-inset":_CGInsetMakeZero(),
@"knob-inset": _CGInsetMakeZero(),
@"minimum-knob-length":21.0,
@"track-border-overlay": 9.0
}];
@"minimum-knob-length":21.0
}]
}
+ (float)scrollerWidth
// Calculating Layout
- (id)initWithFrame:(CGRect)aFrame
{
return [self scrollerWidthInStyle:CPScrollerStyleLegacy];
self = [super initWithFrame:aFrame];
if (self)
{
_controlSize = CPRegularControlSize;
_partRects = [];
[self setFloatValue:0.0];
[self setKnobProportion:1.0];
_hitPart = CPScrollerNoPart;
[self _calculateIsVertical];
}
return self;
}
// Determining CPScroller Size
/*!
Returns the CPScroller's width for a CPRegularControlSize.
*/
+ (float)scrollerWidthInStyle:(int)aStyle
+ (float)scrollerWidth
{
var scroller = [[self alloc] init];
if (aStyle == CPScrollerStyleLegacy)
return [scroller valueForThemeAttribute:@"scroller-width" inState:CPThemeStateScrollViewLegacy];
return [scroller currentValueForThemeAttribute:@"scroller-width"];
}
/*!
Returns the CPScroller's overlay value.
*/
+ (float)scrollerOverlay
{
return [[[self alloc] init] currentValueForThemeAttribute:@"track-border-overlay"];
return [[[CPScroller alloc] init] currentValueForThemeAttribute:@"scroller-width"];
}
/*!
@@ -150,87 +132,6 @@ CPThemeStateScrollerKnobDark = CPThemeState("scroller-knob-dark");
return [self scrollerWidth];
}
#pragma mark -
#pragma mark Initialization
- (id)initWithFrame:(CGRect)aFrame
{
if (self = [super initWithFrame:aFrame])
{
_controlSize = CPRegularControlSize;
_partRects = [];
[self setFloatValue:0.0];
[self setKnobProportion:1.0];
_hitPart = CPScrollerNoPart;
_allowFadingOut = YES;
_isMouseOver = NO;
_style = CPScrollerStyleOverlay;
var paramAnimFadeOut = [CPDictionary dictionaryWithObjects:[self, CPViewAnimationFadeOutEffect]
forKeys:[CPViewAnimationTargetKey, CPViewAnimationEffectKey]];
_animationScroller = [[CPViewAnimation alloc] initWithDuration:0.2 animationCurve:CPAnimationEaseInOut];
[_animationScroller setViewAnimations:[paramAnimFadeOut]];
[_animationScroller setDelegate:self];
[self setAlphaValue:0.0];
[self _calculateIsVertical];
}
return self;
}
#pragma mark -
#pragma mark Getters / Setters
/*!
Returns the scroller's style
*/
- (void)style
{
return _style;
}
/*!
Set the scroller's control size
@param aStyle the scroller style: CPScrollerStyleLegacy or CPScrollerStyleOverlay
*/
- (void)setStyle:(id)aStyle
{
if (_style != nil && _style === aStyle)
return;
_style = aStyle;
if (_style === CPScrollerStyleLegacy)
{
[self fadeIn];
[self setThemeState:CPThemeStateScrollViewLegacy];
}
else
{
_allowFadingOut = YES;
[self unsetThemeState:CPThemeStateScrollViewLegacy];
}
[self _adjustScrollerSize];
}
- (void)setObjectValue:(id)aValue
{
[super setObjectValue:MIN(1.0, MAX(0.0, +aValue))];
}
/*!
Returns the scroller's control size
*/
- (CPControlSize)controlSize
{
return _controlSize;
}
/*!
Sets the scroller's size.
@param aControlSize the scroller's size
@@ -247,17 +148,18 @@ CPThemeStateScrollerKnobDark = CPThemeState("scroller-knob-dark");
}
/*!
Return's the knob's proportion
Returns the scroller's control size
*/
- (float)knobProportion
- (CPControlSize)controlSize
{
return _knobProportion;
return _controlSize;
}
- (void)setObjectValue:(id)aValue
{
[super setObjectValue:MIN(1.0, MAX(0.0, +aValue))];
}
/*!
Set the knob's proportion
@param aProportion the desired proportion
*/
- (void)setKnobProportion:(float)aProportion
{
_knobProportion = MIN(1.0, MAX(0.0001, aProportion));
@@ -266,35 +168,25 @@ CPThemeStateScrollerKnobDark = CPThemeState("scroller-knob-dark");
[self setNeedsLayout];
}
#pragma mark -
#pragma mark Privates
/*! @ignore */
- (void)_adjustScrollerSize
/*!
Return's the knob's proportion
*/
- (float)knobProportion
{
var frame = [self frame],
scrollerWidth = [self currentValueForThemeAttribute:@"scroller-width"];
if ([self isVertical] && CGRectGetWidth(frame) !== scrollerWidth)
frame.size.width = scrollerWidth;
if (![self isVertical] && CGRectGetHeight(frame) !== scrollerWidth)
frame.size.height = scrollerWidth;
[self setFrame:frame];
return _knobProportion;
}
/*! @ignore */
- (void)_performFadeOut:(CPTimer)aTimer
- (id)currentValueForThemeAttribute:(CPString)anAttributeName
{
[self fadeOut];
_timerFadeOut = nil;
var themeState = _themeState;
if (NAMES_FOR_PARTS[_hitPart] + "-color" !== anAttributeName)
themeState &= ~CPThemeStateHighlighted;
return [self valueForThemeAttribute:anAttributeName inState:themeState];
}
#pragma mark -
#pragma mark Utilities
// Calculating Layout
- (CGRect)rectForPart:(CPScrollerPart)aPart
{
@@ -316,9 +208,6 @@ CPThemeStateScrollerKnobDark = CPThemeState("scroller-knob-dark");
// The ordering of these tests is important. We check the knob and
// page rects first since they may overlap with the arrows.
if (![self hasThemeState:CPThemeStateSelected])
return CPScrollerNoPart;
if (CGRectContainsPoint([self rectForPart:CPScrollerKnob], aPoint))
return CPScrollerKnob;
@@ -441,35 +330,7 @@ CPThemeStateScrollerKnobDark = CPThemeState("scroller-knob-dark");
return _usableParts;
}
/*!
Display the scroller
*/
- (void)fadeIn
{
if (_isMouseOver && _knobProportion != 1.0)
[self setThemeState:CPThemeStateSelected];
if (_timerFadeOut)
[_timerFadeOut invalidate];
[self setAlphaValue:1.0];
}
/*!
Start the fade out anination
*/
- (void)fadeOut
{
if ([self hasThemeState:CPThemeStateScrollViewLegacy])
return;
[_animationScroller startAnimation];
}
#pragma mark -
#pragma mark Drawing
// Drawing the Parts
/*!
Draws the specified arrow and sets the highlight.
@param anArrow the arrow to draw
@@ -597,8 +458,7 @@ CPThemeStateScrollerKnobDark = CPThemeState("scroller-knob-dark");
[CPApp setTarget:self selector:@selector(trackKnob:) forNextEventMatchingMask:CPLeftMouseDraggedMask | CPLeftMouseUpMask untilDate:nil inMode:nil dequeue:YES];
if (type === CPLeftMouseDragged)
[self sendAction:[self action] to:[self target]];
[self sendAction:[self action] to:[self target]];
}
/*!
@@ -704,20 +564,6 @@ CPThemeStateScrollerKnobDark = CPThemeState("scroller-knob-dark");
[self setNeedsLayout];
}
#pragma mark -
#pragma mark Overrides
- (id)currentValueForThemeAttribute:(CPString)anAttributeName
{
var themeState = _themeState;
if (NAMES_FOR_PARTS[_hitPart] + "-color" !== anAttributeName)
themeState &= ~CPThemeStateHighlighted;
return [self valueForThemeAttribute:anAttributeName inState:themeState];
}
- (void)mouseDown:(CPEvent)anEvent
{
if (![self isEnabled])
@@ -736,52 +582,10 @@ CPThemeStateScrollerKnobDark = CPThemeState("scroller-knob-dark");
}
}
- (void)mouseEntered:(CPEvent)anEvent
{
[super mouseEntered:anEvent];
if (_timerFadeOut)
[_timerFadeOut invalidate];
if (![self isEnabled])
return;
_allowFadingOut = NO;
_isMouseOver = YES;
if ([self alphaValue] > 0 && _knobProportion != 1.0)
[self setThemeState:CPThemeStateSelected];
}
- (void)mouseExited:(CPEvent)anEvent
{
[super mouseExited:anEvent];
if ([self isHidden] || ![self isEnabled] || !_isMouseOver)
return;
_allowFadingOut = YES;
_isMouseOver = NO;
if (_timerFadeOut)
[_timerFadeOut invalidate];
_timerFadeOut = [CPTimer scheduledTimerWithTimeInterval:1.2 target:self selector:@selector(_performFadeOut:) userInfo:nil repeats:NO];
}
#pragma mark -
#pragma mark Delegates
- (void)animationDidEnd:(CPAnimation)animation
{
[self unsetThemeState:CPThemeStateSelected];
}
@end
var CPScrollerControlSizeKey = @"CPScrollerControlSize",
CPScrollerKnobProportionKey = @"CPScrollerKnobProportion",
CPScrollerStyleKey = @"CPScrollerStyleKey";
var CPScrollerControlSizeKey = "CPScrollerControlSize",
CPScrollerKnobProportionKey = "CPScrollerKnobProportion";
@implementation CPScroller (CPCoding)
@@ -801,18 +605,20 @@ var CPScrollerControlSizeKey = @"CPScrollerControlSize",
_hitPart = CPScrollerNoPart;
_allowFadingOut = YES;
_isMouseOver = NO;
var paramAnimFadeOut = [CPDictionary dictionaryWithObjects:[self, CPViewAnimationFadeOutEffect]
forKeys:[CPViewAnimationTargetKey, CPViewAnimationEffectKey]];
_animationScroller = [[CPViewAnimation alloc] initWithDuration:0.2 animationCurve:CPAnimationEaseInOut];
[_animationScroller setViewAnimations:[paramAnimFadeOut]];
[_animationScroller setDelegate:self];
[self setAlphaValue:0.0];
[self _calculateIsVertical];
[self setStyle:[aCoder decodeIntForKey:CPScrollerStyleKey]];
// Adjust the size of the scroller if the size from cib
// isn't equal to the scrollerWidth
var frame = [self frame],
scrollerWidth = [CPScroller scrollerWidth];
if ([self isVertical] && CGRectGetWidth(frame) !== scrollerWidth)
frame.size.width = scrollerWidth;
if (![self isVertical] && CGRectGetHeight(frame) !== scrollerWidth)
frame.size.height = scrollerWidth;
[self setFrame:frame];
}
return self;
@@ -824,7 +630,6 @@ var CPScrollerControlSizeKey = @"CPScrollerControlSize",
[aCoder encodeInt:_controlSize forKey:CPScrollerControlSizeKey];
[aCoder encodeFloat:_knobProportion forKey:CPScrollerKnobProportionKey];
[aCoder encodeInt:_style forKey:CPScrollerStyleKey];
}
@end
-14
View File
@@ -45,7 +45,6 @@ CPSoundPlayBackStatePause = 2;
CPString _name @accessors(property=name);
id _delegate @accessors(property=delegate);
BOOL _playRequestBeforeLoad;
HTMLAudioElement _audioTag;
int _loadStatus;
int _playBackStatus;
@@ -62,7 +61,6 @@ CPSoundPlayBackStatePause = 2;
_loops = NO;
_audioTag = document.createElement("audio");
_audioTag.preload = YES;
_playRequestBeforeLoad = NO;
_audioTag.addEventListener("canplay", function()
{
@@ -140,12 +138,6 @@ CPSoundPlayBackStatePause = 2;
- (void)_soundDidload
{
_loadStatus = CPSoundLoadStateCanBePlayed;
if (_playRequestBeforeLoad)
{
_playRequestBeforeLoad = NO;
[self play];
}
}
/*! @ignore
@@ -175,12 +167,6 @@ CPSoundPlayBackStatePause = 2;
*/
- (BOOL)play
{
if (_loadStatus === CPSoundLoadStateLoading)
{
_playRequestBeforeLoad = YES;
return YES;
}
if ((_loadStatus !== CPSoundLoadStateCanBePlayed)
|| (_playBackStatus === CPSoundPlayBackStatePlay))
return NO;
+33 -256
View File
@@ -20,43 +20,16 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "../Foundation/Foundation.h"
@import "CPButtonBar.j"
@import "CPImage.j"
@import "CPView.j"
#define SPLIT_VIEW_MAYBE_POST_WILL_RESIZE() \
if ((_suppressResizeNotificationsMask & DidPostWillResizeNotification) === 0) \
{ \
[self _postNotificationWillResize]; \
_suppressResizeNotificationsMask |= DidPostWillResizeNotification; \
}
#define SPLIT_VIEW_MAYBE_POST_DID_RESIZE() \
if ((_suppressResizeNotificationsMask & ShouldSuppressResizeNotifications) !== 0) \
_suppressResizeNotificationsMask |= DidSuppressResizeNotification; \
else \
[self _postNotificationDidResize];
#define SPLIT_VIEW_DID_SUPPRESS_RESIZE_NOTIFICATION() \
((_suppressResizeNotificationsMask & DidSuppressResizeNotification) !== 0)
#define SPLIT_VIEW_SUPPRESS_RESIZE_NOTIFICATIONS(shouldSuppress) \
if (shouldSuppress) \
_suppressResizeNotificationsMask |= ShouldSuppressResizeNotifications; \
else \
_suppressResizeNotificationsMask = 0;
CPSplitViewDidResizeSubviewsNotification = @"CPSplitViewDidResizeSubviewsNotification";
CPSplitViewWillResizeSubviewsNotification = @"CPSplitViewWillResizeSubviewsNotification";
var CPSplitViewHorizontalImage = nil,
CPSplitViewVerticalImage = nil,
ShouldSuppressResizeNotifications = 1,
DidPostWillResizeNotification = 1 << 1,
DidSuppressResizeNotification = 1 << 2;
CPSplitViewVerticalImage = nil;
/*!
@ingroup appkit
@@ -72,29 +45,24 @@ var CPSplitViewHorizontalImage = nil,
@implementation CPSplitView : CPView
{
id _delegate;
BOOL _isVertical;
BOOL _isPaneSplitter;
id _delegate;
BOOL _isVertical;
BOOL _isPaneSplitter;
int _currentDivider;
float _initialOffset;
CPDictionary _preCollapsePositions;
int _currentDivider;
float _initialOffset;
float _preCollapsePosition;
CPString _originComponent;
CPString _sizeComponent;
CPString _originComponent;
CPString _sizeComponent;
CPArray _DOMDividerElements;
CPString _dividerImagePath;
int _drawingDivider;
CPArray _DOMDividerElements;
CPString _dividerImagePath;
int _drawingDivider;
CPString _autosaveName;
BOOL _shouldAutosave;
BOOL _needsRestoreFromAutosave;
BOOL _needsResizeSubviews;
BOOL _needsResizeSubviews;
int _suppressResizeNotificationsMask;
CPArray _buttonBars;
CPArray _buttonBars;
}
+ (CPString)defaultThemeClass
@@ -125,15 +93,11 @@ var CPSplitViewHorizontalImage = nil,
{
if (self = [super initWithFrame:aFrame])
{
_suppressResizeNotificationsMask = 0;
_preCollapsePositions = [CPMutableDictionary new];
_currentDivider = CPNotFound;
_DOMDividerElements = [];
_buttonBars = [];
_shouldAutosave = YES;
[self _setVertical:YES];
}
@@ -448,6 +412,7 @@ var CPSplitViewHorizontalImage = nil,
{
_currentDivider = CPNotFound;
[self _updateResizeCursor:anEvent];
[self _postNotificationDidResize];
}
return;
@@ -471,8 +436,7 @@ var CPSplitViewHorizontalImage = nil,
[_delegate respondsToSelector:@selector(splitView:shouldCollapseSubview:forDoubleClickOnDividerAtIndex:)])
{
var minPosition = [self minPossiblePositionOfDividerAtIndex:i],
maxPosition = [self maxPossiblePositionOfDividerAtIndex:i],
_preCollapsePosition = [_preCollapsePositions objectForKey:"" + i] || 0;
maxPosition = [self maxPossiblePositionOfDividerAtIndex:i];
if ([_delegate splitView:self canCollapseSubview:_subviews[i]] && [_delegate splitView:self shouldCollapseSubview:_subviews[i] forDoubleClickOnDividerAtIndex:i])
{
@@ -562,34 +526,20 @@ var CPSplitViewHorizontalImage = nil,
// If we are currently tracking, keep the resize cursor active even outside of hit areas.
if (_currentDivider === i || (_currentDivider == CPNotFound && [self cursorAtPoint:point hitDividerAtIndex:i]))
{
var frameA = [_subviews[i] frame],
sizeA = frameA.size[_sizeComponent],
startPosition = frameA.origin[_originComponent] + sizeA,
frameB = [_subviews[i + 1] frame],
sizeB = frameB.size[_sizeComponent],
var frame = [_subviews[i] frame],
size = frame.size[_sizeComponent],
startPosition = frame.origin[_originComponent] + size,
canShrink = [self _realPositionForPosition:startPosition - 1 ofDividerAtIndex:i] < startPosition,
canGrow = [self _realPositionForPosition:startPosition + 1 ofDividerAtIndex:i] > startPosition,
cursor = [CPCursor arrowCursor];
if (sizeA === 0)
if (size === 0)
canGrow = YES; // Subview is collapsed.
else if (!canShrink &&
[_delegate respondsToSelector:@selector(splitView:canCollapseSubview:)] &&
[_delegate splitView:self canCollapseSubview:_subviews[i]])
canShrink = YES; // Subview is collapsible.
if (sizeB === 0)
{
// Right/lower subview is collapsed.
canGrow = NO;
// It's safe to assume it can always be uncollapsed.
canShrink = YES;
}
else if (!canGrow &&
[_delegate respondsToSelector:@selector(splitView:canCollapseSubview:)] &&
[_delegate splitView:self canCollapseSubview:_subviews[i + 1]])
canGrow = YES; // Right/lower subview is collapsible.
if (_isVertical && canShrink && canGrow)
cursor = [CPCursor resizeLeftRightCursor];
else if (_isVertical && canShrink)
@@ -647,15 +597,7 @@ var CPSplitViewHorizontalImage = nil,
{
// not sure where this should override other positions?
if ([_delegate respondsToSelector:@selector(splitView:constrainSplitPosition:ofSubviewAt:)])
{
var proposedPosition = [_delegate splitView:self constrainSplitPosition:position ofSubviewAt:dividerIndex];
// Silently ignore bad positions which could result from odd delegate responses. We don't want these
// bad results to go into the system and cause havoc with frame sizes as the split view tries to resize
// its subviews.
if (_IS_NUMERIC(proposedPosition))
position = proposedPosition;
}
position = [_delegate splitView:self constrainSplitPosition:position ofSubviewAt:dividerIndex];
var proposedMax = [self maxPossiblePositionOfDividerAtIndex:dividerIndex],
proposedMin = [self minPossiblePositionOfDividerAtIndex:dividerIndex],
@@ -663,33 +605,18 @@ var CPSplitViewHorizontalImage = nil,
actualMin = proposedMin;
if ([_delegate respondsToSelector:@selector(splitView:constrainMinCoordinate:ofSubviewAt:)])
{
var proposedActualMin = [_delegate splitView:self constrainMinCoordinate:proposedMin ofSubviewAt:dividerIndex];
if (_IS_NUMERIC(proposedActualMin))
actualMin = proposedActualMin;
}
actualMin = [_delegate splitView:self constrainMinCoordinate:proposedMin ofSubviewAt:dividerIndex];
if ([_delegate respondsToSelector:@selector(splitView:constrainMaxCoordinate:ofSubviewAt:)])
{
var proposedActualMax = [_delegate splitView:self constrainMaxCoordinate:proposedMax ofSubviewAt:dividerIndex];
if (_IS_NUMERIC(proposedActualMax))
actualMax = proposedActualMax;
}
actualMax = [_delegate splitView:self constrainMaxCoordinate:proposedMax ofSubviewAt:dividerIndex];
var viewA = _subviews[dividerIndex],
viewB = _subviews[dividerIndex + 1],
realPosition = MAX(MIN(position, actualMax), actualMin);
// Is this position past the halfway point to collapse?
if (position < proposedMin + (actualMin - proposedMin) / 2)
if (position < proposedMin + (actualMin - proposedMin) / 2)
if ([_delegate respondsToSelector:@selector(splitView:canCollapseSubview:)])
if ([_delegate splitView:self canCollapseSubview:viewA])
realPosition = proposedMin;
// We can also collapse to the right.
if (position > proposedMax - (proposedMax - actualMax) / 2)
if ([_delegate respondsToSelector:@selector(splitView:canCollapseSubview:)])
if ([_delegate splitView:self canCollapseSubview:viewB])
realPosition = proposedMax;
return realPosition;
}
@@ -701,7 +628,6 @@ var CPSplitViewHorizontalImage = nil,
*/
- (void)setPosition:(float)position ofDividerAtIndex:(int)dividerIndex
{
SPLIT_VIEW_SUPPRESS_RESIZE_NOTIFICATIONS(YES);
[self _adjustSubviewsWithCalculatedSize];
var realPosition = [self _realPositionForPosition:position ofDividerAtIndex:dividerIndex];
@@ -709,59 +635,32 @@ var CPSplitViewHorizontalImage = nil,
var viewA = _subviews[dividerIndex],
frameA = [viewA frame],
viewB = _subviews[dividerIndex + 1],
frameB = [viewB frame],
_preCollapsePosition = 0;
frameB = [viewB frame];
_preCollapsePosition = 0;
var preSize = frameA.size[_sizeComponent];
frameA.size[_sizeComponent] = realPosition - frameA.origin[_originComponent];
if (preSize !== 0 && frameA.size[_sizeComponent] === 0)
_preCollapsePosition = preSize;
if (preSize !== frameA.size[_sizeComponent])
{
SPLIT_VIEW_MAYBE_POST_WILL_RESIZE();
[_subviews[dividerIndex] setFrame:frameA];
SPLIT_VIEW_MAYBE_POST_DID_RESIZE();
}
[_subviews[dividerIndex] setFrame:frameA];
preSize = frameB.size[_sizeComponent];
var preOrigin = frameB.origin[_originComponent];
frameB.size[_sizeComponent] = frameB.origin[_originComponent] + frameB.size[_sizeComponent] - realPosition - [self dividerThickness];
if (preSize !== 0 && frameB.size[_sizeComponent] === 0)
_preCollapsePosition = frameB.origin[_originComponent];
_preCollapsePosition = preSize;
frameB.origin[_originComponent] = realPosition + [self dividerThickness];
if (preSize !== frameB.size[_sizeComponent] || preOrigin !== frameB.origin[_originComponent])
{
SPLIT_VIEW_MAYBE_POST_WILL_RESIZE();
[_subviews[dividerIndex + 1] setFrame:frameB];
SPLIT_VIEW_MAYBE_POST_DID_RESIZE();
}
if (_preCollapsePosition)
[_preCollapsePositions setObject:_preCollapsePosition forKey:"" + dividerIndex];
[_subviews[dividerIndex + 1] setFrame:frameB];
[self setNeedsDisplay:YES];
if (SPLIT_VIEW_DID_SUPPRESS_RESIZE_NOTIFICATION())
[self _postNotificationDidResize];
SPLIT_VIEW_SUPPRESS_RESIZE_NOTIFICATIONS(NO);
}
- (void)setFrameSize:(CGSize)aSize
{
if (_needsRestoreFromAutosave)
_shouldAutosave = NO;
else
[self _adjustSubviewsWithCalculatedSize];
[self _adjustSubviewsWithCalculatedSize];
[super setFrameSize:aSize];
if (_needsRestoreFromAutosave)
{
_needsRestoreFromAutosave = NO;
[self _restoreFromAutosave];
_shouldAutosave = YES;
}
[self setNeedsDisplay:YES];
}
@@ -773,7 +672,6 @@ var CPSplitViewHorizontalImage = nil,
return;
}
SPLIT_VIEW_MAYBE_POST_WILL_RESIZE();
[self _postNotificationWillResize];
var index = 0,
@@ -832,10 +730,9 @@ var CPSplitViewHorizontalImage = nil,
bounds.origin[_originComponent] += viewFrame.size[_sizeComponent] + dividerThickness;
[view setFrame:viewFrame];
}
SPLIT_VIEW_MAYBE_POST_DID_RESIZE();
[self _postNotificationDidResize];
}
/*!
@@ -934,7 +831,6 @@ The sum of the views and the sum of the dividers should be equal to the size of
@param CPButtonBar - The supplied button bar.
@param unsigned int - The divider index the button bar will be assigned to.
*/
// FIXME Should be renamed to setButtonBar:ofDividerAtIndex:.
- (void)setButtonBar:(CPButtonBar)aButtonBar forDividerAtIndex:(unsigned)dividerIndex
{
if (!aButtonBar)
@@ -971,121 +867,15 @@ The sum of the views and the sum of the dividers should be equal to the size of
- (void)_postNotificationDidResize
{
[self _autosave];
[[CPNotificationCenter defaultCenter] postNotificationName:CPSplitViewDidResizeSubviewsNotification object:self];
}
/*!
Set the name under which the split view divider positions is automatically saved to CPUserDefaults.
@param autosaveName the name to save under or nil to not save
*/
- (void)setAutosaveName:(CPString)autosaveName
{
if (_autosaveName == autosaveName)
return;
_autosaveName = autosaveName;
}
/*!
Get the name under which the split view divider position is automatically saved to CPUserDefaults.
@return the name to save under or nil if no auto save is active
*/
- (CPString)autosaveName
{
return _autosaveName;
}
/*!
@ignore
*/
- (void)_autosave
{
if (!_shouldAutosave)
return;
var userDefaults = [CPUserDefaults standardUserDefaults],
autosaveName = [self _framesKeyForAutosaveName:[self autosaveName]],
autosavePrecollapseName = [self _precollapseKeyForAutosaveName:[self autosaveName]],
count = [_subviews count],
positions = [CPMutableArray new],
preCollapseArray = [CPMutableArray new];
for (var i = 0; i < count; i++)
{
var frame = [_subviews[i] frame];
[positions addObject:CPStringFromRect(frame)];
[preCollapseArray addObject:[_preCollapsePositions objectForKey:"" + i]];
}
[userDefaults setObject:positions forKey:autosaveName];
[userDefaults setObject:preCollapseArray forKey:autosavePrecollapseName];
}
/*!
@ignore
*/
- (void)_restoreFromAutosave
{
if (!_autosaveName)
return;
var autosaveName = [self _framesKeyForAutosaveName:[self autosaveName]],
autosavePrecollapseName = [self _precollapseKeyForAutosaveName:[self autosaveName]],
userDefaults = [CPUserDefaults standardUserDefaults],
frames = [userDefaults objectForKey:autosaveName],
preCollapseArray = [userDefaults objectForKey:autosavePrecollapseName];
if (frames)
{
var dividerThickness = [self dividerThickness],
position = 0;
_shouldAutosave = NO;
for (var i = 0, count = [frames count] - 1; i < count; i++)
{
var frame = CPRectFromString(frames[i]);
position += frame.size[_sizeComponent];
[self setPosition:position ofDividerAtIndex:i];
position += dividerThickness;
}
_shouldAutosave = YES;
}
if (preCollapseArray)
{
_preCollapsePositions = [CPMutableDictionary new];
for (var i = 0, count = [preCollapseArray count]; i < count; i++)
[_preCollapsePositions setObject:preCollapseArray[i] forKey:i + ""];
}
}
/*!
@ignore
*/
- (CPString)_framesKeyForAutosaveName:(CPString)theAutosaveName
{
return @"CPSplitView Subview Frames " + theAutosaveName;
}
/*!
@ignore
*/
- (CPString)_precollapseKeyForAutosaveName:(CPString)theAutosaveName
{
return @"CPSplitView Subview Precollapse Positions " + theAutosaveName;
}
@end
var CPSplitViewDelegateKey = "CPSplitViewDelegateKey",
CPSplitViewIsVerticalKey = "CPSplitViewIsVerticalKey",
CPSplitViewIsPaneSplitterKey = "CPSplitViewIsPaneSplitterKey",
CPSplitViewButtonBarsKey = "CPSplitViewButtonBarsKey",
CPSplitViewAutosaveNameKey = "CPSplitViewAutosaveNameKey";
CPSplitViewButtonBarsKey = "CPSplitViewButtonBarsKey";
@implementation CPSplitView (CPCoding)
@@ -1099,11 +889,7 @@ var CPSplitViewDelegateKey = "CPSplitViewDelegateKey",
if (self)
{
_suppressResizeNotificationsMask = 0;
_preCollapsePositions = [CPMutableDictionary new];
_currentDivider = CPNotFound;
_shouldAutosave = YES;
_DOMDividerElements = [];
@@ -1113,13 +899,6 @@ var CPSplitViewDelegateKey = "CPSplitViewDelegateKey",
_isPaneSplitter = [aCoder decodeBoolForKey:CPSplitViewIsPaneSplitterKey];
[self _setVertical:[aCoder decodeBoolForKey:CPSplitViewIsVerticalKey]];
[self setAutosaveName:[aCoder decodeObjectForKey:CPSplitViewAutosaveNameKey]];
// We have to wait until we know our frame size before restoring, or the frame resize later will throw
// away the restored size.
if (_autosaveName)
_needsRestoreFromAutosave = YES;
}
return self;
@@ -1140,8 +919,6 @@ var CPSplitViewDelegateKey = "CPSplitViewDelegateKey",
[aCoder encodeBool:_isVertical forKey:CPSplitViewIsVerticalKey];
[aCoder encodeBool:_isPaneSplitter forKey:CPSplitViewIsPaneSplitterKey];
[aCoder encodeObject:_autosaveName forKey:CPSplitViewAutosaveNameKey];
}
@end
+25 -44
View File
@@ -25,11 +25,11 @@
@import <AppKit/CPTextField.j>
var CPStepperButtonsSize = CPSizeMake(19, 13);
/*!
CPStepper is an implementation of Cocoa NSStepper.
/*! CPStepper is an implementation of Cocoa NSStepper.
This control displays a two part button that can be used to increase or decrease a value with a given interval.
This control display a two part button that can be used to increase or decrease a value with a given interval.
*/
@implementation CPStepper: CPControl
{
@@ -45,8 +45,7 @@
#pragma mark -
#pragma mark Initialization
/*!
Initializes a CPStepper with given values.
/*! Initializes a CPStepper with given values
@param aValue the initial value of the CPStepper
@param minValue the minimal acceptable value of the stepper
@param maxValue the maximal acceptable value of the stepper
@@ -54,7 +53,7 @@
*/
+ (CPStepper)stepperWithInitialValue:(float)aValue minValue:(float)aMinValue maxValue:(float)aMaxValue
{
var stepper = [[CPStepper alloc] initWithFrame:_CGRectMake(0, 0, 19, 25)];
var stepper = [[CPStepper alloc] initWithFrame:CPRectMake(0, 0, 19, 25)];
[stepper setDoubleValue:aValue];
[stepper setMinValue:aMinValue];
[stepper setMaxValue:aMaxValue];
@@ -62,12 +61,10 @@
return stepper;
}
/*!
Initializes a CPStepper with default values:
/*! Initializes a CPStepper with default values:
- minValue = 0.0
- maxValue = 59.0
- value = 0.0
@return Initialized CPStepper
*/
+ (CPStepper)stepper
@@ -75,8 +72,7 @@
return [CPStepper stepperWithInitialValue:0.0 minValue:0.0 maxValue:59.0];
}
/*!
Initializes a CPStepper.
/*! Initializes the CPStepper
@param aFrame the frame of the control
@return initialized CPStepper
*/
@@ -91,14 +87,14 @@
[self setDoubleValue:0.0];
_buttonUp = [[CPButton alloc] initWithFrame:_CGRectMakeZero()];
_buttonUp = [[CPButton alloc] initWithFrame:CPRectMake(aFrame.size.width - CPStepperButtonsSize.width, 0, CPStepperButtonsSize.width, CPStepperButtonsSize.height)];
[_buttonUp setContinuous:YES];
[_buttonUp setTarget:self];
[_buttonUp setAction:@selector(_buttonDidClick:)];
[_buttonUp setAutoresizingMask:CPViewNotSizable];
[self addSubview:_buttonUp];
_buttonDown = [[CPButton alloc] initWithFrame:_CGRectMakeZero()];
_buttonDown = [[CPButton alloc] initWithFrame:CPRectMake(aFrame.size.width - CPStepperButtonsSize.width, CPStepperButtonsSize.height, CPStepperButtonsSize.width, CPStepperButtonsSize.height - 1)];
[_buttonDown setContinuous:YES];
[_buttonDown setTarget:self];
[_buttonDown setAction:@selector(_buttonDidClick:)];
@@ -114,8 +110,7 @@
#pragma mark -
#pragma mark Superclass overrides
/*!
Set if the CPStepper is enabled or not.
/*! set if the CPStepper is enabled or not
@param shouldEnabled BOOL that define if stepper is enabled or not.
*/
- (void)setEnabled:(BOOL)shouldEnabled
@@ -126,30 +121,19 @@
[_buttonDown setEnabled:shouldEnabled];
}
/*! set the frame of the CPStepper and check if width is not smaller than theme min-size
@param aFrame the frame
*/
- (void)setFrame:(CGRect)aFrame
{
var upSize = [self valueForThemeAttribute:@"up-button-size"],
downSize = [self valueForThemeAttribute:@"down-button-size"],
minSize = _CGSizeMake(upSize.width, upSize.height + downSize.height),
frame = _CGRectMakeCopy(aFrame);
frame.size.width = Math.max(minSize.width, frame.size.width);
frame.size.height = Math.max(minSize.height, frame.size.height);
[super setFrame:frame];
if (aFrame.size.width >= CGRectGetWidth(aFrame))
[super setFrame:aFrame];
}
/*! @ignore */
/*! @ignore
*/
- (void)layoutSubviews
{
var aFrame = [self frame],
upSize = [self valueForThemeAttribute:@"up-button-size"],
downSize = [self valueForThemeAttribute:@"down-button-size"],
upFrame = _CGRectMake(aFrame.size.width - upSize.width, 0, upSize.width, upSize.height),
downFrame = _CGRectMake(aFrame.size.width - downSize.width, upSize.height, downSize.width, downSize.height);
[_buttonUp setFrame:upFrame];
[_buttonDown setFrame:downFrame];
[_buttonUp setValue:[self valueForThemeAttribute:@"bezel-color-up-button" inState:CPThemeStateBordered] forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered];
[_buttonUp setValue:[self valueForThemeAttribute:@"bezel-color-up-button" inState:CPThemeStateBordered | CPThemeStateDisabled] forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered | CPThemeStateDisabled];
[_buttonUp setValue:[self valueForThemeAttribute:@"bezel-color-up-button" inState:CPThemeStateBordered | CPThemeStateHighlighted] forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered | CPThemeStateHighlighted];
@@ -158,8 +142,7 @@
[_buttonDown setValue:[self valueForThemeAttribute:@"bezel-color-down-button" inState:CPThemeStateBordered | CPThemeStateHighlighted] forThemeAttribute:@"bezel-color" inState:CPThemeStateBordered | CPThemeStateHighlighted];
}
/*!
Set if CPStepper should autorepeat.
/*! set if CPStepper should autorepeat
@param shouldAutoRepeat if YES, the first mouse down does one increment (decrement) and, after each delay of 0.5 seconds
*/
- (void)setAutorepeat:(BOOL)shouldAutoRepeat
@@ -168,8 +151,7 @@
[_buttonDown setContinuous:shouldAutoRepeat];
}
/*!
Set the current value of the stepper.
/*! set the current value of the stepper
@param aValue a float containing the value
*/
- (void)setDoubleValue:(float)aValue
@@ -185,7 +167,8 @@
#pragma mark -
#pragma mark Actions
/*! @ignore */
/*! @ignore
*/
- (IBAction)_buttonDidClick:(id)aSender
{
if (![self isEnabled])
@@ -200,8 +183,7 @@
[self sendAction:_action to:_target];
}
/*!
Perform a programatic click on up button.
/*! @perform a programatic click on up button
@param aSender sender of the action
*/
- (IBAction)performClickUp:(id)aSender
@@ -209,8 +191,7 @@
[_buttonUp performClick:aSender];
}
/*!
Perform a programatic click on down button.
/*! @perform a programatic click on down button
@param aSender sender of the action
*/
- (IBAction)performClickDown:(id)aSender
@@ -229,8 +210,8 @@
+ (id)themeAttributes
{
return [CPDictionary dictionaryWithObjects:[[CPNull null], [CPNull null], _CGSizeMakeZero(), _CGSizeMakeZero()]
forKeys:[@"bezel-color-up-button", @"bezel-color-down-button", @"up-button-size", @"down-button-size"]];
return [CPDictionary dictionaryWithObjects:[[CPNull null], [CPNull null]]
forKeys:[@"bezel-color-up-button", @"bezel-color-down-button"]];
}
@end
+12 -27
View File
@@ -132,7 +132,7 @@ CPTableColumnUserResizingMask = 1 << 1;
{
var min = [self minWidth],
max = [self maxWidth],
newWidth = ROUND(MIN(MAX(width, min), max));
newWidth = MIN(MAX(width, min), max);
[self setWidth:newWidth];
@@ -332,18 +332,18 @@ CPTableColumnUserResizingMask = 1 << 1;
individual cell that is shown. As a result, changes made after calling this method won't be reflected.
Example:
@code
[tableColumn setDataView:someView]; // snapshot taken
[[tableColumn dataView] setSomething:x]; //won't work
@endcode
@code
[tableColumn setDataView:someView]; // snapshot taken
[[tableColumn dataView] setSomething:x]; //won't work
@endcode
This doesn't work because the snapshot is taken before the new property is applied. Instead, do:
@code
[someView setSomething:x];
[tableColumn setDataView:someView];
@endcode
@code
[someView setSomething:x];
[tableColumn setDataView:someView];
@endcode
@note you should implement CPKeyedArchiving otherwise you might see unexpected results.
@note You should implement CPKeyedArchiving otherwise you might see unexpected results.
This is done by adding the following methods to your class:
@endnote
@@ -380,7 +380,7 @@ CPTableColumnUserResizingMask = 1 << 1;
}
@endcode
@section Themeing
@section Theming
When you set a dataview and it is added to the tableview the theme state will be set to \c CPThemeStateTableDataView
When the dataview becomes selected the theme state will be set to \c CPThemeStateSelectedDataView.
@@ -594,22 +594,7 @@ CPTableColumnUserResizingMask = 1 << 1;
[super bind:aBinding toObject:anObject withKeyPath:aKeyPath options:options];
if (![aBinding isEqual:@"someListOfExceptedBindings(notAcceptedBindings)"])
{
// Bind the table to the array controller this column is bound to.
// Note that anObject might not be the array controller. E.g. the keypath could be something like
// somePathTo.anArrayController.arrangedObjects.aKey. Cocoa doesn't support this but it is consistent
// and it makes sense.
var acIndex = aKeyPath.lastIndexOf("arrangedObjects."),
arrayController = anObject;
if (acIndex > 1)
{
var firstPart = aKeyPath.substring(0, acIndex - 1);
arrayController = [anObject valueForKeyPath:firstPart];
}
[[self tableView] _establishBindingsIfUnbound:arrayController];
}
[[self tableView] _establishBindingsIfUnbound:anObject];
}
/*!
+7 -11
View File
@@ -323,6 +323,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
{
_tableViewFlags = 0;
_lastSelectedRow = -1;
_clickedRow = -1;
_selectedColumnIndexes = [CPIndexSet indexSet];
_selectedRowIndexes = [CPIndexSet indexSet];
@@ -509,11 +510,6 @@ NOT YET IMPLEMENTED
_objectValues = { };
_cachedRowHeights = [];
// Otherwise, if we have a row marked as group with a
// index greater than the new number or rows
// it keeps the the graphical group style.
[_groupRows removeAllIndexes];
// This updates the size too.
[self noteNumberOfRowsChanged];
@@ -1989,7 +1985,7 @@ NOT YET IMPLEMENTED
// so we should size the last resized to fit
// find the last visisble column
while (count-- && [_tableColumns[count] isHidden]);
while (count-- && [_tableColumns[count] isHidden]) ;
// find the max x, but subtract a single pixel since the spacing isn't applicable here.
var delta = superviewWidth - _CGRectGetMaxX([self rectOfColumn:count]) - ([self intercellSpacing].width || 1),
@@ -2775,7 +2771,7 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
*/
- (BOOL)canDragRowsWithIndexes:(CPIndexSet)rowIndexes atPoint:(CGPoint)mouseDownPoint
{
return [rowIndexes count] > 0 && [self numberOfRows] > 0;
return YES;
}
/*!
@@ -3549,16 +3545,16 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
}
var exposedRows = [self _unboundedRowsInRect:aRect],
firstRow = FLOOR(exposedRows.location / colorCount) * colorCount,
lastRow = CPMaxRange(exposedRows),
colorIndex = 0,
groupRowRects = [];
groupRowRects = [],
row = exposedRows.location;
//loop through each color so we only draw once for each color
while (colorIndex < colorCount)
{
CGContextBeginPath(context);
for (var row = firstRow + colorIndex; row <= lastRow; row += colorCount)
for (var row = colorIndex; row <= lastRow; row += colorCount)
{
// if it's not a group row draw it otherwise we draw it later
if (![_groupRows containsIndex:row])
@@ -4614,7 +4610,7 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
}
_wasSelectionBroken = true;
}
else if (_wasSelectionBroken && ((shouldGoUpward && i !== [selectedIndexes firstIndex]) || (!shouldGoUpward && i !== [selectedIndexes lastIndex])))
else if (_wasSelectionBroken && ((shouldGoUpward && i !== [selectedIndexes firstIndex]) || (!shouldGoUpward && i !== [selectedIndexes lastindex])))
{
shouldGoUpward ? i = [selectedIndexes firstIndex] - 1 : i = [selectedIndexes lastIndex];
_wasSelectionBroken = false;
+73 -192
View File
@@ -1,3 +1,4 @@
/*
* CPTextField.j
* AppKit
@@ -20,15 +21,13 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#import "../Foundation/Ref.h"
@import "CPControl.j"
@import "CPStringDrawing.j"
@import "CPCompatibility.j"
@import "_CPImageAndTextView.j"
CPTextFieldSquareBezel = 0; /*! A textfield bezel with squared corners. */
CPTextFieldSquareBezel = 0; /*! A textfield bezel with a squared corners. */
CPTextFieldRoundedBezel = 1; /*! A textfield bezel with rounded corners. */
CPTextFieldDidFocusNotification = @"CPTextFieldDidFocusNotification";
@@ -84,11 +83,12 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
CPColor _textFieldBackgroundColor;
CPString _placeholderString;
CPString _stringValue;
id _placeholderString;
id _delegate;
CPString _textDidChangeValue;
// NS-style Display Properties
CPTextFieldBezelStyle _bezelStyle;
BOOL _isBordered;
@@ -481,17 +481,17 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
[self setNeedsLayout];
_isEditing = NO;
_stringValue = [self stringValue];
#if PLATFORM(DOM)
var element = [self _inputElement],
var string = [self stringValue],
element = [self _inputElement],
font = [self currentValueForThemeAttribute:@"font"];
// generate the font metric
[font _getMetrics];
element.value = _stringValue;
element.value = string;
element.style.color = [[self currentValueForThemeAttribute:@"text-color"] cssString];
element.style.font = [font cssString];
element.style.zIndex = 1000;
@@ -548,6 +548,8 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
CPTextFieldInputOwner = self;
}, 0.0);
element.value = [self stringValue];
[[[self window] platformWindow] _propagateCurrentDOMEvent:YES];
CPTextFieldInputIsActive = YES;
@@ -570,39 +572,17 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
{
[self unsetThemeState:CPThemeStateEditing];
#if PLATFORM(DOM)
var element = [self _inputElement],
newValue = element.value,
error = @"";
if (newValue !== _stringValue)
{
[self _setStringValue:newValue];
}
// If there is a formatter, always give it a chance to reject the resignation,
// even if the value has not changed.
if ([self _valueIsValid:newValue] === NO)
{
[self setThemeState:CPThemeStateEditing];
element.focus();
return NO;
}
#endif
// Cache the formatted string
_stringValue = [self stringValue];
_willBecomeFirstResponderByClick = NO;
[self _updatePlaceholderState];
[self setNeedsLayout];
#if PLATFORM(DOM)
var element = [self _inputElement];
if ([self stringValue] !== element.value)
[self _setStringValue:element.value];
CPTextFieldInputResigning = YES;
if (CPTextFieldInputIsActive)
@@ -630,7 +610,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
#endif
// post CPControlTextDidEndEditingNotification
//post CPControlTextDidEndEditingNotification
if (_isEditing)
{
_isEditing = NO;
@@ -645,28 +625,6 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
return YES;
}
- (BOOL)_valueIsValid:(CPString)aValue
{
#if PLATFORM(DOM)
var error = @"";
if ([self _setStringValue:aValue isNewValue:NO errorDescription:AT_REF(error)] === NO)
{
var acceptInvalidValue = NO;
if ([_delegate respondsToSelector:@selector(control:didFailToFormatString:errorDescription:)])
acceptInvalidValue = [_delegate control:self didFailToFormatString:[self _inputElement] errorDescription:error];
if (acceptInvalidValue === NO)
return NO;
}
#endif
return YES;
}
/*!
Text fields require panels to become key window, so this returns \c YES.
*/
@@ -727,14 +685,11 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
- (void)keyUp:(CPEvent)anEvent
{
#if PLATFORM(DOM)
var oldValue = [self stringValue];
[self _setStringValue:[self _inputElement].value];
var newValue = [self _inputElement].value;
if (newValue !== _stringValue)
if (oldValue !== [self stringValue])
{
[self _setStringValue:newValue];
if (!_isEditing)
{
_isEditing = YES;
@@ -744,8 +699,6 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
[self textDidChange:[CPNotification notificationWithName:CPControlTextDidChangeNotification object:self userInfo:nil]];
}
#endif
[[[self window] platformWindow] _propagateCurrentDOMEvent:YES];
}
@@ -779,60 +732,26 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
- (void)insertNewline:(id)sender
{
var newValue = [self _inputElement].value;
if (newValue !== _stringValue)
if (_isEditing)
{
[self _setStringValue:newValue];
_isEditing = NO;
[self textDidEndEditing:[CPNotification notificationWithName:CPControlTextDidEndEditingNotification object:self userInfo:nil]];
}
if ([self _valueIsValid:_stringValue])
{
// If _isEditing == YES then the target action can also be called via
// resignFirstResponder, and it is possible that the target action
// itself will change this textfield's responder status, so start by
// setting the _isEditing flag to NO to prevent the target action being
// called twice (once below and once from resignFirstResponder).
if (_isEditing)
{
_isEditing = NO;
[self textDidEndEditing:[CPNotification notificationWithName:CPControlTextDidEndEditingNotification object:self userInfo:nil]];
}
// If there is no target action, or the sendAction call returns
// success.
if (![self action] || [self sendAction:[self action] to:[self target]])
{
[self selectAll:nil];
}
}
[self sendAction:[self action] to:[self target]];
[self selectText:nil];
[[[self window] platformWindow] _propagateCurrentDOMEvent:NO];
}
- (void)insertNewlineIgnoringFieldEditor:(id)sender
{
[self _insertCharacterIgnoringFieldEditor:CPNewlineCharacter];
}
var oldValue = [self stringValue];
- (void)insertTabIgnoringFieldEditor:(id)sender
{
[self _insertCharacterIgnoringFieldEditor:CPTabCharacter];
}
[self _inputElement].value += CPNewlineCharacter;
[self _setStringValue:[self _inputElement].value];
- (void)_insertCharacterIgnoringFieldEditor:(CPString)aCharacter
{
#if PLATFORM(DOM)
var oldValue = _stringValue,
range = [self selectedRange],
element = [self _inputElement];
element.value = [element.value stringByReplacingCharactersInRange:[self selectedRange] withString:aCharacter];
[self _setStringValue:element.value];
// NOTE: _stringValue is now the current input element value
if (oldValue !== _stringValue)
if (oldValue !== [self stringValue])
{
if (!_isEditing)
{
@@ -842,8 +761,25 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
[self textDidChange:[CPNotification notificationWithName:CPControlTextDidChangeNotification object:self userInfo:nil]];
}
}
#endif
- (void)insertTabIgnoringFieldEditor:(id)sender
{
var oldValue = [self stringValue];
[self _inputElement].value += CPTabCharacter;
[self _setStringValue:[self _inputElement].value];
if (oldValue !== [self stringValue])
{
if (!_isEditing)
{
_isEditing = YES;
[self textDidBeginEditing:[CPNotification notificationWithName:CPControlTextDidBeginEditingNotification object:self userInfo:nil]];
}
[self textDidChange:[CPNotification notificationWithName:CPControlTextDidChangeNotification object:self userInfo:nil]];
}
}
- (void)textDidBlur:(CPNotification)note
@@ -874,8 +810,15 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
[super textDidChange:note];
}
- (void)sendAction:(SEL)anAction to:(id)anObject
{
[self _reverseSetBinding];
[CPApp sendAction:anAction to:anObject from:self];
}
/*!
Returns the string in the text field.
Returns the string the text field.
*/
- (id)objectValue
{
@@ -884,84 +827,24 @@ 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.
Sets the internal string value without updating the value in the input element
*/
- (BOOL)_setStringValue:(CPString)aValue
- (void)_setStringValue:(id)aValue
{
return [self _setStringValue:aValue isNewValue:YES errorDescription:nil];
}
/*
@ignore
Sets the internal string value without updating the value in the input element.
If there is a formatter and formatting fails, returns NO. Otherwise returns YES.
*/
- (BOOL)_setStringValue:(CPString)aValue isNewValue:(BOOL)isNewValue errorDescription:(CPStringRef)anError
{
_stringValue = aValue;
var objectValue = aValue,
formatter = [self formatter],
result = YES;
if (formatter)
{
var object = nil;
if ([formatter getObjectValue:AT_REF(object) forString:aValue errorDescription:anError])
objectValue = object;
else
{
objectValue = undefined; // Mark the value as invalid
result = NO;
}
isNewValue |= objectValue !== [super objectValue];
}
if (isNewValue)
{
[self willChangeValueForKey:@"objectValue"];
[super setObjectValue:objectValue];
[self _updatePlaceholderState];
[self didChangeValueForKey:@"objectValue"];
}
return result;
[self willChangeValueForKey:@"objectValue"];
[super setObjectValue:String(aValue)];
[self _updatePlaceholderState];
[self didChangeValueForKey:@"objectValue"];
}
- (void)setObjectValue:(id)aValue
{
[super setObjectValue:aValue];
var formatter = [self formatter];
if (formatter)
{
// If there is a formatter, make sure the object value can be formatted successfully
var formattedString = [self hasThemeState:CPThemeStateEditing] ? [formatter editingStringForObjectValue:aValue] : [formatter stringForObjectValue:aValue];
if (formattedString === nil)
{
var value = nil;
// Formatting failed, get an "empty" object by formatting an empty string.
// If that fails, the value is undefined.
if ([formatter getObjectValue:AT_REF(value) forString:@"" errorDescription:nil] === NO)
value = undefined;
[super setObjectValue:value];
}
}
_stringValue = [self stringValue];
#if PLATFORM(DOM)
if (CPTextFieldInputOwner === self || [[self window] firstResponder] === self)
[self _inputElement].value = _stringValue;
[self _inputElement].value = aValue;
#endif
[self _updatePlaceholderState];
@@ -969,7 +852,9 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
- (void)_updatePlaceholderState
{
if ((!_stringValue || _stringValue.length === 0) && ![self hasThemeState:CPThemeStateEditing])
var string = [self stringValue];
if ((!string || string.length === 0) && ![self hasThemeState:CPThemeStateEditing])
[self setThemeState:CPTextFieldStatePlaceholder];
else
[self unsetThemeState:CPTextFieldStatePlaceholder];
@@ -1022,6 +907,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
However, since you don't know how tall it needs to be if you change the font, sizeToFit will still be
useful for making the textfield an appropriate height.
*/
- (void)sizeToFit
{
[self setFrameSize:[self _minimumFrameSize]];
@@ -1034,7 +920,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
minSize = [self currentValueForThemeAttribute:@"min-size"],
maxSize = [self currentValueForThemeAttribute:@"max-size"],
lineBreakMode = [self lineBreakMode],
text = (_stringValue || @" "),
text = ([self stringValue] || @" "),
textSize = _CGSizeMakeCopy(frameSize),
font = [self currentValueForThemeAttribute:@"font"];
@@ -1105,7 +991,8 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
return;
var pasteboard = [CPPasteboard generalPasteboard],
stringForPasting = [_stringValue substringWithRange:selectedRange];
stringValue = [self stringValue],
stringForPasting = [stringValue substringWithRange:selectedRange];
[pasteboard declareTypes:[CPStringPboardType] owner:nil];
[pasteboard setString:stringForPasting forType:CPStringPboardType];
@@ -1135,8 +1022,9 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
[self deleteBackward:sender];
var selectedRange = [self selectedRange],
stringValue = [self stringValue],
pasteString = [pasteboard stringForType:CPStringPboardType],
newValue = [_stringValue stringByReplacingCharactersInRange:selectedRange withString:pasteString];
newValue = [stringValue stringByReplacingCharactersInRange:selectedRange withString:pasteString];
[self setStringValue:newValue];
[self setSelectedRange:CPMakeRange(selectedRange.location + pasteString.length, 0)];
@@ -1150,8 +1038,6 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
if ([[self window] firstResponder] !== self)
return CPMakeRange(0, 0);
#if PLATFORM(DOM)
// we wrap this in try catch because firefox will throw an exception in certain instances
try
{
@@ -1178,8 +1064,6 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
// fall through to the return
}
#endif
return CPMakeRange(0, 0);
}
@@ -1188,8 +1072,6 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
if (![[self window] firstResponder] === self)
return;
#if PLATFORM(DOM)
var inputElement = [self _inputElement];
try
@@ -1218,8 +1100,6 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
catch (e)
{
}
#endif
}
- (void)selectAll:(id)sender
@@ -1237,7 +1117,8 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
selectedRange.location += 1;
selectedRange.length -= 1;
var newValue = [_stringValue stringByReplacingCharactersInRange:selectedRange withString:""];
var stringValue = [self stringValue],
newValue = [stringValue stringByReplacingCharactersInRange:selectedRange withString:""];
[self setStringValue:newValue];
[self setSelectedRange:CPMakeRange(selectedRange.location, 0)];
@@ -1390,7 +1271,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
string = [self placeholderString];
else
{
string = _stringValue;
string = [self stringValue];
if ([self isSecure])
string = secureStringForString(string);
+57 -9
View File
@@ -25,9 +25,10 @@
@import <Foundation/CPKeyedUnarchiver.j>
var CPThemesByName = { },
CPThemeDefaultTheme = nil,
CPThemeDefaultHudTheme = nil;
var CPThemesByName = { },
CPThemeNamesByInheritance = [],
CPThemeDefaultTheme = nil,
CPThemeDefaultHudTheme = nil;
/*!
@@ -76,6 +77,52 @@ var CPThemesByName = { },
return CPThemesByName[aName];
}
/*!
Returns an array of names of all loaded themes, in the order they were loaded.
*/
+ (CPArray)allThemeNames
{
return [CPThemeNamesByInheritance copy];
}
/*!
Returns the closest matching theme for a given view or view class.
The matching proceeds as follows:
- The default theme class name for the class is retrieved.
- Starting with the last loaded theme and proceeding towards the default theme,
each theme is checked to see if it defines that theme class.
- If the theme defines the class name, that theme is returned.
- If no themes match, the default theme is returned.
@param aViewOrClass The view or view class to match with a theme
@return The first matching theme
*/
+ (CPTheme)themeForView:(id)aViewOrClass
{
var themeClass = nil;
if (class_isMetaClass(aViewOrClass.isa))
themeClass = [aViewOrClass defaultThemeClass];
else
themeClass = [aViewOrClass themeClass];
if (themeClass)
{
var count = CPThemeNamesByInheritance.length;
while (count--)
{
var theme = CPThemesByName[CPThemeNamesByInheritance[count]];
if ([theme._attributes containsKey:themeClass])
return theme;
}
}
return CPThemeDefaultTheme;
}
- (id)initWithName:(CPString)aName
{
self = [super init];
@@ -86,6 +133,9 @@ var CPThemesByName = { },
_attributes = [CPDictionary dictionary];
CPThemesByName[_name] = self;
if (![CPThemeNamesByInheritance containsObject:_name])
CPThemeNamesByInheritance.push(_name);
}
return self;
@@ -299,6 +349,9 @@ var CPThemeNameKey = @"CPThemeNameKey",
_attributes = [aCoder decodeObjectForKey:CPThemeAttributesKey];
CPThemesByName[_name] = self;
if (![CPThemeNamesByInheritance containsObject:_name])
CPThemeNamesByInheritance.push(_name);
}
return self;
@@ -466,12 +519,7 @@ CPThemeStateCircular = CPThemeState("circular");
- (void)setValue:(id)aValue
{
_cache = {};
if (aValue === undefined || aValue === nil)
_values = [CPDictionary dictionary];
else
_values = [CPDictionary dictionaryWithObject:aValue forKey:String(CPThemeStateNormal)];
[self setValue:aValue forState:CPThemeStateNormal];
}
- (void)setValue:(id)aValue forState:(CPThemeState)aState
+56 -137
View File
@@ -97,66 +97,61 @@ var CPThemeStateAutoCompleting = @"CPThemeStateAutoCompleting",
{
if (self = [super initWithFrame:frame])
{
_selectedRange = CPMakeRange(0, 0);
_tokenScrollView = [[CPScrollView alloc] initWithFrame:CGRectMakeZero()];
[_tokenScrollView setHasHorizontalScroller:NO];
[_tokenScrollView setHasVerticalScroller:NO];
[_tokenScrollView setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
var contentView = [[CPView alloc] initWithFrame:CGRectMakeZero()];
[contentView setAutoresizingMask:CPViewWidthSizable];
[_tokenScrollView setDocumentView:contentView];
[self addSubview:_tokenScrollView];
_tokenIndex = 0;
_cachedCompletions = [];
_completionDelay = [CPTokenField defaultCompletionDelay];
_tokenizingCharacterSet = [[self class] defaultTokenizingCharacterSet];
_autocompleteContainer = [[CPView alloc] initWithFrame:CPRectMake(0.0, 0.0, frame.size.width, 92.0)];
[_autocompleteContainer setBackgroundColor:[_CPMenuWindow backgroundColorForBackgroundStyle:_CPMenuWindowPopUpBackgroundStyle]];
_autocompleteScrollView = [[CPScrollView alloc] initWithFrame:CPRectMake(1.0, 1.0, frame.size.width - 2.0, 90.0)];
[_autocompleteScrollView setAutohidesScrollers:YES];
[_autocompleteScrollView setHasHorizontalScroller:NO];
[_autocompleteContainer addSubview:_autocompleteScrollView];
_autocompleteView = [[CPTableView alloc] initWithFrame:CPRectMakeZero()];
var tableColumn = [[CPTableColumn alloc] initWithIdentifier:CPTokenFieldTableColumnIdentifier];
[tableColumn setResizingMask:CPTableColumnAutoresizingMask];
[_autocompleteView addTableColumn:tableColumn];
[_autocompleteView setDataSource:self];
[_autocompleteView setDelegate:self];
[_autocompleteView setAllowsMultipleSelection:NO];
[_autocompleteView setHeaderView:nil];
[_autocompleteView setCornerView:nil];
[_autocompleteView setRowHeight:30.0];
[_autocompleteView setGridStyleMask:CPTableViewSolidHorizontalGridLineMask];
[_autocompleteView setBackgroundColor:[CPColor clearColor]];
[_autocompleteView setGridColor:[CPColor colorWithRed:242.0 / 255.0 green:243.0 / 255.0 blue:245.0 / 255.0 alpha:1.0]];
[_autocompleteScrollView setDocumentView:_autocompleteView];
[self setBezeled:YES];
[self _init];
[self setObjectValue:[]];
[self setNeedsLayout];
}
return self;
}
- (void)_init
{
_selectedRange = CPMakeRange(0, 0);
var frame = [self frame];
_tokenScrollView = [[CPScrollView alloc] initWithFrame:CGRectMakeZero()];
[_tokenScrollView setHasHorizontalScroller:NO];
[_tokenScrollView setHasVerticalScroller:NO];
[_tokenScrollView setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
var contentView = [[CPView alloc] initWithFrame:CGRectMakeZero()];
[contentView setAutoresizingMask:CPViewWidthSizable];
[_tokenScrollView setDocumentView:contentView];
[self addSubview:_tokenScrollView];
_cachedCompletions = [];
_autocompleteContainer = [[CPView alloc] initWithFrame:CPRectMake(0.0, 0.0, frame.size.width, 92.0)];
[_autocompleteContainer setBackgroundColor:[_CPMenuWindow backgroundColorForBackgroundStyle:_CPMenuWindowPopUpBackgroundStyle]];
_autocompleteScrollView = [[CPScrollView alloc] initWithFrame:CPRectMake(1.0, 1.0, frame.size.width - 2.0, 90.0)];
[_autocompleteScrollView setAutohidesScrollers:YES];
[_autocompleteScrollView setHasHorizontalScroller:NO];
[_autocompleteContainer addSubview:_autocompleteScrollView];
_autocompleteView = [[CPTableView alloc] initWithFrame:CPRectMakeZero()];
var tableColumn = [[CPTableColumn alloc] initWithIdentifier:CPTokenFieldTableColumnIdentifier];
[tableColumn setResizingMask:CPTableColumnAutoresizingMask];
[_autocompleteView addTableColumn:tableColumn];
[_autocompleteView setDataSource:self];
[_autocompleteView setDelegate:self];
[_autocompleteView setAllowsMultipleSelection:NO];
[_autocompleteView setHeaderView:nil];
[_autocompleteView setCornerView:nil];
[_autocompleteView setRowHeight:30.0];
[_autocompleteView setGridStyleMask:CPTableViewSolidHorizontalGridLineMask];
[_autocompleteView setBackgroundColor:[CPColor clearColor]];
[_autocompleteView setGridColor:[CPColor colorWithRed:242.0 / 255.0 green:243.0 / 255.0 blue:245.0 / 255.0 alpha:1.0]];
[_autocompleteScrollView setDocumentView:_autocompleteView];
}
// ===============
// = CONVENIENCE =
// ===============
@@ -164,7 +159,7 @@ var CPThemeStateAutoCompleting = @"CPThemeStateAutoCompleting",
{
var indexOfSelectedItem = 0;
_cachedCompletions = [self tokenField:self completionsForSubstring:[self _inputElement].value indexOfToken:0 indexOfSelectedItem:indexOfSelectedItem];
_cachedCompletions = [self tokenField:self completionsForSubstring:[self _inputElement].value indexOfToken:_tokenIndex indexOfSelectedItem:indexOfSelectedItem];
[_autocompleteView selectRowIndexes:[CPIndexSet indexSetWithIndex:indexOfSelectedItem] byExtendingSelection:NO];
[_autocompleteView reloadData];
@@ -172,20 +167,19 @@ var CPThemeStateAutoCompleting = @"CPThemeStateAutoCompleting",
- (void)_autocompleteWithDOMEvent:(JSObject)DOMEvent
{
if (![self _inputElement].value && (!_cachedCompletions || ![self hasThemeState:CPThemeStateAutoCompleting]))
if (!_cachedCompletions || ![self hasThemeState:CPThemeStateAutoCompleting])
return;
[self _hideCompletions];
var token = _cachedCompletions ? _cachedCompletions[[_autocompleteView selectedRow]] : nil,
var token = _cachedCompletions[[_autocompleteView selectedRow]],
shouldRemoveLastObject = token !== @"" && [self _inputElement].value !== @"";
if (!token)
token = [self _inputElement].value;
// Make sure the user typed an actual token to prevent the previous token from being emptied
// If the input area is empty, we want to fall back to the normal behavior, resigning first
// responder or selecting the next or previous key view.
// If the input area is empty, we want to fallback to the normal behavior, resigning first responder or select the next or previous key view
if (!token || token === @"")
{
if (DOMEvent && DOMEvent.keyCode === CPTabKeyCode)
@@ -200,6 +194,7 @@ var CPThemeStateAutoCompleting = @"CPThemeStateAutoCompleting",
return;
}
var objectValue = [self objectValue];
// Remove the uncompleted token and add the token string.
@@ -207,25 +202,10 @@ var CPThemeStateAutoCompleting = @"CPThemeStateAutoCompleting",
if (shouldRemoveLastObject)
[objectValue removeObjectAtIndex:_selectedRange.location];
// Give the delegate a chance to confirm, replace or add to the list of tokens being added.
var delegateApprovedObjects = [self tokenField:self shouldAddObjects:[CPArray arrayWithObject:token] atIndex:_selectedRange.location],
delegateApprovedObjectsCount = [delegateApprovedObjects count];
if (delegateApprovedObjects)
{
for (var i = 0; i < delegateApprovedObjectsCount; i++)
{
[objectValue insertObject:[delegateApprovedObjects objectAtIndex:i] atIndex:_selectedRange.location + i];
}
}
// Put the cursor after the last inserted token.
[objectValue insertObject:token atIndex:_selectedRange.location];
var location = _selectedRange.location;
[self setObjectValue:objectValue];
if (delegateApprovedObjectsCount)
location += delegateApprovedObjectsCount;
_selectedRange = CPMakeRange(location, 0);
_selectedRange = CPMakeRange(location + 1, 0);
[self _inputElement].value = @"";
[self setNeedsLayout];
@@ -270,13 +250,8 @@ var CPThemeStateAutoCompleting = @"CPThemeStateAutoCompleting",
var indexOfToken = [[self _tokens] indexOfObject:token],
objectValue = [self objectValue];
// If the selection was to the right of the deleted token, move it to the left. If the deleted token was
// selected, deselect it.
if (indexOfToken < _selectedRange.location)
_selectedRange.location--;
else
[self _deselectToken:token];
// If the token was selected, deselect it for selection preservation.
[self _deselectToken:token];
// Preserve selection.
var selection = CPCopyRange(_selectedRange);
[objectValue removeObjectAtIndex:indexOfToken];
@@ -316,14 +291,6 @@ var CPThemeStateAutoCompleting = @"CPThemeStateAutoCompleting",
[self _controlTextDidChange];
}
- (void)_updatePlaceholderState
{
if (([[self _tokens] count] === 0) && ![self hasThemeState:CPThemeStateEditing])
[self setThemeState:CPTextFieldStatePlaceholder];
else
[self unsetThemeState:CPTextFieldStatePlaceholder];
}
// =============
// = RESPONDER =
// =============
@@ -608,16 +575,14 @@ var CPThemeStateAutoCompleting = @"CPThemeStateAutoCompleting",
{
}
// ========
// = VIEW =
// ========
- (void)viewDidMoveToWindow
{
[[[self window] contentView] addSubview:_autocompleteContainer];
#if PLATFORM(DOM)
_autocompleteContainer._DOMElement.style.zIndex = 1000; // Anything else doesn't seem to work
#endif
}
- (void)removeFromSuperview
@@ -1158,7 +1123,7 @@ var CPThemeStateAutoCompleting = @"CPThemeStateAutoCompleting",
{
if ([[self delegate] respondsToSelector:@selector(tokenField:completionsForSubstring:indexOfToken:indexOfSelectedItem:)])
{
return [[self delegate] tokenField:tokenField completionsForSubstring:substring indexOfToken:tokenIndex indexOfSelectedItem:selectedIndex];
return [[self delegate] tokenField:tokenField completionsForSubstring:substring indexOfToken:_tokenIndex indexOfSelectedItem:selectedIndex];
}
return [];
@@ -1184,19 +1149,7 @@ var CPThemeStateAutoCompleting = @"CPThemeStateAutoCompleting",
// // return an array of represented objects you want to add.
// // If you want to reject the add, return an empty array.
// // returning nil will cause an error.
- (CPArray)tokenField:(CPTokenField)tokenField shouldAddObjects:(CPArray)tokens atIndex:(int)index
{
var delegate = [self delegate];
if ([delegate respondsToSelector:@selector(tokenField:shouldAddObjects:atIndex:)])
{
var approvedObjects = [delegate tokenField:tokenField shouldAddObjects:tokens atIndex:index];
if (approvedObjects !== nil)
return approvedObjects;
}
return tokens;
}
// - (NSArray *)tokenField:(NSTokenField *)tokenField shouldAddObjects:(NSArray *)tokens atIndex:(NSUInteger)index;
//
// // If you return nil or don't implement these delegate methods, we will assume
// // editing string = display string = represented object
@@ -1339,37 +1292,3 @@ var CPThemeStateAutoCompleting = @"CPThemeStateAutoCompleting",
}
@end
var CPTokenFieldTokenizingCharacterSetKey = "CPTokenFieldTokenizingCharacterSetKey",
CPTokenFieldCompletionDelayKey = "CPTokenFieldCompletionDelay";
@implementation CPTokenField (CPCoding)
- (id)initWithCoder:(CPCoder)aCoder
{
self = [super initWithCoder:aCoder];
if (self)
{
_tokenizingCharacterSet = [aCoder decodeObjectForKey:CPTokenFieldTokenizingCharacterSetKey] || [[self class] defaultTokenizingCharacterSet];
_completionDelay = [aCoder decodeDoubleForKey:CPTokenFieldCompletionDelayKey] || [[self class] defaultCompletionDelay];
[self _init];
[self setNeedsLayout];
[self setNeedsDisplay:YES];
}
return self;
}
- (void)encodeWithCoder:(CPCoder)aCoder
{
[super encodeWithCoder:aCoder];
[aCoder encodeInt:_tokenizingCharacterSet forKey:CPTokenFieldTokenizingCharacterSetKey];
[aCoder encodeDouble:_completionDelay forKey:CPTokenFieldCompletionDelayKey];
}
@end
+1 -1
View File
@@ -1015,7 +1015,7 @@ var TOP_MARGIN = 5.0,
_labelSize = [_labelField frame].size;
_minSize = CGSizeMake(MAX(_labelSize.width, minSize.width), _labelSize.height + minSize.height + LABEL_MARGIN + TOP_MARGIN);
_maxSize = CGSizeMake(MAX(_labelSize.width, maxSize.width), 100000000.0);
_maxSize = CGSizeMake(MAX(_labelSize.width, minSize.width), 100000000.0);
[_toolbar tile];
}
+2 -2
View File
@@ -295,7 +295,7 @@ var CPViewFlags = { },
_DOMImageSizes = [];
#endif
_theme = [CPTheme defaultTheme];
_theme = [CPTheme themeForView:self];
_themeState = CPThemeStateNormal;
[self setupViewFlags];
@@ -2695,7 +2695,7 @@ var CPViewAutoresizingMaskKey = @"CPViewAutoresizingMask",
[self setupViewFlags];
_theme = [CPTheme defaultTheme];
_theme = [CPTheme themeForView:self];
_themeClass = [aCoder decodeObjectForKey:CPViewThemeClassKey];
_themeState = CPThemeState([aCoder decodeIntForKey:CPViewThemeStateKey]);
_themeAttributes = {};
+7 -8
View File
@@ -111,8 +111,7 @@ CPViewAnimationFadeOutEffect = @"CPViewAnimationFadeOutEffect";
view = [self _targetView:dictionary],
startFrame = [self _startFrame:dictionary],
endFrame = [self _endFrame:dictionary],
differenceFrame = _CGRectMakeZero(),
value = [super currentValue];
differenceFrame = _CGRectMakeZero();
differenceFrame.origin.x = endFrame.origin.x - startFrame.origin.x;
differenceFrame.origin.y = endFrame.origin.y - startFrame.origin.y;
@@ -120,19 +119,19 @@ CPViewAnimationFadeOutEffect = @"CPViewAnimationFadeOutEffect";
differenceFrame.size.height = endFrame.size.height - startFrame.size.height;
var intermediateFrame = _CGRectMakeZero();
intermediateFrame.origin.x = startFrame.origin.x + differenceFrame.origin.x * value;
intermediateFrame.origin.y = startFrame.origin.y + differenceFrame.origin.y * value;
intermediateFrame.size.width = startFrame.size.width + differenceFrame.size.width * value;
intermediateFrame.size.height = startFrame.size.height + differenceFrame.size.height * value;
intermediateFrame.origin.x = startFrame.origin.x + differenceFrame.origin.x * progress;
intermediateFrame.origin.y = startFrame.origin.y + differenceFrame.origin.y * progress;
intermediateFrame.size.width = startFrame.size.width + differenceFrame.size.width * progress;
intermediateFrame.size.height = startFrame.size.height + differenceFrame.size.height * progress;
[view setFrame:intermediateFrame];
// Update the view's alpha value
var effect = [self _effect:dictionary];
if (effect === CPViewAnimationFadeInEffect)
[view setAlphaValue:1.0 * value];
[view setAlphaValue:1.0 * progress];
else if (effect === CPViewAnimationFadeOutEffect)
[view setAlphaValue:1.0 + ( 0.0 - 1.0 ) * value];
[view setAlphaValue:1.0 + ( 0.0 - 1.0 ) * progress];
if (progress === 1.0)
[self _targetView:view setHidden:_CGRectIsNull(endFrame) || [view alphaValue] === 0.0];
+12 -83
View File
@@ -271,7 +271,6 @@ var CPWindowActionMessageKeys = [
BOOL _isAnimating;
BOOL _hasShadow;
BOOL _isMovableByWindowBackground;
BOOL _isMovable;
unsigned _shadowStyle;
BOOL _showsResizeIndicator;
@@ -405,7 +404,6 @@ CPTexturedBackgroundWindowMask
_registeredDraggedTypesArray = [];
_isSheet = NO;
_acceptsMouseMovedEvents = YES;
_isMovable = YES;
// Set up our window number.
_windowNumber = [CPApp._windows count];
@@ -428,7 +426,6 @@ CPTexturedBackgroundWindowMask
// Create a generic content view.
[self setContentView:[[CPView alloc] initWithFrame:CGRectMakeZero()]];
[self setInitialFirstResponder:[self contentView]];
_firstResponder = self;
@@ -483,7 +480,6 @@ CPTexturedBackgroundWindowMask
[self close];
_platformWindow = aPlatformWindow;
[_platformWindow _setTitle:_title window:self];
if (wasVisible)
[self orderFront:self];
@@ -953,12 +949,6 @@ CPTexturedBackgroundWindowMask
var bounds = CGRectMake(0.0, 0.0, CGRectGetWidth(_frame), CGRectGetHeight(_frame));
// During init the initial first responder is set to the contentView
// if it hasn't changed in the mean time we need to update that reference
// to the new contentView
if ([self initialFirstResponder] === _contentView)
[self setInitialFirstResponder:aView];
_contentView = aView;
[_contentView setFrame:[self contentRectForFrameRect:bounds]];
@@ -1283,17 +1273,17 @@ CPTexturedBackgroundWindowMask
- (BOOL)acceptsFirstResponder
{
return NO;
return YES;
}
- (CPView)initialFirstResponder
- (id)initialFirstResponder
{
return _initialFirstResponder;
}
- (void)setInitialFirstResponder:(CPView)aView
- (void)setInitialFirstResponder:(id)aResponder
{
_initialFirstResponder = aView;
_initialFirstResponder = aResponder;
}
/*!
@@ -1369,7 +1359,6 @@ CPTexturedBackgroundWindowMask
_title = aTitle;
[_windowView setTitle:aTitle];
[_platformWindow _setTitle:_title window:self];
[self _synchronizeMenuBarTitleWithWindowTitle];
}
@@ -1440,23 +1429,6 @@ CPTexturedBackgroundWindowMask
return _isMovableByWindowBackground;
}
/*!
Sets whether the window can be moved.
@param shouldBeMovable \c YES makes the window movable.
*/
- (void)setMovable:(BOOL)shouldBeMovable
{
_isMovable = shouldBeMovable;
}
/*!
Returns \c YES if the window can be moved.
*/
- (void)isMovable
{
return _isMovable;
}
/*!
Sets the window location to be the center of the screen
*/
@@ -2513,70 +2485,30 @@ CPTexturedBackgroundWindowMask
- (void)selectNextKeyView:(id)sender
{
if (_keyViewLoopIsDirty && [self autorecalculatesKeyViewLoop])
[self recalculateKeyViewLoop];
var nextValidKeyView = nil;
if ([_firstResponder isKindOfClass:[CPView class]])
nextValidKeyView = [_firstResponder nextValidKeyView];
if (!nextValidKeyView)
{
var initialFirstResponder = [self initialFirstResponder];
if ([initialFirstResponder acceptsFirstResponder])
nextValidKeyView = initialFirstResponder;
else
nextValidKeyView = [initialFirstResponder nextValidKeyView];
}
[self makeFirstResponder:nextValidKeyView];
[self selectKeyViewFollowingView:_firstResponder];
}
- (void)selectPreviousKeyView:(id)sender
{
if (_keyViewLoopIsDirty && [self autorecalculatesKeyViewLoop])
[self recalculateKeyViewLoop];
var previousValidKeyView = nil;
if ([_firstResponder isKindOfClass:[CPView class]])
previousValidKeyView = [_firstResponder previousValidKeyView];
if (!previousValidKeyView)
{
var initialFirstResponder = [self initialFirstResponder];
if ([initialFirstResponder acceptsFirstResponder])
previousValidKeyView = initialFirstResponder;
else
previousValidKeyView = [initialFirstResponder previousValidKeyView];
}
[self makeFirstResponder:previousValidKeyView];
[self selectKeyViewPrecedingView:_firstResponder];
}
- (void)selectKeyViewFollowingView:(CPView)aView
{
if (_keyViewLoopIsDirty && [self autorecalculatesKeyViewLoop])
if (_keyViewLoopIsDirty)
[self recalculateKeyViewLoop];
var nextValidKeyView = [aView nextValidKeyView];
if ([nextValidKeyView isKindOfClass:[CPView class]])
[self makeFirstResponder:nextValidKeyView];
[self makeFirstResponder:[aView nextValidKeyView]];
}
- (void)selectKeyViewPrecedingView:(CPView)aView
{
if (_keyViewLoopIsDirty && [self autorecalculatesKeyViewLoop])
if (_keyViewLoopIsDirty)
[self recalculateKeyViewLoop];
var previousValidKeyView = [aView previousValidKeyView];
if ([previousValidKeyView isKindOfClass:[CPView class]])
[self makeFirstResponder:previousValidKeyView];
[self makeFirstResponder:[aView previousValidKeyView]];
}
/*!
@@ -2664,11 +2596,9 @@ CPTexturedBackgroundWindowMask
var allViews = function(aWindow)
{
var views = [CPArray arrayWithObject:[aWindow contentView]];
var views = [[aWindow contentView] subviews],
index = 0;
[views addObjectsFromArray:[[aWindow contentView] subviews]];
var index = 0;
for (; index < views.length; ++index)
views = views.concat([views[index] subviews]);
@@ -2998,6 +2928,5 @@ CPCustomWindowShadowStyle = 3;
@import "_CPHUDWindowView.j"
@import "_CPBorderlessWindowView.j"
@import "_CPBorderlessBridgeWindowView.j"
@import "_CPAttachedWindowView.j"
@import "CPDragServer.j"
@import "CPView.j"
-300
View File
@@ -1,300 +0,0 @@
/*
* _CPAttachedWindowView.j
* AppKit
*
* Created by Antoine Mercadal
* Copyright 2011 <primalmotion@archipelproject.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "_CPWindowView.j"
/*!
@ignore
A custom CPWindowView that manage border and cursor
*/
@implementation _CPAttachedWindowView : _CPWindowView
{
BOOL _mouseDownPressed @accessors(getter=isMouseDownPressed, setter=setMouseDownPressed:);
float _arrowOffsetX @accessors(property=arrowOffsetX);
float _arrowOffsetY @accessors(property=arrowOffsetY);
int _appearance @accessors(property=appearance);
unsigned _preferredEdge @accessors(property=preferredEdge);
CPSize _cursorSize;
}
/*!
Compute the contentView frame from a given window frame
@param aFrameRect the window frame
*/
- (CGRect)contentRectForFrameRect:(CGRect)aFrameRect
{
var contentRect = CGRectMakeCopy(aFrameRect);
// @todo change border art and remove this pixel perfect adaptation
// return CGRectInset(contentRect, 20, 20);
contentRect.origin.x += 18;
contentRect.origin.y += 17;
contentRect.size.width -= 35;
contentRect.size.height -= 37;
return contentRect;
}
/*!
Compute the window frame from a given contentView frame
@param aContentRect the contentView frame
*/
+ (CGRect)frameRectForContentRect:(CGRect)aContentRect
{
var frameRect = CGRectMakeCopy(aContentRect);
// @todo change border art and remove this pixel perfect adaptation
//return CGRectOffset(frameRect, 20, 20);
frameRect.origin.x -= 18;
frameRect.origin.y -= 17;
frameRect.size.width += 35;
frameRect.size.height += 37;
return frameRect;
}
/*!
Initialize the _CPWindowView
*/
- (id)initWithFrame:(CPRect)aFrame styleMask:(unsigned)aStyleMask
{
if (self = [super initWithFrame:aFrame styleMask:aStyleMask])
{
var bundle = [CPBundle bundleForClass:[self class]];
_arrowOffsetX = 0.0;
_arrowOffsetY = 0.0;
// @TODO: make this themable
_useGlowingEffect = YES;
_appearance = CPPopoverAppearanceMinimal;
_cursorSize = CPSizeMake(15, 10);
}
return self;
}
/*!
Hide the cursor
*/
- (void)hideCursor
{
_cursorSize = CPSizeMakeZero();
[self setNeedsDisplay:YES];
}
/*!
Show the cursor
*/
- (void)showCursor
{
_cursorSize = CPSizeMake(15, 10);
[self setNeedsDisplay:YES];
_mouseDownPressed = NO;
}
/*!
Draw the view
*/
- (void)drawRect:(CGRect)aRect
{
[super drawRect:aRect];
var context = [[CPGraphicsContext currentContext] graphicsPort],
radius = 5,
arrowWidth = _cursorSize.width,
arrowHeight = _cursorSize.height,
strokeWidth = 1,
strokeColor,
shadowColor = [[CPColor blackColor] colorWithAlphaComponent:.2],
shadowSize = CGSizeMake(0, 7),
shadowBlur = 15,
gradient;
if (_appearance == CPPopoverAppearanceMinimal)
{
gradient = CGGradientCreateWithColorComponents(CGColorSpaceCreateDeviceRGB(), [(254.0 / 255), (254.0 / 255), (254.0 / 255), 0.93,
(231.0 / 255), (231.0 / 255), (231.0 / 255), 0.93], [0,1], 2);
strokeColor = [CPColor colorWithHexString:@"B8B8B8"];
}
else
{
gradient = CGGradientCreateWithColorComponents(CGColorSpaceCreateDeviceRGB(), [(38.0 / 255), (38.0 / 255), (38.0 / 255), 0.93,
(18.0 / 255), (18.0 / 255), (18.0 / 255), 0.93], [0,1], 2);
strokeColor = [CPColor colorWithHexString:@"222222"];
}
// fix rect to take care of stroke and shadow
aRect.origin.x += strokeWidth + shadowBlur;
aRect.origin.y += strokeWidth + (shadowBlur + shadowSize.height / 2);
aRect.size.width -= (strokeWidth * 2) + (shadowBlur * 2);
aRect.size.height -= (strokeWidth * 2) + (shadowBlur * 2 + shadowSize.height);
CGContextSetStrokeColor(context, strokeColor);
CGContextSetLineWidth(context, strokeWidth);
CGContextBeginPath(context);
CGContextSetShadowWithColor(context, shadowSize, shadowBlur, shadowColor);
CGContextDrawLinearGradient(context, gradient, CGPointMake(CPRectGetMidX(aRect), 0.0), CGPointMake(CPRectGetMidX(aRect), aRect.size.height), 0);
var xMin = _CGRectGetMinX(aRect),
xMax = _CGRectGetMaxX(aRect),
yMin = _CGRectGetMinY(aRect),
yMax = _CGRectGetMaxY(aRect);
// draw!
switch (_preferredEdge)
{
case CPMinXEdge:
// origin ne
CGContextMoveToPoint(context, xMin + radius, yMin);
// ne
CGContextAddLineToPoint(context, xMax - radius, yMin);
CGContextAddCurveToPoint(context, xMax - radius, yMin, xMax, yMin, xMax, yMin + radius);
// arrow CPMinXEdge
CGContextAddLineToPoint(context, xMax, (aRect.size.height / 2) + aRect.origin.y + _arrowOffsetY - (arrowHeight - 2));
CGContextAddLineToPoint(context, aRect.size.width + arrowHeight + aRect.origin.x + _arrowOffsetX, (aRect.size.height / 2) + aRect.origin.y + _arrowOffsetY);
CGContextAddLineToPoint(context, aRect.size.width + aRect.origin.x + _arrowOffsetX, (aRect.size.height / 2 + (arrowWidth / 2)) + aRect.origin.y + _arrowOffsetY);
// se
CGContextAddLineToPoint(context, xMax, yMax - radius);
CGContextAddCurveToPoint(context, xMax, yMax - radius, xMax, yMax, xMax - radius, yMax);
// sw
CGContextAddLineToPoint(context, xMin + radius, yMax);
CGContextAddCurveToPoint(context, xMin + radius, yMax, xMin, yMax, xMin, yMax - radius);
// nw
CGContextAddLineToPoint(context, xMin, yMin + radius);
CGContextAddCurveToPoint(context, xMin, yMin + radius, xMin, yMin, xMin + radius, yMin);
break;
case CPMaxXEdge:
// origin ne
CGContextMoveToPoint(context, xMin + radius, yMin);
// ne
CGContextAddLineToPoint(context, xMax - radius, yMin);
CGContextAddCurveToPoint(context, xMax - radius, yMin, xMax, yMin, xMax, yMin + radius);
// se
CGContextAddLineToPoint(context, xMax, yMax - radius);
CGContextAddCurveToPoint(context, xMax, yMax - radius, xMax, yMax, xMax - radius, yMax);
// sw
CGContextAddLineToPoint(context, xMin + radius, yMax);
CGContextAddCurveToPoint(context, xMin + radius, yMax, xMin, yMax, xMin, yMax - radius);
// arrow CPMaxXEdge
CGContextAddLineToPoint(context, xMin, (aRect.size.height / 2 + (arrowWidth / 2) + aRect.origin.y + _arrowOffsetY));
CGContextAddLineToPoint(context, aRect.origin.x - arrowHeight + _arrowOffsetX, (aRect.size.height / 2) + aRect.origin.y + _arrowOffsetY);
CGContextAddLineToPoint(context, aRect.origin.x + _arrowOffsetX, (aRect.size.height / 2 - (arrowWidth / 2) + aRect.origin.y + _arrowOffsetY));
// nw
CGContextAddLineToPoint(context, xMin, yMin + radius);
CGContextAddCurveToPoint(context, xMin, yMin + radius, xMin, yMin, xMin + radius, yMin);
break;
case CPMaxYEdge:
// origin nw
CGContextMoveToPoint(context, xMin, yMin + yMin);
// nw
CGContextAddLineToPoint(context, xMin, yMin + radius);
CGContextAddCurveToPoint(context, xMin, yMin + radius, xMin, yMin, xMin + radius, yMin);
// arrow CPMaxYEdge
CGContextAddLineToPoint(context, (aRect.size.width / 2) + aRect.origin.x + _arrowOffsetX - (arrowWidth / 2), yMin);
CGContextAddLineToPoint(context, (aRect.size.width / 2) + aRect.origin.x + _arrowOffsetX, aRect.origin.y - arrowHeight + _arrowOffsetY);
CGContextAddLineToPoint(context, (aRect.size.width / 2) + (arrowWidth / 2) + aRect.origin.x + _arrowOffsetX, aRect.origin.y + _arrowOffsetY);
// ne
CGContextAddLineToPoint(context, xMax - radius, yMin);
CGContextAddCurveToPoint(context, xMax - radius, yMin, xMax, yMin, xMax, yMin + radius);
// se
CGContextAddLineToPoint(context, xMax, yMax - radius);
CGContextAddCurveToPoint(context, xMax, yMax - radius, xMax, yMax, xMax - radius, yMax);
// sw
CGContextAddLineToPoint(context, xMin + radius, yMax);
CGContextAddCurveToPoint(context, xMin + radius, yMax, xMin, yMax, xMin, yMax - radius);
break;
case CPMinYEdge:
// origin nw
CGContextMoveToPoint(context, xMin, yMin + yMin);
// nw
CGContextAddLineToPoint(context, xMin, yMin + radius);
CGContextAddCurveToPoint(context, xMin, yMin + radius, xMin, yMin, xMin + radius, yMin);
// ne
CGContextAddLineToPoint(context, xMax - radius, yMin);
CGContextAddCurveToPoint(context, xMax - radius, yMin, xMax, yMin, xMax, yMin + radius);
// se
CGContextAddLineToPoint(context, xMax, yMax - radius);
CGContextAddCurveToPoint(context, xMax, yMax - radius, xMax, yMax, xMax - radius, yMax);
// arrow CPMinYEdge
CGContextAddLineToPoint(context, (aRect.size.width / 2) + (arrowWidth / 2) + aRect.origin.x + _arrowOffsetX , yMax);
CGContextAddLineToPoint(context, (aRect.size.width / 2) + aRect.origin.x + _arrowOffsetX, aRect.size.height + aRect.origin.y + arrowHeight + _arrowOffsetY);
CGContextAddLineToPoint(context, (aRect.size.width / 2) - (arrowWidth / 2) + aRect.origin.x + _arrowOffsetX, aRect.size.height + aRect.origin.y + _arrowOffsetY);
// sw
CGContextAddLineToPoint(context, xMin + radius, yMax);
CGContextAddCurveToPoint(context, xMin + radius, yMax, xMin, yMax, xMin, yMax - radius);
break;
default:
// no computed edge means standard rounded rect
CGContextAddPath(context, CGPathWithRoundedRectangleInRect(aRect, radius, radius, YES, YES, YES, YES));
}
CGContextClosePath(context);
//Draw it
CGContextStrokePath(context);
CGContextFillPath(context);
}
- (void)mouseDown:(CPEvent)anEvent
{
_mouseDownPressed = YES;
[super mouseDown:anEvent];
}
- (void)mouseUp:(CPEvent)anEvent
{
_mouseDownPressed = NO;
[super mouseUp:anEvent];
}
@end
+1 -4
View File
@@ -111,7 +111,7 @@ var _CPWindowViewResizeIndicatorImage = nil;
return [self trackResizeWithEvent:anEvent];
}
if ([theWindow isMovable] && [theWindow isMovableByWindowBackground])
if ([theWindow isMovableByWindowBackground])
[self trackMoveWithEvent:anEvent];
else
@@ -174,9 +174,6 @@ var _CPWindowViewResizeIndicatorImage = nil;
- (void)trackMoveWithEvent:(CPEvent)anEvent
{
if (![[self window] isMovable])
return;
var type = [anEvent type];
if (type === CPLeftMouseUp)
+3 -3
View File
@@ -34,9 +34,9 @@
@import "_CPCibWindowTemplate.j"
CPCibOwner = @"CPCibOwner";
CPCibTopLevelObjects = @"CPCibTopLevelObjects";
CPCibReplacementClasses = @"CPCibReplacementClasses";
CPCibOwner = @"CPCibOwner",
CPCibTopLevelObjects = @"CPCibTopLevelObjects",
CPCibReplacementClasses = @"CPCibReplacementClasses",
CPCibExternalObjects = @"CPCibExternalObjects";
var CPCibObjectDataKey = @"CPCibObjectDataKey";
@@ -0,0 +1,64 @@
/*
* CPCibRuntimeAttributesConnector.j
* AppKit
*
* Created by Aparajita Fishman.
* Copyright 2011, 280 North, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "CPCibConnector.j"
var CPCibRuntimeAttributesConnectorObjectKey = @"CPCibRuntimeAttributesConnectorObjectKey",
CPCibRuntimeAttributesConnectorKeyPathsKey = @"CPCibRuntimeAttributesConnectorKeyPathsKey",
CPCibRuntimeAttributesConnectorValuesKey = @"CPCibRuntimeAttributesConnectorValuesKey";
@implementation CPCibRuntimeAttributesConnector : CPCibConnector
{
id _keyPaths;
id _values;
}
- (id)initWithCoder:(CPCoder)aCoder
{
if (self = [super initWithCoder:aCoder])
{
_source = [aCoder decodeObjectForKey:CPCibRuntimeAttributesConnectorObjectKey];
_keyPaths = [aCoder decodeObjectForKey:CPCibRuntimeAttributesConnectorKeyPathsKey];
_values = [aCoder decodeObjectForKey:CPCibRuntimeAttributesConnectorValuesKey];
}
return self;
}
- (void)encodeWithCoder:(CPCoder)aCoder
{
[super encodeWithCoder:aCoder];
[aCoder encodeObject:_source forKey:CPCibRuntimeAttributesConnectorObjectKey];
[aCoder encodeObject:_keyPaths forKey:CPCibRuntimeAttributesConnectorKeyPathsKey];
[aCoder encodeObject:_values forKey:CPCibRuntimeAttributesConnectorValuesKey];
}
- (void)establishConnection
{
var count = [_keyPaths count];
while (count--)
[_source setValue:_values[count] forKeyPath:_keyPaths[count]];
}
@end
+2 -2
View File
@@ -61,14 +61,14 @@ var _CPCibClassSwapperClassNameKey = @"_CPCibClassSwapperClassNameKey",
if (!object)
{
CPLog.error("Unable to find class " + theClassName + " in cib file.");
CPLog.error("Unable to find class " + theClassName + " referenced in cib file.");
object = [self allocObjectWithCoder:aCoder className:[aCoder decodeObjectForKey:_CPCibClassSwapperOriginalClassNameKey]];
}
}
if (!object)
[CPException raise:CPInvalidArgumentException reason:@"Unable to find class " + theClassName + " in cib file."];
[CPException raise:CPInvalidArgumentException reason:@"Unable to find class " + theClassName + " referenced in cib file."];
return object;
}
+17 -1
View File
@@ -43,6 +43,11 @@ var _CPCibCustomResourceClassNameKey = @"_CPCibCustomResourceClassNameKey",
return [[self alloc] initWithClassName:@"CPImage" resourceName:aResourceName properties:[CPDictionary dictionaryWithObject:aSize forKey:@"size"]];
}
+ (id)imageResourceWithName:(CPString)aResourceName size:(CGSize)aSize bundleClass:(CPString)aBundleClass
{
return [[self alloc] initWithClassName:@"CPImage" resourceName:aResourceName properties:[CPDictionary dictionaryWithObjects:[aSize, aBundleClass] forKeys:[@"size", @"bundleClass"]]];
}
- (id)initWithClassName:(CPString)aClassName resourceName:(CPString)aResourceName properties:(CPDictionary)properties
{
self = [super init];
@@ -89,7 +94,18 @@ var _CPCibCustomResourceClassNameKey = @"_CPCibCustomResourceClassNameKey",
else if (_resourceName == "CPRemoveTemplate")
return [[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:[CPButtonBar class]] pathForResource:@"minus_button.png"] size:CGSizeMake(11, 4)];
return [[CPImage alloc] initWithContentsOfFile:[[aCoder bundle] pathForResource:_resourceName] size:_properties.valueForKey(@"size")];
var bundleClass = _properties.valueForKey(@"bundleClass"),
bundle = nil;
if (bundleClass)
{
bundleClass = CPClassFromString(bundleClass);
if (bundleClass)
bundle = [CPBundle bundleForClass:bundleClass];
}
return [[CPImage alloc] initWithContentsOfFile:[(bundle || [aCoder bundle]) pathForResource:_resourceName] size:_properties.valueForKey(@"size")];
}
return self;
+21 -2
View File
@@ -29,6 +29,7 @@
@import "CPCibControlConnector.j"
@import "CPCibOutletConnector.j"
@import "CPCibBindingConnector.j"
@import "CPCibRuntimeAttributesConnector.j"
@implementation _CPCibObjectData : CPObject
@@ -257,11 +258,29 @@ var _CPCibObjectDataNamesKeysKey = @"_CPCibObjectDataNamesKeysKey
_replacementObjects[[_fileOwner UID]] = anOwner;
var index = 0,
count = _connections.length;
count = _connections.length,
runtimeAttributeConnectors = [],
connection = nil;
for (; index < count; ++index)
{
var connection = _connections[index];
connection = _connections[index];
if ([connection isKindOfClass:[CPCibRuntimeAttributesConnector class]])
// Defer runtime attribute connections until after all other connections are made
runtimeAttributeConnectors.push(connection);
else
{
[connection replaceObjects:_replacementObjects];
[connection establishConnection];
}
}
count = runtimeAttributeConnectors.length;
for (index = 0; index < count; ++index)
{
connection = runtimeAttributeConnectors[index];
[connection replaceObjects:_replacementObjects];
[connection establishConnection];
+3 -4
View File
@@ -108,7 +108,7 @@ function CGColorCreateCopy(aColor)
*/
function CGColorCreateGenericGray(gray, alpha)
{
return CGColorCreate(CGColorSpaceCreateDeviceRGB(), [gray, gray, gray, alpha]);
return CGColorCreate(CGColorSpaceCreateDeviceRGB(), [gray,gray,gray, alpha]);
}
/*!
@@ -137,7 +137,7 @@ function CGColorCreateGenericRGB(red, green, blue, alpha)
*/
function CGColorCreateGenericCMYK(cyan, magenta, yellow, black, alpha)
{
return CGColorCreate(CGColorSpaceCreateDeviceCMYK(),
return CGColorCreate(CGColorSpaceCreateDeviceCMYK(),
[cyan, magenta, yellow, black, alpha]);
}
@@ -150,8 +150,7 @@ function CGColorCreateGenericCMYK(cyan, magenta, yellow, black, alpha)
*/
function CGColorCreateCopyWithAlpha(aColor, anAlpha)
{
if (!aColor)
return aColor; // Avoid error null pointer in next line
if ( !aColor ) return aColor; // Avoid error null pointer in next line
var components = aColor.components.slice();
-9
View File
@@ -42,16 +42,7 @@
#include "DOM/CPPlatformString.j"
#else
@implementation CPPlatformString : CPBasePlatformString
+ (CGSize)sizeOfString:(CPString)aString withFont:(CPFont)aFont forWidth:(float)aWidth
{
return _CGSizeMakeZero();
}
+ (CPDictionary)metricsOfFont:(CPFont)aFont
{
return [CPDictionary dictionaryWithObjectsAndKeys:0, @"ascender", 0, @"descender", 0, @"lineHeight"];
}
@end
#endif
-17
View File
@@ -32,7 +32,6 @@ var PrimaryPlatformWindow = NULL;
CPInteger _level;
BOOL _hasShadow;
unsigned _shadowStyle;
CPString _title;
#if PLATFORM(DOM)
DOMWindow _DOMWindow;
@@ -259,22 +258,6 @@ var PrimaryPlatformWindow = NULL;
return [CPPlatform isBrowser];
}
- (void)_setTitle:(CPString)aTitle window:(CPWindow)aWindow
{
_title = aTitle;
#if PLATFORM(DOM)
if (_DOMWindow && _DOMWindow.document
&& (aWindow === [CPApp mainWindow] || [aWindow platformWindow] !== [CPPlatformWindow primaryPlatformWindow]))
_DOMWindow.document.title = _title;
#endif
}
- (CPString)title
{
return _title;
}
@end
#if PLATFORM(BROWSER)
+2 -5
View File
@@ -534,15 +534,13 @@ var ModifierKeyCodes = [
if (_DOMWindow)
return _DOMWindow.focus();
_DOMWindow = window.open("about:blank", "_blank", "menubar=no,location=no,resizable=yes,scrollbars=no,status=no,left=" + _CGRectGetMinX(_contentRect) + ",top=" + _CGRectGetMinY(_contentRect) + ",width=" + _CGRectGetWidth(_contentRect) + ",height=" + _CGRectGetHeight(_contentRect));
_DOMWindow = window.open("", "_blank", "menubar=no,location=no,resizable=yes,scrollbars=no,status=no,left=" + _CGRectGetMinX(_contentRect) + ",top=" + _CGRectGetMinY(_contentRect) + ",width=" + _CGRectGetWidth(_contentRect) + ",height=" + _CGRectGetHeight(_contentRect));
[PlatformWindows addObject:self];
// FIXME: cpSetFrame?
_DOMWindow.document.write("<!DOCTYPE html><html lang='en'><head></head><body style='background-color:transparent;'></body></html>");
_DOMWindow.document.close();
if (self != [CPPlatformWindow primaryPlatformWindow])
_DOMWindow.document.title = _title;
if (![CPPlatform isBrowser])
{
@@ -708,8 +706,7 @@ var ModifierKeyCodes = [
var characters;
// Handle key codes for which String.fromCharCode won't work.
// Refs #1036: In Internet Explorer, both 'which' and 'charCode' are undefined for special keys.
if (aDOMEvent.which === 0 || aDOMEvent.charCode === 0 || (aDOMEvent.which === undefined && aDOMEvent.charCode === undefined))
if (aDOMEvent.which === 0 || aDOMEvent.charCode === 0)
characters = KeyCodesToUnicodeMap[_keyCode];
if (!characters)
Binary file not shown.

After

Width:  |  Height:  |  Size: 161 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 123 B

After

Width:  |  Height:  |  Size: 146 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 120 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 162 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 155 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 154 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 436 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 452 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 205 B

After

Width:  |  Height:  |  Size: 444 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 122 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 158 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 157 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 208 B

After

Width:  |  Height:  |  Size: 460 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 147 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 147 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 185 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 179 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 145 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 220 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 122 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 158 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 152 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 218 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 147 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 123 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 158 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 157 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 145 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 285 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 301 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 153 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 123 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 157 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 310 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 139 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 302 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 189 B

After

Width:  |  Height:  |  Size: 423 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 119 B

After

Width:  |  Height:  |  Size: 136 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 160 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 119 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 163 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 421 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 143 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 424 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 154 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 116 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 154 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 186 B

After

Width:  |  Height:  |  Size: 433 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 213 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 145 B

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