94 #define NUMBER_OF_COLUMNS() (_tableColumns.length)
95 #define UPDATE_COLUMN_RANGES_IF_NECESSARY() if (_dirtyTableColumnRangeIndex !== CPNotFound) [self _recalculateTableColumnRanges];
98 @implementation _CPTableDrawView :
CPView
108 _tableView = aTableView;
113 - (void)drawRect:(CGRect)aRect
115 var
frame = [
self frame],
120 [_tableView _drawRect:aRect];
151 CPInteger _implementedDataSourceMethods;
154 CPInteger _implementedDelegateMethods;
158 CPInteger _dirtyTableColumnRangeIndex;
159 CPInteger _numberOfHiddenColumns;
162 Object _objectValues;
168 Object _dataViewsForTableColumns;
169 Object _cachedDataViews;
172 BOOL _allowsColumnReordering;
173 BOOL _allowsColumnResizing;
174 BOOL _allowsColumnSelection;
175 BOOL _allowsMultipleSelection;
176 BOOL _allowsEmptySelection;
181 CGSize _intercellSpacing;
184 BOOL _usesAlternatingRowBackgroundColors;
185 CPArray _alternatingRowBackgroundColors;
187 unsigned _selectionHighlightStyle;
189 unsigned _gridStyleMask;
191 unsigned _numberOfRows;
198 BOOL _autosaveTableColumns;
201 _CPCornerView _cornerView;
205 CPInteger _selectionAnchorRow;
206 CPInteger _lastSelectedRow;
208 CGPoint _startTrackingPoint;
209 CPDate _startTrackingTimestamp;
210 BOOL _trackingPointMovedOutOfClickSlop;
211 CGPoint _editingCellIndex;
213 _CPTableDrawView _tableDrawView;
216 CPInteger _clickedRow;
217 CPInteger _clickedColumn;
218 unsigned _columnAutoResizingStyle;
220 int _lastTrackedRowIndex;
221 CGPoint _originalMouseDownPoint;
222 BOOL _verticalMotionCanDrag;
223 unsigned _destinationDragStyle;
224 BOOL _isSelectingSession;
226 BOOL _wasSelectionBroken;
228 _CPDropOperationDrawingView _dropOperationFeedbackView;
229 CPDragOperation _dragOperationDefaultMask;
230 int _retargetedDropRow;
231 CPDragOperation _retargetedDropOperation;
233 BOOL _disableAutomaticResizing;
234 BOOL _lastColumnShouldSnap;
235 BOOL _implementsCustomDrawRow;
236 BOOL _contentBindingExpicitelySet;
239 CPArray _differedColumnDataToRemove;
253 + (id)themeAttributes
256 forKeys:["alternating-row-colors", "grid-color", "highlighted-grid-color", "selection-color", "sourcelist-selection-color", "sort-image", "sort-image-reversed", "selection-radius"]];
259 - (id)initWithFrame:(CGRect)aFrame
266 _allowsColumnReordering = YES;
267 _allowsColumnResizing = YES;
268 _allowsMultipleSelection = NO;
269 _allowsEmptySelection = YES;
270 _allowsColumnSelection = NO;
271 _disableAutomaticResizing = NO;
281 _tableColumnRanges = [];
283 _numberOfHiddenColumns = 0;
285 _intercellSpacing = _CGSizeMake(3.0, 2.0);
294 _currentHighlightedTableColumn = nil;
297 _verticalMotionCanDrag = YES;
298 _isSelectingSession = NO;
299 _retargetedDropRow = nil;
300 _retargetedDropOperation = nil;
301 _dragOperationDefaultMask = nil;
303 _contentBindingExpicitelySet = NO;
320 _lastSelectedRow = _clickedColumn = _clickedRow = -1;
325 _dropOperationFeedbackView = [[_CPDropOperationDrawingView alloc] initWithFrame:_CGRectMakeZero()];
326 [_dropOperationFeedbackView setTableView:self];
328 _lastColumnShouldSnap = NO;
330 if (!_alternatingRowBackgroundColors)
333 _tableColumnRanges = [];
334 _dirtyTableColumnRangeIndex = 0;
335 _numberOfHiddenColumns = 0;
338 _dataViewsForTableColumns = { };
342 _cachedDataViews = { };
344 _cachedRowHeights = [];
348 _tableDrawView = [[_CPTableDrawView alloc] initWithTableView:self];
350 [
self addSubview:_tableDrawView];
352 _draggedColumn = nil;
359 _differedColumnDataToRemove = [];
360 _implementsCustomDrawRow = [
self implementsSelector:@selector(drawRow:clipRect:)];
362 if (!_sortDescriptors)
363 _sortDescriptors = [];
431 - (void)setDataSource:(
id)aDataSource
433 if (_dataSource === aDataSource)
436 _dataSource = aDataSource;
437 _implementedDataSourceMethods = 0;
444 if ([_dataSource respondsToSelector:
@selector(numberOfRowsInTableView:)])
447 if ([_dataSource respondsToSelector:
@selector(
tableView:objectValueForTableColumn:row:)])
450 if ([_dataSource respondsToSelector:
@selector(
tableView:setObjectValue:forTableColumn:row:)])
453 if ([_dataSource respondsToSelector:
@selector(
tableView:acceptDrop:row:dropOperation:)])
456 if ([_dataSource respondsToSelector:
@selector(
tableView:namesOfPromisedFilesDroppedAtDestination:forDraggedRowsWithIndexes:)])
459 if ([_dataSource respondsToSelector:
@selector(
tableView:validateDrop:proposedRow:proposedDropOperation:)])
462 if ([_dataSource respondsToSelector:
@selector(
tableView:writeRowsWithIndexes:toPasteboard:)])
465 if ([_dataSource respondsToSelector:
@selector(
tableView:sortDescriptorsDidChange:)])
501 _reloadAllRows = YES;
503 _cachedRowHeights = [];
508 [_groupRows removeAllIndexes];
524 - (void)setDoubleAction:(
SEL)anAction
526 _doubleAction = anAction;
534 return _doubleAction;
540 - (CPInteger)clickedColumn
542 return _clickedColumn;
548 - (CPInteger)clickedRow
558 - (void)setAllowsColumnReordering:(BOOL)shouldAllowColumnReordering
560 _allowsColumnReordering = !!shouldAllowColumnReordering;
566 - (BOOL)allowsColumnReordering
568 return _allowsColumnReordering;
575 - (void)setAllowsColumnResizing:(BOOL)shouldAllowColumnResizing
577 _allowsColumnResizing = !!shouldAllowColumnResizing;
583 - (BOOL)allowsColumnResizing
585 return _allowsColumnResizing;
592 - (void)setAllowsMultipleSelection:(BOOL)shouldAllowMultipleSelection
594 _allowsMultipleSelection = !!shouldAllowMultipleSelection;
602 - (BOOL)allowsMultipleSelection
604 return _allowsMultipleSelection;
611 - (void)setAllowsEmptySelection:(BOOL)shouldAllowEmptySelection
613 _allowsEmptySelection = !!shouldAllowEmptySelection;
619 - (BOOL)allowsEmptySelection
621 return _allowsEmptySelection;
629 - (void)setAllowsColumnSelection:(BOOL)shouldAllowColumnSelection
631 _allowsColumnSelection = !!shouldAllowColumnSelection;
638 - (BOOL)allowsColumnSelection
640 return _allowsColumnSelection;
650 - (void)setIntercellSpacing:(CGSize)aSize
652 if (_CGSizeEqualToSize(_intercellSpacing, aSize))
655 _intercellSpacing = _CGSizeMakeCopy(aSize);
657 _dirtyTableColumnRangeIndex = 0;
658 [
self _recalculateTableColumnRanges];
661 [_headerView setNeedsDisplay:YES];
662 [_headerView setNeedsLayout];
670 - (CGSize)intercellSpacing
672 return _CGSizeMakeCopy(_intercellSpacing);
681 - (void)setRowHeight:(
unsigned)aRowHeight
684 aRowHeight = +aRowHeight;
686 if (_rowHeight === aRowHeight)
689 _rowHeight = MAX(0.0, aRowHeight);
697 - (unsigned)rowHeight
707 - (void)setUsesAlternatingRowBackgroundColors:(BOOL)shouldUseAlternatingRowBackgroundColors
709 _usesAlternatingRowBackgroundColors = shouldUseAlternatingRowBackgroundColors;
715 - (BOOL)usesAlternatingRowBackgroundColors
717 return _usesAlternatingRowBackgroundColors;
725 - (void)setAlternatingRowBackgroundColors:(
CPArray)alternatingRowBackgroundColors
751 - (unsigned)selectionHighlightStyle
753 return _selectionHighlightStyle;
767 - (void)setSelectionHighlightStyle:(
unsigned)aSelectionHighlightStyle
769 _selectionHighlightStyle = aSelectionHighlightStyle;
783 - (void)setSelectionHighlightColor:(
CPColor)aColor
853 - (void)setGridStyleMask:(
unsigned)aGrideStyleMask
855 if (_gridStyleMask === aGrideStyleMask)
858 _gridStyleMask = aGrideStyleMask;
866 - (unsigned)gridStyleMask
868 return _gridStyleMask;
879 [_tableColumns addObject:aTableColumn];
882 if (_dirtyTableColumnRangeIndex < 0)
885 _dirtyTableColumnRangeIndex = MIN(
NUMBER_OF_COLUMNS() - 1, _dirtyTableColumnRangeIndex);
887 if ([[
self sortDescriptors] count] > 0)
891 if (aTableColumn === [
self _tableColumnForSortDescriptor:mainSortDescriptor])
893 var image = [mainSortDescriptor ascending] ? [
self _tableHeaderSortImage] : [
self _tableHeaderReverseSortImage];
911 var index = [_tableColumns indexOfObjectIdenticalTo:aTableColumn];
917 [_differedColumnDataToRemove addObject:{"column":aTableColumn, "shouldBeHidden": [aTableColumn
isHidden]}];
922 var tableColumnUID = [aTableColumn
UID];
924 if (_objectValues[tableColumnUID])
925 _objectValues[tableColumnUID] = nil;
927 if (_dirtyTableColumnRangeIndex < 0)
928 _dirtyTableColumnRangeIndex = index;
930 _dirtyTableColumnRangeIndex = MIN(index, _dirtyTableColumnRangeIndex);
941 if (_draggedColumn === aColumn)
944 _draggedColumn = aColumn;
953 - (void)_moveColumn:(
unsigned)fromIndex toColumn:(
unsigned)toIndex
956 fromIndex = +fromIndex;
959 if (fromIndex === toIndex)
962 if (_dirtyTableColumnRangeIndex < 0)
963 _dirtyTableColumnRangeIndex = MIN(fromIndex, toIndex);
965 _dirtyTableColumnRangeIndex = MIN(fromIndex, toIndex, _dirtyTableColumnRangeIndex);
967 var tableColumn = _tableColumns[fromIndex];
969 [_tableColumns removeObjectAtIndex:fromIndex];
970 [_tableColumns insertObject:tableColumn atIndex:toIndex];
972 [[
self headerView] setNeedsLayout];
973 [[
self headerView] setNeedsDisplay:YES];
978 [
self reloadDataForRowIndexes:rowIndexes columnIndexes:columnIndexes];
985 forKeys:[@"CPOldColumn", @"CPNewColumn"]]];
993 - (void)moveColumn:(
int)theColumnIndex toColumn:(
int)theToIndex
995 [
self _moveColumn:theColumnIndex toColumn:theToIndex];
1003 - (void)_tableColumnVisibilityDidChange:(
CPTableColumn)aColumn
1005 var columnIndex = [[
self tableColumns] indexOfObjectIdenticalTo:aColumn];
1007 if (_dirtyTableColumnRangeIndex < 0)
1008 _dirtyTableColumnRangeIndex = columnIndex;
1010 _dirtyTableColumnRangeIndex = MIN(columnIndex, _dirtyTableColumnRangeIndex);
1012 [[
self headerView] setNeedsLayout];
1013 [[
self headerView] setNeedsDisplay:YES];
1024 return _tableColumns;
1033 - (CPInteger)columnWithIdentifier:(
CPString)anIdentifier
1038 for (; index < count; ++index)
1039 if ([_tableColumns[index] identifier] === anIdentifier)
1058 return _tableColumns[index];
1077 - (void)selectColumnIndexes:(
CPIndexSet)columns byExtendingSelection:(BOOL)shouldExtendSelection
1080 if (([columns firstIndex] !=
CPNotFound && [columns firstIndex] < 0) || [columns lastIndex] >= [
self numberOfColumns])
1084 if ([_selectedRowIndexes count] > 0)
1086 [
self _updateHighlightWithOldRows:_selectedRowIndexes newRows:[
CPIndexSet indexSet]];
1090 var previousSelectedIndexes = [_selectedColumnIndexes copy];
1092 if (shouldExtendSelection)
1093 [_selectedColumnIndexes addIndexes:columns];
1095 _selectedColumnIndexes = [columns
copy];
1097 [
self _updateHighlightWithOldColumns:previousSelectedIndexes newColumns:_selectedColumnIndexes];
1101 [_headerView setNeedsDisplay:YES];
1103 [
self _noteSelectionDidChange];
1109 - (void)_setSelectedRowIndexes:(
CPIndexSet)rows
1111 if ([_selectedRowIndexes isEqualToIndexSet:rows])
1114 var previousSelectedIndexes = _selectedRowIndexes;
1116 _lastSelectedRow = ([rows count] > 0) ? [rows lastIndex] : -1;
1117 _selectedRowIndexes = [rows copy];
1119 [
self _updateHighlightWithOldRows:previousSelectedIndexes newRows:_selectedRowIndexes];
1120 [
self setNeedsDisplay:YES];
1123 var binderClass = [[
self class] _binderClassForBinding:@"selectionIndexes"];
1124 [[binderClass getBinding:@"selectionIndexes" forObject:self] reverseSetValueFor:@"selectedRowIndexes"];
1126 [
self _noteSelectionDidChange];
1135 - (void)selectRowIndexes:(
CPIndexSet)rows byExtendingSelection:(BOOL)shouldExtendSelection
1137 if ([rows isEqualToIndexSet:_selectedRowIndexes] ||
1138 (([rows firstIndex] !=
CPNotFound && [rows firstIndex] < 0) || [rows lastIndex] >= [
self numberOfRows]))
1142 if ([_selectedColumnIndexes count] > 0)
1144 [
self _updateHighlightWithOldColumns:_selectedColumnIndexes newColumns:[
CPIndexSet indexSet]];
1147 [_headerView setNeedsDisplay:YES];
1150 var newSelectedIndexes;
1151 if (shouldExtendSelection)
1153 newSelectedIndexes = [_selectedRowIndexes copy];
1154 [newSelectedIndexes addIndexes:rows];
1157 newSelectedIndexes = [rows
copy];
1159 [
self _setSelectedRowIndexes:newSelectedIndexes];
1167 var firstExposedRow = [_exposedRows firstIndex],
1168 exposedLength = [_exposedRows lastIndex] - firstExposedRow + 1,
1171 deselectRowIndexes = [oldRows copy],
1172 selectRowIndexes = [newRows copy];
1174 [deselectRowIndexes removeMatches:selectRowIndexes];
1175 [deselectRowIndexes getIndexes:deselectRows maxCount:-1 inIndexRange:CPMakeRange(firstExposedRow, exposedLength)];
1176 [selectRowIndexes getIndexes:selectRows maxCount:-1 inIndexRange:CPMakeRange(firstExposedRow, exposedLength)];
1178 for (var identifier in _dataViewsForTableColumns)
1180 var dataViewsInTableColumn = _dataViewsForTableColumns[identifier],
1181 count = deselectRows.length;
1183 [
self _performSelection:NO forRow:deselectRows[count] context:dataViewsInTableColumn];
1185 count = selectRows.length;
1187 [
self _performSelection:YES forRow:selectRows[count] context:dataViewsInTableColumn];
1194 - (void)_performSelection:(BOOL)select forRow:(CPInteger)rowIndex context:(
id)context
1196 var view = context[rowIndex],
1197 selector = select ?
@"setThemeState:" :
@"unsetThemeState:";
1199 [view performSelector:CPSelectorFromString(selector) withObject:CPThemeStateSelectedDataView];
1205 - (void)_updateHighlightWithOldColumns:(
CPIndexSet)oldColumns newColumns:(
CPIndexSet)newColumns
1207 var firstExposedColumn = [_exposedColumns firstIndex],
1208 exposedLength = [_exposedColumns lastIndex] - firstExposedColumn +1,
1209 deselectColumns = [],
1211 deselectColumnIndexes = [oldColumns copy],
1212 selectColumnIndexes = [newColumns copy],
1215 [deselectColumnIndexes removeMatches:selectColumnIndexes];
1216 [deselectColumnIndexes getIndexes:deselectColumns maxCount:-1 inIndexRange:CPMakeRange(firstExposedColumn, exposedLength)];
1217 [selectColumnIndexes getIndexes:selectColumns maxCount:-1 inIndexRange:CPMakeRange(firstExposedColumn, exposedLength)];
1218 [_exposedRows getIndexes:selectRows maxCount:-1 inIndexRange:nil];
1220 var rowsCount = selectRows.length,
1221 count = deselectColumns.length;
1224 var columnIndex = deselectColumns[count],
1225 identifier = [_tableColumns[columnIndex] UID],
1226 dataViewsInTableColumn = _dataViewsForTableColumns[identifier];
1228 for (var i = 0; i < rowsCount; i++)
1230 var rowIndex = selectRows[i],
1231 dataView = dataViewsInTableColumn[rowIndex];
1232 [dataView unsetThemeState:CPThemeStateSelectedDataView];
1237 var headerView = [_tableColumns[columnIndex] headerView];
1238 [headerView unsetThemeState:CPThemeStateSelected];
1242 count = selectColumns.length;
1245 var columnIndex = selectColumns[count],
1246 identifier = [_tableColumns[columnIndex] UID],
1247 dataViewsInTableColumn = _dataViewsForTableColumns[identifier];
1249 for (var i = 0; i < rowsCount; i++)
1251 var rowIndex = selectRows[i],
1252 dataView = dataViewsInTableColumn[rowIndex];
1253 [dataView setThemeState:CPThemeStateSelectedDataView];
1257 var headerView = [_tableColumns[columnIndex] headerView];
1258 [headerView setThemeState:CPThemeStateSelected];
1266 - (int)selectedColumn
1268 return [_selectedColumnIndexes lastIndex];
1276 return _selectedColumnIndexes;
1284 return _lastSelectedRow;
1292 return [_selectedRowIndexes copy];
1300 - (void)deselectColumn:(CPInteger)anIndex
1302 var selectedColumnIndexes = [_selectedColumnIndexes copy];
1305 [
self _noteSelectionDidChange];
1313 - (void)deselectRow:(CPInteger)aRow
1315 var selectedRowIndexes = [_selectedRowIndexes copy];
1318 [
self _noteSelectionDidChange];
1324 - (CPInteger)numberOfSelectedColumns
1326 return [_selectedColumnIndexes count];
1332 - (CPInteger)numberOfSelectedRows
1334 return [_selectedRowIndexes count];
1343 - (BOOL)isColumnSelected:(CPInteger)anIndex
1345 return [_selectedColumnIndexes containsIndex:anIndex];
1354 - (BOOL)isRowSelected:(CPInteger)aRow
1356 return [_selectedRowIndexes containsIndex:aRow];
1372 - (int)numberOfColumns
1382 if (_numberOfRows !== nil)
1383 return _numberOfRows;
1387 if (contentBindingInfo)
1389 var destination = [contentBindingInfo objectForKey:CPObservedObjectKey],
1390 keyPath = [contentBindingInfo objectForKey:CPObservedKeyPathKey];
1392 _numberOfRows = [[destination valueForKeyPath:keyPath] count];
1395 _numberOfRows = [_dataSource numberOfRowsInTableView:self] || 0;
1399 CPLog(
@"no content binding established and data source " + [_dataSource description] +
" does not implement numberOfRowsInTableView:");
1403 return _numberOfRows;
1415 - (void)editColumn:(CPInteger)columnIndex row:(CPInteger)rowIndex withEvent:(
CPEvent)theEvent select:(BOOL)flag
1420 if (![
self isRowSelected:rowIndex])
1428 _editingCellIndex = CGPointMake(columnIndex, rowIndex);
1429 _editingCellIndex._shouldSelect = flag;
1438 - (CPInteger)editedColumn
1440 if (!_editingCellIndex)
1442 return _editingCellIndex.x;
1448 - (CPInteger)editedRow
1450 if (!_editingCellIndex)
1452 return _editingCellIndex.y;
1468 if (_cornerView === aView)
1471 _cornerView = aView;
1475 if ([scrollView isKindOfClass:[
CPScrollView class]] && [scrollView documentView] ===
self)
1476 [scrollView _updateCornerAndHeaderView];
1497 if (_headerView === aHeaderView)
1500 [_headerView setTableView:nil];
1502 _headerView = aHeaderView;
1506 [_headerView setTableView:self];
1507 [_headerView setFrameSize:_CGSizeMake(_CGRectGetWidth([
self frame]), _CGRectGetHeight([_headerView frame]))];
1512 [_cornerView removeFromSuperview];
1518 if ([scrollView isKindOfClass:[
CPScrollView class]] && [scrollView documentView] ===
self)
1519 [scrollView _updateCornerAndHeaderView];
1529 - (void)_recalculateTableColumnRanges
1531 if (_dirtyTableColumnRangeIndex < 0)
1534 _numberOfHiddenColumns = 0;
1536 var index = _dirtyTableColumnRangeIndex,
1538 x = index === 0 ? 0.0 : CPMaxRange(_tableColumnRanges[index - 1]);
1540 for (; index < count; ++index)
1542 var tableColumn = _tableColumns[index];
1544 if ([tableColumn isHidden])
1546 _numberOfHiddenColumns += 1;
1551 var
width = [_tableColumns[index] width] + _intercellSpacing.width;
1553 _tableColumnRanges[index] =
CPMakeRange(x, width);
1559 _tableColumnRanges.length = count;
1571 - (CGRect)rectOfColumn:(CPInteger)aColumnIndex
1574 aColumnIndex = +aColumnIndex;
1577 return _CGRectMakeZero();
1581 if ([column isHidden])
1582 return _CGRectMakeZero();
1586 var range = _tableColumnRanges[aColumnIndex];
1588 return _CGRectMake(range.location, 0.0, range.length, _CGRectGetHeight([
self bounds]));
1600 - (CGRect)_rectOfRow:(CPInteger)aRowIndex checkRange:(BOOL)checkRange
1602 var lastIndex = [
self numberOfRows] - 1;
1604 if (checkRange && (aRowIndex > lastIndex || aRowIndex < 0))
1605 return _CGRectMakeZero();
1609 var rowToLookUp = MIN(aRowIndex, lastIndex);
1614 var y = _cachedRowHeights[rowToLookUp].heightAboveRow,
1615 height = _cachedRowHeights[rowToLookUp].height + _intercellSpacing.height,
1616 rowDelta = aRowIndex - rowToLookUp;
1620 y = aRowIndex * (_rowHeight + _intercellSpacing.height);
1621 height = _rowHeight + _intercellSpacing.height;
1627 y += rowDelta * (_rowHeight + _intercellSpacing.height);
1628 height = _rowHeight + _intercellSpacing.height;
1633 var y = aRowIndex * (_rowHeight + _intercellSpacing.height),
1634 height = _rowHeight + _intercellSpacing.height;
1637 return _CGRectMake(0.0, y, _CGRectGetWidth([
self bounds]), height);
1645 - (CGRect)rectOfRow:(CPInteger)aRowIndex
1647 return [
self _rectOfRow:aRowIndex checkRange:YES];
1657 - (CPRange)rowsInRect:(CGRect)aRect
1660 if (_numberOfRows <= 0)
1663 var bounds = [
self bounds];
1666 if (!CGRectIntersectsRect(aRect, bounds))
1669 var firstRow = [
self rowAtPoint:aRect.origin];
1675 var lastRow = [
self rowAtPoint:_CGPointMake(0.0, _CGRectGetMaxY(aRect))];
1679 lastRow = _numberOfRows - 1;
1681 return CPMakeRange(firstRow, lastRow - firstRow + 1);
1688 - (CPRange)_unboundedRowsInRect:(CGRect)aRect
1690 var boundedRange = [
self rowsInRect:aRect],
1691 lastRow = CPMaxRange(boundedRange),
1692 rectOfLastRow = [
self _rectOfRow:lastRow checkRange:NO],
1693 bottom = _CGRectGetMaxY(aRect),
1694 bottomOfBoundedRows = _CGRectGetMaxY(rectOfLastRow);
1697 if (bottom <= bottomOfBoundedRows)
1698 return boundedRange;
1700 var numberOfNewRows = CEIL(bottom - bottomOfBoundedRows) / ([
self rowHeight] + _intercellSpacing.height);
1702 boundedRange.length += numberOfNewRows + 1;
1704 return boundedRange;
1718 var column = MAX(0, [
self columnAtPoint:_CGPointMake(aRect.origin.x, 0.0)]),
1719 lastColumn = [
self columnAtPoint:_CGPointMake(_CGRectGetMaxX(aRect), 0.0)];
1725 if (_numberOfHiddenColumns <= 0)
1731 for (; column <= lastColumn; ++column)
1733 var tableColumn = _tableColumns[column];
1735 if (![tableColumn isHidden])
1736 [indexSet addIndex:column];
1750 - (CPInteger)columnAtPoint:(CGPoint)aPoint
1752 var bounds = [
self bounds];
1754 if (!_CGRectContainsPoint(bounds, aPoint))
1761 high = _tableColumnRanges.length - 1;
1765 var middle = FLOOR(low + (high - low) / 2),
1766 range = _tableColumnRanges[middle];
1768 if (x < range.location)
1771 else if (x >= CPMaxRange(range))
1776 var numberOfColumns = _tableColumnRanges.length;
1778 while (middle < numberOfColumns && [_tableColumns[middle] isHidden])
1781 if (middle < numberOfColumns)
1799 - (CPInteger)rowAtPoint:(CGPoint)aPoint
1803 return [_cachedRowHeights indexOfObject:aPoint
1806 usingComparator:function(aPoint, rowCache)
1808 var upperBound = rowCache.heightAboveRow;
1810 if (aPoint.y < upperBound)
1811 return CPOrderedAscending;
1813 if (aPoint.y > upperBound + rowCache.height + _intercellSpacing.height)
1814 return CPOrderedDescending;
1816 return CPOrderedSame;
1821 row = FLOOR(y / (_rowHeight + _intercellSpacing.height));
1823 if (row >= _numberOfRows)
1836 - (CGRect)frameOfDataViewAtColumn:(CPInteger)aColumn row:(CPInteger)aRow
1840 if (aColumn > [
self numberOfColumns] || aRow > [
self numberOfRows])
1841 return _CGRectMakeZero();
1843 var tableColumnRange = _tableColumnRanges[aColumn],
1845 leftInset = FLOOR(_intercellSpacing.width / 2.0),
1846 topInset = FLOOR(_intercellSpacing.height / 2.0);
1848 return _CGRectMake(tableColumnRange.location + leftInset, _CGRectGetMinY(rectOfRow) + topInset, tableColumnRange.length - _intercellSpacing.width, _CGRectGetHeight(rectOfRow) - _intercellSpacing.height);
1854 - (void)resizeWithOldSuperviewSize:(CGSize)aSize
1858 if (_disableAutomaticResizing)
1861 var mask = _columnAutoResizingStyle;
1864 if (!_lastColumnShouldSnap)
1869 if (!superview || ![superview isKindOfClass:[
CPClipView class]])
1872 var superviewWidth = [superview bounds].size.width,
1873 lastColumnMaxX = _CGRectGetMaxX([
self rectOfColumn:[
self numberOfColumns] -1]);
1876 if (lastColumnMaxX >= superviewWidth && lastColumnMaxX <= aSize.width || lastColumnMaxX <= superviewWidth && lastColumnMaxX >= aSize.width)
1877 _lastColumnShouldSnap = YES;
1883 [
self _resizeAllColumnUniformlyWithOldSize:aSize];
1887 [
self _autoResizeFirstColumn];
1893 - (void)_autoResizeFirstColumn
1895 var superview = [
self superview];
1903 columnToResize = nil,
1907 for (; i < count; i++)
1909 var column = _tableColumns[i];
1911 if (![column isHidden])
1913 if (!columnToResize)
1914 columnToResize = column;
1915 totalWidth += [column
width] + _intercellSpacing.
width;
1922 var superviewSize = [superview bounds].size,
1923 newWidth = superviewSize.width - totalWidth;
1925 newWidth += [columnToResize
width];
1926 [columnToResize _tryToResizeToWidth:newWidth];
1929 [
self setNeedsLayout];
1937 - (void)_resizeAllColumnUniformlyWithOldSize:(CGSize)oldSize
1941 var superview = [
self superview];
1943 if (!superview || ![superview isKindOfClass:[
CPClipView class]])
1948 var superviewWidth = [superview bounds].size.width,
1951 remainingSpace = 0.0,
1956 for (; i < count; i++)
1958 var tableColumn = _tableColumns[i];
1960 [resizableColumns addIndex:i];
1963 var maxXofColumns = _CGRectGetMaxX([
self rectOfColumn:[resizableColumns lastIndex]]),
1964 remainingSpace = superviewWidth - maxXofColumns,
1965 resizeableColumnsCount = [resizableColumns count],
1968 while (remainingSpace && resizeableColumnsCount)
1971 proportionate += remainingSpace / resizeableColumnsCount;
1974 remainingSpace = 0.0;
1978 while ((index = [resizableColumns indexGreaterThanIndex:index]) !==
CPNotFound)
1980 var item = _tableColumns[index],
1981 proposedWidth = [item width] + proportionate,
1982 resizeLeftovers = [item _tryToResizeToWidth:proposedWidth];
1984 if (resizeLeftovers)
1986 [resizableColumns removeIndex:index];
1988 remainingSpace += resizeLeftovers;
1997 while (count-- && [_tableColumns[count] isHidden]);
2000 var delta = superviewWidth - _CGRectGetMaxX([self rectOfColumn:count]) - ([self intercellSpacing].
width || 1),
2001 newSize = [item width] + delta;
2003 [item _tryToResizeToWidth:newSize];
2017 - (void)setColumnAutoresizingStyle:(
unsigned)style
2020 _columnAutoResizingStyle = style;
2026 - (unsigned)columnAutoresizingStyle
2028 return _columnAutoResizingStyle;
2034 - (void)sizeLastColumnToFit
2036 _lastColumnShouldSnap = YES;
2043 var superviewSize = [superview bounds].size;
2050 while (count-- && [_tableColumns[count] isHidden]);
2055 var columnToResize = _tableColumns[count],
2056 newSize = MAX(0.0, superviewSize.width - CGRectGetMinX([
self rectOfColumn:count]) - _intercellSpacing.width);
2058 [columnToResize _tryToResizeToWidth:newSize];
2067 - (void)noteNumberOfRowsChanged
2069 var oldNumberOfRows = _numberOfRows;
2071 _numberOfRows = nil;
2072 _cachedRowHeights = [];
2080 var hangingSelections = oldNumberOfRows - _numberOfRows;
2082 if (hangingSelections > 0)
2085 var previousSelectionCount = [_selectedRowIndexes count];
2086 [_selectedRowIndexes removeIndexesInRange:CPMakeRange(_numberOfRows, hangingSelections)];
2088 if (![_selectedRowIndexes containsIndex:[
self selectedRow]])
2092 if (previousSelectionCount > [_selectedRowIndexes count])
2093 [
self _noteSelectionDidChange];
2105 - (void)noteHeightOfRowsWithIndexesChanged:(
CPIndexSet)anIndexSet
2113 count = _numberOfRows - i,
2114 heightAbove = (i > 0) ? _cachedRowHeights[i - 1].height + _cachedRowHeights[i - 1].heightAboveRow + _intercellSpacing.height : 0;
2116 for (; i < count; i++)
2119 if ([anIndexSet containsIndex:i])
2120 var height = [_delegate tableView:self heightOfRow:i];
2122 _cachedRowHeights[i] = {
"height":height,
"heightAboveRow":heightAbove};
2124 heightAbove += height + _intercellSpacing.height;
2135 var
width = _tableColumnRanges.length > 0 ? CPMaxRange([_tableColumnRanges lastObject]) : 0.0,
2139 var height = (_rowHeight + _intercellSpacing.height) * _numberOfRows;
2140 else if ([
self numberOfRows] === 0)
2145 if ([
self numberOfRows] !== _cachedRowHeights.length)
2148 var heightObject = _cachedRowHeights[_cachedRowHeights.length - 1],
2149 height = heightObject.heightAboveRow + heightObject.height + _intercellSpacing.height;
2154 if ([superview isKindOfClass:[CPClipView
class]])
2156 var superviewSize = [superview bounds].size;
2158 width = MAX(superviewSize.width, width);
2159 height = MAX(superviewSize.height, height);
2174 - (void)scrollRowToVisible:(
int)rowIndex
2179 visible.origin.y = rowRect.origin.y;
2180 visible.size.height = rowRect.size.height;
2190 - (void)scrollColumnToVisible:(
int)columnIndex
2195 visible.origin.x = colRect.origin.x;
2196 visible.size.width = colRect.size.width;
2199 [_headerView scrollRectToVisible:colRect];
2210 if (_autosaveName === theAutosaveName)
2213 _autosaveName = theAutosaveName;
2216 [
self _restoreFromAutosave];
2224 return _autosaveName;
2233 - (void)setAutosaveTableColumns:(BOOL)shouldAutosave
2235 _autosaveTableColumns = shouldAutosave;
2241 - (BOOL)autosaveTableColumns
2243 return _autosaveTableColumns;
2251 return @"CPTableView Columns " + theAutosaveName;
2257 - (BOOL)_autosaveEnabled
2259 return [
self autosaveName] && [
self autosaveTableColumns];
2270 if (![
self _autosaveEnabled])
2274 autosaveName = [
self autosaveName];
2276 var columns = [
self tableColumns],
2279 for (var i = 0; i < [columns count]; i++)
2281 var column = [columns objectAtIndex:i],
2283 @"identifier": [column identifier],
2284 @"width": [column width]
2287 [columnsSetup addObject:metaData];
2290 [userDefaults setObject:columnsSetup forKey:[
self _columnsKeyForAutosaveName:autosaveName]];
2296 - (void)_restoreFromAutosave
2298 if (![
self _autosaveEnabled])
2302 autosaveName = [
self autosaveName],
2303 tableColumns = [userDefaults objectForKey:[
self _columnsKeyForAutosaveName:autosaveName]];
2305 for (var i = 0; i < [tableColumns count]; i++)
2307 var metaData = [tableColumns objectAtIndex:i],
2308 columnIdentifier = [metaData objectForKey:@"identifier"],
2309 column = [
self columnWithIdentifier:columnIdentifier],
2310 tableColumn = [
self tableColumnWithIdentifier:columnIdentifier];
2312 [
self _moveColumn:column toColumn:i];
2313 [tableColumn setWidth:[metaData objectForKey:@"width"]];
2455 - (void)setDelegate:(
id)aDelegate
2457 if (_delegate === aDelegate)
2464 if ([_delegate respondsToSelector:
@selector(tableViewColumnDidMove:)])
2466 removeObserver:_delegate
2470 if ([_delegate respondsToSelector:
@selector(tableViewColumnDidResize:)])
2472 removeObserver:_delegate
2476 if ([_delegate respondsToSelector:
@selector(tableViewSelectionDidChange:)])
2478 removeObserver:_delegate
2482 if ([_delegate respondsToSelector:
@selector(tableViewSelectionIsChanging:)])
2484 removeObserver:_delegate
2489 _delegate = aDelegate;
2490 _implementedDelegateMethods = 0;
2492 if ([_delegate respondsToSelector:
@selector(selectionShouldChangeInTableView:)])
2495 if ([_delegate respondsToSelector:
@selector(
tableView:dataViewForTableColumn:row:)])
2498 if ([_delegate respondsToSelector:
@selector(
tableView:didClickTableColumn:)])
2501 if ([_delegate respondsToSelector:
@selector(
tableView:didDragTableColumn:)])
2504 if ([_delegate respondsToSelector:
@selector(
tableView:heightOfRow:)])
2507 if ([_delegate respondsToSelector:
@selector(
tableView:isGroupRow:)])
2510 if ([_delegate respondsToSelector:
@selector(
tableView:mouseDownInHeaderOfTableColumn:)])
2513 if ([_delegate respondsToSelector:
@selector(
tableView:nextTypeSelectMatchFromRow:toRow:forString:)])
2516 if ([_delegate respondsToSelector:
@selector(
tableView:selectionIndexesForProposedSelection:)])
2519 if ([_delegate respondsToSelector:
@selector(
tableView:shouldEditTableColumn:row:)])
2522 if ([_delegate respondsToSelector:
@selector(
tableView:shouldSelectRow:)])
2525 if ([_delegate respondsToSelector:
@selector(
tableView:shouldSelectTableColumn:)])
2528 if ([_delegate respondsToSelector:
@selector(
tableView:shouldShowViewExpansionForTableColumn:row:)])
2531 if ([_delegate respondsToSelector:
@selector(
tableView:shouldTrackView:forTableColumn:row:)])
2534 if ([_delegate respondsToSelector:
@selector(
tableView:shouldTypeSelectForEvent:withCurrentSearchString:)])
2537 if ([_delegate respondsToSelector:
@selector(
tableView:toolTipForView:rect:tableColumn:row:mouseLocation:)])
2540 if ([_delegate respondsToSelector:
@selector(
tableView:typeSelectStringForTableColumn:row:)])
2543 if ([_delegate respondsToSelector:
@selector(
tableView:willDisplayView:forTableColumn:row:)])
2546 if ([_delegate respondsToSelector:
@selector(
tableView:menuForTableColumn:row:)])
2549 if ([_delegate respondsToSelector:
@selector(tableViewColumnDidMove:)])
2551 addObserver:_delegate
2552 selector:
@selector(tableViewColumnDidMove:)
2556 if ([_delegate respondsToSelector:
@selector(tableViewColumnDidResize:)])
2558 addObserver:_delegate
2559 selector:
@selector(tableViewColumnDidResize:)
2563 if ([_delegate respondsToSelector:
@selector(tableViewSelectionDidChange:)])
2565 addObserver:_delegate
2566 selector:
@selector(tableViewSelectionDidChange:)
2570 if ([_delegate respondsToSelector:
@selector(tableViewSelectionIsChanging:)])
2572 addObserver:_delegate
2573 selector:
@selector(tableViewSelectionIsChanging:)
2589 - (void)_sendDelegateDidClickColumn:(
int)column
2592 [_delegate
tableView:
self didClickTableColumn:_tableColumns[column]];
2598 - (void)_sendDelegateDidDragColumn:(
int)column
2601 [_delegate
tableView:
self didDragTableColumn:_tableColumns[column]];
2604 - (void)_sendDelegateDidMouseDownInHeader:(
int)column
2607 [_delegate
tableView:
self mouseDownInHeaderOfTableColumn:_tableColumns[column]];
2613 - (BOOL)_sendDelegateDeleteKeyPressed
2615 if ([_delegate respondsToSelector:
@selector(tableViewDeleteKeyPressed:)])
2617 [_delegate tableViewDeleteKeyPressed:self];
2628 - (void)_sendDataSourceSortDescriptorsDidChange:(
CPArray)oldDescriptors
2631 [_dataSource
tableView:
self sortDescriptorsDidChange:oldDescriptors];
2638 - (void)_didClickTableColumn:(
int)clickedColumn modifierFlags:(
unsigned)modifierFlags
2640 [
self _sendDelegateDidClickColumn:clickedColumn];
2642 if (_allowsColumnSelection)
2644 [
self _noteSelectionIsChanging];
2647 if ([
self isColumnSelected:clickedColumn])
2648 [
self deselectColumn:clickedColumn];
2649 else if ([
self allowsMultipleSelection] == YES)
2650 [
self selectColumnIndexes:[
CPIndexSet indexSetWithIndex:clickedColumn] byExtendingSelection:YES];
2657 var startColumn = MIN(clickedColumn, [_selectedColumnIndexes lastIndex]),
2658 endColumn = MAX(clickedColumn, [_selectedColumnIndexes firstIndex]);
2669 [
self _changeSortDescriptorsForClickOnColumn:clickedColumn];
2676 - (void)_changeSortDescriptorsForClickOnColumn:(
int)column
2678 var tableColumn = [_tableColumns objectAtIndex:column],
2679 newMainSortDescriptor = [tableColumn sortDescriptorPrototype];
2681 if (!newMainSortDescriptor)
2684 var oldMainSortDescriptor = nil,
2685 oldSortDescriptors = [
self sortDescriptors],
2688 e = [newSortDescriptors objectEnumerator],
2692 if ([_sortDescriptors count] > 0)
2693 oldMainSortDescriptor = [[
self sortDescriptors] objectAtIndex: 0];
2696 while ((descriptor = [e nextObject]) !== nil)
2698 if ([[descriptor key]
isEqual: [newMainSortDescriptor key]])
2699 [outdatedDescriptors addObject:descriptor];
2703 if ([[newMainSortDescriptor key]
isEqual:[oldMainSortDescriptor key]])
2704 newMainSortDescriptor = [oldMainSortDescriptor reversedSortDescriptor];
2706 [newSortDescriptors removeObjectsInArray:outdatedDescriptors];
2707 [newSortDescriptors insertObject:newMainSortDescriptor atIndex:0];
2709 [
self setHighlightedTableColumn:tableColumn];
2710 [
self setSortDescriptors:newSortDescriptors];
2726 if ([headerView respondsToSelector:
@selector(_setIndicatorImage:)])
2727 [headerView _setIndicatorImage:anImage];
2734 - (
CPImage)_tableHeaderSortImage
2736 return [
self currentValueForThemeAttribute:@"sort-image"];
2742 - (
CPImage)_tableHeaderReverseSortImage
2744 return [
self currentValueForThemeAttribute:@"sort-image-reversed"];
2752 return _currentHighlightedTableColumn;
2760 if (_currentHighlightedTableColumn == aTableColumn)
2765 if (_currentHighlightedTableColumn != nil)
2766 [[_currentHighlightedTableColumn headerView] unsetThemeState:CPThemeStateSelected];
2768 if (aTableColumn != nil)
2772 _currentHighlightedTableColumn = aTableColumn;
2781 - (BOOL)canDragRowsWithIndexes:(
CPIndexSet)rowIndexes atPoint:(CGPoint)mouseDownPoint
2815 var bounds = [
self bounds],
2818 [view setAlphaValue:0.7];
2823 var columnIndex = [theTableColumns
count];
2824 while (columnIndex--)
2826 var tableColumn = [theTableColumns
objectAtIndex:columnIndex],
2831 var dataView = [
self _newDataViewForRow:row tableColumn:tableColumn];
2835 [
self _setObjectValueForTableColumn:tableColumn row:row forView:dataView];
2836 [view addSubview:dataView];
2843 dragViewOffset.x = _CGRectGetWidth(bounds) / 2 - dragPoint.x;
2844 dragViewOffset.y = _CGRectGetHeight(bounds) / 2 - dragPoint.y;
2855 - (
CPView)_dragViewForColumn:(
int)theColumnIndex event:(
CPEvent)theDragEvent offset:(CPPointPointer)theDragViewOffset
2857 var dragView = [[_CPColumnDragView alloc] initWithLineColor:[
self gridColor]],
2858 tableColumn = [[
self tableColumns] objectAtIndex:theColumnIndex],
2859 bounds = _CGRectMake(0.0, 0.0, [tableColumn
width], _CGRectGetHeight([
self exposedRect]) + 23.0),
2860 columnRect = [
self rectOfColumn:theColumnIndex],
2861 headerView = [tableColumn headerView],
2862 row = [_exposedRows firstIndex];
2866 var dataView = [
self _newDataViewForRow:row tableColumn:tableColumn],
2867 dataViewFrame = [
self frameOfDataViewAtColumn:theColumnIndex row:row];
2870 dataViewFrame.origin.x = 0.0;
2873 dataViewFrame.origin.y = ( _CGRectGetMinY(dataViewFrame) - _CGRectGetMinY([self exposedRect]) ) + 23.0;
2874 [dataView setFrame:dataViewFrame];
2876 [
self _setObjectValueForTableColumn:tableColumn row:row forView:dataView];
2877 [dragView addSubview:dataView];
2879 row = [_exposedRows indexGreaterThanIndex:row];
2884 [dragView addSubview:columnHeaderView];
2887 [dragView setAlphaValue:0.7];
2888 [dragView setFrame:bounds];
2897 - (void)setDraggingSourceOperationMask:(CPDragOperation)mask forLocal:(BOOL)isLocal
2900 _dragOperationDefaultMask = mask;
2908 - (void)setDropRow:(CPInteger)row dropOperation:(CPTableViewDropOperation)operation
2913 reason =
@"Attempt to set dropRow=" + row +
2914 " dropOperation=CPTableViewDropOn when [0 - " + numberOfRows +
"] is valid range of rows.";
2920 _retargetedDropRow = row;
2921 _retargetedDropOperation = operation;
2935 - (void)setDraggingDestinationFeedbackStyle:(CPTableViewDraggingDestinationFeedbackStyle)aStyle
2938 _destinationDragStyle = aStyle;
2951 - (CPTableViewDraggingDestinationFeedbackStyle)draggingDestinationFeedbackStyle
2953 return _destinationDragStyle;
2961 - (void)setVerticalMotionCanBeginDrag:(BOOL)aFlag
2963 _verticalMotionCanDrag = aFlag;
2969 - (BOOL)verticalMotionCanBeginDrag
2971 return _verticalMotionCanDrag;
2976 var tableColumns = [
self tableColumns];
2978 for (var i = 0; i < [tableColumns count]; i++)
2980 var tableColumn = [tableColumns objectAtIndex:i],
2981 sortDescriptorPrototype = [tableColumn sortDescriptorPrototype];
2983 if (!sortDescriptorPrototype)
2986 if ([sortDescriptorPrototype key] === [theSortDescriptor key]
2987 && [sortDescriptorPrototype selector] === [theSortDescriptor selector])
3001 - (void)setSortDescriptors:(
CPArray)sortDescriptors
3004 newSortDescriptors = nil;
3006 if (sortDescriptors == nil)
3007 newSortDescriptors = [
CPArray array];
3011 if ([newSortDescriptors
isEqual:oldSortDescriptors])
3014 _sortDescriptors = newSortDescriptors;
3016 var oldColumn = nil,
3019 if ([newSortDescriptors count] > 0)
3021 var newMainSortDescriptor = [newSortDescriptors objectAtIndex:0];
3022 newColumn = [
self _tableColumnForSortDescriptor:newMainSortDescriptor];
3025 if ([oldSortDescriptors count] > 0)
3027 var oldMainSortDescriptor = [oldSortDescriptors objectAtIndex:0];
3028 oldColumn = [
self _tableColumnForSortDescriptor:oldMainSortDescriptor];
3031 var image = [newMainSortDescriptor ascending] ? [
self _tableHeaderSortImage] : [
self _tableHeaderReverseSortImage];
3035 [
self _sendDataSourceSortDescriptorsDidChange:oldSortDescriptors];
3037 var binderClass = [[
self class] _binderClassForBinding:@"sortDescriptors"];
3038 [[binderClass getBinding:@"sortDescriptors" forObject:self] reverseSetValueFor:@"sortDescriptors"];
3046 return _sortDescriptors;
3052 - (id)_objectValueForTableColumn:(
CPTableColumn)aTableColumn row:(CPInteger)aRowIndex
3054 var tableColumnUID = [aTableColumn
UID],
3055 tableColumnObjectValues = _objectValues[tableColumnUID];
3057 if (!tableColumnObjectValues)
3059 tableColumnObjectValues = [];
3060 _objectValues[tableColumnUID] = tableColumnObjectValues;
3063 var objectValue = tableColumnObjectValues[aRowIndex];
3066 if (objectValue === undefined)
3070 objectValue = [_dataSource tableView:self objectValueForTableColumn:aTableColumn row:aRowIndex];
3071 tableColumnObjectValues[aRowIndex] = objectValue;
3073 else if (![
self infoForBinding:
@"content"])
3075 CPLog(
@"no content binding established and data source " + [_dataSource description] +
" does not implement tableView:objectValueForTableColumn:row:");
3086 - (CGRect)exposedRect
3094 if ([superview isKindOfClass:[
CPClipView class]])
3095 _exposedRect = [superview bounds];
3098 _exposedRect = [
self bounds];
3101 return _exposedRect;
3111 [
self _unloadDataViewsInRows:_exposedRows columns:_exposedColumns];
3116 _reloadAllRows = NO;
3122 obscuredRows = [_exposedRows copy],
3123 obscuredColumns = [_exposedColumns copy];
3125 [obscuredRows removeIndexes:exposedRows];
3126 [obscuredColumns removeIndexes:exposedColumns];
3128 var newlyExposedRows = [exposedRows copy],
3129 newlyExposedColumns = [exposedColumns copy];
3131 [newlyExposedRows removeIndexes:_exposedRows];
3132 [newlyExposedColumns removeIndexes:_exposedColumns];
3134 var previouslyExposedRows = [exposedRows copy],
3135 previouslyExposedColumns = [exposedColumns copy];
3137 [previouslyExposedRows removeIndexes:newlyExposedRows];
3138 [previouslyExposedColumns removeIndexes:newlyExposedColumns];
3140 [
self _unloadDataViewsInRows:previouslyExposedRows columns:obscuredColumns];
3141 [
self _unloadDataViewsInRows:obscuredRows columns:previouslyExposedColumns];
3142 [
self _unloadDataViewsInRows:obscuredRows columns:obscuredColumns];
3143 [
self _unloadDataViewsInRows:newlyExposedRows columns:newlyExposedColumns];
3145 [
self _loadDataViewsInRows:previouslyExposedRows columns:newlyExposedColumns];
3146 [
self _loadDataViewsInRows:newlyExposedRows columns:previouslyExposedColumns];
3147 [
self _loadDataViewsInRows:newlyExposedRows columns:newlyExposedColumns];
3149 _exposedRows = exposedRows;
3150 _exposedColumns = exposedColumns;
3152 [_tableDrawView setFrame:exposedRect];
3158 for (var identifier in _cachedDataViews)
3160 var dataViews = _cachedDataViews[identifier],
3161 count = dataViews.length;
3164 [dataViews[count] removeFromSuperview];
3168 if ([_differedColumnDataToRemove count])
3170 for (var i = 0; i < _differedColumnDataToRemove.length; i++)
3172 var data = _differedColumnDataToRemove[i],
3173 column = data.column;
3175 [column setHidden:data.shouldBeHidden];
3176 [_tableColumns removeObject:column];
3178 [_differedColumnDataToRemove removeAllObjects];
3188 if (![rows count] || ![columns count])
3197 var columnIndex = 0,
3198 columnsCount = columnArray.length;
3200 for (; columnIndex < columnsCount; ++columnIndex)
3202 var column = columnArray[columnIndex],
3203 tableColumn = _tableColumns[column],
3204 tableColumnUID = [tableColumn UID],
3206 rowsCount = rowArray.length;
3208 for (; rowIndex < rowsCount; ++rowIndex)
3210 var row = rowArray[rowIndex],
3211 dataViews = _dataViewsForTableColumns[tableColumnUID];
3213 if (!dataViews || row >= dataViews.length)
3216 var dataView = [dataViews objectAtIndex:row];
3218 [dataViews replaceObjectAtIndex:row withObject:nil];
3220 [
self _enqueueReusableDataView:dataView];
3230 if (![rows count] || ![columns count])
3242 var columnIndex = 0,
3243 columnsCount = columnArray.length;
3245 for (; columnIndex < columnsCount; ++columnIndex)
3247 var column = columnArray[columnIndex],
3248 tableColumn = _tableColumns[column];
3250 if ([tableColumn isHidden] || tableColumn === _draggedColumn)
3253 var tableColumnUID = [tableColumn UID];
3255 if (!_dataViewsForTableColumns[tableColumnUID])
3256 _dataViewsForTableColumns[tableColumnUID] = [];
3259 rowsCount = rowArray.length,
3260 isColumnSelected = [_selectedColumnIndexes containsIndex:column];
3262 for (; rowIndex < rowsCount; ++rowIndex)
3264 var row = rowArray[rowIndex],
3265 dataView = [
self _newDataViewForRow:row tableColumn:tableColumn],
3269 [dataView setFrame:[
self frameOfDataViewAtColumn:column row:row]];
3271 [
self _setObjectValueForTableColumn:tableColumn row:row forView:dataView];
3273 if (isColumnSelected || [
self isRowSelected:row])
3276 [dataView unsetThemeState:CPThemeStateSelectedDataView];
3281 if ([_delegate
tableView:
self isGroupRow:row])
3283 [_groupRows addIndex:row];
3284 [dataView setThemeState:CPThemeStateGroupRow];
3288 [_groupRows removeIndexesInRange:CPMakeRange(row, 1)];
3289 [dataView unsetThemeState:CPThemeStateGroupRow];
3292 [
self setNeedsDisplay:YES]
3296 [_delegate
tableView:
self willDisplayView:dataView forTableColumn:tableColumn row:row];
3298 if ([dataView superview] !==
self)
3299 [
self addSubview:dataView];
3301 _dataViewsForTableColumns[tableColumnUID][row] = dataView;
3303 if (isButton || (_editingCellIndex && _editingCellIndex.x === column && _editingCellIndex.y === row))
3307 [dataView setEditable:YES];
3308 [dataView setSendsActionOnEndEditing:YES];
3309 [dataView setSelectable:YES];
3310 [dataView selectText:nil];
3311 [dataView setBezeled:YES];
3312 [dataView setDelegate:self];
3315 [dataView setTarget:self];
3316 [dataView setAction:@selector(_commitDataViewObjectValue:)];
3317 dataView.tableViewEditedColumnObj = tableColumn;
3318 dataView.tableViewEditedRowIndex = row;
3320 else if (isTextField)
3322 [dataView setEditable:NO];
3323 [dataView setSelectable:NO];
3329 - (void)_setObjectValueForTableColumn:(
CPTableColumn)aTableColumn row:(CPInteger)aRow forView:(
CPView)aDataView
3332 [aDataView setObjectValue:[
self _objectValueForTableColumn:aTableColumn row:aRow]];
3337 if (_contentBindingExpicitelySet)
3338 [
self _prepareContentBindedDataView:aDataView forRow:aRow];
3341 [aTableColumn _prepareDataView:aDataView forRow:aRow];
3344 - (void)_prepareContentBindedDataView:(
CPView)dataView forRow:(CPInteger)aRow
3347 content = [binder content],
3348 rowContent = [content objectAtIndex:aRow];
3350 [dataView setObjectValue:rowContent];
3364 var columnIndex = 0,
3365 columnsCount = columnArray.length;
3367 for (; columnIndex < columnsCount; ++columnIndex)
3369 var column = columnArray[columnIndex],
3370 tableColumn = _tableColumns[column],
3371 tableColumnUID = [tableColumn UID],
3372 dataViewsForTableColumn = _dataViewsForTableColumns[tableColumnUID],
3374 rowsCount = rowArray.length;
3376 if (dataViewsForTableColumn)
3378 for (; rowIndex < rowsCount; ++rowIndex)
3380 var row = rowArray[rowIndex],
3381 dataView = dataViewsForTableColumn[row];
3383 [dataView setFrame:[
self frameOfDataViewAtColumn:column row:row]];
3394 - (void)_commitDataViewObjectValue:(
id)sender
3401 if ([sender respondsToSelector:
@selector(sendsActionOnEndEditing)] && [sender sendsActionOnEndEditing] && _editingCellIndex === nil)
3404 _editingCellIndex = nil;
3407 [_dataSource
tableView:
self setObjectValue:[sender objectValue] forTableColumn:sender.tableViewEditedColumnObj row:sender.tableViewEditedRowIndex];
3411 [sender.tableViewEditedColumnObj _reverseSetDataView:sender forRow:sender.tableViewEditedRowIndex];
3413 if ([sender respondsToSelector:
@selector(setEditable:)])
3414 [sender setEditable:NO];
3416 if ([sender respondsToSelector:
@selector(setSelectable:)])
3417 [sender setSelectable:NO];
3420 [sender setBezeled:NO];
3425 [[
self window] makeFirstResponder:self];
3436 var dataView = [theNotification
object];
3438 if ([dataView respondsToSelector:
@selector(setEditable:)])
3439 [dataView setEditable:NO];
3441 if ([dataView respondsToSelector:
@selector(setSelectable:)])
3442 [dataView setSelectable:NO];
3445 [dataView setBezeled:NO];
3447 _editingCellIndex = nil;
3457 var dataView = [_delegate tableView:self dataViewForTableColumn:aTableColumn row:aRow];
3461 return [aTableColumn _newDataViewForRow:aRow];
3467 - (void)_enqueueReusableDataView:(
CPView)aDataView
3473 var identifier = aDataView.identifier;
3475 if (!_cachedDataViews[identifier])
3476 _cachedDataViews[identifier] = [aDataView];
3478 _cachedDataViews[identifier].push(aDataView);
3485 - (void)setFrameSize:(CGSize)aSize
3490 [_headerView setFrameSize:_CGSizeMake(_CGRectGetWidth([
self frame]), _CGRectGetHeight([_headerView frame]))];
3498 - (void)setFrameOrigin:(CGPoint)aPoint
3508 - (void)setBoundsOrigin:(CGPoint)aPoint
3518 - (void)setBoundsSize:(CGSize)aSize
3528 - (void)setNeedsDisplay:(BOOL)aFlag
3531 [_tableDrawView setNeedsDisplay:aFlag];
3539 - (void)setNeedsLayout
3549 - (void)_drawRect:(CGRect)aRect
3554 var exposedRect = [
self exposedRect];
3556 [
self drawBackgroundInClipRect:exposedRect];
3557 [
self highlightSelectionInClipRect:exposedRect];
3558 [
self drawGridInClipRect:exposedRect];
3560 if (_implementsCustomDrawRow)
3561 [
self _drawRows:_exposedRows clipRect:exposedRect];
3569 - (void)drawBackgroundInClipRect:(CGRect)aRect
3571 if (!_usesAlternatingRowBackgroundColors)
3575 colorCount = [rowColors count];
3577 if (colorCount === 0)
3582 if (colorCount === 1)
3590 var exposedRows = [
self _unboundedRowsInRect:aRect],
3591 firstRow = FLOOR(exposedRows.location / colorCount) * colorCount,
3592 lastRow = CPMaxRange(exposedRows),
3597 while (colorIndex < colorCount)
3600 for (var row = firstRow + colorIndex; row <= lastRow; row += colorCount)
3603 if (![_groupRows containsIndex:row])
3604 CGContextAddRect(context, CGRectIntersection(aRect, [
self _rectOfRow:row checkRange:NO]));
3606 groupRowRects.push(CGRectIntersection(aRect, [
self _rectOfRow:row checkRange:NO]));
3616 [
self _drawGroupRowsForRects:groupRowRects];
3623 - (void)drawGridInClipRect:(CGRect)aRect
3635 var exposedRows = [
self _unboundedRowsInRect:aRect],
3636 row = exposedRows.location,
3637 lastRow = CPMaxRange(exposedRows) - 1,
3639 minX = _CGRectGetMinX(aRect),
3640 maxX = _CGRectGetMaxX(aRect);
3642 for (; row <= lastRow; ++row)
3645 var rowRect = [
self _rectOfRow:row checkRange:NO],
3646 rowY = _CGRectGetMaxY(rowRect) - 0.5;
3652 if (_rowHeight > 0.0)
3654 var rowHeight = _rowHeight + _intercellSpacing.height,
3655 totalHeight = _CGRectGetMaxY(aRect);
3657 while (rowY < totalHeight)
3672 [exposedColumnIndexes getIndexes:columnsArray maxCount:-1 inIndexRange:nil];
3674 var columnArrayIndex = 0,
3675 columnArrayCount = columnsArray.length,
3676 minY = _CGRectGetMinY(aRect),
3677 maxY = _CGRectGetMaxY(aRect);
3679 for (; columnArrayIndex < columnArrayCount; ++columnArrayIndex)
3681 var columnRect = [
self rectOfColumn:columnsArray[columnArrayIndex]],
3682 columnX = _CGRectGetMaxX(columnRect) - 0.5;
3699 - (void)highlightSelectionInClipRect:(CGRect)aRect
3706 rectSelector =
@selector(rectOfRow:);
3708 if ([_selectedRowIndexes count] >= 1)
3711 firstRow = [exposedRows firstIndex],
3712 exposedRange =
CPMakeRange(firstRow, [exposedRows lastIndex] - firstRow + 1);
3714 [_selectedRowIndexes getIndexes:indexes maxCount:-1 inIndexRange:exposedRange];
3716 else if ([_selectedColumnIndexes count] >= 1)
3718 rectSelector =
@selector(rectOfColumn:);
3721 firstColumn = [exposedColumns firstIndex],
3722 exposedRange =
CPMakeRange(firstColumn, [exposedColumns lastIndex] - firstColumn + 1);
3724 [_selectedColumnIndexes getIndexes:indexes maxCount:-1 inIndexRange:exposedRange];
3728 count2 = count = [indexes count];
3741 topLineColor = [gradientCache objectForKey:CPSourceListTopLineColor],
3742 bottomLineColor = [gradientCache objectForKey:CPSourceListBottomLineColor],
3743 gradientColor = [gradientCache objectForKey:CPSourceListGradient];
3749 if ([_groupRows count])
3753 gradientGroupColor =
CGGradientCreateWithColorComponents(
CGColorSpaceCreateDeviceRGB(), [212.0 / 255.0, 212.0 / 255.0, 212.0 / 255.0, 1.0, 197.0 / 255.0, 197.0 / 255.0, 197.0 / 255.0, 1.0], [0, 1], 2);
3758 var currentIndex = indexes[count],
3759 rowRect = CGRectIntersection(objj_msgSend(
self, rectSelector, currentIndex), aRect);
3763 var shouldUseGroupGradient = [_groupRows containsIndex:currentIndex];
3765 if (drawGradient || shouldUseGroupGradient)
3767 var minX = _CGRectGetMinX(rowRect),
3768 minY = _CGRectGetMinY(rowRect),
3769 maxX = _CGRectGetMaxX(rowRect),
3770 maxY = _CGRectGetMaxY(rowRect) - deltaHeight;
3775 [normalSelectionHighlightColor setFill];
3782 CGContextDrawLinearGradient(context, (shouldUseGroupGradient) ? gradientGroupColor : gradientColor, rowRect.origin, _CGPointMake(minX, maxY), 0);
3805 var minX = CGRectGetMinX(rowRect),
3806 maxX = CGRectGetMaxX(rowRect),
3807 minY = CGRectGetMinY(rowRect),
3808 maxY = CGRectGetMaxY(rowRect);
3825 [normalSelectionHighlightColor setFill];
3831 for (var i = 0; i < count2; i++)
3833 var rect = objj_msgSend(
self, rectSelector, indexes[i]),
3834 minX = _CGRectGetMinX(rect) - 0.5,
3835 maxX = _CGRectGetMaxX(rect) - 0.5,
3836 minY = _CGRectGetMinY(rect) - 0.5,
3837 maxY = _CGRectGetMaxY(rect) - 0.5;
3842 exposedColumnIndexes = [],
3843 firstExposedColumn = [exposedColumns firstIndex],
3844 exposedRange =
CPMakeRange(firstExposedColumn, [exposedColumns lastIndex] - firstExposedColumn + 1);
3845 [exposedColumns getIndexes:exposedColumnIndexes maxCount:-1 inIndexRange:exposedRange];
3846 var exposedColumnCount = [exposedColumnIndexes count];
3848 for (var c = firstExposedColumn; c < exposedColumnCount; c++)
3850 var colRect = [
self rectOfColumn:exposedColumnIndexes[c]],
3851 colX = _CGRectGetMaxX(colRect) + 0.5;
3859 if ([indexes containsObject:indexes[i] + 1])
3876 - (void)_drawGroupRowsForRects:(
CPArray)rects
3886 var gradientCache = [
self selectionGradientColors],
3890 199.0 / 255.0, 199.0 / 255.0, 199.0 / 255.0, 1.0], [0, 1], 2),
3895 var rowRect = rects[i];
3901 var minX = CGRectGetMinX(rowRect),
3902 minY = CGRectGetMinY(rowRect),
3903 maxX = CGRectGetMaxX(rowRect),
3904 maxY = CGRectGetMaxY(rowRect);
3931 - (void)_drawRows:(
CPIndexSet)rowsIndexes clipRect:(CGRect)clipRect
3937 [
self drawRow:row clipRect:CGRectIntersection(clipRect, [
self rectOfRow:row])];
3948 - (void)drawRow:(CPInteger)row clipRect:(CGRect)rect
3957 - (void)layoutSubviews
3965 - (void)viewWillMoveToSuperview:(
CPView)aView
3974 name:CPViewFrameDidChangeNotification
3979 name:CPViewBoundsDidChangeNotification
3983 if ([aView isKindOfClass:[
CPClipView class]])
3990 selector:@selector(superviewFrameChanged:)
3991 name:CPViewFrameDidChangeNotification
3996 selector:@selector(superviewBoundsChanged:)
3997 name:CPViewBoundsDidChangeNotification
4026 - (BOOL)tracksMouseOutsideOfFrame
4034 - (BOOL)startTrackingAt:(CGPoint)aPoint
4042 if (row < 0 && _allowsEmptySelection)
4045 [
self _noteSelectionIsChanging];
4048 _selectionAnchorRow = (ABS([_selectedRowIndexes firstIndex] - row) < ABS([_selectedRowIndexes lastIndex] - row)) ?
4049 [_selectedRowIndexes firstIndex] : [_selectedRowIndexes lastIndex];
4051 _selectionAnchorRow = row;
4055 _startTrackingPoint = aPoint;
4056 _startTrackingTimestamp =
new Date();
4059 _trackingPointMovedOutOfClickSlop = NO;
4064 [
self _updateSelectionWithMouseAtRow:row];
4082 return [_delegate tableView:self menuForTableColumn:tableColumn row:row];
4091 if (![_draggedRowIndexes count])
4097 [CPApp sendEvent:anEvent];
4103 - (BOOL)continueTracking:(CGPoint)lastPoint at:(CGPoint)aPoint
4111 if (row >= 0 && (ABS(_startTrackingPoint.x - aPoint.x) > 3 || (_verticalMotionCanDrag && ABS(_startTrackingPoint.y - aPoint.y) > 3)) ||
4112 ([_selectedRowIndexes containsIndex:row]))
4114 if ([_selectedRowIndexes containsIndex:row])
4123 if ([
self canDragRowsWithIndexes:_draggedRowIndexes atPoint:aPoint] && [_dataSource
tableView:
self writeRowsWithIndexes:_draggedRowIndexes toPasteboard:pboard])
4125 var currentEvent = [CPApp currentEvent],
4127 tableColumns = [_tableColumns objectsAtIndexes:_exposedColumns];
4143 view = [[
CPImageView alloc] initWithFrame:CPMakeRect(0, 0, [image size].width, [image size].height)];
4144 [view setImage:image];
4147 var bounds = [view bounds],
4148 viewLocation =
CPPointMake(aPoint.x - CGRectGetWidth(bounds) / 2 + offset.x, aPoint.y - CGRectGetHeight(bounds) / 2 + offset.y);
4150 _startTrackingPoint = nil;
4158 else if (ABS(_startTrackingPoint.x - aPoint.x) < 5 && ABS(_startTrackingPoint.y - aPoint.y) < 5)
4162 _isSelectingSession = YES;
4163 if (row >= 0 && row !== _lastTrackedRowIndex)
4165 _lastTrackedRowIndex = row;
4166 [
self _updateSelectionWithMouseAtRow:row];
4170 && !_trackingPointMovedOutOfClickSlop)
4172 var CLICK_SPACE_DELTA = 5.0;
4173 if (ABS(aPoint.x - _startTrackingPoint.x) > CLICK_SPACE_DELTA
4174 || ABS(aPoint.y - _startTrackingPoint.y) > CLICK_SPACE_DELTA)
4176 _trackingPointMovedOutOfClickSlop = YES;
4186 - (void)stopTracking:(CGPoint)lastPoint at:(CGPoint)aPoint mouseIsUp:(BOOL)mouseIsUp
4188 _isSelectingSession = NO;
4190 var CLICK_TIME_DELTA = 1000,
4200 if (rowIndex !== -1)
4202 if ([_draggedRowIndexes count] > 0)
4208 _previouslySelectedRowIndexes = [_selectedRowIndexes copy];
4209 [
self _updateSelectionWithMouseAtRow:rowIndex];
4215 && !_trackingPointMovedOutOfClickSlop
4216 && ([[
CPApp currentEvent] clickCount] > 1)
4218 || [
self infoForBinding:
@"content"]))
4222 if (columnIndex !== -1)
4224 column = _tableColumns[columnIndex];
4226 if ([column isEditable])
4230 if (rowIndex !== -1)
4233 shouldEdit = [_delegate tableView:self shouldEditTableColumn:column row:rowIndex];
4246 if ([[
CPApp currentEvent] clickCount] === 2 && _doubleAction)
4257 - (CPDragOperation)draggingEntered:(
id)sender
4260 dropOperation = [
self _proposedDropOperationAtPoint:location],
4261 row = [
self _proposedRowAtPoint:location];
4263 if (_retargetedDropRow !== nil)
4264 row = _retargetedDropRow;
4267 count = [draggedTypes count],
4270 for (; i < count; i++)
4272 if ([[[sender draggingPasteboard] types] containsObject:[draggedTypes objectAtIndex: i]])
4273 return [
self _validateDrop:sender proposedRow:row proposedDropOperation:dropOperation];
4282 - (void)draggingExited:(
id)sender
4284 [_dropOperationFeedbackView removeFromSuperview];
4290 - (void)draggingEnded:(
id)sender
4292 [
self _draggingEnded];
4298 - (void)_draggingEnded
4300 _retargetedDropOperation = nil;
4301 _retargetedDropRow = nil;
4303 [_dropOperationFeedbackView removeFromSuperview];
4309 - (BOOL)wantsPeriodicDraggingUpdates
4317 - (CPTableViewDropOperation)_proposedDropOperationAtPoint:(CGPoint)theDragPoint
4319 if (_retargetedDropOperation !== nil)
4320 return _retargetedDropOperation;
4322 var row = [
self _proposedRowAtPoint:theDragPoint],
4323 rowRect = [
self rectOfRow:row];
4327 if ([
self intercellSpacing].height < 5.0)
4328 rowRect =
CPRectInset(rowRect, 0.0, 5.0 - [
self intercellSpacing].height);
4333 if (CGRectContainsPoint(rowRect, theDragPoint) && row < _numberOfRows)
4342 - (CPInteger)_proposedRowAtPoint:(CGPoint)dragPoint
4344 var row = [
self rowAtPoint:dragPoint],
4347 rect = [self rectOfRow:row],
4348 bottomPoint = _CGRectGetMaxY(rect),
4349 bottomThirty = bottomPoint - ((bottomPoint - _CGRectGetMinY(rect)) * 0.3),
4350 numberOfRows = [self numberOfRows];
4353 row = (_CGRectGetMaxY(rect) < dragPoint.y) ? numberOfRows : row;
4354 else if (dragPoint.y > MAX(bottomThirty, bottomPoint - 6))
4357 row = MIN(numberOfRows, row);
4365 - (void)_validateDrop:(
id)info proposedRow:(CPInteger)row proposedDropOperation:(CPTableViewDropOperation)dropOperation
4368 return [_dataSource tableView:self validateDrop:info proposedRow:row proposedDropOperation:dropOperation];
4376 - (CPRect)_rectForDropHighlightViewOnRow:(
int)theRowIndex
4378 if (theRowIndex >= [
self numberOfRows])
4379 theRowIndex = [
self numberOfRows] - 1;
4381 return [
self _rectOfRow:theRowIndex checkRange:NO];
4387 - (CPRect)_rectForDropHighlightViewBetweenUpperRow:(
int)theUpperRowIndex andLowerRow:(
int)theLowerRowIndex offset:(CPPoint)theOffset
4389 if (theLowerRowIndex > [
self numberOfRows])
4390 theLowerRowIndex = [
self numberOfRows];
4392 return [
self _rectOfRow:theLowerRowIndex checkRange:NO];
4398 - (CPDragOperation)draggingUpdated:(
id)sender
4400 _retargetedDropRow = nil;
4401 _retargetedDropOperation = nil;
4404 dropOperation = [
self _proposedDropOperationAtPoint:location],
4406 row = [
self _proposedRowAtPoint:location],
4407 dragOperation = [
self _validateDrop:sender proposedRow:row proposedDropOperation:dropOperation];
4409 if (_retargetedDropRow !== nil)
4410 row = _retargetedDropRow;
4411 if (_retargetedDropOperation !== nil)
4412 dropOperation = _retargetedDropOperation;
4416 row = numberOfRows - 1;
4418 var rect = _CGRectMakeZero();
4424 rect = [
self _rectForDropHighlightViewBetweenUpperRow:row - 1 andLowerRow:row offset:location];
4427 rect = [
self _rectForDropHighlightViewOnRow:row];
4429 [_dropOperationFeedbackView setDropOperation:row !== -1 ? dropOperation : CPDragOperationNone];
4430 [_dropOperationFeedbackView setHidden:(dragOperation == CPDragOperationNone)];
4431 [_dropOperationFeedbackView setFrame:rect];
4432 [_dropOperationFeedbackView setCurrentRow:row];
4433 [
self addSubview:_dropOperationFeedbackView];
4435 return dragOperation;
4441 - (BOOL)prepareForDragOperation:(
id)sender
4445 [_dropOperationFeedbackView removeFromSuperview];
4453 - (BOOL)performDragOperation:(
id)sender
4456 operation = [
self _proposedDropOperationAtPoint:location],
4457 row = _retargetedDropRow;
4460 var row = [
self _proposedRowAtPoint:location];
4462 return [_dataSource tableView:self acceptDrop:sender row:row dropOperation:operation];
4468 - (void)concludeDragOperation:(
id)sender
4476 - (void)draggedImage:(
CPImage)anImage endedAt:(CGPoint)aLocation operation:(CPDragOperation)anOperation
4478 if ([_dataSource respondsToSelector:
@selector(
tableView:didEndDraggedImage:atPosition:operation:)])
4479 [_dataSource tableView:self didEndDraggedImage:anImage atPosition:aLocation operation:anOperation];
4486 - (void)draggedView:(
CPImage)aView endedAt:(CGPoint)aLocation operation:(CPDragOperation)anOperation
4488 [
self _draggingEnded];
4495 - (void)_updateSelectionWithMouseAtRow:(CPInteger)aRow
4502 shouldExtendSelection = NO;
4506 if ([_selectedRowIndexes containsIndex:aRow])
4508 newSelection = [_selectedRowIndexes copy];
4510 [newSelection removeIndex:aRow];
4513 else if (_allowsMultipleSelection)
4515 newSelection = [_selectedRowIndexes copy];
4517 [newSelection addIndex:aRow];
4523 else if (_allowsMultipleSelection)
4526 shouldExtendSelection = [
self mouseDownFlags] &
CPShiftKeyMask &&
4527 ((_lastSelectedRow == [_selectedRowIndexes lastIndex] && aRow > _lastSelectedRow) ||
4528 (_lastSelectedRow == [_selectedRowIndexes firstIndex] && aRow < _lastSelectedRow));
4530 else if (aRow >= 0 && aRow < _numberOfRows)
4535 if ([newSelection isEqualToIndexSet:_selectedRowIndexes])
4539 ![_delegate selectionShouldChangeInTableView:
self])
4543 newSelection = [_delegate tableView:self selectionIndexesForProposedSelection:newSelection];
4547 var indexArray = [];
4549 [newSelection getIndexes:indexArray maxCount:-1 inIndexRange:nil];
4551 var indexCount = indexArray.length;
4553 while (indexCount--)
4555 var index = indexArray[indexCount];
4557 if (![_delegate
tableView:
self shouldSelectRow:index])
4558 [newSelection removeIndex:index];
4562 if ([newSelection count] === 0)
4567 if (!_allowsEmptySelection && [newSelection count] === 0)
4570 if ([newSelection isEqualToIndexSet:_selectedRowIndexes])
4573 [
self selectRowIndexes:newSelection byExtendingSelection:shouldExtendSelection];
4575 _lastSelectedRow = [newSelection containsIndex:aRow] ? aRow : [newSelection lastIndex];
4581 - (void)_noteSelectionIsChanging
4592 - (void)_noteSelectionDidChange
4603 - (BOOL)becomeFirstResponder
4611 - (BOOL)acceptsFirstResponder
4631 if ([
self numberOfRows] !== 0)
4633 [
self _moveSelectionWithEvent:anEvent upward:(character === CPUpArrowFunctionKey)];
4641 if ([
self _sendDelegateDeleteKeyPressed])
4653 - (BOOL)_selectionIsBroken
4655 return [
self selectedRowIndexes]._ranges.length !== 1;
4663 - (void)_moveSelectionWithEvent:(
CPEvent)theEvent upward:(BOOL)shouldGoUpward
4667 var selectedIndexes = [
self selectedRowIndexes];
4669 if ([selectedIndexes count] > 0)
4672 i = [
self selectedRow];
4674 if ([
self _selectionIsBroken])
4676 while ([selectedIndexes containsIndex:i])
4678 shouldGoUpward ? i-- : i++;
4680 _wasSelectionBroken =
true;
4682 else if (_wasSelectionBroken && ((shouldGoUpward && i !== [selectedIndexes firstIndex]) || (!shouldGoUpward && i !== [selectedIndexes lastIndex])))
4684 shouldGoUpward ? i = [selectedIndexes firstIndex] - 1 : i = [selectedIndexes lastIndex];
4685 _wasSelectionBroken =
false;
4689 shouldGoUpward ? i-- : i++;
4696 if ([
self numberOfRows] > 0)
4697 var i = shouldGoUpward ? [
self numberOfRows] - 1 : 0;
4700 if (i >= [
self numberOfRows] || i < 0)
4707 while (![_delegate
tableView:
self shouldSelectRow:i] && (i < [
self numberOfRows] || i > 0))
4708 shouldGoUpward ? i-- : i++;
4711 if (![_delegate
tableView:
self shouldSelectRow:i])
4716 if (extend && [selectedIndexes containsIndex:i])
4719 var differedLastSelectedRow = i;
4722 shouldGoUpward ? i++ : i--;
4724 [selectedIndexes removeIndex:i];
4731 if ([selectedIndexes containsIndex:i])
4733 i = shouldGoUpward ? [selectedIndexes firstIndex] -1 : [selectedIndexes lastIndex] + 1;
4734 i = MIN(MAX(i, 0), [
self numberOfRows] - 1);
4737 [selectedIndexes addIndex:i];
4738 var differedLastSelectedRow = i;
4743 var differedLastSelectedRow = i;
4746 [
self selectRowIndexes:selectedIndexes byExtendingSelection:extend];
4749 _lastSelectedRow = differedLastSelectedRow;
4752 [
self scrollRowToVisible:i];
4759 + (id)_binderClassForBinding:(
CPString)aBinding
4761 if (aBinding ==
@"content")
4764 return [
super _binderClassForBinding:aBinding];
4772 if (aBinding ===
@"selectionIndexes")
4773 return @"selectedRowIndexes";
4775 return [
super _replacementKeyPathForBinding:aBinding];
4781 - (void)_establishBindingsIfUnbound:(
id)destination
4785 [
super bind:@"content" toObject:destination withKeyPath:@"arrangedObjects" options:nil];
4786 _contentBindingExpicitelySet = NO;
4790 if (!_contentBindingExpicitelySet)
4792 if ([[
self infoForBinding:
@"selectionIndexes"] objectForKey:
CPObservedObjectKey] !== destination)
4793 [
self bind:@"selectionIndexes" toObject:destination withKeyPath:@"selectionIndexes" options:nil];
4795 if ([[
self infoForBinding:
@"sortDescriptors"] objectForKey:
CPObservedObjectKey] !== destination)
4796 [
self bind:@"sortDescriptors" toObject:destination withKeyPath:@"sortDescriptors" options:nil];
4804 if (aBinding ==
@"content")
4805 _contentBindingExpicitelySet = YES;
4815 - (void)setValueFor:(
id)aBinding
4817 var destination = [_info objectForKey:CPObservedObjectKey],
4818 keyPath = [_info objectForKey:CPObservedKeyPathKey];
4820 _content = [destination valueForKey:keyPath];
4822 [_source reloadData];
4857 _allowsColumnReordering = [aCoder decodeBoolForKey:CPTableViewColumnReorderingKey];
4858 _allowsColumnResizing = [aCoder decodeBoolForKey:CPTableViewColumnResizingKey];
4859 _allowsMultipleSelection = [aCoder decodeBoolForKey:CPTableViewMultipleSelectionKey];
4860 _allowsEmptySelection = [aCoder decodeBoolForKey:CPTableViewEmptySelectionKey];
4861 _allowsColumnSelection = [aCoder decodeBoolForKey:CPTableViewColumnSelectionKey];
4864 _selectionHighlightStyle = [aCoder decodeIntForKey:CPTableViewSelectionHighlightStyleKey];
4865 _columnAutoResizingStyle = [aCoder decodeIntForKey:CPTableViewColumnAutoresizingStyleKey];
4867 _tableColumns = [aCoder decodeObjectForKey:CPTableViewTableColumnsKey] || [];
4868 [_tableColumns makeObjectsPerformSelector:@selector(setTableView:) withObject:self];
4870 _rowHeight = [aCoder decodeFloatForKey:CPTableViewRowHeightKey] || 23.0;
4871 _intercellSpacing = [aCoder decodeSizeForKey:CPTableViewIntercellSpacingKey];
4873 if (_CGSizeEqualToSize(_intercellSpacing, _CGSizeMakeZero()))
4874 _intercellSpacing = _CGSizeMake(3.0, 2.0);
4876 [
self setGridColor:[aCoder decodeObjectForKey:CPTableViewGridColorKey]];
4877 _gridStyleMask = [aCoder decodeIntForKey:CPTableViewGridStyleMaskKey];
4879 _usesAlternatingRowBackgroundColors = [aCoder decodeObjectForKey:CPTableViewUsesAlternatingBackgroundKey];
4882 _headerView = [aCoder decodeObjectForKey:CPTableViewHeaderViewKey];
4883 _cornerView = [aCoder decodeObjectForKey:CPTableViewCornerViewKey];
4885 [
self setDataSource:[aCoder decodeObjectForKey:CPTableViewDataSourceKey]];
4886 [
self setDelegate:[aCoder decodeObjectForKey:CPTableViewDelegateKey]];
4893 [
self setAutosaveName:[aCoder decodeObjectForKey:CPTableViewAutosaveNameKey]];
4903 [aCoder encodeObject:_dataSource forKey:CPTableViewDataSourceKey];
4904 [aCoder encodeObject:_delegate forKey:CPTableViewDelegateKey];
4906 [aCoder encodeFloat:_rowHeight forKey:CPTableViewRowHeightKey];
4907 [aCoder encodeSize:_intercellSpacing forKey:CPTableViewIntercellSpacingKey];
4909 [aCoder encodeInt:_selectionHighlightStyle forKey:CPTableViewSelectionHighlightStyleKey];
4910 [aCoder encodeInt:_columnAutoResizingStyle forKey:CPTableViewColumnAutoresizingStyleKey];
4912 [aCoder encodeBool:_allowsMultipleSelection forKey:CPTableViewMultipleSelectionKey];
4913 [aCoder encodeBool:_allowsEmptySelection forKey:CPTableViewEmptySelectionKey];
4914 [aCoder encodeBool:_allowsColumnReordering forKey:CPTableViewColumnReorderingKey];
4915 [aCoder encodeBool:_allowsColumnResizing forKey:CPTableViewColumnResizingKey];
4916 [aCoder encodeBool:_allowsColumnSelection forKey:CPTableViewColumnSelectionKey];
4918 [aCoder encodeObject:_tableColumns forKey:CPTableViewTableColumnsKey];
4920 [aCoder encodeObject:[
self gridColor] forKey:CPTableViewGridColorKey];
4921 [aCoder encodeInt:_gridStyleMask forKey:CPTableViewGridStyleMaskKey];
4923 [aCoder encodeBool:_usesAlternatingRowBackgroundColors forKey:CPTableViewUsesAlternatingBackgroundKey];
4926 [aCoder encodeObject:_cornerView forKey:CPTableViewCornerViewKey];
4927 [aCoder encodeObject:_headerView forKey:CPTableViewHeaderViewKey];
4929 [aCoder encodeObject:_autosaveName forKey:CPTableViewAutosaveNameKey];
4939 index = MIN(firstindex, [otherSet firstIndex]),
4940 switchFlag = (index == firstindex);
4944 var indexSet = (switchFlag) ? otherSet :
self,
4945 otherIndex = [indexSet indexGreaterThanOrEqualToIndex:index];
4947 if (otherIndex == index)
4954 switchFlag = !switchFlag;
4960 @implementation _CPDropOperationDrawingView :
CPView
4962 unsigned dropOperation;
4968 - (void)drawRect:(CGRect)aRect
4986 var selectedRows = [tableView selectedRowIndexes],
4987 newRect = _CGRectMake(aRect.origin.x + 2, aRect.origin.y + 2, aRect.size.width - 4, aRect.size.height - 5);
5005 [
self setFrameOrigin:_CGPointMake(_frame.origin.x, _frame.origin.y - 8)];
5007 var selectedRows = [tableView selectedRowIndexes];
5045 var showCallback =
function()
5047 objj_msgSend(
self,
"setHidden:", NO)
5051 var hideCallback = function()
5053 objj_msgSend(
self,
"setHidden:", YES)
5057 objj_msgSend(self, "setHidden:", YES);
5058 [
CPTimer scheduledTimerWithTimeInterval:0.1 callback:showCallback repeats:NO];
5059 [
CPTimer scheduledTimerWithTimeInterval:0.19 callback:hideCallback repeats:NO];
5060 [
CPTimer scheduledTimerWithTimeInterval:0.27 callback:showCallback repeats:NO];
5065 @implementation _CPColumnDragView :
CPView
5070 - (id)initWithLineColor:(
CPColor)aColor
5072 self = [
super initWithFrame:_CGRectMakeZero()];
5075 _lineColor = aColor;
5080 - (void)drawRect:(CGRect)aRect
5087 _CGPointMake(0.5, 0),
5088 _CGPointMake(0.5, aRect.size.height)
5094 _CGPointMake(aRect.size.width - 0.5, 0),
5095 _CGPointMake(aRect.size.width - 0.5, aRect.size.height)
5108 - (BOOL)disableAutomaticResizing
5110 return _disableAutomaticResizing;
5116 - (void)setDisableAutomaticResizing:(BOOL)aValue
5118 _disableAutomaticResizing = aValue;
5136 - (void)setContent:(
id)aValue