From 7acfbb9eedbeb887d208834b1c3b89baf370ced3 Mon Sep 17 00:00:00 2001 From: Francisco Ryan Tolmasky I Date: Sun, 20 Dec 2009 13:00:25 -0800 Subject: [PATCH 1/3] Added [CPView setSubviews:] which allows you to add multiple subviews, remove multiple subviews, and reorder multple subviews. Reviewed by me. --- AppKit/CPView.j | 76 ++++++++++++++++++++++++++++++++--- AppKit/CPWindow/CPWindow.j | 6 ++- AppKit/Cib/_CPCibCustomView.j | 4 +- 3 files changed, 76 insertions(+), 10 deletions(-) diff --git a/AppKit/CPView.j b/AppKit/CPView.j index ae8aeb595..d17e7c0cb 100644 --- a/AppKit/CPView.j +++ b/AppKit/CPView.j @@ -308,7 +308,7 @@ var CPViewFlags = { }, */ - (CPArray)subviews { - return _subviews; + return [_subviews copy]; } /*! @@ -441,7 +441,7 @@ var CPViewFlags = { }, [_superview willRemoveSubview:self]; - [[_superview subviews] removeObject:self]; + [_superview._subviews removeObject:self]; #if PLATFORM(DOM) CPDOMDisplayServerRemoveChild(_superview._DOMElement, _DOMElement); @@ -468,6 +468,73 @@ var CPViewFlags = { }, [self _insertSubview:aView atIndex:index]; } +- (void)setSubviews:(CPArray)newSubviews +{ + if (!newSubviews) + [CPException raise:CPInvalidArgumentException reason:"newSubviews cannot be nil in -[CPView setSubviews:]"]; + + // Trivial Case 0: Same array somehow + if ([_subviews isEqual:newSubviews]) + return; + + // Trivial Case 1: No current subviews, simply add all new subviews. + if ([_subviews count] === 0) + { + var index = 0, + count = [newSubviews count]; + + for (; index < count; ++index) + [self addSubview:newSubviews[index]]; + + return; + } + + // Trivial Case 2: No new subviews, simply remove all current subviews. + if ([newSubviews count] === 0) + { + var count = [subviews count]; + + while (count--) + [_subviews[count] removeFromSuperview]; + + return; + } + + // Find out the views that were removed. + var removedSubviews = [CPMutableSet setWithArray:_subviews]; + + [removedSubviews removeObjectsInArray:newSubviews]; + [removedSubviews makeObjectsPerformSelector:@selector(removeFromSuperview)]; + + // Find out which views need to be added. + var addedSubviews = [CPMutableSet setWithArray:newSubviews]; + + [addedSubviews removeObjectsInArray:_subviews]; + + var addedSubview = nil, + addedSubviewEnumerator = [addedSubviews objectEnumerator]; + + while (addedSubview = [addedSubviewEnumerator nextObject]) + [self addSubview:addedSubview]; + + // If the order is fine, no need to reorder. + if ([_subviews isEqual:newSubviews]) + return; + + _subviews = [newSubviews copy]; + + var index = 0, + count = [_subviews count]; + + for (; index < count; ++index) + { + var subview = _subviews[index]; + + CPDOMDisplayServerRemoveChild(_DOMElement, subview._DOMElement); + CPDOMDisplayServerAppendChild(_DOMElement, subview._DOMElement); + } +} + /* @ignore */ - (void)_setWindow:(CPWindow)aWindow { @@ -1863,12 +1930,11 @@ setBoundsOrigin: - (BOOL)performKeyEquivalent:(CPEvent)anEvent { - var subviews = [self subviews], - count = [subviews count]; + var count = [_subviews count]; // Is reverse iteration correct here? It matches the other (correct) code like hit testing. while (count--) - if ([subviews[count] performKeyEquivalent:anEvent]) + if ([_subviews[count] performKeyEquivalent:anEvent]) return YES; return NO; diff --git a/AppKit/CPWindow/CPWindow.j b/AppKit/CPWindow/CPWindow.j index c3f1fe0db..59f1c8c20 100644 --- a/AppKit/CPWindow/CPWindow.j +++ b/AppKit/CPWindow/CPWindow.j @@ -1999,7 +1999,8 @@ CPTexturedBackgroundWindowMask - (void)_setUpMasksForView:(CPView)aView { - var views = [CPArray arrayWithArray:[aView subviews]]; + var views = [aView subviews]; + [views addObject:aView]; for (var i = 0, count = [views count]; i < count; i++) @@ -2014,7 +2015,8 @@ CPTexturedBackgroundWindowMask - (void)_restoreMasksForView:(CPView)aView { - var views = [CPArray arrayWithArray:[aView subviews]]; + var views = [aView subviews]; + [views addObject:aView]; for (var i = 0, count = [views count]; i < count; i++) diff --git a/AppKit/Cib/_CPCibCustomView.j b/AppKit/Cib/_CPCibCustomView.j index 808cf85fc..1e3f9944c 100644 --- a/AppKit/Cib/_CPCibCustomView.j +++ b/AppKit/Cib/_CPCibCustomView.j @@ -97,9 +97,7 @@ var _CPCibCustomViewClassNameKey = @"_CPCibCustomViewClassNameKey"; [view setBounds:[self bounds]]; // Since the object replacement logic hasn't had a chance to kick in yet, we need to do it manually: - - // we need to copy subviews since each time we add a subview to a different view its removed from the original subviews array - var subviews = [[self subviews] copy], + var subviews = [self subviews], index = 0, count = subviews.length; From e15cbfca334d7c3a3f7d862c6eb036fd4e99a19e Mon Sep 17 00:00:00 2001 From: Randall Luecke Date: Sun, 20 Dec 2009 17:41:11 -0600 Subject: [PATCH 2/3] fix bug in CPPlatformWindow where the visible frame for the platform window would offset itself for the menu bar height, even though no menu bar would be displayed because it's not the primaryPlatformWindow --- AppKit/Platform/CPPlatformWindow.j | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AppKit/Platform/CPPlatformWindow.j b/AppKit/Platform/CPPlatformWindow.j index 7c665e9bf..fa1917281 100644 --- a/AppKit/Platform/CPPlatformWindow.j +++ b/AppKit/Platform/CPPlatformWindow.j @@ -104,7 +104,7 @@ var PrimaryPlatformWindow = NULL; frame.origin = CGPointMakeZero(); - if ([CPMenu menuBarVisible]) + if ([CPMenu menuBarVisible] && [CPPlatformWindow primaryPlatformWindow] === self) { var menuBarHeight = [[CPApp mainMenu] menuBarHeight]; From 5352d062d59285817b120ed25a76e50033c91aa5 Mon Sep 17 00:00:00 2001 From: Francisco Ryan Tolmasky I Date: Sun, 20 Dec 2009 17:02:06 -0800 Subject: [PATCH 3/3] Fix for boundsOrigin and boundsSize being affected by bounds. Also changed UID to return a string instead of a Number. Reviewed by me. --- AppKit/CPView.j | 15 +++++++++++++++ AppKit/Cib/_CPCibCustomView.j | 6 ++++++ Foundation/CPObject.j | 4 ++-- 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/AppKit/CPView.j b/AppKit/CPView.j index d17e7c0cb..e67dd263b 100644 --- a/AppKit/CPView.j +++ b/AppKit/CPView.j @@ -238,6 +238,11 @@ var CPViewFlags = { }, return [CPSet setWithObjects:@"frameOrigin", @"frameSize"]; } ++ (CPSet)keyPathsForValuesAffectingBounds +{ + return [CPSet setWithObjects:@"boundsOrigin", @"boundsSize"]; +} + - (id)init { return [self initWithFrame:CGRectMakeZero()]; @@ -883,6 +888,16 @@ var CPViewFlags = { }, return _CGRectMakeCopy(_bounds); } +- (CGPoint)boundsOrigin +{ + return _CGPointMakeCopy(_bounds.origin); +} + +- (CGSize)boundsSize +{ + return _CGSizeMakeCopy(_bounds.size); +} + /*! Sets the location of the receiver inside its frame. The method posts a CPViewBoundsDidChangeNotification to the diff --git a/AppKit/Cib/_CPCibCustomView.j b/AppKit/Cib/_CPCibCustomView.j index 1e3f9944c..e50f0cb58 100644 --- a/AppKit/Cib/_CPCibCustomView.j +++ b/AppKit/Cib/_CPCibCustomView.j @@ -37,7 +37,13 @@ - (void)setCustomClassName:(CPString)aClassName { + if (_className === aClassName) + return; + _className = aClassName; + + [self setNeedsDisplay:YES]; + [self setNeedsLayout]; } @end diff --git a/Foundation/CPObject.j b/Foundation/CPObject.j index d8e90512c..70a5bc23d 100644 --- a/Foundation/CPObject.j +++ b/Foundation/CPObject.j @@ -470,12 +470,12 @@ CPLog(@"Got some class: %@", inst); return [self UID]; } -- (unsigned)UID +- (CPString)UID { if (typeof self.__address === "undefined") self.__address = _objj_generateObjectHash(); - return __address; + return __address + ""; } /*!