Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Updated to latest Kobo version, complete with bugfixes around animati…

…on and item layout. Bumped version to 1.2.
  • Loading branch information...
commit c37e347540cda16bb9d83be898bfb952317f4fa9 1 parent cf2dc26
Jim Dovey authored
View
11 AQGridView.xcodeproj/project.pbxproj
@@ -214,7 +214,14 @@
isa = PBXProject;
buildConfigurationList = 1DEB922208733DC00010E9CD /* Build configuration list for PBXProject "AQGridView" */;
compatibilityVersion = "Xcode 3.1";
+ developmentRegion = English;
hasScannedForEncodings = 1;
+ knownRegions = (
+ English,
+ Japanese,
+ French,
+ German,
+ );
mainGroup = 0867D691FE84028FC02AAC07 /* AQGridView */;
productRefGroup = 034768DFFF38A50411DB9C8B /* Products */;
projectDirPath = "";
@@ -316,7 +323,7 @@
IPHONEOS_DEPLOYMENT_TARGET = 3.0;
OTHER_LDFLAGS = "-ObjC";
PREBINDING = NO;
- SDKROOT = iphoneos3.2;
+ SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
@@ -331,7 +338,7 @@
IPHONEOS_DEPLOYMENT_TARGET = 3.0;
OTHER_LDFLAGS = "-ObjC";
PREBINDING = NO;
- SDKROOT = iphoneos3.2;
+ SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
View
37 Classes/AQGridView.m
@@ -615,11 +615,22 @@ - (void) layoutSubviews
[self layoutAllCells];
}
+
CGRect rect = CGRectZero;
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;
+
+ // Make sure background is an integral number of rows tall. That way, it draws patterned colours correctly on all OSes.
+ CGRect backgroundRect = rect;
+ CGFloat minimumHeight = rect.size.height;
+ CGFloat actualHeight = [_gridData cellSize].height * ([_gridData numberOfItems] / [_gridData numberOfItemsPerRow] + 1);
+ for (; actualHeight < minimumHeight; actualHeight += [_gridData cellSize].height) {
+ }
+ backgroundRect.size.height = actualHeight;
+
+
+ self.backgroundView.frame = backgroundRect;
if ( _headerView != nil )
{
@@ -636,6 +647,7 @@ - (void) layoutSubviews
rect.origin.y = self.contentSize.height - rect.size.height;
rect.size.width = self.bounds.size.width;
_footerView.frame = rect;
+ [self bringSubviewToFront:_footerView];
}
}
@@ -867,9 +879,9 @@ - (void) endUpdateAnimations
[UIView setAnimationCurve: UIViewAnimationCurveEaseInOut];
[UIView setAnimationDuration: 0.3];
+
self.animatingCells = [info animateCellUpdatesUsingVisibleContentRect: [self gridViewVisibleBounds]];
- [UIView commitAnimations];
[_gridData release];
_gridData = [[info newGridViewData] retain];
@@ -878,6 +890,7 @@ - (void) endUpdateAnimations
[info release];
_reloadingSuspendedCount--;
+ [UIView commitAnimations];
}
- (void) cellUpdateAnimationStopped: (NSString *) animationID finished: (BOOL) finished context: (void *) context
@@ -885,7 +898,7 @@ - (void) cellUpdateAnimationStopped: (NSString *) animationID finished: (BOOL) f
AQGridViewUpdateInfo * info = (AQGridViewUpdateInfo *)context;
// if nothing was animated, we don't have to do anything at all
- if ( self.animatingCells.count != 0 )
+// if ( self.animatingCells.count != 0 )
[self fixCellsFromAnimation];
// NB: info becomes invalid at this point
@@ -1479,7 +1492,7 @@ - (void) updateVisibleGridCellsNow
{
for ( AQGridViewAnimatorItem * item in _animatingCells )
{
- if ( [animatingInserted containsIndex: item.index] == NO )
+ if ( [newVisibleIndices containsIndex: item.index] == NO )
continue;
if ( [item.animatingView isKindOfClass: [AQGridViewCell class]] )
@@ -1525,7 +1538,12 @@ - (void) updateVisibleGridCellsNow
if ( [_visibleCells count] > [newVisibleIndices count] )
{
- NSLog( @"Have to prune visible cell list, I've still got extra cells in there!" );
+ //NSLog( @"Have to prune visible cell list, I've still got extra cells in there!" );
+ NSMutableIndexSet * animatingDestinationIndices = [[NSMutableIndexSet alloc] init];
+ for ( AQGridViewAnimatorItem * item in _animatingCells )
+ {
+ [animatingDestinationIndices addIndex: item.index];
+ }
NSMutableIndexSet * toRemove = [[NSMutableIndexSet alloc] init];
NSMutableIndexSet * seen = [[NSMutableIndexSet alloc] init];
@@ -1533,7 +1551,8 @@ - (void) updateVisibleGridCellsNow
for ( i = 0; i < count; i++ )
{
AQGridViewCell * cell = [_visibleCells objectAtIndex: i];
- if ( [newVisibleIndices containsIndex: cell.displayIndex] == NO )
+ if ( [newVisibleIndices containsIndex: cell.displayIndex] == NO &&
+ [animatingDestinationIndices containsIndex: cell.displayIndex] == NO )
{
NSLog( @"Cell for index %lu is still in visible list, removing...", (unsigned long)cell.displayIndex );
[cell removeFromSuperview];
@@ -1547,12 +1566,12 @@ - (void) updateVisibleGridCellsNow
}
[seen addIndex: cell.displayIndex];
- i++;
}
// all removed from superview, just need to remove from the list now
[_visibleCells removeObjectsAtIndexes: toRemove];
[toRemove release];
+ [seen release];
}
if ( [_visibleCells count] < [newVisibleIndices count] )
@@ -1583,6 +1602,8 @@ - (void) updateVisibleGridCellsNow
idx = [missingSet indexGreaterThanIndex: idx];
}
+
+ [missingSet release];
}
// everything should match up now, so update the visible range
@@ -2059,6 +2080,8 @@ - (void) delegateWillDisplayCell: (AQGridViewCell *) cell atIndex: (NSUInteger)
cell.separatorEdge = edge;
}
+
+ //NSLog( @"Displaying cell at index %lu", (unsigned long) index );
if ( _flags.delegateWillDisplayCell == 0 )
return;
View
4 Classes/AQGridViewAnimatorItem.m
@@ -43,9 +43,9 @@ - (NSComparisonResult) compare: (id) obj
{
if ( [obj isKindOfClass: [self class]] == NO )
{
- if ( (id)self < obj )
+ if ( (void *)self < (void *)obj )
return ( NSOrderedAscending );
- if ( (id)self > obj )
+ if ( (void *)self > (void *)obj )
return ( NSOrderedDescending );
return ( NSOrderedSame ); // how ??!?!?
}
View
39 Classes/AQGridViewCell.m
@@ -38,10 +38,7 @@
#import "AQGridViewCell+AQGridViewCellPrivate.h"
#import "UIColor+AQGridView.h"
#import <QuartzCore/QuartzCore.h>
-
-#ifdef BUILTIN_IMAGES
-#import "AQGridViewCell_png.h"
-#endif
+#import <objc/runtime.h>
@interface AQGridViewCell ()
@property (nonatomic, retain) UIView * contentView;
@@ -300,39 +297,6 @@ - (void) _beginBackgroundHighlight: (BOOL) highlightOn animated: (BOOL) animated
{
if ( (_cellFlags.usingDefaultSelectedBackgroundView == 1) && (_selectedBackgroundView == nil) )
{
-#ifdef BUILTIN_IMAGES
- unsigned char * pngBytes = AQGridSelection_png;
- NSUInteger pngLength = AQGridSelection_png_len;
- switch ( _cellFlags.selectionStyle )
- {
- case AQGridViewCellSelectionStyleBlue:
- default:
- break;
-
- case AQGridViewCellSelectionStyleGray:
- pngBytes = AQGridSelectionGray_png;
- pngLength = AQGridSelectionGray_png_len;
- break;
-
- case AQGridViewCellSelectionStyleBlueGray:
- pngBytes = AQGridSelectionGrayBlue_png;
- pngLength = AQGridSelectionGrayBlue_png_len;
- break;
-
- case AQGridViewCellSelectionStyleGreen:
- pngBytes = AQGridSelectionGreen_png;
- pngLength = AQGridSelectionGreen_png_len;
- break;
-
- case AQGridViewCellSelectionStyleRed:
- pngBytes = AQGridSelectionRed_png;
- pngLength = AQGridSelectionRed_png_len;
- break;
- }
-
- NSData *pngData = [NSData dataWithBytesNoCopy: pngBytes length: pngLength freeWhenDone: NO];
- _selectedBackgroundView = [[UIImageView alloc] initWithImage: [UIImage imageWithData: pngData]];
-#else
NSString * imageName = @"AQGridSelection.png";
switch ( _cellFlags.selectionStyle )
{
@@ -358,7 +322,6 @@ - (void) _beginBackgroundHighlight: (BOOL) highlightOn animated: (BOOL) animated
}
_selectedBackgroundView = [[UIImageView alloc] initWithImage: [UIImage imageNamed: imageName]];
-#endif
_selectedBackgroundView.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;
_selectedBackgroundView.contentMode = UIViewContentModeScaleToFill;
}
View
4 Classes/AQGridViewController.h
@@ -39,10 +39,12 @@
#define POPOVER_SIZE CGSizeMake( 345, 525 )
-@interface AQGridViewController : UIViewController <AQGridViewDelegate, AQGridViewDataSource>
+@interface AQGridViewController : UIViewController <AQGridViewDelegate, AQGridViewDataSource, UIPopoverControllerDelegate>
{
@private
BOOL _clearsSelectionOnViewWillAppear;
+ @protected
+ BOOL _popoverShowing;
}
@property (nonatomic, retain) AQGridView * gridView;
View
10 Classes/AQGridViewController.m
@@ -71,6 +71,8 @@ - (void) viewDidLoad
{
[super viewDidLoad];
[self.gridView reloadData];
+
+ _popoverShowing = NO;
}
- (AQGridView *) gridView
@@ -168,4 +170,12 @@ - (AQGridViewCell *) gridView: (AQGridView *) gridView cellForItemAtIndex: (NSUI
return ( nil );
}
+#pragma mark -
+#pragma mark UIPopoverControllerDelegate methods
+
+- (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController
+{
+ _popoverShowing = NO;
+}
+
@end
View
126 Classes/AQGridViewUpdateInfo.m
@@ -146,6 +146,18 @@ - (NSUInteger) numberOfUpdates
- (void) updateNewGridDataAndCreateMappingTables
{
+#define GUARD_ITEMS 1
+#if GUARD_ITEMS
+# define TEST_GUARD(array,count) \
+ for ( int j = 0; j < 8; j++ ) \
+ { \
+ NSAssert((array)[(count)+j] == 0x55555555, @"Overwrote the guard area!" ); \
+ } \
+ do {} while (0)
+#else
+# define TEST_GUARD(array,count)
+#endif
+
NSUInteger numberOfItems = _oldGridData.numberOfItems;
numberOfItems += [_insertItems count];
numberOfItems -= [_deleteItems count];
@@ -174,8 +186,19 @@ - (void) updateNewGridDataAndCreateMappingTables
if ( _oldGridData.numberOfItems > 0 )
{
- _oldToNewIndexMap = NSZoneMalloc( [self zone], _oldGridData.numberOfItems * sizeof(NSUInteger) );
+#if GUARD_ITEMS
+ NSUInteger count = _oldGridData.numberOfItems + 8;
+#else
+ NSUInteger count = _oldGridData.numberOfItems;
+#endif
+ _oldToNewIndexMap = NSZoneMalloc( [self zone], count * sizeof(NSUInteger) );
+#if GUARD_ITEMS
+ memset(_oldToNewIndexMap, 0x55, count * sizeof(NSUInteger));
+#endif
memset_pattern4( _oldToNewIndexMap, &stamp, _oldGridData.numberOfItems * sizeof(NSUInteger) );
+#if GUARD_ITEMS
+ NSAssert(_oldToNewIndexMap[_oldGridData.numberOfItems] == 0x55555555, @"Eeek! Scribbling on guards didn't work!");
+#endif
}
else
{
@@ -184,8 +207,19 @@ - (void) updateNewGridDataAndCreateMappingTables
if ( _newGridData.numberOfItems > 0 )
{
- _newToOldIndexMap = NSZoneMalloc( [self zone], _newGridData.numberOfItems * sizeof(NSUInteger) );
+#if GUARD_ITEMS
+ NSUInteger count = _newGridData.numberOfItems + 8;
+#else
+ NSUInteger count = _newGridData.numberOfItems;
+#endif
+ _newToOldIndexMap = NSZoneMalloc( [self zone], count * sizeof(NSUInteger) );
+#if GUARD_ITEMS
+ memset(_newToOldIndexMap, 0x55, count * sizeof(NSUInteger));
+#endif
memset_pattern4( _newToOldIndexMap, &stamp, _newGridData.numberOfItems * sizeof(NSUInteger) );
+#if GUARD_ITEMS
+ NSAssert(_newToOldIndexMap[_newGridData.numberOfItems] == 0x55555555, @"Eeek! Scribbling on guards didn't work!");
+#endif
}
else
{
@@ -202,6 +236,7 @@ - (void) updateNewGridDataAndCreateMappingTables
if ( [newToOldIndices containsIndex: i] == NO )
{
_oldToNewIndexMap[i] = NSNotFound;
+ TEST_GUARD(_oldToNewIndexMap, _oldGridData.numberOfItems);
continue;
}
@@ -212,6 +247,49 @@ - (void) updateNewGridDataAndCreateMappingTables
for ( AQGridViewUpdateItem * item in _moveItems )
{
_oldToNewIndexMap[item.index] = item.newIndex;
+ TEST_GUARD(_oldToNewIndexMap, _oldGridData.numberOfItems);
+
+ if ( _moveItems.count == 1 )
+ {
+ if ( item.index < item.newIndex )
+ {
+ // moving forwards-- shuffle middle items down one place
+ for ( NSInteger i = item.index+1; i <= item.newIndex && i < _oldGridData.numberOfItems; i++ )
+ {
+ if ( _oldToNewIndexMap[i] != NSNotFound )
+ {
+ if ( i < _oldGridData.numberOfItems-1 )
+ {
+ _oldToNewIndexMap[i] = _oldToNewIndexMap[i]-1;
+ TEST_GUARD(_oldToNewIndexMap, _oldGridData.numberOfItems);
+ }
+ }
+ else
+ {
+ break; // stop when we reach a gap
+ }
+ }
+ }
+ else if ( item.index > item.newIndex )
+ {
+ // moving backwards-- shuffle middle items up one place
+ for ( NSInteger i = MIN(item.index-1, (_oldGridData.numberOfItems-1)); i >= item.newIndex; i-- )
+ {
+ if ( _oldToNewIndexMap[i] != NSNotFound )
+ {
+ if ( i >= 0 )
+ {
+ _oldToNewIndexMap[i] = _oldToNewIndexMap[i]+1;
+ TEST_GUARD(_oldToNewIndexMap, _oldGridData.numberOfItems);
+ }
+ }
+ else
+ {
+ break; // stop when we reach a gap
+ }
+ }
+ }
+ }
}
}
@@ -223,6 +301,7 @@ - (void) updateNewGridDataAndCreateMappingTables
if ( [oldToNewIndices containsIndex: i] == NO )
{
_newToOldIndexMap[i] = NSNotFound;
+ TEST_GUARD(_newToOldIndexMap, _newGridData.numberOfItems);
continue;
}
@@ -233,6 +312,49 @@ - (void) updateNewGridDataAndCreateMappingTables
for ( AQGridViewUpdateItem * item in _moveItems )
{
_newToOldIndexMap[item.newIndex] = item.index;
+ TEST_GUARD(_newToOldIndexMap, _newGridData.numberOfItems);
+
+ if ( _moveItems.count == 1 )
+ {
+ if ( item.index < item.newIndex )
+ {
+ // moving forwards-- shuffle middle items down one place
+ for ( NSInteger i = item.index; i <= item.newIndex && i < _newGridData.numberOfItems; i++ )
+ {
+ if ( _newToOldIndexMap[i] != NSNotFound )
+ {
+ if ( i < _newGridData.numberOfItems-1 )
+ {
+ _newToOldIndexMap[i] = _newToOldIndexMap[i]+1;
+ TEST_GUARD(_newToOldIndexMap, _newGridData.numberOfItems);
+ }
+ }
+ else
+ {
+ break; // stop when we reach a gap
+ }
+ }
+ }
+ else
+ {
+ // moving backwards-- shuffle middle items up one place
+ for ( NSInteger i = MIN(item.newIndex, (_newGridData.numberOfItems-1)); (i < item.index && i < _newGridData.numberOfItems); i++ )
+ {
+ if ( _newToOldIndexMap[i] != NSNotFound )
+ {
+ if ( i >= 0 )
+ {
+ _newToOldIndexMap[i] = _newToOldIndexMap[i]-1;
+ TEST_GUARD(_newToOldIndexMap, _newGridData.numberOfItems);
+ }
+ }
+ else
+ {
+ break; // stop when we reach a gap
+ }
+ }
+ }
+ }
}
}
View
5 Examples/ExpanderDemo/ExpanderDemo.xcodeproj/project.pbxproj
@@ -323,6 +323,7 @@
};
buildConfigurationList = 38D6F05F12197E62006909B6 /* Build configuration list for PBXProject "ExpanderDemo" */;
compatibilityVersion = "Xcode 3.2";
+ developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
en,
@@ -435,7 +436,7 @@
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
PREBINDING = NO;
- SDKROOT = iphoneos3.2;
+ SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = 2;
};
name = Debug;
@@ -450,7 +451,7 @@
GCC_WARN_UNUSED_VARIABLE = YES;
OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1";
PREBINDING = NO;
- SDKROOT = iphoneos3.2;
+ SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = 2;
};
name = Release;
View
11 Examples/ImageDemo/ImageDemo.xcodeproj/project.pbxproj
@@ -321,7 +321,14 @@
isa = PBXProject;
buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "ImageDemo" */;
compatibilityVersion = "Xcode 3.1";
+ developmentRegion = English;
hasScannedForEncodings = 1;
+ knownRegions = (
+ English,
+ Japanese,
+ French,
+ German,
+ );
mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */;
projectDirPath = "";
projectRoot = "";
@@ -436,7 +443,7 @@
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
PREBINDING = NO;
- SDKROOT = iphoneos3.2;
+ SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = 2;
};
name = Debug;
@@ -452,7 +459,7 @@
GCC_WARN_UNUSED_VARIABLE = YES;
OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1";
PREBINDING = NO;
- SDKROOT = iphoneos3.2;
+ SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = 2;
};
name = Release;
View
11 Examples/SpringBoard/SpringBoard.xcodeproj/project.pbxproj
@@ -207,7 +207,14 @@
isa = PBXProject;
buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "SpringBoard" */;
compatibilityVersion = "Xcode 3.1";
+ developmentRegion = English;
hasScannedForEncodings = 1;
+ knownRegions = (
+ English,
+ Japanese,
+ French,
+ German,
+ );
mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */;
projectDirPath = "";
projectRoot = "";
@@ -291,7 +298,7 @@
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
PREBINDING = NO;
- SDKROOT = iphoneos3.2;
+ SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = 2;
};
name = Debug;
@@ -307,7 +314,7 @@
GCC_WARN_UNUSED_VARIABLE = YES;
OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1";
PREBINDING = NO;
- SDKROOT = iphoneos3.2;
+ SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = 2;
};
name = Release;
View
2  LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2010, Kobo Inc.
+Copyright (c) 2010-2011, Kobo Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
View
2  README.textile
@@ -2,7 +2,7 @@ h1=. AQGridView
h3=. Winner of the _Best Developer Tool/Helper_ award at iPadDevCamp 2010 in San Jose
-p=. Version 1.1 -- 26 May 2010
+p=. Version 1.2 -- 10 January 2011
p=. By "Jim Dovey":mailto:jimdovey@mac.com <br />
Originally written for the "Kobo iPad Application":http://itunes.apple.com/ca/app/ebooks-by-kobo/id301259483?mt=8
Please sign in to comment.
Something went wrong with that request. Please try again.