Permalink
Browse files

A whole great big bag of changes imported from the Kobo app. This inc…

…ludes lots of bug-fixes. LOTS of bug-fixes.
  • Loading branch information...
1 parent 79e8abe commit be175b6834e587ddd868fd6cb4f439ad34cf0e6f Jim Dovey committed Aug 9, 2010
@@ -170,6 +170,8 @@ extern NSString * const AQGridViewSelectionDidChangeNotification;
@property (nonatomic, readonly) CGSize gridCellSize;
+- (void)doAddVisibleCell: (UIView *)cell;
+
- (CGRect) rectForItemAtIndex: (NSUInteger) index;
- (CGRect) gridViewVisibleBounds;
- (AQGridViewCell *) cellForItemAtIndex: (NSUInteger) index;
View
@@ -523,30 +523,35 @@ - (void) setBounds: (CGRect) bounds
- (AQGridViewCell *) dequeueReusableCellWithIdentifier: (NSString *) reuseIdentifier
{
- NSMutableArray * cells = [_reusableGridCells objectForKey: reuseIdentifier];
- AQGridViewCell * cell = [[cells lastObject] retain];
+ NSMutableSet * cells = [_reusableGridCells objectForKey: reuseIdentifier];
+ AQGridViewCell * cell = [[cells anyObject] retain];
if ( cell == nil )
return ( nil );
[cell prepareForReuse];
- [cells removeLastObject];
+ [cells removeObject: cell];
return ( [cell autorelease] );
}
- (void) enqueueReusableCells: (NSArray *) reusableCells
{
for ( AQGridViewCell * cell in reusableCells )
{
- NSMutableArray * reuseArray = [_reusableGridCells objectForKey: cell.reuseIdentifier];
- if ( reuseArray == nil )
+ if ( [_visibleCells containsObject: cell] )
{
- reuseArray = [[NSMutableArray alloc] init];
- [_reusableGridCells setObject: reuseArray forKey: cell.reuseIdentifier];
- [reuseArray release];
+ NSLog( @"Warning: tried to add duplicate gridview cell" );
+ continue;
+ }
+ NSMutableSet * reuseSet = [_reusableGridCells objectForKey: cell.reuseIdentifier];
+ if ( reuseSet == nil )
+ {
+ reuseSet = [[NSMutableSet alloc] initWithCapacity: 32];
+ [_reusableGridCells setObject: reuseSet forKey: cell.reuseIdentifier];
+ [reuseSet release];
}
- [reuseArray addObject: cell];
+ [reuseSet addObject: cell];
}
}
@@ -611,8 +616,8 @@ - (void) layoutSubviews
}
CGRect rect = CGRectZero;
- rect.size = self.contentSize;
- rect.size.height -= (_gridData.topPadding + _gridData.bottomPadding);
+ rect.size.width = self.bounds.size.width;
+ rect.size.height = self.contentSize.height - (_gridData.topPadding + _gridData.bottomPadding);
rect.origin.y += _gridData.topPadding;
self.backgroundView.frame = rect;
@@ -785,7 +790,7 @@ - (void) fixCellsFromAnimation
[newVisibleCells addObject: item.animatingView];
}
- NSAssert2([newVisibleCells count] == _visibleIndices.length, @"visible cell count after animation (%lu) doesn't match visible indices (%lu)", (unsigned long)[newVisibleCells count], (unsigned long)_visibleIndices.length);
+ //NSAssert([newVisibleCells count] == _visibleIndices.length, @"visible cell count after animation doesn't match visible indices");
[newVisibleCells sortUsingSelector: @selector(compareOriginAgainstCell:)];
[_visibleCells removeObjectsInArray: newVisibleCells];
@@ -794,15 +799,14 @@ - (void) fixCellsFromAnimation
[newVisibleCells release];
self.animatingCells = nil;
- // build a list of the grid view cells in our view tree which aren't in the visible list
NSMutableSet * removals = [[NSMutableSet alloc] init];
for ( UIView * view in self.subviews )
{
if ( [view isKindOfClass: [AQGridViewCell class]] == NO )
continue;
if ( [_visibleCells containsObject: view] == NO )
- [removals addObject: view]; // it's not in the visible list, so it shouldn't be here
+ [removals addObject: view];
}
[removals makeObjectsPerformSelector: @selector(removeFromSuperview)];
@@ -1087,7 +1091,7 @@ - (void) setBackgroundView: (UIView *) newView
_backgroundView.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;
CGRect frame = self.bounds;
frame.size = self.contentSize;
- _backgroundView.frame = UIEdgeInsetsInsetRect( frame, self.contentInset );
+ _backgroundView.frame = self.bounds;//UIEdgeInsetsInsetRect( frame, self.contentInset );
[self insertSubview: _backgroundView atIndex: 0];
@@ -1331,6 +1335,21 @@ - (void) touchesCancelled: (NSSet *) touches withEvent: (UIEvent *) event
[super touchesCancelled: touches withEvent: event];
}
+- (void)doAddVisibleCell: (UIView *)cell
+{
+ [_visibleCells addObject: cell];
+ // updated: if we're adding it to our visibleCells collection, really it should be in the gridview.
+ if ( cell.superview == nil )
+ {
+ NSLog( @"Visible cell not in gridview - adding" );
+ if ( _backgroundView.superview == self )
+ [self insertSubview: cell aboveSubview: _backgroundView];
+ else
+ [self insertSubview: cell atIndex: 0];
+ }
+}
+
+
@end
#pragma mark -
@@ -1419,7 +1438,7 @@ - (void) updateVisibleGridCellsNow
NSMutableArray * removedCells = [[_visibleCells objectsAtIndexes: shifted] mutableCopy];
// remove them from the visible list
- [_visibleCells removeObjectsAtIndexes: shifted];
+ [_visibleCells removeObjectsInArray: removedCells];
//NSLog( @"After removals, visible cells count = %lu", (unsigned long)[_visibleCells count] );
// don't need this any more
@@ -1466,14 +1485,16 @@ - (void) updateVisibleGridCellsNow
{
// ensure this is in the visible cell list
if ( [_visibleCells containsObject: item.animatingView] == NO )
- [_visibleCells addObject: item.animatingView];
+ //[_visibleCells addObject: item.animatingView];
+ [self doAddVisibleCell: item.animatingView];
}
else
{
// it's an image that's being moved, likely because it *was* going offscreen before
// the user scrolled. Create a real cell, but hide it until the animation is complete.
AQGridViewCell * cell = [self createPreparedCellForIndex: idx];
- [_visibleCells addObject: cell];
+ //[_visibleCells addObject: cell];
+ [self doAddVisibleCell: cell];
// we don't tell the delegate yet, we just hide it
cell.hiddenForAnimation = YES;
@@ -1491,7 +1512,8 @@ - (void) updateVisibleGridCellsNow
while ( idx != NSNotFound )
{
AQGridViewCell * cell = [self createPreparedCellForIndex: idx];
- [_visibleCells addObject: cell];
+ //[_visibleCells addObject: cell];
+ [self doAddVisibleCell: cell];
// tell the delegate
[self delegateWillDisplayCell: cell atIndex: idx];
@@ -1506,9 +1528,10 @@ - (void) updateVisibleGridCellsNow
NSMutableIndexSet * toRemove = [[NSMutableIndexSet alloc] init];
NSMutableIndexSet * seen = [[NSMutableIndexSet alloc] init];
- NSUInteger i = 0;
- for ( AQGridViewCell * cell in _visibleCells )
+ NSUInteger i, count = [_visibleCells count];
+ for ( i = 0; i < count; i++ )
{
+ AQGridViewCell * cell = [_visibleCells objectAtIndex: i];
if ( [newVisibleIndices containsIndex: cell.displayIndex] == NO )
{
NSLog( @"Cell for index %lu is still in visible list, removing...", (unsigned long)cell.displayIndex );
@@ -1519,6 +1542,7 @@ - (void) updateVisibleGridCellsNow
{
NSLog( @"Multiple cells with index %lu found-- removing duplicate...", (unsigned long)cell.displayIndex );
[cell removeFromSuperview];
+ [toRemove addIndex: i];
}
[seen addIndex: cell.displayIndex];
@@ -1550,7 +1574,8 @@ - (void) updateVisibleGridCellsNow
while ( idx != NSNotFound )
{
AQGridViewCell * cell = [self createPreparedCellForIndex: idx];
- [_visibleCells addObject: cell];
+ //[_visibleCells addObject: cell];
+ [self doAddVisibleCell: cell];
// tell the delegate
[self delegateWillDisplayCell: cell atIndex: idx];
@@ -1955,6 +1980,7 @@ - (AQGridViewCell *) createPreparedCellForIndex: (NSUInteger) index usingGridDat
else
[self insertSubview: cell atIndex: 0];
[UIView setAnimationsEnabled: YES];
+
return ( cell );
}
@@ -1977,13 +2003,15 @@ - (void) deleteVisibleCell: (AQGridViewCell *) cell atIndex: (NSUInteger) visibl
return;
[_visibleCells removeObjectAtIndex: visibleCellListIndex];
- [_visibleCells addObject: newCell];
+ //[_visibleCells addObject: newCell];
+ [self doAddVisibleCell: newCell];
}
- (void) ensureCellInVisibleList: (AQGridViewCell *) cell
{
if ( [_visibleCells containsObject: cell] == NO )
- [_visibleCells addObject: cell];
+ //[_visibleCells addObject: cell];
+ [self doAddVisibleCell: cell];
[_visibleCells sortUsingSelector: @selector(compareOriginAgainstCell:)];
}
@@ -15,4 +15,8 @@
@property (nonatomic, retain) UIView * animatingView; // probably an AQGridViewCell, maybe a UIImageView
@property (nonatomic, assign) NSUInteger index; // the DESTINATION index -- use NSNotFound if this is being deleted
+- (NSUInteger) hash;
+- (BOOL) isEqual: (AQGridViewAnimatorItem *) o;
+- (NSComparisonResult) compare: (id) obj;
+
@end
@@ -26,17 +26,37 @@ - (void) dealloc
[super dealloc];
}
-- (BOOL) isEqual: (AQGridViewAnimatorItem *) object
+- (NSUInteger) hash
+{
+ return ( self.index );
+}
+
+- (BOOL) isEqual: (AQGridViewAnimatorItem *) o
{
- if ( [object isKindOfClass: [self class]] == NO )
+ if ( [o isKindOfClass: [self class]] == NO )
return ( NO );
- return ( object.index == self.index );
+ return ( o.index == self.index );
}
-- (NSUInteger) hash
+- (NSComparisonResult) compare: (id) obj
{
- return ( self.index );
+ if ( [obj isKindOfClass: [self class]] == NO )
+ {
+ if ( (id)self < obj )
+ return ( NSOrderedAscending );
+ if ( (id)self > obj )
+ return ( NSOrderedDescending );
+ return ( NSOrderedSame ); // how ??!?!?
+ }
+
+ AQGridViewAnimatorItem * item = (AQGridViewAnimatorItem *) obj;
+ if ( self.index < item.index )
+ return ( NSOrderedAscending );
+ if ( self.index > item.index )
+ return ( NSOrderedDescending );
+
+ return ( NSOrderedSame );
}
@end
@@ -163,7 +163,7 @@ - (CGSize) sizeForEntireGrid
CGFloat height = ( ((CGFloat)ceilf((CGFloat)numRows * _actualCellSize.height)) + _topPadding + _bottomPadding );
if (height < _gridView.bounds.size.height)
- height = _gridView.bounds.size.height + 1;
+ height = _gridView.bounds.size.height;
return ( CGSizeMake(((CGFloat)ceilf(_actualCellSize.width * numPerRow)) + _leftPadding + _rightPadding, height) );
}
@@ -383,7 +383,7 @@ - (UIImageView *) animateDeletionForCell: (AQGridViewCell *) cell withAnimation:
CGSize cellSize = cell.frame.size;
[_animatingCells addObject: imageView];
- // swap 'em aroundAQGrid
+ // swap 'em around
// image view goes underneath all real cells
if ( _gridView.backgroundView != nil )
[_gridView insertSubview: imageView aboveSubview: _gridView.backgroundView];
@@ -608,7 +608,7 @@ - (NSSet *) animateCellUpdatesUsingVisibleContentRect: (CGRect) contentRect
// indices of items visible from old grid
NSIndexSet * oldVisibleIndices = [_oldGridData indicesOfCellsInRect: contentRect];
- //NSLog( @"Updating from original content rect %@", NSStringFromCGRect(contentRect) );
+ NSLog( @"Updating from original content rect %@", NSStringFromCGRect(contentRect) );
if ( (isVertical) && (maxY > gridSize.height) )
{
@@ -637,7 +637,7 @@ - (NSSet *) animateCellUpdatesUsingVisibleContentRect: (CGRect) contentRect
[_gridView updateGridViewBoundsForNewGridData: _newGridData];
}
- //NSLog( @"Updated content rect: %@", NSStringFromCGRect(contentRect) );
+ NSLog( @"Updated content rect: %@", NSStringFromCGRect(contentRect) );
NSIndexSet * newVisibleIndices = [_newGridData indicesOfCellsInRect: contentRect];
NSMutableSet * newVisibleCells = [[NSMutableSet alloc] initWithSet: _gridView.animatingCells];
@@ -705,17 +705,9 @@ - (NSSet *) animateCellUpdatesUsingVisibleContentRect: (CGRect) contentRect
// keep the cell in our internal list
if ( animatingItem != nil )
- {
animatingItem.index = newIndex; // just update the index on the existing item
- }
else
- {
- animatingItem = [AQGridViewAnimatorItem itemWithView: cell index: newIndex];
- [newVisibleCells addObject: animatingItem];
-
- // put it into the lookup table so we can make other modifications later
- //CFDictionarySetValue( animatingCellTable, (void *)newIndex, animatingItem );
- }
+ [newVisibleCells addObject: [AQGridViewAnimatorItem itemWithView: cell index: newIndex]];
// animate it into its new location
CGRect frame = [_gridView fixCellFrame: cell.frame forGridRect: [_newGridData cellRectAtIndex: newIndex]];
@@ -771,26 +763,19 @@ - (NSSet *) animateCellUpdatesUsingVisibleContentRect: (CGRect) contentRect
{
[self animateInsertionForCell: cell withAnimation: item.animation];
[_gridView delegateWillDisplayCell: cell atIndex: item.index];
-
- AQGridViewAnimatorItem * item = [AQGridViewAnimatorItem itemWithView: cell index: item.index];
- [newVisibleCells addObject: item];
-
- // add to the lookup table
- //CFDictionarySetValue( animatingCellTable, (void *)item.index, item );
+ [newVisibleCells addObject: [AQGridViewAnimatorItem itemWithView: cell index: item.index]];
}
}
}
// now reload items
for ( AQGridViewUpdateItem * item in _reloadItems )
{
- // if it won't be visible after other insertions/deletions, ignore it
if ( [newVisibleIndices containsIndex: item.index] == NO )
continue;
AQGridViewAnimatorItem * animatingItem = (AQGridViewAnimatorItem *)CFDictionaryGetValue( animatingCellTable, (void *)item.originalIndex );
- //
AQGridViewCell * origCell = (AQGridViewCell *)animatingItem.animatingView;
if ( origCell == nil )
origCell = [_gridView cellForItemAtIndex: item.originalIndex];
@@ -803,19 +788,24 @@ - (NSSet *) animateCellUpdatesUsingVisibleContentRect: (CGRect) contentRect
if ( animatingItem != nil )
{
animatingItem.animatingView = newCell;
- animatingItem.index = item.index;
+ animatingItem.index = item.originalIndex;
}
else
{
- // we MUST replace any existing items with the reloaded versions
- animatingItem = [AQGridViewAnimatorItem itemWithView: newCell index: item.index];
+ AQGridViewAnimatorItem * tmp = [AQGridViewAnimatorItem itemWithView: newCell index: item.index];
- // if anything in the set refers to the same item, this will remove it
- [newVisibleCells removeObject: animatingItem];
- [newVisibleCells addObject: animatingItem];
+ // newVisibleCells is a set, meaning that it will probably not actually insert the new item
+ // if there is something matching this index, let's just update that value
+ animatingItem = [newVisibleCells member: tmp];
+ if ( animatingItem == nil )
+ [newVisibleCells addObject: tmp];
+ else
+ animatingItem.animatingView = newCell;
}
}
+ CFRelease( animatingCellTable );
+
return ( [newVisibleCells autorelease] );
}

0 comments on commit be175b6

Please sign in to comment.