Skip to content
This repository
Newer
Older
100644 824 lines (581 sloc) 24.419 kb
a224b799 »
2010-02-10 Initial commit. Split out from DTKit.
1 //
2 // DTGridView.m
3 // GridViewTester
4 //
5 // Created by Daniel Tull on 05.12.2008.
6 // Copyright 2008 Daniel Tull. All rights reserved.
7 //
8
9 #import "DTGridView.h"
10 #import "DTGridViewCellInfoProtocol.h"
11
2ec82bdc »
2010-10-29 Changing to lazy load from accessor.
12 NSInteger const DTGridViewInvalid = -1;
13
14
a224b799 »
2010-02-10 Initial commit. Split out from DTKit.
15 @interface DTGridViewCellInfo : NSObject <DTGridViewCellInfoProtocol> {
cdcebdfb »
2011-02-20 Fix warnings found in the DCTKit project
16 NSUInteger xPosition, yPosition;
a224b799 »
2010-02-10 Initial commit. Split out from DTKit.
17 CGRect frame;
18 CGFloat x, y, width, height;
19 }
20 @property (nonatomic, assign) CGFloat x, y, width, height;
21 @end
22
23 @implementation DTGridViewCellInfo
24 @synthesize xPosition, yPosition, x, y, width, height, frame;
25 - (NSString *)description {
26 return [NSString stringWithFormat:@"DTGridViewCellInfo: frame=(%i %i; %i %i) x=%i, y=%i", (NSInteger)self.frame.origin.x, (NSInteger)self.frame.origin.y, (NSInteger)self.frame.size.width, (NSInteger)self.frame.size.height, self.xPosition, self.yPosition];
27 }
28 @end
29
30 @interface DTGridView ()
5d321c73 »
2010-10-29 Add method for awakeFromNib.
31 - (void)dctInternal_setupInternals;
a224b799 »
2010-02-10 Initial commit. Split out from DTKit.
32 - (void)loadData;
33 - (void)checkViews;
34 - (void)initialiseViews;
35 - (void)fireEdgeScroll;
36 - (void)checkNewRowStartingWithCellInfo:(NSObject<DTGridViewCellInfoProtocol> *)info goingUp:(BOOL)goingUp;
cdcebdfb »
2011-02-20 Fix warnings found in the DCTKit project
37 - (NSObject<DTGridViewCellInfoProtocol> *)cellInfoForRow:(NSUInteger)row column:(NSUInteger)col;
a224b799 »
2010-02-10 Initial commit. Split out from DTKit.
38 - (void)checkRow:(NSInteger)row column:(NSInteger)col goingLeft:(BOOL)goingLeft;
eb32e782 »
2010-02-13 Moved the dragging and decelerating checks to the main gridview class.
39
40
41 - (void)decelerationTimer:(NSTimer *)timer;
42 - (void)draggingTimer:(NSTimer *)timer;
43
44 @property (nonatomic, retain) NSTimer *decelerationTimer, *draggingTimer;
a224b799 »
2010-02-10 Initial commit. Split out from DTKit.
45 @end
46
47 @implementation DTGridView
48
37c92c00 »
2010-02-12 Modified the Grid View to not rely on being its own delegate. The pro…
49 @dynamic delegate;
50 @synthesize dataSource, gridCells, numberOfRows, cellOffset, outset;
eb32e782 »
2010-02-13 Moved the dragging and decelerating checks to the main gridview class.
51 @synthesize decelerationTimer, draggingTimer;
a224b799 »
2010-02-10 Initial commit. Split out from DTKit.
52
0a47fe12 »
2010-10-29 Fix memory leaks.
53 - (void)dealloc {
54 super.delegate = nil;
55 self.dataSource = nil;
56 [cellsOnScreen release], cellsOnScreen = nil;
57 [gridRows release], gridRows = nil;
58 [rowPositions release], rowPositions = nil;
59 [rowHeights release], rowHeights = nil;
60 [freeCells release], freeCells = nil;
61 [cellInfoForCellsOnScreen release], cellInfoForCellsOnScreen = nil;
62 [super dealloc];
63 }
64
0b88c6fe »
2010-02-12 Added the gridDelegate property back and linked it to the delegate pr…
65 - (void)setGridDelegate:(id <DTGridViewDelegate>)aDelegate {
66 self.delegate = aDelegate;
67 }
68 - (id <DTGridViewDelegate>)gridDelegate {
69 return self.delegate;
70 }
71
a224b799 »
2010-02-10 Initial commit. Split out from DTKit.
72 NSInteger intSort(id info1, id info2, void *context) {
73
74 DTGridViewCellInfo *i1 = (DTGridViewCellInfo *)info1;
75 DTGridViewCellInfo *i2 = (DTGridViewCellInfo *)info2;
76
77 if (i1.yPosition < i2.yPosition)
78 return NSOrderedAscending;
79 else if (i1.yPosition > i2.yPosition)
80 return NSOrderedDescending;
81 else if (i1.xPosition < i2.xPosition)
82 return NSOrderedAscending;
83 else if (i1.xPosition > i2.xPosition)
84 return NSOrderedDescending;
85 else
86 return NSOrderedSame;
87 }
88
89
9814ba01 »
2010-02-12 Trialling a new way of refreshing the data.
90 - (id)initWithFrame:(CGRect)frame {
91
92 if (!(self = [super initWithFrame:frame])) return nil;
5d321c73 »
2010-10-29 Add method for awakeFromNib.
93
94 [self dctInternal_setupInternals];
95
96 return self;
a224b799 »
2010-02-10 Initial commit. Split out from DTKit.
97
5d321c73 »
2010-10-29 Add method for awakeFromNib.
98 }
99
100 - (void)awakeFromNib {
101 [self dctInternal_setupInternals];
102 }
103
104 - (void)dctInternal_setupInternals {
2ec82bdc »
2010-10-29 Changing to lazy load from accessor.
105 numberOfRows = DTGridViewInvalid;
106 columnIndexOfSelectedCell = DTGridViewInvalid;
107 rowIndexOfSelectedCell = DTGridViewInvalid;
108
a224b799 »
2010-02-10 Initial commit. Split out from DTKit.
109 gridRows = [[NSMutableArray alloc] init];
110 rowPositions = [[NSMutableArray alloc] init];
111 rowHeights = [[NSMutableArray alloc] init];
112 cellsOnScreen = [[NSMutableArray alloc] init];
113
114 freeCells = [[NSMutableArray alloc] init];
9814ba01 »
2010-02-12 Trialling a new way of refreshing the data.
115
a224b799 »
2010-02-10 Initial commit. Split out from DTKit.
116 cellInfoForCellsOnScreen = [[NSMutableArray alloc] init];
9814ba01 »
2010-02-12 Trialling a new way of refreshing the data.
117 }
118
08c2964c »
2010-02-12 First attempt at reloading when resized.
119 - (void)setFrame:(CGRect)aFrame {
120
121 CGSize oldSize = self.frame.size;
122 CGSize newSize = aFrame.size;
123
124 if (oldSize.height != newSize.height || oldSize.width != newSize.width) {
125 hasResized = YES;
126 }
127
128 [super setFrame:aFrame];
129
130 if (hasResized) {
131 [self setNeedsLayout];
132 }
133 }
134
9814ba01 »
2010-02-12 Trialling a new way of refreshing the data.
135 - (void)reloadData {
136 [self loadData];
4536aaa3 »
2010-11-08 Set needs display when -reloadData is called. Closes #2.
137 [self setNeedsDisplay];
9814ba01 »
2010-02-12 Trialling a new way of refreshing the data.
138 [self setNeedsLayout];
139 }
140
141 - (void)drawRect:(CGRect)rect {
142
cdcebdfb »
2011-02-20 Fix warnings found in the DCTKit project
143 oldContentOffset = CGPointMake(0.0f, 0.0f);
a224b799 »
2010-02-10 Initial commit. Split out from DTKit.
144
145 //hasLoadedData = NO;
146
147 //if (!hasLoadedData)
148
149 [self loadData];
150
151 for (UIView *v in self.subviews)
0d0d422c »
2010-11-08 Only remove a subview if it is a grid view cell.
152 if ([v isKindOfClass:[DTGridViewCell class]])
153 [v removeFromSuperview];
a224b799 »
2010-02-10 Initial commit. Split out from DTKit.
154
155 [self initialiseViews];
156
157 [self didLoad];
158 }
159
160 - (void)didLoad {
37c92c00 »
2010-02-12 Modified the Grid View to not rely on being its own delegate. The pro…
161 if ([self.delegate respondsToSelector:@selector(gridViewDidLoad:)])
162 [self.delegate gridViewDidLoad:self];
a224b799 »
2010-02-10 Initial commit. Split out from DTKit.
163 }
164
eb32e782 »
2010-02-13 Moved the dragging and decelerating checks to the main gridview class.
165 - (void)didEndDragging {}
166 - (void)didEndDecelerating {}
167 - (void)didEndMoving {}
168
a224b799 »
2010-02-10 Initial commit. Split out from DTKit.
169 - (void)layoutSubviews {
170 [super layoutSubviews];
171 [self checkViews];
37c92c00 »
2010-02-12 Modified the Grid View to not rely on being its own delegate. The pro…
172 [self fireEdgeScroll];
eb32e782 »
2010-02-13 Moved the dragging and decelerating checks to the main gridview class.
173
174 if (!self.draggingTimer && !self.decelerationTimer && self.dragging)
175 self.draggingTimer = [NSTimer scheduledTimerWithTimeInterval:0.0 target:self selector:@selector(draggingTimer:) userInfo:nil repeats:NO];
176
177 if (!self.decelerationTimer && self.decelerating) {
178 self.decelerationTimer = [NSTimer scheduledTimerWithTimeInterval:0.0 target:self selector:@selector(decelerationTimer:) userInfo:nil repeats:NO];
179 [self.draggingTimer invalidate];
180 self.draggingTimer = nil;
181 }
182 }
183
184 - (void)decelerationTimer:(NSTimer *)timer {
185 self.decelerationTimer = nil;
186 [self didEndDecelerating];
187 [self didEndMoving];
188 }
189
190 - (void)draggingTimer:(NSTimer *)timer {
191 self.draggingTimer = nil;
192 [self didEndDragging];
193 [self didEndMoving];
a224b799 »
2010-02-10 Initial commit. Split out from DTKit.
194 }
195
196 #pragma mark Adding and Removing Cells
197
198 - (void)addCellWithInfo:(NSObject<DTGridViewCellInfoProtocol> *)info {
199
200 if (![info isMemberOfClass:[DTGridViewCellInfo class]]) return;
201
202 [cellInfoForCellsOnScreen addObject:info];
203
204 [cellInfoForCellsOnScreen sortUsingFunction:intSort context:NULL];
205
206 DTGridViewCell *cell = [[self findViewForRow:info.yPosition column:info.xPosition] retain];
207 [cell setNeedsDisplay];
208 cell.xPosition = info.xPosition;
209 cell.yPosition = info.yPosition;
210 cell.delegate = self;
211 cell.frame = info.frame;
212
213 if (cell.xPosition == columnIndexOfSelectedCell && cell.yPosition == rowIndexOfSelectedCell)
214 cell.selected = YES;
215 else
216 cell.selected = NO;
217
218 [[gridCells objectAtIndex:info.yPosition] replaceObjectAtIndex:info.xPosition withObject:cell];
219
220 [self insertSubview:cell atIndex:0];
991343a5 »
2010-10-21 variable initialisation to keep clang happy/quiet
221
6ebd425e »
2010-10-24 Add check to make sure it's not a scroll bar, this may not be needed,…
222 // remove any existing view at this frame
991343a5 »
2010-10-21 variable initialisation to keep clang happy/quiet
223 for (UIView *v in self.subviews) {
6ebd425e »
2010-10-24 Add check to make sure it's not a scroll bar, this may not be needed,…
224 if ([v isKindOfClass:[DTGridViewCell class]] &&
225 v.frame.origin.x == cell.frame.origin.x &&
991343a5 »
2010-10-21 variable initialisation to keep clang happy/quiet
226 v.frame.origin.y == cell.frame.origin.y &&
6ebd425e »
2010-10-24 Add check to make sure it's not a scroll bar, this may not be needed,…
227 v != cell) {
228
991343a5 »
2010-10-21 variable initialisation to keep clang happy/quiet
229 [v removeFromSuperview];
230 break;
231 }
232 }
233
a224b799 »
2010-02-10 Initial commit. Split out from DTKit.
234 [cell release];
235
236 }
237
238 - (void)removeCellWithInfo:(DTGridViewCellInfo *)info {
239
240
241
242 if (info.yPosition > [gridCells count]) return;
243
244 NSMutableArray *row = [gridCells objectAtIndex:info.yPosition];
245
246 if (info.xPosition > [row count]) return;
247
248 DTGridViewCell *cell = [row objectAtIndex:info.xPosition];
249
250 if (![cell isKindOfClass:[DTGridViewCell class]]) return;
251
252 [cell retain];
253
254 [cell removeFromSuperview];
255
256 [row replaceObjectAtIndex:info.xPosition withObject:info];
257
258 [cellInfoForCellsOnScreen removeObject:info];
259
260 // TODO: Should this be set?
261 //cell.frame = CGRectZero;
262
263 [freeCells addObject:cell];
264
265 [cell release];
266 }
267
0d0d422c »
2010-11-08 Only remove a subview if it is a grid view cell.
268 - (CGRect)visibleRect {
269 CGRect visibleRect;
270 visibleRect.origin = self.contentOffset;
271 visibleRect.size = self.bounds.size;
272 return visibleRect;
273 }
274
275 - (BOOL)rowOfCellInfoShouldBeOnShow:(NSObject<DTGridViewCellInfoProtocol> *)info {
276
277 CGRect visibleRect = [self visibleRect];
278
279 CGRect infoFrame = info.frame;
280
281 CGFloat infoBottom = infoFrame.origin.y + infoFrame.size.height;
282 CGFloat infoTop = infoFrame.origin.y;
283
284 CGFloat visibleBottom = visibleRect.origin.y + visibleRect.size.height;
285 CGFloat visibleTop = visibleRect.origin.y;
286
287 return (infoBottom >= visibleTop &&
288 infoTop <= visibleBottom);
289 }
290
a224b799 »
2010-02-10 Initial commit. Split out from DTKit.
291 - (BOOL)cellInfoShouldBeOnShow:(NSObject<DTGridViewCellInfoProtocol> *)info {
292
293 if (!info || ![info isMemberOfClass:[DTGridViewCellInfo class]]) return NO;
294
0d0d422c »
2010-11-08 Only remove a subview if it is a grid view cell.
295 CGRect visibleRect = [self visibleRect];
296
297 CGFloat infoRight = info.frame.origin.x + info.frame.size.width;
298 CGFloat infoLeft = info.frame.origin.x;
299
300 CGFloat visibleRight = visibleRect.origin.x + visibleRect.size.width;
301 CGFloat visibleLeft = visibleRect.origin.x;
302
303 if (infoRight >= visibleLeft &&
304 infoLeft <= visibleRight &&
305 [self rowOfCellInfoShouldBeOnShow:info]) return YES;
306
307 //NSLog(@"%@ NO: %@", NSStringFromSelector(_cmd), NSStringFromCGRect(info.frame));
308
309 return NO;
a224b799 »
2010-02-10 Initial commit. Split out from DTKit.
310 }
311
0d0d422c »
2010-11-08 Only remove a subview if it is a grid view cell.
312
a224b799 »
2010-02-10 Initial commit. Split out from DTKit.
313 #pragma mark -
314 #pragma mark Finding Infomation from DataSource
315
316 - (CGFloat)findWidthForRow:(NSInteger)row column:(NSInteger)column {
317 return [self.dataSource gridView:self widthForCellAtRow:row column:column];
318 }
319
320 - (NSInteger)findNumberOfRows {
321 return [self.dataSource numberOfRowsInGridView:self];
322 }
323
324 - (NSInteger)findNumberOfColumnsForRow:(NSInteger)row {
325 return [self.dataSource numberOfColumnsInGridView:self forRowWithIndex:row];
326 }
327
328 - (CGFloat)findHeightForRow:(NSInteger)row {
329 return [self.dataSource gridView:self heightForRow:row];
330 }
331
332 - (DTGridViewCell *)findViewForRow:(NSInteger)row column:(NSInteger)column {
333 return [self.dataSource gridView:self viewForRow:row column:column];
334 }
335 #pragma mark -
336
337 - (void)loadData {
338
339 hasLoadedData = YES;
340
341 if (![self.dataSource respondsToSelector:@selector(numberOfRowsInGridView:)])
342 return;
343
344 self.numberOfRows = [self findNumberOfRows];
345
346 if (!self.numberOfRows)
347 return;
348
349 [gridRows removeAllObjects];
350 [rowHeights removeAllObjects];
351 [rowPositions removeAllObjects];
352
353 NSMutableArray *cellInfoArrayRows = [[NSMutableArray alloc] init];
354
991343a5 »
2010-10-21 variable initialisation to keep clang happy/quiet
355 CGFloat maxHeight = 0;
356 CGFloat maxWidth = 0;
a224b799 »
2010-02-10 Initial commit. Split out from DTKit.
357
358
359 for (NSInteger i = 0; i < self.numberOfRows; i++) {
360
361 NSInteger numberOfCols = [self findNumberOfColumnsForRow:i];
362
363 NSMutableArray *cellInfoArrayCols = [[NSMutableArray alloc] init];
364
365 for (NSInteger j = 0; j < numberOfCols; j++) {
366
367
368 DTGridViewCellInfo *info = [[DTGridViewCellInfo alloc] init];
369
370 info.xPosition = j;
371 info.yPosition = i;
372
373
374 CGFloat height = [self findHeightForRow:i];
375 CGFloat width = [self findWidthForRow:i column:j];
376
377 //info.frame.size.height = [dataSource gridView:self heightForRow:i];
378 //info.frame.size.width = [dataSource gridView:self widthForCellAtRow:i column:j];
379 CGFloat y;
380 CGFloat x;
381
382 if (i == 0) {
cdcebdfb »
2011-02-20 Fix warnings found in the DCTKit project
383 y = 0.0f;
a224b799 »
2010-02-10 Initial commit. Split out from DTKit.
384 //info.frame.origin.y = 0.0;
385 } else {
386 DTGridViewCellInfo *previousCellRow = [[cellInfoArrayRows objectAtIndex:i-1] objectAtIndex:0];
387 y = previousCellRow.frame.origin.y + previousCellRow.frame.size.height;
388
389 if (cellOffset.y != 0)
390 y += cellOffset.y;
391 }
392
393 if (j == 0) {
cdcebdfb »
2011-02-20 Fix warnings found in the DCTKit project
394 x = 0.0f;
a224b799 »
2010-02-10 Initial commit. Split out from DTKit.
395 } else {
396 DTGridViewCellInfo *previousCellRow = [cellInfoArrayCols objectAtIndex:j-1];
397 x = previousCellRow.frame.origin.x + previousCellRow.frame.size.width;
398 if (cellOffset.x != 0)
399 x += cellOffset.x;
400 }
401
402 if (maxHeight < y + height)
403 maxHeight = y + height;
404
405 if (maxWidth < x + width)
406 maxWidth = x + width;
407
408 info.frame = CGRectMake(x,y,width,height);
409
410 [cellInfoArrayCols addObject:info];
411
412 [info release];
413 }
414
415 [cellInfoArrayRows addObject:cellInfoArrayCols];
416 [cellInfoArrayCols release];
417 }
418
419
420 self.contentSize = CGSizeMake(maxWidth, maxHeight);
421
422 self.gridCells = cellInfoArrayRows;
423 [cellInfoArrayRows release];
424
991343a5 »
2010-10-21 variable initialisation to keep clang happy/quiet
425 if ([self.subviews count] > [self.gridCells count]) {
426 // the underlying data must have reduced, time to iterate
427 NSSet *gridCellsSet = [NSSet setWithArray:self.gridCells];
428 NSArray *subviewsCopy = [self.subviews copy];
429
652e92aa »
2011-01-05 another place scrollbars can be removed
430 for (UIView *cell in subviewsCopy) {
431 if (
432 [cell isKindOfClass:[DTGridViewCell class]] &&
433 ![gridCellsSet member:cell]
434 )
435 {
991343a5 »
2010-10-21 variable initialisation to keep clang happy/quiet
436 [cell removeFromSuperview];
652e92aa »
2011-01-05 another place scrollbars can be removed
437 }
991343a5 »
2010-10-21 variable initialisation to keep clang happy/quiet
438 }
439
440 [subviewsCopy release];
441 }
a224b799 »
2010-02-10 Initial commit. Split out from DTKit.
442 }
443
444 - (void)checkViews {
445
446 if ([cellInfoForCellsOnScreen count] == 0) {
447 [self initialiseViews];
448 return;
449 }
450
451 NSMutableDictionary *leftRightCells = [[NSMutableDictionary alloc] init];
452
453 NSArray *orderedCells = [cellInfoForCellsOnScreen copy];
454
455 BOOL isGoingUp = NO;
456 BOOL isGoingDown = NO;
457 BOOL isGoingLeft = NO;
458 BOOL isGoingRight = NO;
459
460 if (self.contentOffset.y < oldContentOffset.y && self.contentOffset.y >= 0)
461 isGoingUp = YES;
462 else if (self.contentOffset.y > oldContentOffset.y && self.contentOffset.y + self.frame.size.height < self.contentSize.height)
463 isGoingDown = YES;
08c2964c »
2010-02-12 First attempt at reloading when resized.
464 else if (hasResized)
465 isGoingUp = YES;
a224b799 »
2010-02-10 Initial commit. Split out from DTKit.
466
467 if (self.contentOffset.x < oldContentOffset.x && self.contentOffset.x >= 0)
468 isGoingLeft = YES;
469 else if (self.contentOffset.x > oldContentOffset.x && self.contentOffset.x + self.frame.size.width < self.contentSize.width)
470 isGoingRight = YES;
08c2964c »
2010-02-12 First attempt at reloading when resized.
471 else if (hasResized)
472 isGoingRight = YES;
0d0d422c »
2010-11-08 Only remove a subview if it is a grid view cell.
473
474 // NSLog(@"isGoingUp: %i, isGoingDown: %i, co.y: %f, old.y: %f", isGoingUp, isGoingDown, self.contentOffset.y, oldContentOffset.y);
a224b799 »
2010-02-10 Initial commit. Split out from DTKit.
475
08c2964c »
2010-02-12 First attempt at reloading when resized.
476 hasResized = NO;
a224b799 »
2010-02-10 Initial commit. Split out from DTKit.
477 oldContentOffset = self.contentOffset;
478
479 for (DTGridViewCellInfo *info in orderedCells) {
480
cdcebdfb »
2011-02-20 Fix warnings found in the DCTKit project
481 if (isGoingLeft) {
482 if (info.xPosition > 0 && info.frame.origin.x > self.contentOffset.x) {
a224b799 »
2010-02-10 Initial commit. Split out from DTKit.
483 if (![leftRightCells objectForKey:[NSString stringWithFormat:@"%i", info.yPosition]])
484 [leftRightCells setObject:info forKey:[NSString stringWithFormat:@"%i", info.yPosition]];
485 else if ([[leftRightCells objectForKey:[NSString stringWithFormat:@"%i", info.yPosition]] xPosition] > info.xPosition)
486 [leftRightCells setObject:info forKey:[NSString stringWithFormat:@"%i", info.yPosition]];
cdcebdfb »
2011-02-20 Fix warnings found in the DCTKit project
487 }
a224b799 »
2010-02-10 Initial commit. Split out from DTKit.
488 } else if (isGoingRight) {
cdcebdfb »
2011-02-20 Fix warnings found in the DCTKit project
489 if ([[self.gridCells objectAtIndex:info.yPosition] count] - 1 > info.xPosition && info.frame.origin.x + info.frame.size.width < self.contentOffset.x + self.frame.size.width) {
a224b799 »
2010-02-10 Initial commit. Split out from DTKit.
490 if (![leftRightCells objectForKey:[NSString stringWithFormat:@"%i", info.yPosition]])
491 [leftRightCells setObject:info forKey:[NSString stringWithFormat:@"%i", info.yPosition]];
492 else if ([[leftRightCells objectForKey:[NSString stringWithFormat:@"%i", info.yPosition]] xPosition] < info.xPosition)
493 [leftRightCells setObject:info forKey:[NSString stringWithFormat:@"%i", info.yPosition]];
cdcebdfb »
2011-02-20 Fix warnings found in the DCTKit project
494 }
a224b799 »
2010-02-10 Initial commit. Split out from DTKit.
495 }
496
497 if (![self cellInfoShouldBeOnShow:info])
498 [self removeCellWithInfo:info];
499
500 }
501
502 if (isGoingLeft) {
503 for (NSString *yPos in [leftRightCells allKeys]) {
504 DTGridViewCellInfo *info = [leftRightCells objectForKey:yPos];
505 [self checkRow:info.yPosition column:info.xPosition goingLeft:YES];
506 }
507
508 } else if (isGoingRight) {
509 for (NSString *yPos in [leftRightCells allKeys]) {
510 DTGridViewCellInfo *info = [leftRightCells objectForKey:yPos];
511 [self checkRow:info.yPosition column:info.xPosition goingLeft:NO];
512 }
513 }
514
515 if (isGoingUp)
516 [self checkNewRowStartingWithCellInfo:[orderedCells objectAtIndex:0] goingUp:YES];
517 else if (isGoingDown)
518 [self checkNewRowStartingWithCellInfo:[orderedCells lastObject] goingUp:NO];
519
520
521 [leftRightCells release];
522 [orderedCells release];
523 }
524
525 - (void)initialiseViews {
526
cdcebdfb »
2011-02-20 Fix warnings found in the DCTKit project
527 for (NSUInteger i = 0; i < [cellInfoForCellsOnScreen count]; i++) {
a224b799 »
2010-02-10 Initial commit. Split out from DTKit.
528
529 DTGridViewCellInfo *info = [cellInfoForCellsOnScreen objectAtIndex:i];
530
531 if (![self cellInfoShouldBeOnShow:info])
532 [self removeCellWithInfo:info];
533
534 }
535
cdcebdfb »
2011-02-20 Fix warnings found in the DCTKit project
536 for (NSUInteger i = 0; i < [gridCells count]; i++) {
a224b799 »
2010-02-10 Initial commit. Split out from DTKit.
537
538 NSMutableArray *row = [gridCells objectAtIndex:i];
539
cdcebdfb »
2011-02-20 Fix warnings found in the DCTKit project
540 for (NSUInteger j = 0; j < [row count]; j++) {
a224b799 »
2010-02-10 Initial commit. Split out from DTKit.
541
542 id object = [row objectAtIndex:j];
543
544 if ([object isMemberOfClass:[DTGridViewCellInfo class]]) {
545
546 DTGridViewCellInfo *info = (DTGridViewCellInfo *)object;
547
548 if ([self cellInfoShouldBeOnShow:info])
549 [self addCellWithInfo:info];
550
551 }
552 }
553 }
554 }
555
556 - (void)checkRow:(NSInteger)row column:(NSInteger)col goingLeft:(BOOL)goingLeft {
557
558 NSObject<DTGridViewCellInfoProtocol> *info = [self cellInfoForRow:row column:col];
559
560 if (!info) return;
561
562 if ([self cellInfoShouldBeOnShow:info])
563 [self addCellWithInfo:info];
564
565 if (goingLeft) {
566 if (info.frame.origin.x > self.contentOffset.x)
567 [self checkRow:row column:(col - 1) goingLeft:goingLeft];
568 } else {
569 if (info.frame.origin.x + info.frame.size.width < self.contentOffset.x + self.frame.size.width)
570 [self checkRow:row column:(col + 1) goingLeft:goingLeft];
571 }
572 }
573
cdcebdfb »
2011-02-20 Fix warnings found in the DCTKit project
574 - (NSObject<DTGridViewCellInfoProtocol> *)cellInfoForRow:(NSUInteger)row column:(NSUInteger)col {
a224b799 »
2010-02-10 Initial commit. Split out from DTKit.
575
576 if ([self.gridCells count] <= row) return nil;
577
578 NSArray *rowArray = [self.gridCells objectAtIndex:row];
579
580 if ([rowArray count] <= col) return nil;
581
582 return (NSObject<DTGridViewCellInfoProtocol> *)[rowArray objectAtIndex:col];
583 }
584
585 - (void)checkNewRowStartingWithCellInfo:(NSObject<DTGridViewCellInfoProtocol> *)info goingUp:(BOOL)goingUp {
586
0d0d422c »
2010-11-08 Only remove a subview if it is a grid view cell.
587 //NSLog(@"%@", info);
588
a224b799 »
2010-02-10 Initial commit. Split out from DTKit.
589 if (!info) return;
590
0d0d422c »
2010-11-08 Only remove a subview if it is a grid view cell.
591 if (![self rowOfCellInfoShouldBeOnShow:info]) return;
a224b799 »
2010-02-10 Initial commit. Split out from DTKit.
592
593 NSObject<DTGridViewCellInfoProtocol> *infoToCheck = info;
594
595 NSInteger row = info.yPosition;
596 NSInteger total = [[self.gridCells objectAtIndex:row] count];
597 NSInteger goingRightPosition = info.xPosition;
598 NSInteger goingLeftPosition = info.xPosition;
599 BOOL goingLeft = NO;
600
601 while (![self cellInfoShouldBeOnShow:infoToCheck]) {
602
603 goingLeft = !goingLeft;
604
605 if (goingLeft)
606 infoToCheck = [self cellInfoForRow:row column:--goingLeftPosition];
607 else
608 infoToCheck = [self cellInfoForRow:row column:++goingRightPosition];
609
610 if (goingRightPosition > total)
611 return;
612 }
613
614 if ([infoToCheck isEqual:info]) {
615 [self checkRow:infoToCheck.yPosition column:infoToCheck.xPosition goingLeft:YES];
616 [self checkRow:infoToCheck.yPosition column:infoToCheck.xPosition goingLeft:NO];
617 } else {
618 [self checkRow:infoToCheck.yPosition column:infoToCheck.xPosition goingLeft:goingLeft];
619 }
620
621 NSObject<DTGridViewCellInfoProtocol> *nextInfo = nil;
622
623 if (goingUp)
624 nextInfo = [self cellInfoForRow:info.yPosition - 1 column:info.xPosition];
625 else
626 nextInfo = [self cellInfoForRow:info.yPosition + 1 column:info.xPosition];
627
628 if (nextInfo)
629 [self checkNewRowStartingWithCellInfo:nextInfo goingUp:goingUp];
630 }
631
632 #pragma mark Public methods
633
634 - (DTGridViewCell *)dequeueReusableCellWithIdentifier:(NSString *)identifier {
635
636 for (DTGridViewCell *c in freeCells) {
637 if ([c.identifier isEqualToString:identifier]) {
638 [c retain];
639 [freeCells removeObject:c];
640 [c prepareForReuse];
641 return [c autorelease];
642 }
643 }
644
645 return nil;
646 }
647
cdcebdfb »
2011-02-20 Fix warnings found in the DCTKit project
648 - (DTGridViewCell *)cellForRow:(NSUInteger)rowIndex column:(NSUInteger)columnIndex {
19277e4b »
2010-03-10 Added a method to retrieve an onscreen cell for the index given posit…
649
650 for (UIView *v in self.subviews) {
651 if ([v isKindOfClass:[DTGridViewCell class]]) {
652 DTGridViewCell *c = (DTGridViewCell *)v;
653 if (c.xPosition == columnIndex && c.yPosition == rowIndex)
654 return c;
655 }
656 }
657
658 return nil;
659 }
660
cdcebdfb »
2011-02-20 Fix warnings found in the DCTKit project
661 - (void)scrollViewToRow:(NSUInteger)rowIndex column:(NSUInteger)columnIndex scrollPosition:(DTGridViewScrollPosition)position animated:(BOOL)animated {
a224b799 »
2010-02-10 Initial commit. Split out from DTKit.
662
991343a5 »
2010-10-21 variable initialisation to keep clang happy/quiet
663 CGFloat xPos = 0, yPos = 0;
a224b799 »
2010-02-10 Initial commit. Split out from DTKit.
664
665 CGRect cellFrame = [[[self.gridCells objectAtIndex:rowIndex] objectAtIndex:columnIndex] frame];
666
667 // working out x co-ord
668
669 if (position == DTGridViewScrollPositionTopLeft || position == DTGridViewScrollPositionMiddleLeft || position == DTGridViewScrollPositionBottomLeft)
670 xPos = cellFrame.origin.x;
671
672 else if (position == DTGridViewScrollPositionTopRight || position == DTGridViewScrollPositionMiddleRight || position == DTGridViewScrollPositionBottomRight)
673 xPos = cellFrame.origin.x + cellFrame.size.width - self.frame.size.width;
674
675 else if (position == DTGridViewScrollPositionTopCenter || position == DTGridViewScrollPositionMiddleCenter || position == DTGridViewScrollPositionBottomCenter)
676 xPos = (cellFrame.origin.x + (cellFrame.size.width / 2)) - (self.frame.size.width / 2);
677
678 else if (position == DTGridViewScrollPositionNone) {
679
680 BOOL isBig = NO;
681
682 if (cellFrame.size.width > self.frame.size.width)
683 isBig = YES;
684
685 if ((cellFrame.origin.x < self.contentOffset.x)
686 && ((cellFrame.origin.x + cellFrame.size.width) > (self.contentOffset.x + self.frame.size.width)))
687 xPos = self.contentOffset.x;
688
689 else if (cellFrame.origin.x < self.contentOffset.x)
690 if (isBig)
691 xPos = (cellFrame.origin.x + cellFrame.size.width) - self.frame.size.width;
692 else
693 xPos = cellFrame.origin.x;
694
695 else if ((cellFrame.origin.x + cellFrame.size.width) > (self.contentOffset.x + self.frame.size.width))
696 if (isBig)
697 xPos = cellFrame.origin.x;
698 else
699 xPos = (cellFrame.origin.x + cellFrame.size.width) - self.frame.size.width;
700 else
701 xPos = self.contentOffset.x;
702 }
703
704 // working out y co-ord
705
706 if (position == DTGridViewScrollPositionTopLeft || position == DTGridViewScrollPositionTopCenter || position == DTGridViewScrollPositionTopRight) {
707 yPos = cellFrame.origin.y;
708
709 } else if (position == DTGridViewScrollPositionBottomLeft || position == DTGridViewScrollPositionBottomCenter || position == DTGridViewScrollPositionBottomRight) {
710 yPos = cellFrame.origin.y + cellFrame.size.height - self.frame.size.height;
711
712 } else if (position == DTGridViewScrollPositionMiddleLeft || position == DTGridViewScrollPositionMiddleCenter || position == DTGridViewScrollPositionMiddleRight) {
713 yPos = (cellFrame.origin.y + (cellFrame.size.height / 2)) - (self.frame.size.height / 2);
714
715 } else if (position == DTGridViewScrollPositionNone) {
716 BOOL isBig = NO;
717
718 if (cellFrame.size.height > self.frame.size.height)
719 isBig = YES;
720
721 if ((cellFrame.origin.y < self.contentOffset.y)
722 && ((cellFrame.origin.y + cellFrame.size.height) > (self.contentOffset.y + self.frame.size.height)))
723 yPos = self.contentOffset.y;
724
725 else if (cellFrame.origin.y < self.contentOffset.y)
726 if (isBig)
727 yPos = (cellFrame.origin.y + cellFrame.size.height) - self.frame.size.height;
728 else
729 yPos = cellFrame.origin.y;
730 else if ((cellFrame.origin.y + cellFrame.size.height) > (self.contentOffset.y + self.frame.size.height))
731 if (isBig)
732 yPos = cellFrame.origin.y;
733 else
734 yPos = (cellFrame.origin.y + cellFrame.size.height) - self.frame.size.height;
735 else
736 yPos = self.contentOffset.y;
737 }
738
739 if (xPos == self.contentOffset.x && yPos == self.contentOffset.y)
740 return;
741
742 if (xPos > self.contentSize.width - self.frame.size.width)
743 xPos = self.contentSize.width - self.frame.size.width;
744 else if (xPos < 0)
cdcebdfb »
2011-02-20 Fix warnings found in the DCTKit project
745 xPos = 0.0f;
a224b799 »
2010-02-10 Initial commit. Split out from DTKit.
746
747 if (yPos > self.contentSize.height - self.frame.size.height)
748 yPos = self.contentSize.height - self.frame.size.height;
749 else if (yPos < 0)
cdcebdfb »
2011-02-20 Fix warnings found in the DCTKit project
750 yPos = 0.0f;
a224b799 »
2010-02-10 Initial commit. Split out from DTKit.
751
752 [self scrollRectToVisible:CGRectMake(xPos, yPos, self.frame.size.width, self.frame.size.height) animated:animated];
753
754 if (!animated)
755 [self checkViews];
756
37c92c00 »
2010-02-12 Modified the Grid View to not rely on being its own delegate. The pro…
757 if ([self.delegate respondsToSelector:@selector(gridView:didProgrammaticallyScrollToRow:column:)])
758 [self.delegate gridView:self didProgrammaticallyScrollToRow:rowIndex column:columnIndex];
a224b799 »
2010-02-10 Initial commit. Split out from DTKit.
759
760
761 }
762
cdcebdfb »
2011-02-20 Fix warnings found in the DCTKit project
763 - (void)selectRow:(NSUInteger)rowIndex column:(NSUInteger)columnIndex scrollPosition:(DTGridViewScrollPosition)position animated:(BOOL)animated {
a224b799 »
2010-02-10 Initial commit. Split out from DTKit.
764
765 for (UIView *v in self.subviews) {
766 if ([v isKindOfClass:[DTGridViewCell class]]) {
767 DTGridViewCell *c = (DTGridViewCell *)v;
768 if (c.xPosition == columnIndex && c.yPosition == rowIndex)
769 c.selected = YES;
770 else if (c.xPosition == columnIndexOfSelectedCell && c.yPosition == rowIndexOfSelectedCell)
771 c.selected = NO;
772 }
773 }
774 rowIndexOfSelectedCell = rowIndex;
775 columnIndexOfSelectedCell = columnIndex;
776
777 [self scrollViewToRow:rowIndex column:columnIndex scrollPosition:position animated:animated];
778 }
779
780 - (void)fireEdgeScroll {
781
782 if (self.pagingEnabled)
37c92c00 »
2010-02-12 Modified the Grid View to not rely on being its own delegate. The pro…
783 if ([self.delegate respondsToSelector:@selector(pagedGridView:didScrollToRow:column:)])
784 [self.delegate pagedGridView:self didScrollToRow:((NSInteger)(self.contentOffset.y / self.frame.size.height)) column:((NSInteger)(self.contentOffset.x / self.frame.size.width))];
a224b799 »
2010-02-10 Initial commit. Split out from DTKit.
785
37c92c00 »
2010-02-12 Modified the Grid View to not rely on being its own delegate. The pro…
786 if ([self.delegate respondsToSelector:@selector(gridView:scrolledToEdge:)]) {
a224b799 »
2010-02-10 Initial commit. Split out from DTKit.
787
788 if (self.contentOffset.x <= 0)
37c92c00 »
2010-02-12 Modified the Grid View to not rely on being its own delegate. The pro…
789 [self.delegate gridView:self scrolledToEdge:DTGridViewEdgeLeft];
a224b799 »
2010-02-10 Initial commit. Split out from DTKit.
790
791 if (self.contentOffset.x >= self.contentSize.width - self.frame.size.width)
37c92c00 »
2010-02-12 Modified the Grid View to not rely on being its own delegate. The pro…
792 [self.delegate gridView:self scrolledToEdge:DTGridViewEdgeRight];
a224b799 »
2010-02-10 Initial commit. Split out from DTKit.
793
794 if (self.contentOffset.y <= 0)
37c92c00 »
2010-02-12 Modified the Grid View to not rely on being its own delegate. The pro…
795 [self.delegate gridView:self scrolledToEdge:DTGridViewEdgeTop];
a224b799 »
2010-02-10 Initial commit. Split out from DTKit.
796
797 if (self.contentOffset.y >= self.contentSize.height - self.frame.size.height)
37c92c00 »
2010-02-12 Modified the Grid View to not rely on being its own delegate. The pro…
798 [self.delegate gridView:self scrolledToEdge:DTGridViewEdgeBottom];
a224b799 »
2010-02-10 Initial commit. Split out from DTKit.
799 }
800 }
801
802 - (void)gridViewCellWasTouched:(DTGridViewCell *)cell {
803
804 [self bringSubviewToFront:cell];
805
37c92c00 »
2010-02-12 Modified the Grid View to not rely on being its own delegate. The pro…
806 if ([self.delegate respondsToSelector:@selector(gridView:selectionMadeAtRow:column:)])
807 [self.delegate gridView:self selectionMadeAtRow:cell.yPosition column:cell.xPosition];
a224b799 »
2010-02-10 Initial commit. Split out from DTKit.
808 }
809
2ec82bdc »
2010-10-29 Changing to lazy load from accessor.
810
811 #pragma mark -
812 #pragma mark Accessors
813
814 - (NSInteger)numberOfRows {
c9e61398 »
2010-12-10 Fixed typo with numberOfRows in DTGridView.
815 if (numberOfRows == DTGridViewInvalid) {
2ec82bdc »
2010-10-29 Changing to lazy load from accessor.
816 numberOfRows = [self.dataSource numberOfRowsInGridView:self];
817 }
818
819 return numberOfRows;
820 }
821
a224b799 »
2010-02-10 Initial commit. Split out from DTKit.
822 @end
823
Something went wrong with that request. Please try again.