Much improved but still unbearable CPTableView

This commit is contained in:
tlrobinson committed 2009-03-02 20:07:52 -08:00
1 parent 3200f1c6ca
commit 1188da3c21
2 files changed
+143 -117

No files matched your search

+23 -11
View File
@@ -350,8 +350,11 @@ CPTableColumnUserResizingMask;
_purgableInfosForDataView[dataViewHash] = {};
}
if (!isPurgable)
delete _purgableInfosForDataView[dataViewHash][viewHash];
if (!isPurgable) {
if (_purgableInfosForDataView[dataViewHash][viewHash])
CPLog.warn("removing unpurgable " + _purgableInfosForDataView[dataViewHash][viewHash]);
delete _purgableInfosForDataView[dataViewHash][viewHash];
}
else
_purgableInfosForDataView[dataViewHash][viewHash] = PurgableInfoMake(aView, aRow);
}
@@ -367,12 +370,14 @@ CPTableColumnUserResizingMask;
for (var key in purgableInfos)
{
var info = purgableInfos[key];
if (!CPLocationInRange(PurgableInfoRow(info), rows))
{
//if (!CPLocationInRange(PurgableInfoRow(info), rows))
//{
//CPLog.debug("yes, a purged view is usable, its called: " + PurgableInfoView(info));
delete purgableInfos[key];
return PurgableInfoView(info);
}
//}
//else
// CPLog.warn("avoiding");
}
}
@@ -386,7 +391,7 @@ CPTableColumnUserResizingMask;
// map the new view's hash to it's data view prototype
_dataViewForView[[newView hash]] = view;
//CPLog.warn("nope, time for creation: %s", newView);
CPLog.warn("creating cell: %s", newView);
return newView;
}
@@ -400,11 +405,18 @@ CPTableColumnUserResizingMask;
for (var key in purgableInfos)
{
var view = PurgableInfoView(purgableInfos[key]);
//CPLog.error("PURGING: " + view);
[view removeFromSuperview];
delete purgableInfos[key];
if (!view)
CPLog.info("key="+key+" view=" + view + " purgableInfos[key]="+purgableInfos[key])
else if (view._superview) {
//CPLog.error("PURGING: (removing)" + view);
//[view removeFromSuperview];
[view setHidden:YES];
}
//else
// CPLog.warn("PURGING: (already removed)" + view);
//delete purgableInfos[key];
}
}
}
+120 -106
View File
@@ -83,7 +83,7 @@ var _CPTableViewWillDisplayCellSelector = 1 << 0,
//CPScrollView _scrollView;
unsigned _numberOfRows;
unsigned _numberOfColumns;
//unsigned _numberOfColumns;
BOOL _hasVariableHeightRows;
@@ -114,6 +114,8 @@ var _CPTableViewWillDisplayCellSelector = 1 << 0,
CPIndexSet _currentlySelected;
CPArray _selectionViews;
CPArray _selectionViewsPool;
CPDate _scrollTimer;
}
+ (void)initialize
@@ -136,7 +138,7 @@ var _CPTableViewWillDisplayCellSelector = 1 << 0,
- (void)_init
{
_tableColumns = [];
_numberOfColumns = 0;
//_numberOfColumns = 0;
_selectedRowIndexes = [CPIndexSet indexSet];
@@ -231,7 +233,7 @@ var _CPTableViewWillDisplayCellSelector = 1 << 0,
visibleRows = CPMakeRange(rowStart, rowEnd - rowStart),
columnStart = MAX(0, [self _columnAtX:CGRectGetMinX(aRect)]),
columnEnd = MIN(_numberOfColumns, [self _columnAtX:CGRectGetMaxX(aRect)] + 1),
columnEnd = MIN(_tableColumns.length, [self _columnAtX:CGRectGetMaxX(aRect)] + 1),
visibleColumns = CPMakeRange(columnStart, columnEnd - columnStart);
@@ -241,102 +243,111 @@ var _CPTableViewWillDisplayCellSelector = 1 << 0,
var unionVisibleRows = CPUnionRange(_visibleRows, visibleRows),
unionVisibleColumns = CPUnionRange(_visibleColumns, visibleColumns);
// Determine whether to use 2 sweeps or one. If we have lots of overlap of cells, use just one.
//if (unionVisibleRows.length * unionVisibleColumns.length <=
// (_visibleRows.length * _visibleColumns.length) + (visibleRows.length * visibleColumns.length))
//{
var column = unionVisibleColumns.location,
columnEnd = CPMaxRange(unionVisibleColumns),
rowStart = unionVisibleRows.location,
rowEnd = CPMaxRange(unionVisibleRows);
for (; column < columnEnd; ++column)
if (unionVisibleRows.length * unionVisibleColumns.length <=
(_visibleRows.length * _visibleColumns.length) + (visibleRows.length * visibleColumns.length))
{
//CPLog.info("single sweep");
var cEnd = CPMaxRange(unionVisibleColumns),
rEnd = CPMaxRange(unionVisibleRows),
cell;
for (var column = unionVisibleColumns.location; column < cEnd; ++column)
{
var row = rowStart,
tableColumn = _tableColumns[column],
var tableColumn = _tableColumns[column],
tableColumnCells = _tableCells[column],
columnIsVisible = CPLocationInRange(column, visibleColumns);
for (; row < rowEnd; ++row)
columnIsVisible = CPLocationInRange(column, visibleColumns),
newCells = [];
for (var row = unionVisibleRows.location; row < rEnd; ++row)
{
var cell = tableColumnCells[row];
if (cell)
if (cell = tableColumnCells[row])
{
if (columnIsVisible && CPLocationInRange(row, visibleRows))
[tableColumn _markView:cell inRow:row asPurgable:NO];
else {
//!!!
if (!columnIsVisible || !CPLocationInRange(row, visibleRows))
{
tableColumnCells[row] = nil;
[tableColumn _markView:cell inRow:row asPurgable:YES];
}
}
else
{
// ASSERT(CPLocationInRange(row, visibleRows) && CPLocationInRange(column, visibleColumns))
tableColumnCells[row] = [self newCellForRow:row column:column avoidingRows:visibleRows];
[_tableColumnViews[column] addSubview:tableColumnCells[row]];
newCells.push(row);
}
}
while (newCells.length > 0)
{
var row = newCells.pop();
tableColumnCells[row] = [self newCellForRow:row column:column avoidingRows:visibleRows];
if (!tableColumnCells[row]._superview)
[_tableColumnViews[column] addSubview:tableColumnCells[row]];
else if (tableColumnCells[row]._isHidden)
[tableColumnCells[row] setHidden:NO];
}
[tableColumn _purge];
}
}
else {
//CPLog.info("double sweep");
// first sweep: remove old cells
var cEnd = CPMaxRange(_visibleColumns),
rEnd = CPMaxRange(_visibleRows),
cell;
for (var column = _visibleColumns.location; column < cEnd; ++column)
{
var tableColumn = _tableColumns[column],
tableColumnCells = _tableCells[column],
columnIsVisible = CPLocationInRange(column, visibleColumns);
for (var row = _visibleRows.location; row < rEnd; ++row)
{
if (cell = tableColumnCells[row])
{
if (!columnIsVisible || !CPLocationInRange(row, visibleRows))
{
tableColumnCells[row] = nil;
[tableColumn _markView:cell inRow:row asPurgable:YES];
}
}
}
}
// second sweep: add new cells
var cEnd = CPMaxRange(visibleColumns),
rEnd = CPMaxRange(visibleRows);
for (var column = visibleColumns.location; column < cEnd; ++column)
{
var tableColumn = _tableColumns[column],
tableColumnCells = _tableCells[column];
for (var row = visibleRows.location; row < rEnd; ++row)
{
tableColumnCells[row] = [self newCellForRow:row column:column avoidingRows:visibleRows];
if (!tableColumnCells[row]._superview)
[_tableColumnViews[column] addSubview:tableColumnCells[row]];
else if (tableColumnCells[row]._isHidden)
[tableColumnCells[row] setHidden:NO];
}
[tableColumn _purge];
}
//}
//else
// CPLog.error("CPTable double sweep not implemented");
}
_visibleRows = visibleRows;
_visibleColumns = visibleColumns;
/*
var column = columnStart;
for (; column < _numberOfColumns && CGRectIntersectsRect([_tableColumnViews[column] frame], aRect); ++column)
{
var row = rowStart,
tableColumn = _tableColumns[column];
for (; row < rowEnd; ++row)
{
//if (CPLocationInRange(row, _visibleRows))
// continue;
var cell = _tableCells[column][row];
if (cell)
[tableColumn _markView:cell inRow:row asPurgable:NO];
else
_tableCells[column][row] = [self newCellForRow:row column:column avoidingRows:visibleRows];
}
}
var visibleRows = visibleRowsCPMakeRange(rowStart, rowEnd - rowStart),
visibleColumns = CPMakeRange(columnStart, rememberColumn - columnStart);
var columnEnd = CPMaxRange(_visibelColumns);
for (column = _visibleColumns.location; column < columnEnd; ++column)
{
var tableColumn = _tableColumns[tableColumn],
tableColumnCells = _tableCells[column];
for (row = _visibleRows.location, rowEnd = CPMaxRange(_visibleRows); row < rowEnd; ++row)
if (!CPLocationInRange(row, visibleRows) || !CPLocationInRange(column, visibleColumns))
{
var view = tableColumnCells[row];
if (view)
[tableColumn _markView:view inRow:row asPurgable:YES];
}
}
_visibleRows = visibleRows;
_visibleColumns = visibleColumns;*/
}
// Setting display attributes
@@ -352,7 +363,7 @@ var _CPTableViewWillDisplayCellSelector = 1 << 0,
delta = aSize.width - _intercellSpacing.width;
total = delta;
for (; i < _numberOfColumns; ++i, total += delta)
for (; i < _tableColumns.length; ++i, total += delta)
{
var origin = [_tableColumnViews[i] frame].origin;
[_tableColumnViews[i] setFrameOrigin:CGPointMake(origin.x + total, origin.y)];
@@ -363,7 +374,7 @@ var _CPTableViewWillDisplayCellSelector = 1 << 0,
{
var i = 0;
for (; i < _numberOfColumns; ++i, total += delta)
for (; i < _tableColumns.length; ++i, total += delta)
{
[_tableColumnViews[i] setFrameSize:CGSizeMake([_tableColumnViews[i] width], _numberOfRows * (_rowHeight + _intercellSpacing.height))];
@@ -410,7 +421,7 @@ var _CPTableViewWillDisplayCellSelector = 1 << 0,
return;
for (var row = 0; row < _numberOfRows; ++row)
for (var column = 0; column < _numberOfColumns; ++column)
for (var column = 0; column < _tableColumns.length; ++column)
[_tableCells[column][row] setFrameOrigin:CPPointMake(0.0, row * (_rowHeight + _intercellSpacing.height))];
}
@@ -429,7 +440,7 @@ var _CPTableViewWillDisplayCellSelector = 1 << 0,
- (void)addTableColumn:(CPTableColumn)aTableColumn
{
var i = 0,
x = _numberOfColumns ? CPRectGetMaxX([self rectOfColumn:_numberOfColumns - 1]) + _intercellSpacing.width : 0.0,
x = _tableColumns.length ? CPRectGetMaxX([self rectOfColumn:_tableColumns.length - 1]) + _intercellSpacing.width : 0.0,
tableColumnView = [[CPView alloc] initWithFrame:CPRectMake(x, 0.0, [aTableColumn width], [self _columnHeight])],
tableColumnCells = [];
@@ -444,9 +455,9 @@ var _CPTableViewWillDisplayCellSelector = 1 << 0,
// TODO: do we really need to initialize this, or is undefined good enough?
for (; i < _numberOfRows; ++i)
_tableCells[_numberOfColumns][i] = nil;
_tableCells[_tableColumns.length-1][i] = nil;
++_numberOfColumns;
//++_numberOfColumns;
}
/*
@@ -467,7 +478,7 @@ var _CPTableViewWillDisplayCellSelector = 1 << 0,
[_tabelColumnViews removeObjectAtIndex:index];
// Shift remaining column views to the left.
for (; index < _numberOfColumns; ++ index)
for (; index < _tableColumns.length; ++ index)
[_tableColumnViews[index] setFrameOrigin:CPPointMake(CPRectGetMinX([_tableColumnViews[index] frame]) - width, 0.0)]
// Resize ourself.
@@ -513,7 +524,7 @@ var _CPTableViewWillDisplayCellSelector = 1 << 0,
*/
- (int)numberOfColumns
{
return _numberOfColumns;
return _tableColumns.length;
}
/*
@@ -731,21 +742,23 @@ var _CPTableViewWillDisplayCellSelector = 1 << 0,
[self clearCells];
[self setNeedsDisplay:YES];
[self setNeedsLayout];
}
- (void)viewWillDraw
- (void)layoutSubviews
{
[self loadTableCellsInRect:[self visibleRectInParent]];
}
- (void)drawRect:(CGRect)aRect
{
}
- (void)displaySoon
{
// window.setTimeout();
[_scrollTimer invalidate];
_scrollTimer = [CPTimer scheduledTimerWithTimeInterval:0.05 target:self selector:@selector(displayNow) userInfo:nil repeats:NO];
}
- (void)displayNow
{
[self setNeedsLayout];
}
- (void)viewDidMoveToSuperview
@@ -761,9 +774,10 @@ var _CPTableViewWillDisplayCellSelector = 1 << 0,
- (void)viewBoundsChanged:(CPNotification)aNotification
{
//console.warn(_cmd + CPStringFromRect([[[self enclosingScrollView] contentView] bounds]));
//CPLog.info(_cmd + CPStringFromRect([[[self enclosingScrollView] contentView] bounds]));
//objj_debug_print_backtrace();
[self setNeedsDisplay:YES];
//[self setNeedsLayout];
[self displayNow];
}
/*
@@ -850,7 +864,7 @@ var _CPTableViewWillDisplayCellSelector = 1 << 0,
{
var index = [self _columnAtX:aPoint.x]
if (index >= 0 && index < _numberOfColumns)
if (index >= 0 && index < _tableColumns.length)
return index;
else
return CPNotFound;
@@ -901,21 +915,21 @@ var _CPTableViewWillDisplayCellSelector = 1 << 0,
- (int)_columnAtX:(float)y
{
var a = 0,
b = _numberOfColumns;
b = _tableColumns.length;
var last = [_tableColumnViews[_numberOfColumns-1] frame];
var last = [_tableColumnViews[_tableColumns.length-1] frame];
if (y < [_tableColumnViews[0] frame].origin.x)
return -1;
if (y >= last.origin.x + last.size.width)
return _numberOfColumns;
return _tableColumns.length;
// binary search
while (true)
{
var half = a + Math.floor((b - a) / 2);
if (half === _numberOfColumns - 1)
return _numberOfColumns - 1;
if (half === _tableColumns.length - 1)
return _tableColumns.length - 1;
if (y >= [_tableColumnViews[half+1] frame].origin.x)
a = half;
@@ -1157,14 +1171,14 @@ var _CPTableViewWillDisplayCellSelector = 1 << 0,
for (var i = 0; i < indexesToRemove.length; i++)
{
var row = indexesToRemove[i];
for (var column = 0; column < _numberOfColumns; column++)
for (var column = 0; column < _tableColumns.length; column++)
if ([_tableCells[column][row] respondsToSelector:@selector(highlight:)])
[_tableCells[column][row] highlight:NO];
}
for (var i = 0; i < indexesToAdd.length; i++)
{
var row = indexesToAdd[i];
for (var column = 0; column < _numberOfColumns; column++)
for (var column = 0; column < _tableColumns.length; column++)
if ([_tableCells[column][row] respondsToSelector:@selector(highlight:)])
[_tableCells[column][row] highlight:YES];
}
@@ -1284,4 +1298,4 @@ var CPTableViewDataSourceKey = @"CPTableViewDataSourceKey",
return [[CPColor alloc] _initWithRGBA:[0.83, 0.83, 0.83, 1.0]];
}
@end
@end