100 #define NUMBER_OF_COLUMNS() (_tableColumns.length)
101 #define UPDATE_COLUMN_RANGES_IF_NECESSARY() \
102 if (_dirtyTableColumnRangeIndex !== CPNotFound) \
103 [self _recalculateTableColumnRanges];
104 #define FULL_ROW_HEIGHT() (_rowHeight + _intercellSpacing.height)
105 #define ROW_BOTTOM(__heightInfo) (__heightInfo.y + __heightInfo.height + _intercellSpacing.height)
106 #define HAS_VARIABLE_ROW_HEIGHTS() (_implementedDelegateMethods & CPTableViewDelegate_tableView_heightOfRow_)
115 - (CPDragOperation)
tableView:(
CPTableView)aTableView validateDrop:(
id <
CPDraggingInfo>)info proposedRow:(CPInteger)aRowIndex proposedDropOperation:(CPTableViewDropOperation)anOperation;
116 - (CPInteger)numberOfRowsInTableView:(
CPTableView)aTableView;
126 - (BOOL)selectionShouldChangeInTableView:(
CPTableView)aTableView;
129 - (BOOL)
tableView:(
CPTableView)aTableView shouldReorderColumn:(CPInteger)columnIndex toColumn:(NSInteger)newColumnIndex;
136 - (CPInteger)
tableView:(
CPTableView)aTableView nextTypeSelectMatchFromRow:(CPInteger)startRow toRow:(CPInteger)endRow forString:(
CPString)searchString;
137 - (
CPMenu)tableViewMenuForTableColumn:(
CPTableColumn)aTableColumn row:(CPInteger)aRowIndex;
148 - (void)tableViewSelectionDidChange:(
CPNotification)aNotification;
149 - (void)tableViewSelectionIsChanging:(
CPNotification)aNotification;
153 @implementation _CPTableDrawView :
CPView
163 _tableView = aTableView;
168 - (void)drawRect:(CGRect)aRect
170 var
frame = [
self frame],
175 [_tableView _drawRect:aRect];
204 id <CPTableViewDataSource> _dataSource;
205 CPInteger _implementedDataSourceMethods;
207 id <CPTableViewDelegate> _delegate;
208 CPInteger _implementedDelegateMethods;
210 CPArray _tableColumns;
211 CPArray _tableColumnRanges;
212 CPInteger _dirtyTableColumnRangeIndex;
213 CPInteger _numberOfHiddenColumns;
216 BOOL _invalidateObjectValuesCache;
217 Object _objectValues;
223 Object _dataViewsForRows;
224 Object _cachedDataViews;
226 Object _unavailable_custom_cibs;
229 BOOL _allowsColumnReordering;
230 BOOL _allowsColumnResizing;
231 BOOL _allowsColumnSelection;
232 BOOL _allowsMultipleSelection;
233 BOOL _allowsEmptySelection;
235 CPArray _sortDescriptors;
238 CGSize _intercellSpacing;
241 BOOL _usesAlternatingRowBackgroundColors;
242 CPArray _alternatingRowBackgroundColors;
244 unsigned _selectionHighlightStyle;
245 CPColor _unfocusedSelectionHighlightColor;
248 unsigned _gridStyleMask;
250 unsigned _numberOfRows;
253 CPArray _cachedRowHeights;
257 BOOL _autosaveTableColumns;
260 _CPCornerView _cornerView;
264 CPInteger _selectionAnchorRow;
265 CPInteger _lastSelectedRow;
267 CGPoint _startTrackingPoint;
268 CPDate _startTrackingTimestamp;
269 BOOL _trackingPointMovedOutOfClickSlop;
270 CPInteger _editingRow;
271 CPInteger _editingColumn;
273 _CPTableDrawView _tableDrawView;
276 CPInteger _clickedRow;
277 CPInteger _clickedColumn;
278 unsigned _columnAutoResizingStyle;
280 int _lastTrackedRowIndex;
281 CGPoint _originalMouseDownPoint;
282 BOOL _verticalMotionCanDrag;
283 unsigned _destinationDragStyle;
284 BOOL _isSelectingSession;
286 BOOL _wasSelectionBroken;
288 _CPDropOperationDrawingView _dropOperationFeedbackView;
289 CPDragOperation _dragOperationDefaultMask;
290 int _retargetedDropRow;
291 CPDragOperation _retargetedDropOperation;
293 BOOL _disableAutomaticResizing;
294 BOOL _lastColumnShouldSnap;
295 BOOL _implementsCustomDrawRow;
297 BOOL _contentBindingExplicitlySet;
299 SEL _viewForTableColumnRowSelector;
301 CPInteger _draggedColumnIndex;
302 BOOL _draggedColumnIsSelected;
303 BOOL _needsDifferedTableColumnRemove;
304 CPArray _differedColumnDataToRemove;
306 Function _BlockDeselectView;
307 Function _BlockSelectView;
328 @"grid-line-thickness": 1.0,
336 @"default-row-height": 25.0,
337 @"dropview-on-background-color": [
CPNull null],
341 @"dropview-on-selected-background-color": [
CPNull null],
342 @"dropview-on-selected-border-color": [
CPNull null],
343 @"dropview-on-selected-border-width": [
CPNull null],
344 @"dropview-on-selected-border-radius": [
CPNull null],
345 @"dropview-above-border-color": [
CPNull null],
346 @"dropview-above-border-width": [
CPNull null],
347 @"dropview-above-selected-border-color": [
CPNull null],
348 @"dropview-above-selected-border-width": [
CPNull null]
352 - (id)initWithFrame:(CGRect)aFrame
359 _allowsColumnReordering = YES;
360 _allowsColumnResizing = YES;
361 _allowsMultipleSelection = NO;
362 _allowsEmptySelection = YES;
363 _allowsColumnSelection = NO;
364 _disableAutomaticResizing = NO;
374 _tableColumnRanges = [];
376 _numberOfHiddenColumns = 0;
378 _intercellSpacing = CGSizeMake(3.0, 2.0);
387 _currentHighlightedTableColumn = nil;
390 _verticalMotionCanDrag = YES;
391 _isSelectingSession = NO;
392 _retargetedDropRow = nil;
393 _retargetedDropOperation = nil;
394 _dragOperationDefaultMask = nil;
396 _contentBindingExplicitlySet = NO;
413 _lastSelectedRow = _clickedColumn = _clickedRow = -1;
418 _dropOperationFeedbackView = [[_CPDropOperationDrawingView alloc] initWithFrame:CGRectMakeZero()];
419 [_dropOperationFeedbackView setTableView:self];
421 _lastColumnShouldSnap = NO;
423 if (!_alternatingRowBackgroundColors)
426 _tableColumnRanges = [];
427 _dirtyTableColumnRangeIndex = 0;
428 _numberOfHiddenColumns = 0;
431 _invalidateObjectValuesCache = NO;
432 _dataViewsForRows = { };
436 _cachedDataViews = { };
437 _archivedDataViews = nil;
438 _viewForTableColumnRowSelector = nil;
439 _unavailable_custom_cibs = { };
440 _cachedRowHeights = [];
444 _tableDrawView = [[_CPTableDrawView alloc] initWithTableView:self];
446 [
self addSubview:_tableDrawView];
448 _draggedColumnIndex = -1;
449 _draggedColumnIsSelected = NO;
459 _differedColumnDataToRemove = [];
460 _needsDifferedTableColumnRemove = NO;
461 _implementsCustomDrawRow = [
self implementsSelector:@selector(drawRow:clipRect:)];
463 if (!_sortDescriptors)
464 _sortDescriptors = [];
466 [
self _initSubclass];
469 - (void)_initSubclass
471 _BlockDeselectView =
function(view, row, column)
473 [view unsetThemeState:CPThemeStateSelectedDataView];
476 _BlockSelectView =
function(view, row, column)
478 [view setThemeState:CPThemeStateSelectedDataView];
549 if (_dataSource === aDataSource)
552 _dataSource = aDataSource;
553 _implementedDataSourceMethods = 0;
560 if ([_dataSource respondsToSelector:
@selector(numberOfRowsInTableView:)])
563 if ([_dataSource respondsToSelector:
@selector(
tableView:objectValueForTableColumn:row:)])
566 if ([_dataSource respondsToSelector:
@selector(
tableView:setObjectValue:forTableColumn:row:)])
569 if ([_dataSource respondsToSelector:
@selector(
tableView:acceptDrop:row:dropOperation:)])
572 if ([_dataSource respondsToSelector:
@selector(
tableView:namesOfPromisedFilesDroppedAtDestination:forDraggedRowsWithIndexes:)])
575 if ([_dataSource respondsToSelector:
@selector(
tableView:validateDrop:proposedRow:proposedDropOperation:)])
578 if ([_dataSource respondsToSelector:
@selector(
tableView:writeRowsWithIndexes:toPasteboard:)])
581 if ([_dataSource respondsToSelector:
@selector(
tableView:sortDescriptorsDidChange:)])
584 [
self _reloadDataViews];
601 [
self _reloadDataViews];
617 [
self _enumerateViewsInRows:rowIndexes columns:columnIndexes usingBlock:function(view, row, column, stop)
619 var tableColumn = [_tableColumns objectAtIndex:column];
620 [
self _setObjectValueForTableColumn:tableColumn row:row forView:view useCache:NO];
625 - (void)_reloadDataViews
630 _reloadAllRows = YES;
632 _cachedRowHeights = [];
637 [_groupRows removeAllIndexes];
640 [
self noteNumberOfRowsChanged];
642 [
self setNeedsLayout];
643 [
self setNeedsDisplay:YES];
653 - (void)setDoubleAction:(
SEL)anAction
655 _doubleAction = anAction;
663 return _doubleAction;
669 - (CPInteger)clickedColumn
671 return _clickedColumn;
677 - (CPInteger)clickedRow
687 - (void)setAllowsColumnReordering:(BOOL)shouldAllowColumnReordering
689 _allowsColumnReordering = !!shouldAllowColumnReordering;
695 - (BOOL)allowsColumnReordering
697 return _allowsColumnReordering;
704 - (void)setAllowsColumnResizing:(BOOL)shouldAllowColumnResizing
706 _allowsColumnResizing = !!shouldAllowColumnResizing;
712 - (BOOL)allowsColumnResizing
714 return _allowsColumnResizing;
721 - (void)setAllowsMultipleSelection:(BOOL)shouldAllowMultipleSelection
723 _allowsMultipleSelection = !!shouldAllowMultipleSelection;
731 - (BOOL)allowsMultipleSelection
733 return _allowsMultipleSelection;
740 - (void)setAllowsEmptySelection:(BOOL)shouldAllowEmptySelection
742 _allowsEmptySelection = !!shouldAllowEmptySelection;
748 - (BOOL)allowsEmptySelection
750 return _allowsEmptySelection;
758 - (void)setAllowsColumnSelection:(BOOL)shouldAllowColumnSelection
760 _allowsColumnSelection = !!shouldAllowColumnSelection;
767 - (BOOL)allowsColumnSelection
769 return _allowsColumnSelection;
779 - (void)setIntercellSpacing:(CGSize)aSize
781 if (CGSizeEqualToSize(_intercellSpacing, aSize))
784 _intercellSpacing = CGSizeMakeCopy(aSize);
786 _dirtyTableColumnRangeIndex = 0;
787 [
self _recalculateTableColumnRanges];
789 [_headerView setNeedsDisplay:YES];
790 [_headerView setNeedsLayout];
792 [
self _reloadDataViews];
798 - (CGSize)intercellSpacing
800 return CGSizeMakeCopy(_intercellSpacing);
809 - (void)setRowHeight:(
unsigned)aRowHeight
812 aRowHeight = +aRowHeight;
814 if (_rowHeight === aRowHeight)
817 _rowHeight = MAX(0.0, aRowHeight);
825 - (unsigned)rowHeight
835 - (void)setUsesAlternatingRowBackgroundColors:(BOOL)shouldUseAlternatingRowBackgroundColors
837 _usesAlternatingRowBackgroundColors = shouldUseAlternatingRowBackgroundColors;
843 - (BOOL)usesAlternatingRowBackgroundColors
845 return _usesAlternatingRowBackgroundColors;
853 - (void)setAlternatingRowBackgroundColors:(CPArray)alternatingRowBackgroundColors
863 - (CPArray)alternatingRowBackgroundColors
879 - (unsigned)selectionHighlightStyle
881 return _selectionHighlightStyle;
895 - (void)setSelectionHighlightStyle:(
unsigned)aSelectionHighlightStyle
897 _selectionHighlightStyle = aSelectionHighlightStyle;
905 [
self _updateHighlightWithOldColumns:[
CPIndexSet indexSet] newColumns:_selectedColumnIndexes];
914 - (void)setSelectionHighlightColor:(
CPColor)aColor
916 if ([[
self selectionHighlightColor]
isEqual:aColor])
936 if (!_unfocusedSelectionHighlightColor)
937 _unfocusedSelectionHighlightColor = [
self _unfocusedSelectionColorFromColor:[
self selectionHighlightColor] saturation:0];
939 return _unfocusedSelectionHighlightColor;
983 if (!_unfocusedSourceListSelectionColor)
987 _unfocusedSourceListSelectionColor = @{
988 CPSourceListGradient: [
self _unfocusedGradientFromGradient:[sourceListColors objectForKey:CPSourceListGradient]],
989 CPSourceListTopLineColor: [
self _unfocusedSelectionColorFromColor:[sourceListColors objectForKey:CPSourceListTopLineColor] saturation:0.2],
990 CPSourceListBottomLineColor: [
self _unfocusedSelectionColorFromColor:[sourceListColors objectForKey:CPSourceListBottomLineColor] saturation:0.2]
994 return _unfocusedSourceListSelectionColor;
997 - (
CPColor)_unfocusedSelectionColorFromColor:(
CPColor)aColor saturation:(
float)saturation
1004 - (CGGradient)_unfocusedGradientFromGradient:(CGGradient)aGradient
1006 var colors = [aGradient.colors copy],
1007 count = [colors count];
1014 colors[count] =
CGColorCreate(aGradient.colorspace, [[hsb components] copy]);
1044 - (void)setGridStyleMask:(
unsigned)aGrideStyleMask
1046 if (_gridStyleMask === aGrideStyleMask)
1049 _gridStyleMask = aGrideStyleMask;
1057 - (unsigned)gridStyleMask
1059 return _gridStyleMask;
1070 [_tableColumns addObject:aTableColumn];
1073 if (_dirtyTableColumnRangeIndex < 0)
1076 _dirtyTableColumnRangeIndex = MIN(
NUMBER_OF_COLUMNS() - 1, _dirtyTableColumnRangeIndex);
1078 if ([[
self sortDescriptors] count] > 0)
1082 if (aTableColumn === [
self _tableColumnForSortDescriptor:mainSortDescriptor])
1084 var image = [mainSortDescriptor ascending] ? [
self _tableHeaderSortImage] : [
self _tableHeaderReverseSortImage];
1102 var index = [_tableColumns indexOfObjectIdenticalTo:aTableColumn];
1108 [_differedColumnDataToRemove addObject:{"column":aTableColumn, "shouldBeHidden": [aTableColumn
isHidden]}];
1109 _needsDifferedTableColumnRemove = YES;
1114 var tableColumnUID = [aTableColumn
UID];
1116 if (_objectValues[tableColumnUID])
1117 _objectValues[tableColumnUID] = nil;
1119 if (_dirtyTableColumnRangeIndex < 0)
1120 _dirtyTableColumnRangeIndex = index;
1122 _dirtyTableColumnRangeIndex = MIN(index, _dirtyTableColumnRangeIndex);
1132 - (void)_setDraggedColumn:(CPInteger)columnIndex
1138 if (
columnIndex === -1 && _draggedColumnIsSelected)
1139 [_selectedColumnIndexes addIndex:_draggedColumnIndex];
1148 - (void)_moveColumn:(
unsigned)fromIndex toColumn:(
unsigned)toIndex
1151 fromIndex = +fromIndex;
1154 if (fromIndex === toIndex)
1157 if (_dirtyTableColumnRangeIndex < 0)
1158 _dirtyTableColumnRangeIndex = MIN(fromIndex, toIndex);
1160 _dirtyTableColumnRangeIndex = MIN(fromIndex, toIndex, _dirtyTableColumnRangeIndex);
1162 var tableColumn = _tableColumns[fromIndex],
1163 selectedTableColumns = [_tableColumns objectsAtIndexes:_selectedColumnIndexes];
1165 [_tableColumns removeObjectAtIndex:fromIndex];
1166 [_tableColumns insertObject:tableColumn atIndex:toIndex];
1168 [[
self headerView] setNeedsLayout];
1169 [[
self headerView] setNeedsDisplay:YES];
1171 var range =
CPMakeRange(MIN(fromIndex, toIndex), ABS(fromIndex - toIndex) + 1),
1175 [_tableColumns enumerateObjectsUsingBlock:function(tableColumn, idx, stop)
1177 if ([selectedTableColumns containsObjectIdenticalTo:tableColumn])
1178 [selectedColumnIndexes addIndex:idx];
1181 if ([_selectedColumnIndexes containsIndex:fromIndex])
1182 [selectedColumnIndexes addIndex:toIndex];
1184 if (_draggedColumnIndex !== -1)
1185 [layoutColumnIndexes removeIndex:toIndex];
1187 [
self _layoutViewsForRowIndexes:_exposedRows columnIndexes:layoutColumnIndexes];
1188 [
self selectColumnIndexes:selectedColumnIndexes byExtendingSelection:NO];
1189 [
self setNeedsDisplay:YES];
1195 userInfo:@{ @"CPOldColumn": fromIndex, @"CPNewColumn": toIndex }];
1206 - (void)moveColumn:(CPInteger)theColumnIndex toColumn:(CPInteger)theToIndex
1208 [
self _moveColumn:theColumnIndex toColumn:theToIndex];
1216 - (void)_tableColumnVisibilityDidChange:(
CPTableColumn)aColumn
1218 var
columnIndex = [[
self tableColumns] indexOfObjectIdenticalTo:aColumn];
1220 if (_dirtyTableColumnRangeIndex < 0)
1223 _dirtyTableColumnRangeIndex = MIN(columnIndex, _dirtyTableColumnRangeIndex);
1225 [[
self headerView] setNeedsLayout];
1226 [[
self headerView] setNeedsDisplay:YES];
1235 - (CPArray)tableColumns
1237 return _tableColumns;
1246 - (CPInteger)columnWithIdentifier:(
CPString)anIdentifier
1251 for (; index < count; ++index)
1252 if ([_tableColumns[index] identifier] === anIdentifier)
1271 return _tableColumns[index];
1277 - (void)_didResizeTableColumn:(
CPTableColumn)theColumn oldWidth:(
int)oldWidth
1284 userInfo:@{ @"CPTableColumn": theColumn, @"CPOldWidth": oldWidth }];
1298 - (void)selectColumnIndexes:(
CPIndexSet)columns byExtendingSelection:(BOOL)shouldExtendSelection
1301 if (([columns firstIndex] !=
CPNotFound && [columns firstIndex] < 0) || [columns lastIndex] >= [
self numberOfColumns] || (!shouldExtendSelection && [columns isEqualToIndexSet:_selectedColumnIndexes]) || (shouldExtendSelection && [columns count] === 0))
1305 if ([_selectedRowIndexes count] > 0)
1307 [
self _updateHighlightWithOldRows:_selectedRowIndexes newRows:[
CPIndexSet indexSet]];
1311 var previousSelectedIndexes = [_selectedColumnIndexes copy];
1313 if (shouldExtendSelection)
1314 [_selectedColumnIndexes addIndexes:columns];
1316 _selectedColumnIndexes = [columns
copy];
1318 [
self _updateHighlightWithOldColumns:previousSelectedIndexes newColumns:_selectedColumnIndexes];
1322 [_headerView setNeedsDisplay:YES];
1324 [
self _noteSelectionDidChange];
1330 - (void)_setSelectedRowIndexes:(
CPIndexSet)rows
1332 if ([_selectedRowIndexes isEqualToIndexSet:rows])
1335 var previousSelectedIndexes = _selectedRowIndexes;
1337 _lastSelectedRow = ([rows count] > 0) ? [rows lastIndex] : -1;
1338 _selectedRowIndexes = [rows copy];
1340 [
self _updateHighlightWithOldRows:previousSelectedIndexes newRows:_selectedRowIndexes];
1341 [
self setNeedsDisplay:YES];
1344 var binderClass = [[
self class] _binderClassForBinding:@"selectionIndexes"];
1345 [[binderClass getBinding:@"selectionIndexes" forObject:self] reverseSetValueFor:@"selectedRowIndexes"];
1347 [
self _noteSelectionDidChange];
1356 - (void)selectRowIndexes:(
CPIndexSet)rows byExtendingSelection:(BOOL)shouldExtendSelection
1358 if ([rows isEqualToIndexSet:_selectedRowIndexes] ||
1359 (([rows firstIndex] !=
CPNotFound && [rows firstIndex] < 0) || [rows lastIndex] >= [
self numberOfRows]) ||
1364 if ([_selectedColumnIndexes count] > 0)
1366 [
self _updateHighlightWithOldColumns:_selectedColumnIndexes newColumns:[
CPIndexSet indexSet]];
1369 [_headerView setNeedsDisplay:YES];
1372 var newSelectedIndexes;
1373 if (shouldExtendSelection)
1375 newSelectedIndexes = [_selectedRowIndexes copy];
1376 [newSelectedIndexes addIndexes:rows];
1379 newSelectedIndexes = [rows
copy];
1381 [
self _setSelectedRowIndexes:newSelectedIndexes];
1391 if ([
self _delegateRespondsToSelectionIndexesForProposedSelection])
1393 return [
self _sendDelegateSelectionIndexesForProposedSelection:anIndexSet];
1395 else if ([
self _delegateRespondsToShouldSelectRow])
1402 if (![
self _sendDelegateShouldSelectRow:currentIndex])
1403 [indexesToRemove addIndex:currentIndex];
1421 [
self _enumerateViewsInRows:oldRows columns:_exposedColumns usingBlock:_BlockDeselectView];
1424 [
self _enumerateViewsInRows:newRows columns:_exposedColumns usingBlock:_BlockSelectView];
1430 - (void)_updateHighlightWithOldColumns:(
CPIndexSet)oldColumns newColumns:(
CPIndexSet)newColumns
1432 var blockDeselectHeader =
function(column, stop)
1434 var headerView = [_tableColumns[column] headerView];
1435 [headerView unsetThemeState:CPThemeStateSelected];
1440 [
self _enumerateViewsInRows:_exposedRows columns:oldColumns usingBlock:_BlockDeselectView];
1445 [
self _enumerateViewsInRows:_exposedRows columns:newColumns usingBlock:_BlockSelectView];
1448 var headerView = [_tableColumns[column] headerView];
1449 [headerView setThemeState:CPThemeStateSelected];
1457 - (int)selectedColumn
1459 return [_selectedColumnIndexes lastIndex];
1467 return _selectedColumnIndexes;
1475 return _lastSelectedRow;
1483 return [_selectedRowIndexes copy];
1491 - (void)deselectColumn:(CPInteger)anIndex
1493 var selectedColumnIndexes = [_selectedColumnIndexes copy];
1496 [
self _noteSelectionDidChange];
1504 - (void)deselectRow:(CPInteger)aRow
1506 var selectedRowIndexes = [_selectedRowIndexes copy];
1509 [
self _noteSelectionDidChange];
1515 - (CPInteger)numberOfSelectedColumns
1517 return [_selectedColumnIndexes count];
1523 - (CPInteger)numberOfSelectedRows
1525 return [_selectedRowIndexes count];
1534 - (BOOL)isColumnSelected:(CPInteger)anIndex
1536 return [_selectedColumnIndexes containsIndex:anIndex];
1545 - (BOOL)isRowSelected:(CPInteger)aRow
1547 return [_selectedRowIndexes containsIndex:aRow];
1561 - (void)selectAll:(
id)sender
1563 if (_allowsMultipleSelection)
1565 if (![
self _sendDelegateSelectionShouldChangeInTableView])
1568 if ([[
self selectedColumnIndexes] count])
1578 - (void)deselectAll:(
id)sender
1580 if ([
self allowsEmptySelection])
1582 if (![
self _sendDelegateSelectionShouldChangeInTableView])
1592 - (int)numberOfColumns
1602 return _numberOfRows;
1605 - (int)_numberOfRows
1608 contentBindingInfo = [
self infoForBinding:@"content"];
1610 if (contentBindingInfo)
1612 var destination = [contentBindingInfo objectForKey:CPObservedObjectKey],
1613 keyPath = [contentBindingInfo objectForKey:CPObservedKeyPathKey];
1615 numberOfRows = [[destination valueForKeyPath:keyPath] count];
1618 numberOfRows = [_dataSource numberOfRowsInTableView:self] || 0;
1622 CPLog(
@"no content binding established and data source " + [_dataSource description] +
" does not implement numberOfRowsInTableView:");
1626 return numberOfRows;
1643 if (_cornerView === aView)
1646 _cornerView = aView;
1650 if ([scrollView isKindOfClass:[
CPScrollView class]] && [scrollView documentView] ===
self)
1651 [scrollView _updateCornerAndHeaderView];
1672 if (_headerView === aHeaderView)
1675 [_headerView setTableView:nil];
1677 _headerView = aHeaderView;
1681 [_headerView setTableView:self];
1682 [_headerView setFrameSize:CGSizeMake(CGRectGetWidth([
self frame]), CGRectGetHeight([_headerView frame]))];
1687 [_cornerView removeFromSuperview];
1693 if ([scrollView isKindOfClass:[
CPScrollView class]] && [scrollView documentView] ===
self)
1694 [scrollView _updateCornerAndHeaderView];
1702 - (void)_recalculateTableColumnRanges
1707 if (_dirtyTableColumnRangeIndex < 0)
1710 _numberOfHiddenColumns = 0;
1712 var index = _dirtyTableColumnRangeIndex,
1714 x = index === 0 ? 0.0 :
CPMaxRange(_tableColumnRanges[index - 1]);
1716 for (; index < count; ++index)
1718 var tableColumn = _tableColumns[index];
1722 _numberOfHiddenColumns += 1;
1727 var
width = [_tableColumns[index] width] + _intercellSpacing.width;
1729 _tableColumnRanges[index] =
CPMakeRange(x, width);
1735 _tableColumnRanges.length = count;
1745 - (CGRect)rectOfColumn:(CPInteger)aColumnIndex
1751 aColumnIndex = +aColumnIndex;
1754 return CGRectMakeZero();
1756 if ([[_tableColumns objectAtIndex:aColumnIndex]
isHidden])
1757 return CGRectMakeZero();
1761 var range = _tableColumnRanges[aColumnIndex];
1763 return CGRectMake(range.location, 0.0, range.length, CGRectGetHeight([
self bounds]));
1773 - (CGRect)_rectOfRow:(CPInteger)aRowIndex checkRange:(BOOL)checkRange
1778 var lastIndex = [
self numberOfRows] - 1,
1779 validIndex = aRowIndex >= 0 && aRowIndex <= lastIndex;
1781 if (checkRange && !validIndex)
1782 return CGRectMakeZero();
1786 fixedHeightRows = 0;
1790 [
self _populateRowHeightCacheIfNeeded];
1798 heightInfo = _cachedRowHeights[aRowIndex];
1800 height = heightInfo.height + _intercellSpacing.height;
1806 if (_numberOfRows > 0)
1808 heightInfo = _cachedRowHeights[lastIndex];
1813 fixedHeightRows = aRowIndex - _numberOfRows;
1819 fixedHeightRows = aRowIndex;
1825 return CGRectMake(0.0, y, CGRectGetWidth([
self bounds]), height);
1833 - (CGRect)rectOfRow:(CPInteger)aRowIndex
1835 return [
self _rectOfRow:aRowIndex checkRange:YES];
1843 - (CPRange)rowsInRect:(CGRect)aRect
1849 if (_numberOfRows <= 0)
1855 if (!CGRectIntersectsRect(aRect, bounds))
1858 var firstRow = [
self rowAtPoint:aRect.origin];
1864 var lastRow = [
self rowAtPoint:CGPointMake(0.0, CGRectGetMaxY(aRect))];
1868 lastRow = _numberOfRows - 1;
1870 return CPMakeRange(firstRow, lastRow - firstRow + 1);
1878 - (CPRange)_exposedRowsInRect:(CGRect)aRect
1880 var rowRange = [
self rowsInRect:aRect],
1882 rectOfLastRealRow = [self _rectOfRow:lastRealRow checkRange:NO],
1883 bottomOfRealRows = CGRectGetMaxY(rectOfLastRealRow),
1884 rectBottom = CGRectGetMaxY(aRect);
1887 if (bottomOfRealRows >= rectBottom)
1890 var numberOfSynthesizedRows = CEIL((rectBottom - bottomOfRealRows) /
FULL_ROW_HEIGHT());
1892 rowRange.length += numberOfSynthesizedRows;
1908 var column = MAX(0, [
self columnAtPoint:CGPointMake(aRect.origin.x, 0.0)]),
1909 lastColumn = [
self columnAtPoint:CGPointMake(CGRectGetMaxX(aRect), 0.0)];
1915 if (_numberOfHiddenColumns <= 0)
1920 for (; column <= lastColumn; ++column)
1922 var tableColumn = _tableColumns[column];
1925 [indexSet addIndex:column];
1936 - (CPInteger)columnAtPoint:(CGPoint)aPoint
1944 if (!CGRectContainsPoint(bounds, aPoint))
1951 high = _tableColumnRanges.length - 1;
1955 var middle = FLOOR(low + (high - low) / 2),
1956 range = _tableColumnRanges[middle];
1958 if (x < range.location)
1966 var numberOfColumns = _tableColumnRanges.length;
1968 while (middle < numberOfColumns && [_tableColumns[middle]
isHidden])
1971 if (middle < numberOfColumns)
1986 - (CPInteger)rowAtPoint:(CGPoint)aPoint
1995 if (aPoint.x < CGRectGetMinX(bounds) || aPoint.x >= CGRectGetMaxX(bounds))
2004 var heightInfo = [_cachedRowHeights lastObject];
2006 if (!heightInfo || aPoint.y >=
ROW_BOTTOM(heightInfo))
2009 return [_cachedRowHeights indexOfObject:aPoint
2012 usingComparator:function(aPoint, heightInfo)
2014 if (aPoint.y < heightInfo.y)
2015 return CPOrderedAscending;
2017 if (aPoint.y > ROW_BOTTOM(heightInfo))
2018 return CPOrderedDescending;
2020 return CPOrderedSame;
2027 return row >= _numberOfRows ? -1 : row;
2068 - (void)getColumn:(Function)columnRef row:(Function)rowRef forView:(
CPView)aView
2070 var columnResult = -1,
2073 if (aView && [aView isKindOfClass:[
CPView class]] && ![aView isKindOfClass:[
CPTableView class]])
2075 var cellView = aView,
2082 if (!cellView || cellView === contentView)
2089 var superview = [cellView superview];
2091 if ([superview isKindOfClass:[
CPTableView class]])
2097 cellView = superview;
2103 [
self _enumerateViewsInRows:_exposedRows columns:_exposedColumns usingBlock:function(view, row, column, stop)
2106 if (view === cellView)
2108 columnResult = column;
2117 columnRef(columnResult);
2130 - (CGRect)frameOfDataViewAtColumn:(CPInteger)aColumn row:(CPInteger)aRow
2134 if (aColumn > [
self numberOfColumns] || aRow > [
self numberOfRows])
2135 return CGRectMakeZero();
2137 var tableColumnRange = _tableColumnRanges[aColumn],
2139 leftInset = FLOOR(_intercellSpacing.width / 2.0),
2140 topInset = FLOOR(_intercellSpacing.height / 2.0);
2142 return CGRectMake(tableColumnRange.location + leftInset, CGRectGetMinY(rectOfRow) + topInset, tableColumnRange.length - _intercellSpacing.width, CGRectGetHeight(rectOfRow) - _intercellSpacing.height);
2148 - (void)resizeWithOldSuperviewSize:(CGSize)aSize
2152 if (_disableAutomaticResizing)
2155 var mask = _columnAutoResizingStyle;
2158 if (!_lastColumnShouldSnap)
2163 if (!superview || ![superview isKindOfClass:[
CPClipView class]])
2166 var superviewWidth = [superview bounds].size.width,
2167 lastColumnMaxX = CGRectGetMaxX([
self rectOfColumn:[
self numberOfColumns] -1]);
2170 if (lastColumnMaxX >= superviewWidth && lastColumnMaxX <= aSize.width || lastColumnMaxX <= superviewWidth && lastColumnMaxX >= aSize.width)
2171 _lastColumnShouldSnap = YES;
2177 [
self _resizeAllColumnUniformlyWithOldSize:aSize];
2181 [
self _autoResizeFirstColumn];
2187 - (void)_autoResizeFirstColumn
2189 var superview = [
self superview];
2197 columnToResize = nil,
2201 for (; i < count; i++)
2203 var column = _tableColumns[i];
2207 if (!columnToResize)
2208 columnToResize = column;
2209 totalWidth += [column
width] + _intercellSpacing.
width;
2216 var superviewSize = [superview bounds].size,
2217 newWidth = superviewSize.width - totalWidth;
2219 newWidth += [columnToResize
width];
2220 [columnToResize _tryToResizeToWidth:newWidth];
2223 [
self setNeedsLayout];
2231 - (void)_resizeAllColumnUniformlyWithOldSize:(CGSize)oldSize
2235 var superview = [
self superview];
2237 if (!superview || ![superview isKindOfClass:[
CPClipView class]])
2242 var superviewWidth = [superview bounds].size.width,
2245 remainingSpace = 0.0,
2250 for (; i < count; i++)
2252 var tableColumn = _tableColumns[i];
2254 [resizableColumns addIndex:i];
2257 var maxXofColumns = CGRectGetMaxX([
self rectOfColumn:[resizableColumns lastIndex]]),
2258 remainingSpace = superviewWidth - maxXofColumns,
2259 resizeableColumnsCount = [resizableColumns count],
2262 while (remainingSpace && resizeableColumnsCount)
2265 proportionate += remainingSpace / resizeableColumnsCount;
2268 remainingSpace = 0.0;
2272 while ((index = [resizableColumns indexGreaterThanIndex:index]) !==
CPNotFound)
2274 var item = _tableColumns[index],
2275 proposedWidth = [item width] + proportionate,
2276 resizeLeftovers = [item _tryToResizeToWidth:proposedWidth];
2278 if (resizeLeftovers)
2280 [resizableColumns removeIndex:index];
2282 remainingSpace += resizeLeftovers;
2291 while (count-- && [_tableColumns[count] isHidden]);
2294 var delta = superviewWidth - CGRectGetMaxX([self rectOfColumn:count]) - ([self intercellSpacing].
width || 1),
2295 newSize = [item width] + delta;
2297 [item _tryToResizeToWidth:newSize];
2311 - (void)setColumnAutoresizingStyle:(
unsigned)style
2314 _columnAutoResizingStyle = style;
2320 - (unsigned)columnAutoresizingStyle
2322 return _columnAutoResizingStyle;
2328 - (void)sizeLastColumnToFit
2330 _lastColumnShouldSnap = YES;
2337 var superviewSize = [superview bounds].size;
2344 while (count-- && [_tableColumns[count] isHidden]);
2349 var columnToResize = _tableColumns[count],
2350 newSize = MAX(0.0, superviewSize.width - CGRectGetMinX([
self rectOfColumn:count]) - _intercellSpacing.width);
2352 [columnToResize _tryToResizeToWidth:newSize];
2361 - (void)noteNumberOfRowsChanged
2363 var oldNumberOfRows = _numberOfRows;
2365 _numberOfRows = [
self _numberOfRows];
2367 _cachedRowHeights = [];
2375 var hangingSelections = oldNumberOfRows - _numberOfRows;
2377 if (hangingSelections > 0)
2379 var previousSelectionCount = [_selectedRowIndexes count];
2380 [_selectedRowIndexes removeIndexesInRange:CPMakeRange(_numberOfRows, hangingSelections)];
2382 if (![_selectedRowIndexes containsIndex:[
self selectedRow]])
2386 if (previousSelectionCount > [_selectedRowIndexes count])
2387 [
self _noteSelectionDidChange];
2396 - (void)_populateRowHeightCacheIfNeeded
2398 if ([
self numberOfRows] !== _cachedRowHeights.length)
2407 - (void)_noteHeightOfRowsWithIndexesChanged:(
CPIndexSet)anIndexSet
2419 var y = i < _cachedRowHeights.length ? _cachedRowHeights[i].y : 0;
2421 for (var count = [
self numberOfRows]; i < count; ++i)
2425 if ([anIndexSet containsIndex:i])
2426 height = [
self _sendDelegateHeightOfRow:i];
2428 height = _cachedRowHeights[i].height || _rowHeight;
2430 _cachedRowHeights[i] = {y:y, height:height};
2431 y += height + _intercellSpacing.height;
2440 - (void)noteHeightOfRowsWithIndexesChanged:(
CPIndexSet)anIndexSet
2442 [
self _noteHeightOfRowsWithIndexesChanged:anIndexSet];
2443 [
self _reloadDataViews];
2453 var
width = _tableColumnRanges.length > 0 ?
CPMaxRange([_tableColumnRanges lastObject]) : 0.0,
2459 else if (_numberOfRows > 0)
2461 [
self _populateRowHeightCacheIfNeeded];
2463 var heightInfo = _cachedRowHeights[_cachedRowHeights.length - 1];
2468 if ([superview isKindOfClass:[CPClipView
class]])
2470 var superviewSize = [superview bounds].size;
2472 width = MAX(superviewSize.width, width);
2473 height = MAX(superviewSize.height, height);
2488 - (void)scrollRowToVisible:(
int)rowIndex
2493 visible.origin.y = rowRect.origin.y;
2494 visible.size.height = rowRect.size.height;
2504 - (void)scrollColumnToVisible:(
int)columnIndex
2509 visible.origin.x = colRect.origin.x;
2510 visible.size.width = colRect.size.width;
2513 [_headerView scrollRectToVisible:colRect];
2524 if (_autosaveName === theAutosaveName)
2527 _autosaveName = theAutosaveName;
2530 [
self _restoreFromAutosave];
2538 return _autosaveName;
2547 - (void)setAutosaveTableColumns:(BOOL)shouldAutosave
2549 _autosaveTableColumns = shouldAutosave;
2555 - (BOOL)autosaveTableColumns
2557 return _autosaveTableColumns;
2565 return @"CPTableView Columns " + theAutosaveName;
2571 - (BOOL)_autosaveEnabled
2573 return [
self autosaveName] && [
self autosaveTableColumns];
2584 if (![
self _autosaveEnabled])
2588 autosaveName = [
self autosaveName];
2590 var columns = [
self tableColumns],
2593 for (var i = 0; i < [columns count]; i++)
2595 var column = [columns objectAtIndex:i],
2597 @"identifier": [column identifier],
2598 @"width": [column width]
2601 [columnsSetup addObject:metaData];
2604 [userDefaults setObject:columnsSetup forKey:[
self _columnsKeyForAutosaveName:autosaveName]];
2610 - (void)_restoreFromAutosave
2612 if (![
self _autosaveEnabled])
2616 autosaveName = [
self autosaveName],
2617 tableColumns = [userDefaults objectForKey:[
self _columnsKeyForAutosaveName:autosaveName]];
2619 if ([tableColumns count] != [[
self tableColumns] count])
2622 for (var i = 0; i < [tableColumns count]; i++)
2624 var metaData = [tableColumns objectAtIndex:i],
2625 columnIdentifier = [metaData objectForKey:@"identifier"],
2626 column = [
self columnWithIdentifier:columnIdentifier],
2627 tableColumn = [
self tableColumnWithIdentifier:columnIdentifier];
2631 [
self _moveColumn:column toColumn:i];
2632 [tableColumn setWidth:[metaData objectForKey:@"width"]];
2786 if (_delegate === aDelegate)
2789 _delegate = aDelegate;
2790 _implementedDelegateMethods = 0;
2792 if ([_delegate respondsToSelector:
@selector(selectionShouldChangeInTableView:)])
2795 if ([_delegate respondsToSelector:
@selector(
tableView:viewForTableColumn:row:)])
2797 else if ([_delegate respondsToSelector:
@selector(
tableView:dataViewForTableColumn:row:)])
2800 CPLog.warn(
"tableView:dataViewForTableColumn: is deprecated. You should use -tableView:viewForTableColumn: where you can request the view with -makeViewWithIdentifier:owner:");
2803 [
self _updateIsViewBased];
2805 if ([_delegate respondsToSelector:
@selector(
tableView:didClickTableColumn:)])
2808 if ([_delegate respondsToSelector:
@selector(
tableView:didDragTableColumn:)])
2811 if ([_delegate respondsToSelector:
@selector(
tableView:heightOfRow:)])
2814 if ([_delegate respondsToSelector:
@selector(
tableView:isGroupRow:)])
2817 if ([_delegate respondsToSelector:
@selector(
tableView:mouseDownInHeaderOfTableColumn:)])
2820 if ([_delegate respondsToSelector:
@selector(
tableView:nextTypeSelectMatchFromRow:toRow:forString:)])
2823 if ([_delegate respondsToSelector:
@selector(
tableView:selectionIndexesForProposedSelection:)])
2826 if ([_delegate respondsToSelector:
@selector(
tableView:shouldEditTableColumn:row:)])
2829 if ([_delegate respondsToSelector:
@selector(
tableView:shouldSelectRow:)])
2832 if ([_delegate respondsToSelector:
@selector(
tableView:shouldSelectTableColumn:)])
2835 if ([_delegate respondsToSelector:
@selector(
tableView:shouldShowViewExpansionForTableColumn:row:)])
2838 if ([_delegate respondsToSelector:
@selector(
tableView:shouldTrackView:forTableColumn:row:)])
2841 if ([_delegate respondsToSelector:
@selector(
tableView:shouldTypeSelectForEvent:withCurrentSearchString:)])
2844 if ([_delegate respondsToSelector:
@selector(
tableView:toolTipForView:rect:tableColumn:row:mouseLocation:)])
2847 if ([_delegate respondsToSelector:
@selector(
tableView:typeSelectStringForTableColumn:row:)])
2850 if ([_delegate respondsToSelector:
@selector(
tableView:willDisplayView:forTableColumn:row:)])
2853 if ([_delegate respondsToSelector:
@selector(
tableView:willRemoveView:forTableColumn:row:)])
2856 if ([_delegate respondsToSelector:
@selector(
tableView:menuForTableColumn:row:)])
2859 if ([_delegate respondsToSelector:
@selector(
tableView:shouldReorderColumn:toColumn:)])
2862 if ([_delegate respondsToSelector:
@selector(tableViewColumnDidMove:)])
2865 if ([_delegate respondsToSelector:
@selector(tableViewColumnDidResize:)])
2868 if ([_delegate respondsToSelector:
@selector(tableViewSelectionDidChange:)])
2871 if ([_delegate respondsToSelector:
@selector(tableViewSelectionIsChanging:)])
2886 - (void)_didClickTableColumn:(CPInteger)clickedColumn modifierFlags:(
unsigned)modifierFlags
2888 [
self _changeSortDescriptorsForClickOnColumn:clickedColumn];
2890 if (_allowsColumnSelection)
2892 if ([
self _sendDelegateSelectionShouldChangeInTableView] && [
self _sendDelegateShouldSelectTableColumn:clickedColumn])
2894 [
self _noteSelectionIsChanging];
2897 if ([
self isColumnSelected:clickedColumn])
2898 [
self deselectColumn:clickedColumn];
2899 else if ([
self allowsMultipleSelection] == YES)
2907 var startColumn = MIN(clickedColumn, [_selectedColumnIndexes lastIndex]),
2908 endColumn = MAX(clickedColumn, [_selectedColumnIndexes firstIndex]);
2920 [
self _sendDelegateDidClickTableColumn:clickedColumn];
2928 - (void)_changeSortDescriptorsForClickOnColumn:(CPInteger)column
2930 var tableColumn = [_tableColumns objectAtIndex:column],
2931 newMainSortDescriptor = [tableColumn sortDescriptorPrototype];
2933 if (!newMainSortDescriptor)
2936 var oldMainSortDescriptor = nil,
2937 oldSortDescriptors = [
self sortDescriptors],
2938 newSortDescriptors = [CPArray arrayWithArray:oldSortDescriptors],
2940 e = [newSortDescriptors objectEnumerator],
2942 outdatedDescriptors = [CPArray array];
2944 if ([_sortDescriptors count] > 0)
2945 oldMainSortDescriptor = [[
self sortDescriptors] objectAtIndex: 0];
2948 while ((descriptor = [e nextObject]) !== nil)
2950 if ([[descriptor key]
isEqual: [newMainSortDescriptor key]])
2951 [outdatedDescriptors addObject:descriptor];
2955 if ([[newMainSortDescriptor key]
isEqual:[oldMainSortDescriptor key]])
2956 newMainSortDescriptor = [oldMainSortDescriptor reversedSortDescriptor];
2958 [newSortDescriptors removeObjectsInArray:outdatedDescriptors];
2959 [newSortDescriptors insertObject:newMainSortDescriptor atIndex:0];
2961 [
self setHighlightedTableColumn:tableColumn];
2962 [
self setSortDescriptors:newSortDescriptors];
2978 if ([headerView respondsToSelector:
@selector(_setIndicatorImage:)])
2979 [headerView _setIndicatorImage:anImage];
2986 - (
CPImage)_tableHeaderSortImage
2988 return [
self currentValueForThemeAttribute:@"sort-image"];
2994 - (
CPImage)_tableHeaderReverseSortImage
2996 return [
self currentValueForThemeAttribute:@"sort-image-reversed"];
3004 return _currentHighlightedTableColumn;
3012 if (_currentHighlightedTableColumn == aTableColumn)
3017 if (_currentHighlightedTableColumn != nil)
3018 [[_currentHighlightedTableColumn headerView] unsetThemeState:CPThemeStateSelected];
3020 if (aTableColumn != nil)
3024 _currentHighlightedTableColumn = aTableColumn;
3033 - (BOOL)canDragRowsWithIndexes:(
CPIndexSet)rowIndexes atPoint:(CGPoint)mouseDownPoint
3048 - (
CPImage)dragImageForRowsWithIndexes:(
CPIndexSet)dragRows tableColumns:(CPArray)theTableColumns event:(
CPEvent)dragEvent offset:(CGPoint)dragImageOffset
3065 - (
CPView)dragViewForRowsWithIndexes:(
CPIndexSet)theDraggedRows tableColumns:(CPArray)theTableColumns event:(
CPEvent)theDragEvent offset:(CGPoint)dragViewOffset
3070 [dragView setAlphaValue:0.7];
3075 [
self _enumerateViewsInRows:theDraggedRows tableColumns:theTableColumns usingBlock:function(v, row, tableColumn, stop)
3077 var column = [_tableColumns indexOfObjectIdenticalTo:tableColumn],
3080 [dragView addSubview:newDataView];
3084 dragViewOffset.x = CGRectGetWidth(bounds) / 2 - dragPoint.x;
3085 dragViewOffset.y = CGRectGetHeight(bounds) / 2 - dragPoint.y;
3090 - (
CPView)_dragViewForColumn:(CPInteger)columnIndex
3092 var headerFrame = [_headerView frame],
3093 visibleRect = [
self visibleRect],
3094 visibleRows = [
self rowsInRect:visibleRect],
3095 columnRect = [
self rectOfColumn:columnIndex],
3096 tableColumn = [[
self tableColumns] objectAtIndex:columnIndex],
3097 tableColumnUID = [tableColumn UID],
3098 columnHeaderView = [tableColumn headerView],
3099 columnHeaderFrame = [columnHeaderView frame],
3100 frame = CGRectMake(MAX(CGRectGetMinX(columnRect) - CGRectGetMinX(visibleRect), 0.0),
3102 CGRectGetWidth(columnHeaderFrame),
3103 CGRectGetHeight(visibleRect) + CGRectGetHeight(headerFrame));
3106 var dragView = [[_CPColumnDragDrawingView alloc] initWithFrame:frame];
3108 [dragView setTableView:self];
3109 [dragView setColumnIndex:columnIndex];
3111 [dragView setAlphaValue:0.6];
3114 var columnVisRect = CGRectIntersection(columnRect, visibleRect);
3116 frame = CGRectMake(0.0, CGRectGetHeight(headerFrame), CGRectGetWidth(columnVisRect), CGRectGetHeight(columnVisRect));
3120 [dragView addSubview:columnClipView];
3121 [dragView setColumnClipView:columnClipView];
3122 _draggedColumnIsSelected = [
self isColumnSelected:columnIndex];
3124 var columnLeft = CGRectGetMinX(columnRect),
3125 offset = CGPointMake(columnLeft, CGRectGetMinY(visibleRect));
3127 [
self _enumerateViewsInRows:_exposedRows columns:[
CPIndexSet indexSetWithIndex:columnIndex] usingBlock:function(dataView, row, column, stop)
3129 [
self _addDraggedDataView:dataView toView:columnClipView forColumn:column row:row offset:offset];
3131 delete (_dataViewsForRows[row][tableColumnUID]);
3135 columnHeaderFrame.origin = CGPointMakeZero();
3137 var dragColumnHeaderView = [[_CPTableColumnHeaderView alloc] initWithFrame:columnHeaderFrame],
3138 image = [columnHeaderView _indicatorImage];
3140 [dragColumnHeaderView setStringValue:[columnHeaderView stringValue]];
3141 [dragColumnHeaderView setThemeState:[columnHeaderView themeState]];
3142 [dragColumnHeaderView _setIndicatorImage:image];
3145 [dragColumnHeaderView setTag:1];
3147 [dragView addSubview:dragColumnHeaderView];
3150 [_selectedColumnIndexes removeIndex:columnIndex];
3155 - (void)_addDraggedDataView:(
CPView)aDataView toView:(
CPView)aSuperview forColumn:(CPInteger)column row:(CPInteger)row offset:(CGPoint)offset
3157 var dataViewFrame = [
self frameOfDataViewAtColumn:column row:row];
3159 dataViewFrame.origin.x -= offset.x;
3161 dataViewFrame.origin.y -= offset.y;
3163 [aDataView
setFrame:dataViewFrame];
3172 - (void)setDraggingSourceOperationMask:(CPDragOperation)mask forLocal:(BOOL)isLocal
3175 _dragOperationDefaultMask = mask;
3183 - (void)setDropRow:(CPInteger)row dropOperation:(CPTableViewDropOperation)operation
3188 reason =
@"Attempt to set dropRow=" + row +
3189 " dropOperation=CPTableViewDropOn when [0 - " + numberOfRows +
"] is valid range of rows.";
3194 _retargetedDropRow = row;
3195 _retargetedDropOperation = operation;
3209 - (void)setDraggingDestinationFeedbackStyle:(CPTableViewDraggingDestinationFeedbackStyle)aStyle
3212 _destinationDragStyle = aStyle;
3225 - (CPTableViewDraggingDestinationFeedbackStyle)draggingDestinationFeedbackStyle
3227 return _destinationDragStyle;
3235 - (void)setVerticalMotionCanBeginDrag:(BOOL)aFlag
3237 _verticalMotionCanDrag = aFlag;
3243 - (BOOL)verticalMotionCanBeginDrag
3245 return _verticalMotionCanDrag;
3250 var tableColumns = [
self tableColumns];
3252 for (var i = 0; i < [tableColumns count]; i++)
3254 var tableColumn = [tableColumns objectAtIndex:i],
3255 sortDescriptorPrototype = [tableColumn sortDescriptorPrototype];
3257 if (!sortDescriptorPrototype)
3260 if ([sortDescriptorPrototype key] === [theSortDescriptor key]
3261 && [sortDescriptorPrototype selector] === [theSortDescriptor selector])
3275 - (void)setSortDescriptors:(CPArray)sortDescriptors
3278 newSortDescriptors = [CPArray array];
3280 if (sortDescriptors !== nil)
3281 [newSortDescriptors addObjectsFromArray:sortDescriptors];
3283 if ([newSortDescriptors
isEqual:oldSortDescriptors])
3286 _sortDescriptors = newSortDescriptors;
3288 var oldColumn = nil,
3291 if ([newSortDescriptors count] > 0)
3293 var newMainSortDescriptor = [newSortDescriptors objectAtIndex:0];
3294 newColumn = [
self _tableColumnForSortDescriptor:newMainSortDescriptor];
3297 if ([oldSortDescriptors count] > 0)
3299 var oldMainSortDescriptor = [oldSortDescriptors objectAtIndex:0];
3300 oldColumn = [
self _tableColumnForSortDescriptor:oldMainSortDescriptor];
3303 var image = [newMainSortDescriptor ascending] ? [
self _tableHeaderSortImage] : [
self _tableHeaderReverseSortImage];
3307 [
self _sendDataSourceSortDescriptorsDidChange:oldSortDescriptors];
3309 var binderClass = [[
self class] _binderClassForBinding:@"sortDescriptors"];
3310 [[binderClass getBinding:@"sortDescriptors" forObject:self] reverseSetValueFor:@"sortDescriptors"];
3316 - (CPArray)sortDescriptors
3318 return _sortDescriptors;
3324 - (id)_objectValueForTableColumn:(
CPTableColumn)aTableColumn row:(CPInteger)aRowIndex useCache:(BOOL)useCache
3328 var tableColumnUID = [aTableColumn
UID],
3329 tableColumnObjectValues = _objectValues[tableColumnUID];
3331 if (!tableColumnObjectValues)
3333 tableColumnObjectValues = [];
3334 _objectValues[tableColumnUID] = tableColumnObjectValues;
3338 objectValue = tableColumnObjectValues[aRowIndex];
3341 if (objectValue === undefined)
3343 if ([
self _dataSourceRespondsToObjectValueForTableColumn])
3345 objectValue = [
self _sendDataSourceObjectValueForTableColumn:aTableColumn row:aRowIndex];
3346 tableColumnObjectValues[aRowIndex] = objectValue;
3348 else if (!_isViewBased && ![
self infoForBinding:
@"content"])
3350 CPLog.warn(
@"no content binding established and data source " + [_dataSource description] +
" does not implement tableView:objectValueForTableColumn:row:");
3361 - (CGRect)exposedRect
3369 if ([superview isKindOfClass:[
CPClipView class]])
3370 _exposedRect = [superview bounds];
3372 _exposedRect = [
self bounds];
3375 return _exposedRect;
3385 [
self _unloadDataViewsInRows:_exposedRows columns:_exposedColumns];
3390 _reloadAllRows = NO;
3396 obscuredRows = [_exposedRows copy],
3397 obscuredColumns = [_exposedColumns copy];
3399 [obscuredRows removeIndexes:exposedRows];
3400 [obscuredColumns removeIndexes:exposedColumns];
3402 var newlyExposedRows = [exposedRows copy],
3403 newlyExposedColumns = [exposedColumns copy];
3405 [newlyExposedRows removeIndexes:_exposedRows];
3406 [newlyExposedColumns removeIndexes:_exposedColumns];
3408 var previouslyExposedRows = [exposedRows copy],
3409 previouslyExposedColumns = [exposedColumns copy];
3411 [previouslyExposedRows removeIndexes:newlyExposedRows];
3412 [previouslyExposedColumns removeIndexes:newlyExposedColumns];
3414 [
self _unloadDataViewsInRows:previouslyExposedRows columns:obscuredColumns];
3415 [
self _unloadDataViewsInRows:obscuredRows columns:previouslyExposedColumns];
3416 [
self _unloadDataViewsInRows:obscuredRows columns:obscuredColumns];
3417 [
self _unloadDataViewsInRows:newlyExposedRows columns:newlyExposedColumns];
3419 [
self _loadDataViewsInRows:previouslyExposedRows columns:newlyExposedColumns];
3420 [
self _loadDataViewsInRows:newlyExposedRows columns:previouslyExposedColumns];
3421 [
self _loadDataViewsInRows:newlyExposedRows columns:newlyExposedColumns];
3423 _exposedRows = exposedRows;
3424 _exposedColumns = exposedColumns;
3426 [_tableDrawView setFrame:exposedRect];
3432 if (_needsDifferedTableColumnRemove)
3434 var removeCount = [_differedColumnDataToRemove count],
3437 for (var i = 0; i < removeCount; i++)
3439 var data = _differedColumnDataToRemove[i],
3440 tableColumn = data.column,
3441 columnIdx = [_tableColumns indexOfObject:tableColumn];
3444 [removeIndexes addIndex:columnIdx];
3448 [
self _unloadDataViewsInRows:rowIndexes columns:removeIndexes];
3450 [_tableColumns removeObjectsAtIndexes:removeIndexes];
3452 _dirtyTableColumnRangeIndex = 0;
3453 [
self _recalculateTableColumnRanges];
3455 [_differedColumnDataToRemove removeAllObjects];
3456 _needsDifferedTableColumnRemove = NO;
3461 for (var identifier in _cachedDataViews)
3463 var dataViews = _cachedDataViews[identifier],
3464 count = dataViews.length;
3467 [dataViews[count] removeFromSuperview];
3476 if (![rowIndexes count] || ![columnIndexes count] || [columnIndexes lastIndex] >= [_tableColumns count])
3480 if ([columnIndexes containsIndex:_editingColumn] && [rowIndexes containsIndex:_editingRow])
3481 [
self _resignEditedView];
3483 var tableColumns = [_tableColumns objectsAtIndexes:columnIndexes];
3485 [
self _enumerateViewsInRows:rowIndexes tableColumns:tableColumns usingBlock:function(dataView, row, tableColumn, stop)
3487 var dataViewsForRows = _dataViewsForRows[row],
3488 tableColumnUID = [tableColumn UID];
3490 delete (dataViewsForRows[tableColumnUID]);
3492 [
self _sendDelegateWillRemoveView:dataView forTableColumn:tableColumn row:row];
3493 [
self _enqueueReusableDataView:dataView];
3502 if (![rowIndexes count] || ![columnIndexes count])
3507 if (_numberOfHiddenColumns > 0)
3510 return ![_tableColumns[idx] isHidden];
3515 if (!_dataViewsForRows[rowIndex])
3516 _dataViewsForRows[rowIndex] = {};
3518 var dataViewsForRow = _dataViewsForRows[rowIndex],
3519 isRowSelected = [
self isRowSelected:rowIndex],
3524 var tableColumn = _tableColumns[columnIndex],
3525 tableColumnUID = [tableColumn UID],
3526 dataView = [
self _preparedViewAtColumn:columnIndex row:row isRowSelected:isRowSelected];
3528 if ([dataView superview] !== self)
3529 [
self addSubview:dataView];
3531 dataViewsForRow[tableColumnUID] = dataView;
3536 - (
CPView)preparedViewAtColumn:(CPInteger)column row:(CPInteger)row
3538 return [
self _preparedViewAtColumn:column row:row isRowSelected:[
self isRowSelected:row]];
3541 - (
CPView)_preparedViewAtColumn:(CPInteger)column row:(CPInteger)row isRowSelected:(BOOL)isRowSelected
3543 var tableColumn = _tableColumns[column],
3544 tableColumnUID = [tableColumn UID],
3545 dataView = [
self _newDataViewForRow:row tableColumn:tableColumn];
3547 [dataView setFrame:[
self frameOfDataViewAtColumn:column row:row]];
3549 [
self _setObjectValueForTableColumn:tableColumn row:row forView:dataView];
3552 _BlockSelectView(dataView, row, column);
3554 _BlockDeselectView(dataView, row, column);
3559 if ([_delegate
tableView:
self isGroupRow:row])
3561 [_groupRows addIndex:row];
3562 [dataView setThemeState:CPThemeStateGroupRow];
3566 [_groupRows removeIndexesInRange:CPMakeRange(row, 1)];
3567 [dataView unsetThemeState:CPThemeStateGroupRow];
3570 [
self setNeedsDisplay:YES];
3573 [
self _sendDelegateWillDisplayView:dataView forTableColumn:tableColumn row:row];
3578 - (void)_setObjectValueForTableColumn:(
CPTableColumn)aTableColumn row:(CPInteger)aRow forView:(
CPView)aDataView
3580 [
self _setObjectValueForTableColumn:aTableColumn row:aRow forView:aDataView useCache:!_invalidateObjectValuesCache];
3583 - (void)_setObjectValueForTableColumn:(
CPTableColumn)aTableColumn row:(CPInteger)aRow forView:(
CPView)aDataView useCache:(BOOL)useCache
3586 [aDataView setObjectValue:[
self _objectValueForTableColumn:aTableColumn row:aRow useCache:useCache]];
3591 if (_contentBindingExplicitlySet)
3592 [
self _prepareContentBindedDataView:aDataView forRow:aRow];
3595 [aTableColumn _prepareDataView:aDataView forRow:aRow];
3598 - (void)_prepareContentBindedDataView:(
CPView)dataView forRow:(CPInteger)aRow
3601 content = [binder content],
3602 rowContent = [content objectAtIndex:aRow];
3604 [dataView setObjectValue:rowContent];
3610 - (void)_layoutViewsForRowIndexes:(
CPIndexSet)rowIndexes columnIndexes:(
CPIndexSet)columnIndexes
3612 [
self _enumerateViewsInRows:rowIndexes columns:columnIndexes usingBlock:function(view, row, column, stop)
3614 [view setFrame:[
self frameOfDataViewAtColumn:column row:row]];
3625 if (_viewForTableColumnRowSelector)
3626 view = objj_msgSend(
self, _viewForTableColumnRowSelector, aTableColumn, aRow);
3638 view = [
self makeViewWithIdentifier:identifier owner:_delegate];
3643 view = [
self makeViewWithIdentifier:identifier owner:_delegate];
3646 view = [aTableColumn _newDataView];
3649 [view setIdentifier:identifier];
3667 - (id)makeViewWithIdentifier:(
CPString)anIdentifier owner:(
id)anOwner
3674 reusableViews = _cachedDataViews[anIdentifier];
3676 if (reusableViews && reusableViews.length)
3677 view = reusableViews.pop();
3679 else if (_isViewBased)
3680 view = [
self _unarchiveViewWithIdentifier:anIdentifier owner:anOwner];
3697 - (id)viewAtColumn:(CPInteger)column row:(CPInteger)row makeIfNecessary:(BOOL)makeIfNecessary
3699 if (row > (_numberOfRows - 1))
3701 reason:@"Row " + row + " out of row range [0-" + (_numberOfRows - 1) + "] for rowViewAtRow:createIfNeeded:"];
3705 reason:@"Column " + column + " out of row range [0-" + (NUMBER_OF_COLUMNS ()- 1) + "] for rowViewAtRow:createIfNeeded:"];
3707 var dataViewsForRow = _dataViewsForRows[row],
3708 tableColumn = _tableColumns[column],
3709 tableColumnUID = [tableColumn UID],
3710 view = dataViewsForRow ? dataViewsForRow[tableColumnUID] : nil;
3712 if (!makeIfNecessary)
3717 if (!dataViewsForRow)
3719 dataViewsForRow = {}
3720 _dataViewsForRows[row] = dataViewsForRow;
3728 if ([view superview] !==
self)
3731 dataViewsForRow[tableColumnUID] = view;
3733 [_exposedRows addIndex:row];
3734 [_exposedColumns addIndex:column];
3746 - (
CPView)_unarchiveViewWithIdentifier:(
CPString)anIdentifier owner:(
id)anOwner
3748 var cib = [_archivedDataViews objectForKey:anIdentifier];
3750 if (!cib && !_unavailable_custom_cibs[anIdentifier])
3758 _unavailable_custom_cibs[anIdentifier] = YES;
3763 load = [cib instantiateCibWithOwner:anOwner topLevelObjects:objects];
3768 var count = objects.length;
3772 var obj = objects[count];
3774 if ([obj isKindOfClass:[
CPView class]])
3776 [obj setIdentifier:anIdentifier];
3777 [obj setAutoresizingMask:CPViewNotSizable];
3786 - (void)_updateIsViewBased
3788 if ([
self _delegateRespondsToViewForTableColumn])
3789 _viewForTableColumnRowSelector =
@selector(_sendDelegateViewForTableColumn:row:);
3790 else if ([
self _delegateRespondsToDataViewForTableColumn])
3791 _viewForTableColumnRowSelector =
@selector(_sendDelegateDataViewForTableColumn:row:);
3793 _isViewBased = (_viewForTableColumnRowSelector !== nil || _archivedDataViews !== nil);
3811 - (void)enumerateAvailableViewsUsingBlock:(Function)handler
3817 [
self _enumerateViewsInRows:_exposedRows columns:_exposedColumns usingBlock:handler];
3824 - (void)_enumerateViewsInRows:(
CPIndexSet)rowIndexes columns:(
CPIndexSet)columnIndexes usingBlock:(Function)handler
3830 var dataViewsForRow = _dataViewsForRows[rowIndex];
3832 if (!dataViewsForRow)
3839 var tableColumnUID = [_tableColumns[columnIndex] UID],
3840 view = dataViewsForRow[tableColumnUID];
3843 handler(view, row, columnIndex, stopCol);
3851 - (void)_enumerateViewsInRows:(
CPIndexSet)rowIndexes tableColumns:(CPArray)tableColumns usingBlock:(Function)handler
3857 var dataViewsForRow = _dataViewsForRows[rowIndex];
3859 if (!dataViewsForRow)
3864 [tableColumns enumerateObjectsUsingBlock:function(tableColumn, idx, stopCol)
3866 var tableColumnUID = [tableColumn UID],
3867 view = dataViewsForRow[tableColumnUID];
3870 handler(view, row, tableColumn, stopCol);
3881 - (void)_enqueueReusableDataView:(
CPView)aDataView
3892 if (!_cachedDataViews[identifier])
3893 _cachedDataViews[identifier] = [aDataView];
3895 _cachedDataViews[identifier].push(aDataView);
3902 - (void)setFrameSize:(CGSize)aSize
3907 [_headerView setFrameSize:CGSizeMake(CGRectGetWidth([
self frame]), CGRectGetHeight([_headerView frame]))];
3915 - (void)setFrameOrigin:(CGPoint)aPoint
3925 - (void)setBoundsOrigin:(CGPoint)aPoint
3935 - (void)setBoundsSize:(CGSize)aSize
3948 [_tableDrawView setNeedsDisplay:aFlag];
3956 - (void)setNeedsLayout
3967 return [[
self window] isKeyWindow] && ([[
self window] firstResponder] ===
self || _editingRow !==
CPNotFound);
3973 - (void)_drawRect:(CGRect)aRect
3978 var exposedRect = [
self exposedRect];
3980 [
self drawBackgroundInClipRect:exposedRect];
3981 [
self highlightSelectionInClipRect:exposedRect];
3982 [
self drawGridInClipRect:exposedRect];
3984 if (_implementsCustomDrawRow)
3985 [
self _drawRows:_exposedRows clipRect:exposedRect];
3993 - (void)drawBackgroundInClipRect:(CGRect)aRect
3995 if (!_usesAlternatingRowBackgroundColors)
3999 colorCount = [rowColors count];
4001 if (colorCount === 0)
4006 if (colorCount === 1)
4014 var exposedRows = [
self _exposedRowsInRect:aRect],
4015 firstRow = FLOOR(exposedRows.location / colorCount) * colorCount,
4021 while (colorIndex < colorCount)
4025 for (var row = firstRow + colorIndex; row <= lastRow; row += colorCount)
4028 if (![_groupRows containsIndex:row])
4029 CGContextAddRect(context, CGRectIntersection(aRect, [
self _rectOfRow:row checkRange:NO]));
4031 groupRowRects.push(CGRectIntersection(aRect, [
self _rectOfRow:row checkRange:NO]));
4042 [
self _drawGroupRowsForRects:groupRowRects];
4049 - (void)drawGridInClipRect:(CGRect)aRect
4062 var exposedRows = [
self _exposedRowsInRect:aRect],
4063 row = exposedRows.location,
4065 rowY = -lineThickness / 2,
4066 minX = CGRectGetMinX(aRect),
4067 maxX = CGRectGetMaxX(aRect);
4069 for (; row <= lastRow; ++row)
4072 var rowRect = [
self _rectOfRow:row checkRange:NO],
4073 rowY = CGRectGetMaxY(rowRect) - lineThickness / 2;
4079 if (_rowHeight > 0.0)
4082 totalHeight = CGRectGetMaxY(aRect) - lineThickness / 2;
4084 while (rowY < totalHeight)
4099 [exposedColumnIndexes getIndexes:columnsArray maxCount:-1 inIndexRange:nil];
4101 var columnArrayIndex = 0,
4102 columnArrayCount = columnsArray.length,
4103 minY = CGRectGetMinY(aRect),
4104 maxY = CGRectGetMaxY(aRect);
4106 for (; columnArrayIndex < columnArrayCount; ++columnArrayIndex)
4108 var columnRect = [
self rectOfColumn:columnsArray[columnArrayIndex]],
4109 columnX = CGRectGetMaxX(columnRect) - lineThickness / 2;
4127 - (void)highlightSelectionInClipRect:(CGRect)aRect
4134 rectSelector =
@selector(rectOfRow:);
4136 if ([_selectedRowIndexes count] >= 1)
4139 firstRow = [exposedRows firstIndex],
4140 exposedRange =
CPMakeRange(firstRow, [exposedRows lastIndex] - firstRow + 1);
4142 [_selectedRowIndexes getIndexes:indexes maxCount:-1 inIndexRange:exposedRange];
4144 else if ([_selectedColumnIndexes count] >= 1)
4146 rectSelector =
@selector(rectOfColumn:);
4149 firstColumn = [exposedColumns firstIndex],
4150 exposedRange =
CPMakeRange(firstColumn, [exposedColumns lastIndex] - firstColumn + 1);
4152 [_selectedColumnIndexes getIndexes:indexes maxCount:-1 inIndexRange:exposedRange];
4156 count2 = count = [indexes count];
4163 focused = [
self _isFocused];
4170 topLineColor = [gradientCache objectForKey:CPSourceListTopLineColor],
4171 bottomLineColor = [gradientCache objectForKey:CPSourceListBottomLineColor],
4172 gradientColor = [gradientCache objectForKey:CPSourceListGradient];
4178 if ([_groupRows count])
4182 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);
4187 var currentIndex = indexes[count],
4188 rowRect = CGRectIntersection(objj_msgSend(
self, rectSelector, currentIndex), aRect);
4192 var shouldUseGroupGradient = [_groupRows containsIndex:currentIndex];
4194 if (drawGradient || shouldUseGroupGradient)
4196 var minX = CGRectGetMinX(rowRect),
4197 minY = CGRectGetMinY(rowRect),
4198 maxX = CGRectGetMaxX(rowRect),
4199 maxY = CGRectGetMaxY(rowRect) - deltaHeight;
4204 [normalSelectionHighlightColor setFill];
4212 CGContextDrawLinearGradient(context, (shouldUseGroupGradient) ? gradientGroupColor : gradientColor, rowRect.origin, CGPointMake(minX, maxY), 0);
4232 var minX = CGRectGetMinX(rowRect),
4233 maxX = CGRectGetMaxX(rowRect),
4234 minY = CGRectGetMinY(rowRect),
4235 maxY = CGRectGetMaxY(rowRect);
4252 [normalSelectionHighlightColor setFill];
4260 for (var i = 0; i < count2; i++)
4262 var rect = objj_msgSend(
self, rectSelector, indexes[i]),
4263 minX = CGRectGetMinX(rect) - 0.5,
4264 maxX = CGRectGetMaxX(rect) - 0.5,
4265 minY = CGRectGetMinY(rect) - 0.5,
4266 maxY = CGRectGetMaxY(rect) - 0.5;
4271 exposedColumnIndexes = [],
4272 firstExposedColumn = [exposedColumns firstIndex],
4273 exposedRange =
CPMakeRange(firstExposedColumn, [exposedColumns lastIndex] - firstExposedColumn + 1);
4275 [exposedColumns getIndexes:exposedColumnIndexes maxCount:-1 inIndexRange:exposedRange];
4277 var exposedColumnCount = [exposedColumnIndexes count];
4279 for (var c = firstExposedColumn; c < exposedColumnCount; c++)
4281 var colRect = [
self rectOfColumn:exposedColumnIndexes[c]],
4282 colX = CGRectGetMaxX(colRect) + 0.5;
4290 if ([indexes containsObject:indexes[i] + 1])
4307 - (void)_drawGroupRowsForRects:(CPArray)rects
4317 var gradientCache = [
self selectionGradientColors],
4321 199.0 / 255.0, 199.0 / 255.0, 199.0 / 255.0, 1.0], [0, 1], 2),
4326 var rowRect = rects[i];
4332 var minX = CGRectGetMinX(rowRect),
4333 minY = CGRectGetMinY(rowRect),
4334 maxX = CGRectGetMaxX(rowRect),
4335 maxY = CGRectGetMaxY(rowRect);
4357 - (void)_drawRows:(
CPIndexSet)rowsIndexes clipRect:(CGRect)clipRect
4363 [
self drawRow:row clipRect:CGRectIntersection(clipRect, [
self rectOfRow:row])];
4374 - (void)drawRow:(CPInteger)row clipRect:(CGRect)rect
4383 - (void)layoutSubviews
4391 - (void)viewWillMoveToSuperview:(
CPView)aView
4393 if ([aView isKindOfClass:[
CPClipView class]])
4395 _observedClipView = aView;
4399 [
self _stopObservingClipView];
4400 _observedClipView = nil;
4430 - (BOOL)tracksMouseOutsideOfFrame
4438 - (BOOL)startTrackingAt:(CGPoint)aPoint
4449 if (row < 0 && _allowsEmptySelection)
4451 if ([
self _sendDelegateSelectionShouldChangeInTableView])
4453 var indexSet = [
self _sendDelegateSelectionIndexesForProposedSelection:[
CPIndexSet indexSet]];
4455 [
self _noteSelectionIsChanging];
4461 _selectionAnchorRow = (ABS([_selectedRowIndexes firstIndex] - row) < ABS([_selectedRowIndexes lastIndex] - row)) ?
4462 [_selectedRowIndexes firstIndex] : [_selectedRowIndexes lastIndex];
4464 _selectionAnchorRow = row;
4467 _startTrackingPoint = aPoint;
4468 _startTrackingTimestamp =
new Date();
4470 if ([
self _dataSourceRespondsToSetObjectValueForTableColumnRow])
4471 _trackingPointMovedOutOfClickSlop = NO;
4475 if (row >= 0 && !([
self _dataSourceRespondsToWriteRowsWithIndexesToPasteboard]))
4476 [
self _updateSelectionWithMouseAtRow:row];
4486 if (!([
self _delegateRespondsToMenuForTableColumnRow]))
4492 tableColumn = [[
self tableColumns] objectAtIndex:column];
4494 return [
self _sendDelegateMenuForTableColumn:tableColumn row:row];
4503 if (![_draggedRowIndexes count])
4509 [CPApp sendEvent:anEvent];
4521 - (BOOL)continueTracking:(CGPoint)lastPoint at:(CGPoint)aPoint
4530 if (!_isSelectingSession && [
self _dataSourceRespondsToWriteRowsWithIndexesToPasteboard])
4532 if (row >= 0 && (ABS(_startTrackingPoint.x - aPoint.x) > 3 || (_verticalMotionCanDrag && ABS(_startTrackingPoint.y - aPoint.y) > 3)) ||
4533 ([_selectedRowIndexes containsIndex:row]))
4535 if ([_selectedRowIndexes containsIndex:row])
4543 if ([
self canDragRowsWithIndexes:_draggedRowIndexes atPoint:aPoint] && [
self _sendDataSourceWriteRowsWithIndexes:_draggedRowIndexes toPasteboard:pboard])
4545 var currentEvent = [CPApp currentEvent],
4546 offset = CGPointMakeZero(),
4547 tableColumns = [_tableColumns objectsAtIndexes:_exposedColumns];
4563 view = [[
CPImageView alloc] initWithFrame:CGRectMake(0, 0, [image size].width, [image size].height)];
4564 [view setImage:image];
4567 var
bounds = [view bounds],
4568 viewLocation = CGPointMake(aPoint.x - CGRectGetWidth(bounds) / 2 + offset.x, aPoint.y - CGRectGetHeight(bounds) / 2 + offset.y);
4570 _startTrackingPoint = nil;
4578 else if (ABS(_startTrackingPoint.x - aPoint.x) < 5 && ABS(_startTrackingPoint.y - aPoint.y) < 5)
4582 _isSelectingSession = YES;
4583 if (row >= 0 && row !== _lastTrackedRowIndex)
4585 _lastTrackedRowIndex = row;
4586 [
self _updateSelectionWithMouseAtRow:row];
4589 if ([
self _dataSourceRespondsToSetObjectValueForTableColumnRow]
4590 && !_trackingPointMovedOutOfClickSlop)
4592 var CLICK_SPACE_DELTA = 5.0;
4593 if (ABS(aPoint.x - _startTrackingPoint.x) > CLICK_SPACE_DELTA
4594 || ABS(aPoint.y - _startTrackingPoint.y) > CLICK_SPACE_DELTA)
4596 _trackingPointMovedOutOfClickSlop = YES;
4606 - (void)stopTracking:(CGPoint)lastPoint at:(CGPoint)aPoint mouseIsUp:(BOOL)mouseIsUp
4608 _isSelectingSession = NO;
4610 var CLICK_TIME_DELTA = 1000,
4619 if ([
self _dataSourceRespondsToWriteRowsWithIndexesToPasteboard])
4621 rowIndex = _clickedRow;
4623 if (rowIndex !== -1)
4625 if ([_draggedRowIndexes count] > 0)
4631 _previouslySelectedRowIndexes = [_selectedRowIndexes copy];
4632 [
self _updateSelectionWithMouseAtRow:rowIndex];
4637 if (!_isViewBased && mouseIsUp
4638 && !_trackingPointMovedOutOfClickSlop
4639 && ([[
CPApp currentEvent] clickCount] > 1)
4640 && ([
self _dataSourceRespondsToSetObjectValueForTableColumnRow]
4641 || [
self infoForBinding:
@"content"]))
4647 column = _tableColumns[columnIndex];
4649 if ([column isEditable])
4653 if (rowIndex !== -1)
4655 if ([
self _sendDelegateShouldEditTableColumn:column row:rowIndex])
4667 if ([[
CPApp currentEvent] clickCount] === 2 && _doubleAction)
4674 - (CPDragOperation)draggingEntered:(
id)sender
4677 dropOperation = [
self _proposedDropOperationAtPoint:location],
4678 row = [
self _proposedRowAtPoint:location];
4680 if (_retargetedDropRow !== nil)
4681 row = _retargetedDropRow;
4684 count = [draggedTypes count],
4687 for (; i < count; i++)
4689 if ([[[sender draggingPasteboard] types] containsObject:[draggedTypes objectAtIndex: i]])
4690 return [
self _sendDataSourceValidateDrop:sender proposedRow:row proposedDropOperation:dropOperation];
4699 - (void)draggingExited:(
id)sender
4701 [_dropOperationFeedbackView removeFromSuperview];
4707 - (void)draggingEnded:(
id)sender
4709 [
self _draggingEnded];
4715 - (void)_draggingEnded
4717 _retargetedDropOperation = nil;
4718 _retargetedDropRow = nil;
4720 [_dropOperationFeedbackView removeFromSuperview];
4726 - (BOOL)wantsPeriodicDraggingUpdates
4734 - (CPTableViewDropOperation)_proposedDropOperationAtPoint:(CGPoint)theDragPoint
4736 if (_retargetedDropOperation !== nil)
4737 return _retargetedDropOperation;
4739 var row = [
self _proposedRowAtPoint:theDragPoint],
4740 rowRect = [
self rectOfRow:row];
4744 if ([
self intercellSpacing].height < 5.0)
4745 rowRect = CGRectInset(rowRect, 0.0, 5.0 - [
self intercellSpacing].height);
4750 if (CGRectContainsPoint(rowRect, theDragPoint) && row < _numberOfRows)
4759 - (CPInteger)_proposedRowAtPoint:(CGPoint)dragPoint
4761 var row = [
self rowAtPoint:dragPoint],
4764 rect = [self rectOfRow:row],
4765 bottomPoint = CGRectGetMaxY(rect),
4766 bottomThirty = bottomPoint - ((bottomPoint - CGRectGetMinY(rect)) * 0.3),
4767 numberOfRows = [self numberOfRows];
4770 row = (CGRectGetMaxY(rect) < dragPoint.y) ? numberOfRows : row;
4771 else if (dragPoint.y > MAX(bottomThirty, bottomPoint - 6))
4774 row = MIN(numberOfRows, row);
4782 - (CGRect)_rectForDropHighlightViewOnRow:(CPInteger)theRowIndex
4784 if (theRowIndex >= [
self numberOfRows])
4785 theRowIndex = [
self numberOfRows] - 1;
4787 return [
self _rectOfRow:theRowIndex checkRange:NO];
4793 - (CGRect)_rectForDropHighlightViewBetweenUpperRow:(CPInteger)theUpperRowIndex andLowerRow:(CPInteger)theLowerRowIndex offset:(CGPoint)theOffset
4795 if (theLowerRowIndex > [
self numberOfRows])
4796 theLowerRowIndex = [
self numberOfRows];
4798 return [
self _rectOfRow:theLowerRowIndex checkRange:NO];
4804 - (CPDragOperation)draggingUpdated:(
id)sender
4806 _retargetedDropRow = nil;
4807 _retargetedDropOperation = nil;
4810 dropOperation = [
self _proposedDropOperationAtPoint:location],
4812 row = [
self _proposedRowAtPoint:location],
4813 dragOperation = [
self _sendDataSourceValidateDrop:sender proposedRow:row proposedDropOperation:dropOperation];
4815 if (_retargetedDropRow !== nil)
4816 row = _retargetedDropRow;
4818 if (_retargetedDropOperation !== nil)
4819 dropOperation = _retargetedDropOperation;
4822 row = numberOfRows - 1;
4824 var rect = CGRectMakeZero();
4829 rect = [
self _rectForDropHighlightViewBetweenUpperRow:row - 1 andLowerRow:row offset:location];
4831 rect = [
self _rectForDropHighlightViewOnRow:row];
4833 [_dropOperationFeedbackView setDropOperation:row !== -1 ? dropOperation : CPDragOperationNone];
4834 [_dropOperationFeedbackView setHidden:(dragOperation == CPDragOperationNone)];
4835 [_dropOperationFeedbackView setFrame:rect];
4836 [_dropOperationFeedbackView setCurrentRow:row];
4837 [
self addSubview:_dropOperationFeedbackView];
4839 return dragOperation;
4845 - (BOOL)prepareForDragOperation:(
id)sender
4849 [_dropOperationFeedbackView removeFromSuperview];
4851 return [
self _dataSourceRespondsToValidateDropProposedRowProposedDropOperation];
4857 - (BOOL)performDragOperation:(
id)sender
4860 operation = [
self _proposedDropOperationAtPoint:location],
4861 row = _retargetedDropRow;
4864 var row = [
self _proposedRowAtPoint:location];
4866 return [
self _sendDataSourceAcceptDrop:sender row:row dropOperation:operation];
4872 - (void)concludeDragOperation:(
id)sender
4874 [
self _reloadDataViews];
4881 - (void)draggedView:(
CPImage)aView endedAt:(CGPoint)aLocation operation:(CPDragOperation)anOperation
4883 [
self _draggingEnded];
4890 - (void)_updateSelectionWithMouseAtRow:(CPInteger)aRow
4897 shouldExtendSelection = NO;
4902 if ([_selectedRowIndexes containsIndex:aRow])
4904 newSelection = [_selectedRowIndexes copy];
4906 [newSelection removeIndex:aRow];
4908 else if (_allowsMultipleSelection)
4910 newSelection = [_selectedRowIndexes copy];
4912 [newSelection addIndex:aRow];
4917 else if (_allowsMultipleSelection)
4920 _selectionAnchorRow = [
self numberOfRows] - 1;
4923 shouldExtendSelection = [
self mouseDownFlags] &
CPShiftKeyMask &&
4924 ((_lastSelectedRow == [_selectedRowIndexes lastIndex] && aRow > _lastSelectedRow) ||
4925 (_lastSelectedRow == [_selectedRowIndexes firstIndex] && aRow < _lastSelectedRow));
4927 else if (aRow >= 0 && aRow < _numberOfRows)
4932 if ([newSelection isEqualToIndexSet:_selectedRowIndexes])
4935 if (![
self _sendDelegateSelectionShouldChangeInTableView])
4938 newSelection = [
self _sendDelegateSelectionIndexesForProposedSelection:newSelection];
4940 if (![
self _delegateRespondsToSelectionIndexesForProposedSelection] && [
self _delegateRespondsToShouldSelectRow])
4942 var indexArray = [];
4944 [newSelection getIndexes:indexArray maxCount:-1 inIndexRange:nil];
4946 var indexCount = indexArray.length;
4948 while (indexCount--)
4950 var index = indexArray[indexCount];
4952 if (![
self _sendDelegateShouldSelectRow:index])
4953 [newSelection removeIndex:index];
4957 if ([newSelection count] === 0)
4962 if (!_allowsEmptySelection && [newSelection count] === 0)
4965 if ([newSelection isEqualToIndexSet:_selectedRowIndexes])
4968 [
self _noteSelectionIsChanging];
4969 [
self selectRowIndexes:newSelection byExtendingSelection:shouldExtendSelection];
4971 _lastSelectedRow = [newSelection containsIndex:aRow] ? aRow : [newSelection lastIndex];
4977 - (void)_noteSelectionIsChanging
4991 - (void)_noteSelectionDidChange
5005 - (void)becomeKeyWindow
5013 - (void)resignKeyWindow
5021 - (BOOL)acceptsFirstResponder
5029 - (BOOL)needsPanelToBecomeKey
5039 var hit = [
super hitTest:aPoint];
5044 return [
self _hitTest:hit];
5047 - (id)_hitTest:(
CPView)aView
5052 if ([aView acceptsFirstResponder])
5054 [
self getColumn:@ref(column) row:@ref(row) forView:aView];
5056 if (![
self isRowSelected:row])
5064 else if (!_isViewBased && [aView isKindOfClass:[
CPControl class]] && ![aView isKindOfClass:[
CPTextField class]])
5066 [
self getColumn:@ref(column) row:@ref(row) forView:aView];
5068 _editingColumn = column;
5077 - (void)_removeObservers
5082 [
self _stopObservingClipView];
5083 [
super _removeObservers];
5086 - (void)_addObservers
5091 [
self _startObservingClipView];
5092 [
super _addObservers];
5103 [
self _stopObservingFirstResponderForWindow:aWindow];
5106 [
self _startObservingFirstResponderForWindow:aWindow];
5109 - (void)_startObservingClipView
5111 if (!_observedClipView)
5116 [_observedClipView setPostsFrameChangedNotifications:YES];
5117 [_observedClipView setPostsBoundsChangedNotifications:YES];
5119 [defaultCenter addObserver:self
5120 selector:@selector(superviewFrameChanged:)
5121 name:CPViewFrameDidChangeNotification
5122 object:_observedClipView];
5124 [defaultCenter addObserver:self
5125 selector:@selector(superviewBoundsChanged:)
5126 name:CPViewBoundsDidChangeNotification
5127 object:_observedClipView];
5130 - (void)_stopObservingClipView
5132 if (!_observedClipView)
5137 [defaultCenter removeObserver:self
5138 name:CPViewFrameDidChangeNotification
5139 object:_observedClipView];
5141 [defaultCenter removeObserver:self
5142 name:CPViewBoundsDidChangeNotification
5143 object:_observedClipView];
5146 - (void)_startObservingFirstResponderForWindow:(
CPWindow)aWindow
5151 - (void)_stopObservingFirstResponderForWindow:(
CPWindow)aWindow
5158 var responder = [[
self window] firstResponder],
5162 [
self getColumn:@ref(column) row:@ref(row) forView:responder];
5165 _editingColumn = column;
5171 [
self _notifyViewDidResignFirstResponder];
5173 [
self _notifyViewDidBecomeFirstResponder];
5176 if (!_isViewBased && _editingRow !==
CPNotFound && [responder isKindOfClass:[
CPTextField class]] && [responder isEditable])
5178 [responder setBezeled:YES];
5179 [
self _registerForEndEditingNote:responder];
5183 - (void)_registerForEndEditingNote:(
CPView)aTextField
5188 - (void)_unregisterForEndEditingNote:(
CPView)aTextField
5197 var textField = [aNote
object];
5199 [
self _unregisterForEndEditingNote:textField];
5203 [
self _setEditingState:NO forView:textField];
5204 [
self _commitDataViewObjectValue:textField];
5207 [textField setBezeled:NO];
5209 [
self _resignFirstResponderWithoutSendingAction:textField];
5212 - (void)_resignFirstResponderWithoutSendingAction:(
CPView)aView
5214 var action = [
self _disableActionIfExists:aView];
5216 [[
self window] makeFirstResponder:self];
5219 [aView setAction:action];
5222 - (void)_resignEditedView
5224 var view = [[
self window] firstResponder];
5226 if ([view respondsToSelector:
@selector(selectText:)])
5227 [view selectText:nil];
5231 [
self _unregisterForEndEditingNote:view];
5232 [
self _setEditingState:NO forView:view];
5235 [
self _resignFirstResponderWithoutSendingAction:view];
5238 - (SEL)_disableActionIfExists:(
CPView)aView
5243 if ([aView respondsToSelector:
@selector(action)] && (action = [aView action]))
5244 [aView setAction:nil];
5254 - (void)_commitDataViewObjectValue:(
id)aDataView
5256 var editingTableColumn = _tableColumns[_editingColumn];
5259 [_dataSource tableView:self setObjectValue:[aDataView objectValue] forTableColumn:editingTableColumn row:_editingRow];
5263 [editingTableColumn _reverseSetDataView:aDataView forRow:_editingRow];
5269 - (void)_setEditingState:(BOOL)editingState forView:(
CPView)aView
5271 if ([aView respondsToSelector:
@selector(setEditable:)])
5272 [aView setEditable:editingState];
5274 if ([aView respondsToSelector:
@selector(setSelectable:)])
5275 [aView setSelectable:editingState];
5278 [aView setBezeled:editingState];
5289 - (void)editColumn:(CPInteger)columnIndex row:(CPInteger)rowIndex withEvent:(
CPEvent)theEvent select:(BOOL)flag
5291 if (![
self isRowSelected:rowIndex])
5304 _editingRow = rowIndex;
5307 var editingTableColumnUID = [_tableColumns[_editingColumn] UID],
5308 editingView = _dataViewsForRows[_editingRow][editingTableColumnUID];
5310 [
self _setEditingState:YES forView:editingView];
5314 - (void)observeValueForKeyPath:(
CPString)keyPath ofObject:(
id)object change:(
CPDictionary)change context:(
void)context
5316 if (context ===
"editing" && [
object superview] ===
self)
5318 [object removeObserver:self forKeyPath:keyPath];
5319 [
self _commitDataViewObjectValue:object];
5328 - (CPInteger)editedColumn
5330 return _editingColumn;
5336 - (CPInteger)editedRow
5356 if ([
self numberOfRows] !== 0)
5358 [
self _moveSelectionWithEvent:anEvent upward:(character === CPUpArrowFunctionKey)];
5366 if ([
self _sendDelegateDeleteKeyPressed])
5378 - (BOOL)_selectionIsBroken
5380 return [
self selectedRowIndexes]._ranges.length !== 1;
5388 - (void)_moveSelectionWithEvent:(
CPEvent)theEvent upward:(BOOL)shouldGoUpward
5390 if (![
self _sendDelegateSelectionShouldChangeInTableView])
5393 var selectedIndexes = [
self selectedRowIndexes];
5395 if ([selectedIndexes count] > 0)
5398 i = [
self selectedRow];
5400 if ([
self _selectionIsBroken])
5402 while ([selectedIndexes containsIndex:i])
5404 shouldGoUpward ? i-- : i++;
5406 _wasSelectionBroken =
true;
5408 else if (_wasSelectionBroken && ((shouldGoUpward && i !== [selectedIndexes firstIndex]) || (!shouldGoUpward && i !== [selectedIndexes lastIndex])))
5410 shouldGoUpward ? i = [selectedIndexes firstIndex] - 1 : i = [selectedIndexes lastIndex];
5411 _wasSelectionBroken =
false;
5415 shouldGoUpward ? i-- : i++;
5422 if ([
self numberOfRows] > 0)
5423 var i = shouldGoUpward ? [
self numberOfRows] - 1 : 0;
5426 if (i >= [
self numberOfRows] || i < 0)
5429 if ([
self _delegateRespondsToSelectionIndexesForProposedSelection] || [
self _delegateRespondsToShouldSelectRow])
5437 while (!shouldSelect && (i < [
self numberOfRows] && i > 0))
5439 shouldGoUpward ? --i : ++i;
5448 if (extend && [selectedIndexes containsIndex:i])
5451 var differedLastSelectedRow = i;
5454 shouldGoUpward ? i++ : i--;
5456 [selectedIndexes removeIndex:i];
5463 if ([selectedIndexes containsIndex:i])
5465 i = shouldGoUpward ? [selectedIndexes firstIndex] -1 : [selectedIndexes lastIndex] + 1;
5466 i = MIN(MAX(i, 0), [
self numberOfRows] - 1);
5469 [selectedIndexes addIndex:i];
5470 var differedLastSelectedRow = i;
5475 var differedLastSelectedRow = i;
5478 selectedIndexes = [
self _sendDelegateSelectionIndexesForProposedSelection:selectedIndexes];
5480 [
self selectRowIndexes:selectedIndexes byExtendingSelection:extend];
5483 _lastSelectedRow = differedLastSelectedRow;
5486 [
self scrollRowToVisible:i];
5498 - (BOOL)_dataSourceRespondsToObjectValueForTableColumn
5507 - (BOOL)_dataSourceRespondsToWriteRowsWithIndexesToPasteboard
5516 - (BOOL)_dataSourceRespondsToSetObjectValueForTableColumnRow
5525 - (BOOL)_dataSourceRespondsToValidateDropProposedRowProposedDropOperation
5534 - (BOOL)_dataSourceRespondsToNumberOfRowsinTableView
5544 - (int)_sendDataSourceNumberOfRowsInTableView
5549 return [_dataSource numberOfRowsInTableView:self];
5557 - (id)_sendDataSourceObjectValueForTableColumn:(
CPTableColumn)aTableColumn row:(CPInteger)aRowIndex
5562 return [_dataSource tableView:self objectValueForTableColumn:aTableColumn row:aRowIndex];
5569 - (void)_sendDataSourceSetObjectValue:(
id)anObject forTableColumn:(
CPTableColumn)aTableColumn row:(CPInteger)aRowIndex
5574 [_dataSource tableView:self setObjectValue:anObject forTableColumn:aTableColumn row:aRowIndex];
5581 - (void)_sendDataSourceSortDescriptorsDidChange:(CPArray)descriptors
5586 [_dataSource tableView:self sortDescriptorsDidChange:descriptors];
5593 - (BOOL)_sendDataSourceAcceptDrop:(
id)info row:(CPInteger)aRowIndex dropOperation:(CPTableViewDropOperation)operation
5598 return [_dataSource tableView:self acceptDrop:info row:aRowIndex dropOperation:operation];
5605 - (CPDragOperation)_sendDataSourceValidateDrop:(
id)info proposedRow:(CPInteger)aRowIndex proposedDropOperation:(CPTableViewDropOperation)operation
5610 return [_dataSource tableView:self validateDrop:info proposedRow:aRowIndex proposedDropOperation:operation];
5622 return [_dataSource tableView:self writeRowsWithIndexes:rowIndexes toPasteboard:pboard];
5628 - (void)draggedImage:(
CPImage)anImage endedAt:(CGPoint)aLocation operation:(CPDragOperation)anOperation
5630 if ([_dataSource respondsToSelector:
@selector(
tableView:didEndDraggedImage:atPosition:operation:)])
5631 [_dataSource tableView:self didEndDraggedImage:anImage atPosition:aLocation operation:anOperation];
5636 #pragma mark DataSource methods to implement
5642 - (CPArray)_sendDataSourceNamesOfPromisedFilesDroppedAtDestination:(
CPURL)dropDestination forDraggedRowsWithIndexes:(
CPIndexSet)indexSet
5647 return [_dataSource tableView:self namesOfPromisedFilesDroppedAtDestination:dropDestination forDraggedRowsWithIndexes:indexSet];
5659 - (BOOL)_delegateRespondsToDataViewForTableColumn
5668 - (BOOL)_delegateRespondsToViewForTableColumn
5677 - (BOOL)_delegateRespondsToShouldSelectRow
5686 - (BOOL)_delegateRespondsToSelectionShouldChangeInTableView
5695 - (BOOL)_delegateRespondsToSelectionIndexesForProposedSelection
5704 - (BOOL)_delegateRespondsToMenuForTableColumnRow
5713 - (void)_sendDelegateDidClickTableColumn:(CPInteger)column
5716 [_delegate tableView:self didClickTableColumn:_tableColumns[column]];
5723 - (void)_sendDelegateDidDragTableColumn:(CPInteger)column
5726 [_delegate tableView:self didDragTableColumn:_tableColumns[column]];
5733 - (void)_sendDelegateMouseDownInHeaderOfTableColumn:(CPInteger)column
5736 [_delegate tableView:self mouseDownInHeaderOfTableColumn:_tableColumns[column]];
5743 - (BOOL)_sendDelegateDeleteKeyPressed
5745 if ([_delegate respondsToSelector:
@selector(tableViewDeleteKeyPressed:)])
5747 [_delegate tableViewDeleteKeyPressed:self];
5758 - (BOOL)_sendDelegateSelectionShouldChangeInTableView
5763 return [_delegate selectionShouldChangeInTableView:self];
5770 - (BOOL)_sendDelegateIsGroupRow:(CPInteger)anIndex
5775 return [_delegate tableView:self isGroupRow:anIndex];
5782 - (BOOL)_sendDelegateShouldSelectRow:(CPInteger)anIndex
5787 return [_delegate tableView:self shouldSelectRow:anIndex];
5794 - (void)_sendDelegateWillDisplayView:(
id)aCell forTableColumn:(
CPTableColumn)aTableColumn row:(CPInteger)aRowIndex
5799 [_delegate tableView:self willDisplayView:aCell forTableColumn:aTableColumn row:aRowIndex];
5806 - (void)_sendDelegateWillRemoveView:(
id)aCell forTableColumn:(
CPTableColumn)aTableColumn row:(CPInteger)aRowIndex
5811 [_delegate tableView:self willRemoveView:aCell forTableColumn:aTableColumn row:aRowIndex];
5823 return [_delegate tableView:self menuForTableColumn:aTableColumn row:aRowIndex];
5832 - (BOOL)_sendDelegateShouldReorderColumn:(CPInteger)columnIndex toColumn:(CPInteger)newColumnIndex
5834 if ([
self allowsColumnReordering] &&
5837 return [_delegate tableView:self shouldReorderColumn:columnIndex toColumn:newColumnIndex];
5840 return [
self allowsColumnReordering];
5847 - (float)_sendDelegateHeightOfRow:(CPInteger)anIndex
5850 return [
self rowHeight];
5852 return [_delegate tableView:self heightOfRow:anIndex];
5859 - (BOOL)_sendDelegateShouldEditTableColumn:(
CPTableColumn)aTableColumn row:(CPInteger)aRowIndex
5864 return [_delegate tableView:self shouldEditTableColumn:aTableColumn row:aRowIndex];
5876 return [_delegate tableView:self selectionIndexesForProposedSelection:anIndexSet];
5883 - (
CPView)_sendDelegateViewForTableColumn:(
CPTableColumn)aTableColumn row:(CPInteger)aRowIndex
5888 return [_delegate tableView:self viewForTableColumn:aTableColumn row:aRowIndex];
5895 - (
CPView)_sendDelegateDataViewForTableColumn:(
CPTableColumn)aTableColumn row:(CPInteger)aRowIndex
5900 return [_delegate tableView:self dataViewForTableColumn:aTableColumn row:aRowIndex];
5905 #pragma mark Delegate methods to implement
5911 - (BOOL)_sendDelegateShouldSelectTableColumn:(
CPTableColumn)aTableColumn
5916 return [_delegate tableView:self shouldSelectTableColumn:aTableColumn];
5923 - (
CPString)_sendDelegateToolTipForView:(
id)aView rect:(CGRect)aRect tableColumn:(
CPTableColumn)aTableColumn row:(CPInteger)aRowIndex mouseLocation:(CGPoint)aPoint
5928 return [_delegate tableView:self toolTipForView:aView rect:aRect tableColumn:aTableColumn row:aRowIndex mouseLocation:aPoint];
5935 - (BOOL)_sendDelegateShouldTrackView:(
id)aView forTableColumn:(
CPTableColumn)aTableColumn row:(CPInteger)aRowIndex
5940 return [_delegate tableView:self shouldTrackView:aView forTableColumn:aTableColumn row:aRowIndex];
5947 - (BOOL)_sendDelegateShouldShowViewExpansionForTableColumn:(
CPTableColumn)aTableColumn row:(CPInteger)aRowIndex
5952 return [_delegate tableView:self shouldShowViewExpansionForTableColumn:aTableColumn row:aRowIndex];
5959 - (BOOL)_sendDelegateShouldTypeSelectForEvent:(
CPEvent)anEvent withCurrentSearchString:(
CPString)aString
5964 return [_delegate tableView:self shouldTypeSelectForEvent:anEvent withCurrentSearchString:aString];
5971 - (
CPString)_sendDelegateTypeSelectStringForTableColumn:(
CPTableColumn)aTableColumn row:(CPInteger)aRowIndex
5976 return [_delegate tableView:self typeSelectStringForTableColumn:aTableColumn row:aRowIndex];
5983 - (int)_sendDelegateNextTypeSelectMatchFromRow:(CPInteger)aRowIndex toRow:(CPInteger)aSecondRowIndex forString:(
CPString)aString
5988 return [_delegate tableView:self nextTypeSelectMatchFromRow:aRowIndex toRow:aSecondRowIndex forString:aString];
5995 + (Class)_binderClassForBinding:(
CPString)aBinding
5997 if (aBinding ==
@"content")
6000 return [
super _binderClassForBinding:aBinding];
6008 if (aBinding ===
@"selectionIndexes")
6009 return @"selectedRowIndexes";
6011 return [
super _replacementKeyPathForBinding:aBinding];
6017 - (void)_establishBindingsIfUnbound:(
id)destination
6021 [
super bind:@"content" toObject:destination withKeyPath:@"arrangedObjects" options:nil];
6022 _contentBindingExplicitlySet = NO;
6026 if (!_contentBindingExplicitlySet)
6028 if ([[
self infoForBinding:
@"selectionIndexes"] objectForKey:
CPObservedObjectKey] !== destination)
6029 [
self bind:@"selectionIndexes" toObject:destination withKeyPath:@"selectionIndexes" options:nil];
6031 if ([[
self infoForBinding:
@"sortDescriptors"] objectForKey:
CPObservedObjectKey] !== destination)
6032 [
self bind:@"sortDescriptors" toObject:destination withKeyPath:@"sortDescriptors" options:nil];
6038 if (aBinding ==
@"content")
6039 _contentBindingExplicitlySet = YES;
6054 var destination = [_info objectForKey:CPObservedObjectKey],
6055 keyPath = [_info objectForKey:CPObservedKeyPathKey];
6057 _content = [destination valueForKey:keyPath];
6059 [_source _reloadDataViews];
6096 _allowsColumnReordering = [aCoder decodeBoolForKey:CPTableViewColumnReorderingKey];
6097 _allowsColumnResizing = [aCoder decodeBoolForKey:CPTableViewColumnResizingKey];
6098 _allowsMultipleSelection = [aCoder decodeBoolForKey:CPTableViewMultipleSelectionKey];
6099 _allowsEmptySelection = [aCoder decodeBoolForKey:CPTableViewEmptySelectionKey];
6100 _allowsColumnSelection = [aCoder decodeBoolForKey:CPTableViewColumnSelectionKey];
6103 _selectionHighlightStyle = [aCoder decodeIntForKey:CPTableViewSelectionHighlightStyleKey];
6104 _columnAutoResizingStyle = [aCoder decodeIntForKey:CPTableViewColumnAutoresizingStyleKey];
6106 _tableColumns = [aCoder decodeObjectForKey:CPTableViewTableColumnsKey] || [];
6107 [_tableColumns makeObjectsPerformSelector:@selector(setTableView:) withObject:self];
6109 _rowHeight = [aCoder decodeFloatForKey:CPTableViewRowHeightKey] || [
self valueForThemeAttribute:@"default-row-height"];
6110 _intercellSpacing = [aCoder decodeSizeForKey:CPTableViewIntercellSpacingKey];
6112 if (CGSizeEqualToSize(_intercellSpacing, CGSizeMakeZero()))
6113 _intercellSpacing = CGSizeMake(3.0, 2.0);
6115 [
self setGridColor:[aCoder decodeObjectForKey:CPTableViewGridColorKey]];
6116 _gridStyleMask = [aCoder decodeIntForKey:CPTableViewGridStyleMaskKey];
6118 _usesAlternatingRowBackgroundColors = [aCoder decodeObjectForKey:CPTableViewUsesAlternatingBackgroundKey];
6121 _headerView = [aCoder decodeObjectForKey:CPTableViewHeaderViewKey];
6122 _cornerView = [aCoder decodeObjectForKey:CPTableViewCornerViewKey];
6124 [
self setDataSource:[aCoder decodeObjectForKey:CPTableViewDataSourceKey]];
6125 [
self setDelegate:[aCoder decodeObjectForKey:CPTableViewDelegateKey]];
6130 _archivedDataViews = [aCoder decodeObjectForKey:CPTableViewArchivedReusableViewsKey];
6132 [
self _updateIsViewBased];
6137 [
self setAutosaveName:[aCoder decodeObjectForKey:CPTableViewAutosaveNameKey]];
6150 [_tableDrawView removeFromSuperview];
6152 [aCoder encodeObject:_dataSource forKey:CPTableViewDataSourceKey];
6153 [aCoder encodeObject:_delegate forKey:CPTableViewDelegateKey];
6155 [aCoder encodeFloat:_rowHeight forKey:CPTableViewRowHeightKey];
6156 [aCoder encodeSize:_intercellSpacing forKey:CPTableViewIntercellSpacingKey];
6158 [aCoder encodeInt:_selectionHighlightStyle forKey:CPTableViewSelectionHighlightStyleKey];
6159 [aCoder encodeInt:_columnAutoResizingStyle forKey:CPTableViewColumnAutoresizingStyleKey];
6161 [aCoder encodeBool:_allowsMultipleSelection forKey:CPTableViewMultipleSelectionKey];
6162 [aCoder encodeBool:_allowsEmptySelection forKey:CPTableViewEmptySelectionKey];
6163 [aCoder encodeBool:_allowsColumnReordering forKey:CPTableViewColumnReorderingKey];
6164 [aCoder encodeBool:_allowsColumnResizing forKey:CPTableViewColumnResizingKey];
6165 [aCoder encodeBool:_allowsColumnSelection forKey:CPTableViewColumnSelectionKey];
6167 [aCoder encodeObject:_tableColumns forKey:CPTableViewTableColumnsKey];
6169 [aCoder encodeObject:[
self gridColor] forKey:CPTableViewGridColorKey];
6170 [aCoder encodeInt:_gridStyleMask forKey:CPTableViewGridStyleMaskKey];
6172 [aCoder encodeBool:_usesAlternatingRowBackgroundColors forKey:CPTableViewUsesAlternatingBackgroundKey];
6175 [aCoder encodeObject:_cornerView forKey:CPTableViewCornerViewKey];
6176 [aCoder encodeObject:_headerView forKey:CPTableViewHeaderViewKey];
6178 [aCoder encodeObject:_autosaveName forKey:CPTableViewAutosaveNameKey];
6180 if (_archivedDataViews)
6181 [aCoder encodeObject:_archivedDataViews forKey:CPTableViewArchivedReusableViewsKey];
6186 @implementation _CPDropOperationDrawingView :
CPView
6188 unsigned dropOperation;
6194 - (void)drawRect:(CGRect)aRect
6207 borderColor = [tableView valueForThemeAttribute:@"dropview-on-border-color"];
6208 borderWidth = [tableView valueForThemeAttribute:@"dropview-on-border-width"];
6218 var selectedRows = [tableView selectedRowIndexes],
6219 newRect = CGRectMake(aRect.origin.x + 2, aRect.origin.y + 2, aRect.size.width - 4, aRect.size.height - 5);
6223 borderRadius = [tableView valueForThemeAttribute:@"dropview-on-selected-border-radius"];
6224 borderColor = [tableView valueForThemeAttribute:@"dropview-on-selected-border-color"];
6225 borderWidth = [tableView valueForThemeAttribute:@"dropview-on-selected-border-width"];
6226 backgroundColor = [tableView valueForThemeAttribute:@"dropview-on-selected-background-color"];
6230 borderRadius = [tableView valueForThemeAttribute:@"dropview-on-border-radius"];
6231 borderColor = [tableView valueForThemeAttribute:@"dropview-on-border-color"];
6232 borderWidth = [tableView valueForThemeAttribute:@"dropview-on-border-width"];
6233 backgroundColor = [tableView valueForThemeAttribute:@"dropview-on-background-color"];
6246 [
self setFrameOrigin:CGPointMake(_frame.origin.x, _frame.origin.y - 8)];
6248 var selectedRows = [tableView selectedRowIndexes];
6252 borderColor = [tableView valueForThemeAttribute:@"dropview-above-selected-border-color"];
6253 borderWidth = [tableView valueForThemeAttribute:@"dropview-above-selected-border-width"];
6257 borderColor = [tableView valueForThemeAttribute:@"dropview-above-border-color"];
6258 borderWidth = [tableView valueForThemeAttribute:@"dropview-above-border-width"];
6279 var showCallback =
function()
6281 objj_msgSend(
self,
"setHidden:", NO)
6285 var hideCallback = function()
6287 objj_msgSend(
self,
"setHidden:", YES)
6291 objj_msgSend(self, "setHidden:", YES);
6292 [
CPTimer scheduledTimerWithTimeInterval:0.1 callback:showCallback repeats:NO];
6293 [
CPTimer scheduledTimerWithTimeInterval:0.19 callback:hideCallback repeats:NO];
6294 [
CPTimer scheduledTimerWithTimeInterval:0.27 callback:showCallback repeats:NO];
6300 @implementation _CPColumnDragDrawingView :
CPView
6307 - (void)drawRect:(CGRect)dirtyRect
6310 columnRect = [tableView rectOfColumn:columnIndex],
6312 bounds = [columnClipView bounds],
6313 visibleRect = [tableView visibleRect],
6314 xScroll = CGRectGetMinX(visibleRect),
6315 yScroll = CGRectGetMinY(visibleRect);
6323 bounds.origin.x = CGRectGetMinX(columnRect) - xScroll;
6324 bounds.size.height += yScroll;
6337 [tableView highlightSelectionInClipRect:bounds];
6341 var minX = CGRectGetMinX(
bounds) + 0.5,
6342 maxX = CGRectGetMaxX(
bounds) - 0.5;
6369 - (void)awakeFromCib
6376 if (aState.isa && [aState isKindOfClass:CPArray])
6377 aState = CPThemeState.apply(null, aState);
6385 if (aState.isa && [aState isKindOfClass:CPArray])
6386 aState = CPThemeState.apply(null, aState);
6392 - (void)recursivelyPerformSelector:(
SEL)selector withObject:(
id)anObject startingFrom:(
id)aView
6394 [[aView subviews] enumerateObjectsUsingBlock:function(view, idx)
6396 [view performSelector:selector withObject:anObject];
6398 if (![view isKindOfClass:[
self class]])
6415 - (BOOL)disableAutomaticResizing
6417 return _disableAutomaticResizing;
6423 - (void)setDisableAutomaticResizing:(BOOL)aValue
6425 _disableAutomaticResizing = aValue;
6443 - (void)setContent:(
id)aValue
6457 return _objectValue;
6463 - (void)setObjectValue:(
id)aValue
6465 _objectValue = aValue;
6481 _textField = aValue;
6497 _imageView = aValue;