35 CPTableViewColumnDidMoveNotification =
@"CPTableViewColumnDidMoveNotification";
36 CPTableViewColumnDidResizeNotification =
@"CPTableViewColumnDidResizeNotification";
37 CPTableViewSelectionDidChangeNotification =
@"CPTableViewSelectionDidChangeNotification";
38 CPTableViewSelectionIsChangingNotification =
@"CPTableViewSelectionIsChangingNotification";
40 var CPTableViewDataSource_numberOfRowsInTableView_ = 1 << 0,
41 CPTableViewDataSource_tableView_objectValueForTableColumn_row_ = 1 << 1,
42 CPTableViewDataSource_tableView_setObjectValue_forTableColumn_row_ = 1 << 2,
43 CPTableViewDataSource_tableView_acceptDrop_row_dropOperation_ = 1 << 3,
44 CPTableViewDataSource_tableView_namesOfPromisedFilesDroppedAtDestination_forDraggedRowsWithIndexes_ = 1 << 4,
45 CPTableViewDataSource_tableView_validateDrop_proposedRow_proposedDropOperation_ = 1 << 5,
46 CPTableViewDataSource_tableView_writeRowsWithIndexes_toPasteboard_ = 1 << 6,
48 CPTableViewDataSource_tableView_sortDescriptorsDidChange_ = 1 << 7;
50 var CPTableViewDelegate_selectionShouldChangeInTableView_ = 1 << 0,
51 CPTableViewDelegate_tableView_viewForTableColumn_row_ = 1 << 1,
52 CPTableViewDelegate_tableView_dataViewForTableColumn_row_ = 1 << 2,
53 CPTableViewDelegate_tableView_didClickTableColumn_ = 1 << 3,
54 CPTableViewDelegate_tableView_didDragTableColumn_ = 1 << 4,
55 CPTableViewDelegate_tableView_heightOfRow_ = 1 << 5,
56 CPTableViewDelegate_tableView_isGroupRow_ = 1 << 6,
57 CPTableViewDelegate_tableView_mouseDownInHeaderOfTableColumn_ = 1 << 7,
58 CPTableViewDelegate_tableView_nextTypeSelectMatchFromRow_toRow_forString_ = 1 << 8,
59 CPTableViewDelegate_tableView_selectionIndexesForProposedSelection_ = 1 << 9,
60 CPTableViewDelegate_tableView_shouldEditTableColumn_row_ = 1 << 10,
61 CPTableViewDelegate_tableView_shouldSelectRow_ = 1 << 11,
62 CPTableViewDelegate_tableView_shouldSelectTableColumn_ = 1 << 12,
63 CPTableViewDelegate_tableView_shouldShowViewExpansionForTableColumn_row_ = 1 << 13,
64 CPTableViewDelegate_tableView_shouldTrackView_forTableColumn_row_ = 1 << 14,
65 CPTableViewDelegate_tableView_shouldTypeSelectForEvent_withCurrentSearchString_ = 1 << 15,
66 CPTableViewDelegate_tableView_toolTipForView_rect_tableColumn_row_mouseLocation_ = 1 << 16,
67 CPTableViewDelegate_tableView_typeSelectStringForTableColumn_row_ = 1 << 17,
68 CPTableViewDelegate_tableView_willDisplayView_forTableColumn_row_ = 1 << 18,
69 CPTableViewDelegate_tableViewSelectionDidChange_ = 1 << 19,
70 CPTableViewDelegate_tableViewSelectionIsChanging_ = 1 << 20,
71 CPTableViewDelegate_tableViewMenuForTableColumn_row_ = 1 << 21,
72 CPTableViewDelegate_tableView_shouldReorderColumn_toColumn_ = 1 << 22;
75 CPTableViewDraggingDestinationFeedbackStyleNone = -1;
76 CPTableViewDraggingDestinationFeedbackStyleRegular = 0;
77 CPTableViewDraggingDestinationFeedbackStyleSourceList = 1;
80 CPTableViewDropOn = 0;
81 CPTableViewDropAbove = 1;
83 CPSourceListGradient =
@"CPSourceListGradient";
84 CPSourceListTopLineColor =
@"CPSourceListTopLineColor";
85 CPSourceListBottomLineColor =
@"CPSourceListBottomLineColor";
89 CPTableViewSelectionHighlightStyleNone = -1;
90 CPTableViewSelectionHighlightStyleRegular = 0;
91 CPTableViewSelectionHighlightStyleSourceList = 1;
93 CPTableViewGridNone = 0;
94 CPTableViewSolidVerticalGridLineMask = 1 << 0;
95 CPTableViewSolidHorizontalGridLineMask = 1 << 1;
97 CPTableViewNoColumnAutoresizing = 0;
98 CPTableViewUniformColumnAutoresizingStyle = 1;
99 CPTableViewSequentialColumnAutoresizingStyle = 2;
100 CPTableViewReverseSequentialColumnAutoresizingStyle = 3;
101 CPTableViewLastColumnOnlyAutoresizingStyle = 4;
102 CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
104 #define NUMBER_OF_COLUMNS() (_tableColumns.length)
105 #define UPDATE_COLUMN_RANGES_IF_NECESSARY() if (_dirtyTableColumnRangeIndex !== CPNotFound) [self _recalculateTableColumnRanges];
106 #define FULL_ROW_HEIGHT() (_rowHeight + _intercellSpacing.height)
107 #define ROW_BOTTOM(__heightInfo) (__heightInfo.y + __heightInfo.height + _intercellSpacing.height)
108 #define HAS_VARIABLE_ROW_HEIGHTS() (_implementedDelegateMethods & CPTableViewDelegate_tableView_heightOfRow_)
110 @implementation _CPTableDrawView :
CPView
120 _tableView = aTableView;
125 - (void)drawRect:(CGRect)aRect
127 var
frame = [
self frame],
132 [_tableView _drawRect:aRect];
163 CPInteger _implementedDataSourceMethods;
166 CPInteger _implementedDelegateMethods;
168 CPArray _tableColumns;
169 CPArray _tableColumnRanges;
170 CPInteger _dirtyTableColumnRangeIndex;
171 CPInteger _numberOfHiddenColumns;
174 Object _objectValues;
180 Object _dataViewsForTableColumns;
181 Object _cachedDataViews;
183 Object _unavailable_custom_cibs;
186 BOOL _allowsColumnReordering;
187 BOOL _allowsColumnResizing;
188 BOOL _allowsColumnSelection;
189 BOOL _allowsMultipleSelection;
190 BOOL _allowsEmptySelection;
192 CPArray _sortDescriptors;
195 CGSize _intercellSpacing;
198 BOOL _usesAlternatingRowBackgroundColors;
199 CPArray _alternatingRowBackgroundColors;
201 unsigned _selectionHighlightStyle;
202 CPColor _unfocusedSelectionHighlightColor;
205 unsigned _gridStyleMask;
207 unsigned _numberOfRows;
210 CPArray _cachedRowHeights;
214 BOOL _autosaveTableColumns;
217 _CPCornerView _cornerView;
221 CPInteger _selectionAnchorRow;
222 CPInteger _lastSelectedRow;
224 CGPoint _startTrackingPoint;
225 CPDate _startTrackingTimestamp;
226 BOOL _trackingPointMovedOutOfClickSlop;
227 CGPoint _editingCellIndex;
228 CPInteger _editingRow;
229 CPInteger _editingColumn;
231 _CPTableDrawView _tableDrawView;
234 CPInteger _clickedRow;
235 CPInteger _clickedColumn;
236 unsigned _columnAutoResizingStyle;
238 int _lastTrackedRowIndex;
239 CGPoint _originalMouseDownPoint;
240 BOOL _verticalMotionCanDrag;
241 unsigned _destinationDragStyle;
242 BOOL _isSelectingSession;
244 BOOL _wasSelectionBroken;
246 _CPDropOperationDrawingView _dropOperationFeedbackView;
247 CPDragOperation _dragOperationDefaultMask;
248 int _retargetedDropRow;
249 CPDragOperation _retargetedDropOperation;
250 CPArray _draggingViews;
252 BOOL _disableAutomaticResizing;
253 BOOL _lastColumnShouldSnap;
254 BOOL _implementsCustomDrawRow;
256 BOOL _contentBindingExplicitlySet;
258 SEL _viewForTableColumnRowSelector;
261 CPArray _differedColumnDataToRemove;
280 @"grid-line-thickness": 1.0,
288 @"default-row-height": 25.0,
289 @"dropview-on-background-color": [
CPNull null],
293 @"dropview-on-selected-background-color": [
CPNull null],
294 @"dropview-on-selected-border-color": [
CPNull null],
295 @"dropview-on-selected-border-width": [
CPNull null],
296 @"dropview-on-selected-border-radius": [
CPNull null],
297 @"dropview-above-border-color": [
CPNull null],
298 @"dropview-above-border-width": [
CPNull null],
299 @"dropview-above-selected-border-color": [
CPNull null],
300 @"dropview-above-selected-border-width": [
CPNull null]
304 - (id)initWithFrame:(CGRect)aFrame
306 self = [
super initWithFrame:aFrame];
311 _allowsColumnReordering = YES;
312 _allowsColumnResizing = YES;
313 _allowsMultipleSelection = NO;
314 _allowsEmptySelection = YES;
315 _allowsColumnSelection = NO;
316 _disableAutomaticResizing = NO;
319 _selectionHighlightStyle = CPTableViewSelectionHighlightStyleRegular;
321 [
self setUsesAlternatingRowBackgroundColors:NO];
322 [
self setAlternatingRowBackgroundColors:
326 _tableColumnRanges = [];
328 _numberOfHiddenColumns = 0;
330 _intercellSpacing = CGSizeMake(3.0, 2.0);
331 _rowHeight = [
self valueForThemeAttribute:@"default-row-height"];
334 [
self setGridStyleMask:CPTableViewGridNone];
336 [
self setHeaderView:[[
CPTableHeaderView alloc] initWithFrame:CGRectMake(0, 0, [
self bounds].size.width, _rowHeight)]];
337 [
self setCornerView:[[_CPCornerView alloc] initWithFrame:CGRectMake(0, 0, [
CPScroller scrollerWidth], CGRectGetHeight([_headerView frame]))]];
339 _currentHighlightedTableColumn = nil;
342 _verticalMotionCanDrag = YES;
343 _isSelectingSession = NO;
344 _retargetedDropRow = nil;
345 _retargetedDropOperation = nil;
346 _dragOperationDefaultMask = nil;
347 _destinationDragStyle = CPTableViewDraggingDestinationFeedbackStyleRegular;
348 _contentBindingExplicitlySet = NO;
365 _lastSelectedRow = _clickedColumn = _clickedRow = -1;
370 _dropOperationFeedbackView = [[_CPDropOperationDrawingView alloc] initWithFrame:CGRectMakeZero()];
371 [_dropOperationFeedbackView setTableView:self];
373 _lastColumnShouldSnap = NO;
375 if (!_alternatingRowBackgroundColors)
378 _tableColumnRanges = [];
379 _dirtyTableColumnRangeIndex = 0;
380 _numberOfHiddenColumns = 0;
383 _dataViewsForTableColumns = { };
387 _cachedDataViews = { };
388 _archivedDataViews = nil;
389 _viewForTableColumnRowSelector = nil;
390 _unavailable_custom_cibs = { };
391 _cachedRowHeights = [];
395 _tableDrawView = [[_CPTableDrawView alloc] initWithTableView:self];
397 [
self addSubview:_tableDrawView];
399 _draggedColumn = nil;
400 _draggingViews = [CPArray array];
410 _differedColumnDataToRemove = [];
411 _implementsCustomDrawRow = [
self implementsSelector:@selector(drawRow:clipRect:)];
413 if (!_sortDescriptors)
414 _sortDescriptors = [];
416 [
self _startObservingFirstResponder];
484 - (void)setDataSource:(
id)aDataSource
486 if (_dataSource === aDataSource)
489 _dataSource = aDataSource;
490 _implementedDataSourceMethods = 0;
495 var hasContentBinding = !![
self infoForBinding:@"content"];
497 if ([_dataSource respondsToSelector:
@selector(numberOfRowsInTableView:)])
498 _implementedDataSourceMethods |= CPTableViewDataSource_numberOfRowsInTableView_;
500 if ([_dataSource respondsToSelector:
@selector(tableView:objectValueForTableColumn:row:)])
501 _implementedDataSourceMethods |= CPTableViewDataSource_tableView_objectValueForTableColumn_row_;
503 if ([_dataSource respondsToSelector:
@selector(tableView:setObjectValue:forTableColumn:row:)])
504 _implementedDataSourceMethods |= CPTableViewDataSource_tableView_setObjectValue_forTableColumn_row_;
506 if ([_dataSource respondsToSelector:
@selector(tableView:acceptDrop:row:dropOperation:)])
507 _implementedDataSourceMethods |= CPTableViewDataSource_tableView_acceptDrop_row_dropOperation_;
509 if ([_dataSource respondsToSelector:
@selector(tableView:namesOfPromisedFilesDroppedAtDestination:forDraggedRowsWithIndexes:)])
510 _implementedDataSourceMethods |= CPTableViewDataSource_tableView_namesOfPromisedFilesDroppedAtDestination_forDraggedRowsWithIndexes_;
512 if ([_dataSource respondsToSelector:
@selector(tableView:validateDrop:proposedRow:proposedDropOperation:)])
513 _implementedDataSourceMethods |= CPTableViewDataSource_tableView_validateDrop_proposedRow_proposedDropOperation_;
515 if ([_dataSource respondsToSelector:
@selector(tableView:writeRowsWithIndexes:toPasteboard:)])
516 _implementedDataSourceMethods |= CPTableViewDataSource_tableView_writeRowsWithIndexes_toPasteboard_;
518 if ([_dataSource respondsToSelector:
@selector(tableView:sortDescriptorsDidChange:)])
519 _implementedDataSourceMethods |= CPTableViewDataSource_tableView_sortDescriptorsDidChange_;
554 _reloadAllRows = YES;
556 _cachedRowHeights = [];
561 [_groupRows removeAllIndexes];
564 [
self noteNumberOfRowsChanged];
566 [
self setNeedsLayout];
567 [
self setNeedsDisplay:YES];
577 - (void)setDoubleAction:(
SEL)anAction
579 _doubleAction = anAction;
587 return _doubleAction;
593 - (CPInteger)clickedColumn
595 return _clickedColumn;
601 - (CPInteger)clickedRow
611 - (void)setAllowsColumnReordering:(BOOL)shouldAllowColumnReordering
613 _allowsColumnReordering = !!shouldAllowColumnReordering;
619 - (BOOL)allowsColumnReordering
621 return _allowsColumnReordering;
628 - (void)setAllowsColumnResizing:(BOOL)shouldAllowColumnResizing
630 _allowsColumnResizing = !!shouldAllowColumnResizing;
636 - (BOOL)allowsColumnResizing
638 return _allowsColumnResizing;
645 - (void)setAllowsMultipleSelection:(BOOL)shouldAllowMultipleSelection
647 _allowsMultipleSelection = !!shouldAllowMultipleSelection;
655 - (BOOL)allowsMultipleSelection
657 return _allowsMultipleSelection;
664 - (void)setAllowsEmptySelection:(BOOL)shouldAllowEmptySelection
666 _allowsEmptySelection = !!shouldAllowEmptySelection;
672 - (BOOL)allowsEmptySelection
674 return _allowsEmptySelection;
682 - (void)setAllowsColumnSelection:(BOOL)shouldAllowColumnSelection
684 _allowsColumnSelection = !!shouldAllowColumnSelection;
691 - (BOOL)allowsColumnSelection
693 return _allowsColumnSelection;
703 - (void)setIntercellSpacing:(CGSize)aSize
705 if (CGSizeEqualToSize(_intercellSpacing, aSize))
708 _intercellSpacing = CGSizeMakeCopy(aSize);
710 _dirtyTableColumnRangeIndex = 0;
711 [
self _recalculateTableColumnRanges];
713 [
self setNeedsLayout];
714 [_headerView setNeedsDisplay:YES];
715 [_headerView setNeedsLayout];
723 - (CGSize)intercellSpacing
725 return CGSizeMakeCopy(_intercellSpacing);
734 - (void)setRowHeight:(
unsigned)aRowHeight
737 aRowHeight = +aRowHeight;
739 if (_rowHeight === aRowHeight)
742 _rowHeight = MAX(0.0, aRowHeight);
744 [
self setNeedsLayout];
750 - (unsigned)rowHeight
760 - (void)setUsesAlternatingRowBackgroundColors:(BOOL)shouldUseAlternatingRowBackgroundColors
762 _usesAlternatingRowBackgroundColors = shouldUseAlternatingRowBackgroundColors;
768 - (BOOL)usesAlternatingRowBackgroundColors
770 return _usesAlternatingRowBackgroundColors;
778 - (void)setAlternatingRowBackgroundColors:(CPArray)alternatingRowBackgroundColors
780 [
self setValue:alternatingRowBackgroundColors forThemeAttribute:@"alternating-row-colors"];
782 [
self setNeedsDisplay:YES];
788 - (CPArray)alternatingRowBackgroundColors
790 return [
self currentValueForThemeAttribute:@"alternating-row-colors"];
804 - (unsigned)selectionHighlightStyle
806 return _selectionHighlightStyle;
820 - (void)setSelectionHighlightStyle:(
unsigned)aSelectionHighlightStyle
822 _selectionHighlightStyle = aSelectionHighlightStyle;
824 if (aSelectionHighlightStyle === CPTableViewSelectionHighlightStyleSourceList)
825 _destinationDragStyle = CPTableViewDraggingDestinationFeedbackStyleSourceList;
827 _destinationDragStyle = CPTableViewDraggingDestinationFeedbackStyleRegular;
830 [
self _updateHighlightWithOldColumns:[
CPIndexSet indexSet] newColumns:_selectedColumnIndexes];
831 [
self setNeedsDisplay:YES];
839 - (void)setSelectionHighlightColor:(
CPColor)aColor
841 if ([[
self selectionHighlightColor]
isEqual:aColor])
844 [
self setValue:aColor forThemeAttribute:@"selection-color"];
845 [
self setNeedsDisplay:YES];
851 - (
CPColor)selectionHighlightColor
853 return [
self currentValueForThemeAttribute:@"selection-color"];
859 - (
CPColor)unfocusedSelectionHighlightColor
861 if (!_unfocusedSelectionHighlightColor)
862 _unfocusedSelectionHighlightColor = [
self _unfocusedSelectionColorFromColor:[
self selectionHighlightColor] saturation:0];
864 return _unfocusedSelectionHighlightColor;
878 - (void)setSelectionGradientColors:(
CPDictionary)aDictionary
880 [
self setValue:aDictionary forThemeAttribute:@"sourcelist-selection-color"];
881 [
self setNeedsDisplay:YES];
894 return [
self currentValueForThemeAttribute:@"sourcelist-selection-color"];
906 - (void)unfocusedSelectionGradientColors
908 if (!_unfocusedSourceListSelectionColor)
910 var sourceListColors = [
self selectionGradientColors];
912 _unfocusedSourceListSelectionColor = @{
913 CPSourceListGradient: [
self _unfocusedGradientFromGradient:[sourceListColors objectForKey:CPSourceListGradient]],
914 CPSourceListTopLineColor: [
self _unfocusedSelectionColorFromColor:[sourceListColors objectForKey:CPSourceListTopLineColor] saturation:0.2],
915 CPSourceListBottomLineColor: [
self _unfocusedSelectionColorFromColor:[sourceListColors objectForKey:CPSourceListBottomLineColor] saturation:0.2]
919 return _unfocusedSourceListSelectionColor;
922 - (
CPColor)_unfocusedSelectionColorFromColor:(
CPColor)aColor saturation:(
float)saturation
929 - (CGGradient)_unfocusedGradientFromGradient:(CGGradient)aGradient
931 var colors = [aGradient.colors copy],
932 count = [colors count];
939 colors[count] =
CGColorCreate(aGradient.colorspace, [[hsb components] copy]);
949 - (void)setGridColor:(
CPColor)aColor
951 [
self setValue:aColor forThemeAttribute:@"grid-color"];
953 [
self setNeedsDisplay:YES];
961 return [
self currentValueForThemeAttribute:@"grid-color"];;
969 - (void)setGridStyleMask:(
unsigned)aGrideStyleMask
971 if (_gridStyleMask === aGrideStyleMask)
974 _gridStyleMask = aGrideStyleMask;
976 [
self setNeedsDisplay:YES];
982 - (unsigned)gridStyleMask
984 return _gridStyleMask;
995 [_tableColumns addObject:aTableColumn];
996 [aTableColumn setTableView:self];
998 if (_dirtyTableColumnRangeIndex < 0)
1001 _dirtyTableColumnRangeIndex = MIN(
NUMBER_OF_COLUMNS() - 1, _dirtyTableColumnRangeIndex);
1003 if ([[
self sortDescriptors] count] > 0)
1005 var mainSortDescriptor = [[
self sortDescriptors] objectAtIndex:0];
1007 if (aTableColumn === [
self _tableColumnForSortDescriptor:mainSortDescriptor])
1009 var image = [mainSortDescriptor ascending] ? [
self _tableHeaderSortImage] : [
self _tableHeaderReverseSortImage];
1010 [
self setIndicatorImage:image inTableColumn:aTableColumn];
1015 [
self setNeedsLayout];
1024 if ([aTableColumn tableView] !==
self)
1027 var index = [_tableColumns indexOfObjectIdenticalTo:aTableColumn];
1033 [_differedColumnDataToRemove addObject:{"column":aTableColumn, "shouldBeHidden": [aTableColumn isHidden]}];
1035 [aTableColumn setHidden:YES];
1036 [aTableColumn setTableView:nil];
1038 var tableColumnUID = [aTableColumn UID];
1040 if (_objectValues[tableColumnUID])
1041 _objectValues[tableColumnUID] = nil;
1043 if (_dirtyTableColumnRangeIndex < 0)
1044 _dirtyTableColumnRangeIndex = index;
1046 _dirtyTableColumnRangeIndex = MIN(index, _dirtyTableColumnRangeIndex);
1048 [_tableColumns removeObject:aTableColumn];
1050 [
self setNeedsLayout];
1059 if (_draggedColumn === aColumn)
1062 var previouslyDraggedColumn = _draggedColumn;
1063 _draggedColumn = aColumn;
1070 if (previouslyDraggedColumn)
1071 [
self reloadDataForRowIndexes:_exposedRows columnIndexes:[
CPIndexSet indexSetWithIndex:[_tableColumns indexOfObject:previouslyDraggedColumn]]];
1078 - (void)_moveColumn:(
unsigned)fromIndex toColumn:(
unsigned)toIndex
1081 fromIndex = +fromIndex;
1084 if (fromIndex === toIndex)
1087 if (_dirtyTableColumnRangeIndex < 0)
1088 _dirtyTableColumnRangeIndex = MIN(fromIndex, toIndex);
1090 _dirtyTableColumnRangeIndex = MIN(fromIndex, toIndex, _dirtyTableColumnRangeIndex);
1092 var tableColumn = _tableColumns[fromIndex];
1094 [_tableColumns removeObjectAtIndex:fromIndex];
1095 [_tableColumns insertObject:tableColumn atIndex:toIndex];
1097 [[
self headerView] setNeedsLayout];
1098 [[
self headerView] setNeedsDisplay:YES];
1103 [
self reloadDataForRowIndexes:rowIndexes columnIndexes:columnIndexes];
1109 userInfo:@{ @"CPOldColumn": fromIndex, @"CPNewColumn": toIndex }];
1117 - (void)moveColumn:(CPInteger)theColumnIndex toColumn:(CPInteger)theToIndex
1119 [
self _moveColumn:theColumnIndex toColumn:theToIndex];
1127 - (void)_tableColumnVisibilityDidChange:(
CPTableColumn)aColumn
1129 var columnIndex = [[
self tableColumns] indexOfObjectIdenticalTo:aColumn];
1131 if (_dirtyTableColumnRangeIndex < 0)
1132 _dirtyTableColumnRangeIndex = columnIndex;
1134 _dirtyTableColumnRangeIndex = MIN(columnIndex, _dirtyTableColumnRangeIndex);
1136 [[
self headerView] setNeedsLayout];
1137 [[
self headerView] setNeedsDisplay:YES];
1146 - (CPArray)tableColumns
1148 return _tableColumns;
1157 - (CPInteger)columnWithIdentifier:(
CPString)anIdentifier
1162 for (; index < count; ++index)
1163 if ([_tableColumns[index] identifier] === anIdentifier)
1177 var index = [
self columnWithIdentifier:anIdentifier];
1182 return _tableColumns[index];
1201 - (void)selectColumnIndexes:(
CPIndexSet)columns byExtendingSelection:(BOOL)shouldExtendSelection
1204 if (([columns firstIndex] !=
CPNotFound && [columns firstIndex] < 0) || [columns lastIndex] >= [
self numberOfColumns])
1208 if ([_selectedRowIndexes count] > 0)
1210 [
self _updateHighlightWithOldRows:_selectedRowIndexes newRows:[
CPIndexSet indexSet]];
1214 var previousSelectedIndexes = [_selectedColumnIndexes copy];
1216 if (shouldExtendSelection)
1217 [_selectedColumnIndexes addIndexes:columns];
1219 _selectedColumnIndexes = [columns
copy];
1221 [
self _updateHighlightWithOldColumns:previousSelectedIndexes newColumns:_selectedColumnIndexes];
1222 [
self setNeedsDisplay:YES];
1225 [_headerView setNeedsDisplay:YES];
1227 [
self _noteSelectionDidChange];
1233 - (void)_setSelectedRowIndexes:(
CPIndexSet)rows
1235 if ([_selectedRowIndexes isEqualToIndexSet:rows])
1238 var previousSelectedIndexes = _selectedRowIndexes;
1240 _lastSelectedRow = ([rows count] > 0) ? [rows lastIndex] : -1;
1241 _selectedRowIndexes = [rows copy];
1243 [
self _updateHighlightWithOldRows:previousSelectedIndexes newRows:_selectedRowIndexes];
1244 [
self setNeedsDisplay:YES];
1247 var binderClass = [[
self class] _binderClassForBinding:@"selectionIndexes"];
1248 [[binderClass getBinding:@"selectionIndexes" forObject:self] reverseSetValueFor:@"selectedRowIndexes"];
1250 [
self _noteSelectionDidChange];
1259 - (void)selectRowIndexes:(
CPIndexSet)rows byExtendingSelection:(BOOL)shouldExtendSelection
1261 if ([rows isEqualToIndexSet:_selectedRowIndexes] ||
1262 (([rows firstIndex] !=
CPNotFound && [rows firstIndex] < 0) || [rows lastIndex] >= [
self numberOfRows]) ||
1263 [
self numberOfColumns] <= 0)
1267 if ([_selectedColumnIndexes count] > 0)
1269 [
self _updateHighlightWithOldColumns:_selectedColumnIndexes newColumns:[
CPIndexSet indexSet]];
1272 [_headerView setNeedsDisplay:YES];
1275 var newSelectedIndexes;
1276 if (shouldExtendSelection)
1278 newSelectedIndexes = [_selectedRowIndexes copy];
1279 [newSelectedIndexes addIndexes:rows];
1282 newSelectedIndexes = [rows
copy];
1284 [
self _setSelectedRowIndexes:newSelectedIndexes];
1292 var firstExposedRow = [_exposedRows firstIndex],
1293 exposedLength = [_exposedRows lastIndex] - firstExposedRow + 1,
1296 deselectRowIndexes = [oldRows copy],
1297 selectRowIndexes = [newRows copy];
1299 [deselectRowIndexes removeMatches:selectRowIndexes];
1300 [deselectRowIndexes getIndexes:deselectRows maxCount:-1 inIndexRange:CPMakeRange(firstExposedRow, exposedLength)];
1301 [selectRowIndexes getIndexes:selectRows maxCount:-1 inIndexRange:CPMakeRange(firstExposedRow, exposedLength)];
1303 var showsSelection = _selectionHighlightStyle !== CPTableViewSelectionHighlightStyleNone,
1304 selectors = [@selector(unsetThemeState:), @selector(setThemeState:)],
1306 { rows:deselectRows, selectorIndex:0 },
1307 { rows:selectRows, selectorIndex:showsSelection ? 1 : 0 }
1310 for (var identifier in _dataViewsForTableColumns)
1312 var dataViewsInTableColumn = _dataViewsForTableColumns[identifier];
1314 for (var i = 0; i < selectInfo.length; ++i)
1316 var info = selectInfo[i],
1317 count = info.rows.length;
1321 var view = dataViewsInTableColumn[info.rows[count]];
1322 [view performSelector:selectors[info.selectorIndex] withObject:CPThemeStateSelectedDataView];
1331 - (void)_updateHighlightWithOldColumns:(
CPIndexSet)oldColumns newColumns:(
CPIndexSet)newColumns
1333 var firstExposedColumn = [_exposedColumns firstIndex],
1334 exposedLength = [_exposedColumns lastIndex] - firstExposedColumn +1,
1335 deselectColumns = [],
1337 deselectColumnIndexes = [oldColumns copy],
1338 selectColumnIndexes = [newColumns copy],
1341 [deselectColumnIndexes removeMatches:selectColumnIndexes];
1342 [deselectColumnIndexes getIndexes:deselectColumns maxCount:-1 inIndexRange:CPMakeRange(firstExposedColumn, exposedLength)];
1343 [selectColumnIndexes getIndexes:selectColumns maxCount:-1 inIndexRange:CPMakeRange(firstExposedColumn, exposedLength)];
1344 [_exposedRows getIndexes:selectRows maxCount:-1 inIndexRange:nil];
1346 var showsSelection = _selectionHighlightStyle !== CPTableViewSelectionHighlightStyleNone,
1347 selectors = [@selector(unsetThemeState:), @selector(setThemeState:)],
1352 columns:deselectColumns,
1354 headerSelectorIndex:0
1357 columns:selectColumns,
1358 rowSelectorIndex:showsSelection ? 1 : 0,
1359 headerSelectorIndex:1
1362 rowsCount = selectRows.length;
1364 for (var selectIndex = 0; selectIndex < selectInfo.length; ++selectIndex)
1366 var info = selectInfo[selectIndex],
1367 count = info.columns.length,
1368 rowSelector = selectors[info.rowSelectorIndex],
1369 headerSelector = selectors[info.headerSelectorIndex];
1373 var columnIndex = info.columns[count],
1374 identifier = [_tableColumns[columnIndex] UID],
1375 dataViewsInTableColumn = _dataViewsForTableColumns[identifier];
1377 for (var i = 0; i < rowsCount; i++)
1379 var rowIndex = selectRows[i],
1380 dataView = dataViewsInTableColumn[rowIndex];
1382 [dataView performSelector:rowSelector withObject:CPThemeStateSelectedDataView];
1387 var headerView = [_tableColumns[columnIndex] headerView];
1388 [headerView performSelector:headerSelector withObject:CPThemeStateSelected];
1397 - (int)selectedColumn
1399 return [_selectedColumnIndexes lastIndex];
1407 return _selectedColumnIndexes;
1415 return _lastSelectedRow;
1423 return [_selectedRowIndexes copy];
1431 - (void)deselectColumn:(CPInteger)anIndex
1433 var selectedColumnIndexes = [_selectedColumnIndexes copy];
1434 [selectedColumnIndexes removeIndex:anIndex];
1435 [
self selectColumnIndexes:selectedColumnIndexes byExtendingSelection:NO];
1436 [
self _noteSelectionDidChange];
1444 - (void)deselectRow:(CPInteger)aRow
1446 var selectedRowIndexes = [_selectedRowIndexes copy];
1447 [selectedRowIndexes removeIndex:aRow];
1448 [
self selectRowIndexes:selectedRowIndexes byExtendingSelection:NO];
1449 [
self _noteSelectionDidChange];
1455 - (CPInteger)numberOfSelectedColumns
1457 return [_selectedColumnIndexes count];
1463 - (CPInteger)numberOfSelectedRows
1465 return [_selectedRowIndexes count];
1474 - (BOOL)isColumnSelected:(CPInteger)anIndex
1476 return [_selectedColumnIndexes containsIndex:anIndex];
1485 - (BOOL)isRowSelected:(CPInteger)aRow
1487 return [_selectedRowIndexes containsIndex:aRow];
1501 - (void)selectAll:(
id)sender
1503 if (_allowsMultipleSelection)
1505 if (![
self _sendDelegateSelectionShouldChangeInTableView])
1508 if ([[
self selectedColumnIndexes] count])
1509 [
self selectColumnIndexes:[
CPIndexSet indexSetWithIndexesInRange:
CPMakeRange(0, [
self numberOfColumns])] byExtendingSelection:NO];
1515 - (void)deselectAll:(
id)sender
1517 if ([
self allowsEmptySelection])
1519 if (![
self _sendDelegateSelectionShouldChangeInTableView])
1529 - (int)numberOfColumns
1539 if (_numberOfRows !== nil)
1540 return _numberOfRows;
1542 var contentBindingInfo = [
self infoForBinding:@"content"];
1544 if (contentBindingInfo)
1546 var destination = [contentBindingInfo objectForKey:CPObservedObjectKey],
1547 keyPath = [contentBindingInfo objectForKey:CPObservedKeyPathKey];
1549 _numberOfRows = [[destination valueForKeyPath:keyPath] count];
1553 _numberOfRows = [
self _sendDataSourceNumberOfRowsInTableView];
1557 if (_dataSource && ![
self _dataSourceRespondsToNumberOfRowsinTableView])
1558 CPLog(
@"no content binding established and data source " + [_dataSource description] +
" does not implement numberOfRowsInTableView:");
1564 return _numberOfRows;
1576 - (void)editColumn:(CPInteger)columnIndex row:(CPInteger)rowIndex withEvent:(
CPEvent)theEvent select:(BOOL)flag
1582 var identifier = [_tableColumns[columnIndex] UID],
1583 view = _dataViewsForTableColumns[identifier][rowIndex];
1585 [[
self window] makeFirstResponder:view];
1589 if (![
self isRowSelected:rowIndex])
1592 [
self scrollRowToVisible:rowIndex];
1593 [
self scrollColumnToVisible:columnIndex];
1597 _editingCellIndex = CGPointMake(columnIndex, rowIndex);
1598 _editingCellIndex._shouldSelect = flag;
1608 - (CPInteger)editedColumn
1610 if (!_editingCellIndex)
1613 return _editingCellIndex.x;
1619 - (CPInteger)editedRow
1621 if (!_editingCellIndex)
1624 return _editingCellIndex.y;
1638 - (void)setCornerView:(
CPView)aView
1640 if (_cornerView === aView)
1643 _cornerView = aView;
1645 var scrollView = [
self enclosingScrollView];
1647 if ([scrollView isKindOfClass:[
CPScrollView class]] && [scrollView documentView] ===
self)
1648 [scrollView _updateCornerAndHeaderView];
1667 - (void)setHeaderView:(
CPView)aHeaderView
1669 if (_headerView === aHeaderView)
1672 [_headerView setTableView:nil];
1674 _headerView = aHeaderView;
1678 [_headerView setTableView:self];
1679 [_headerView setFrameSize:CGSizeMake(CGRectGetWidth([
self frame]), CGRectGetHeight([_headerView frame]))];
1684 [_cornerView removeFromSuperview];
1688 var scrollView = [
self enclosingScrollView];
1690 if ([scrollView isKindOfClass:[
CPScrollView class]] && [scrollView documentView] ===
self)
1691 [scrollView _updateCornerAndHeaderView];
1693 [
self setNeedsLayout];
1699 - (void)_recalculateTableColumnRanges
1704 if (_dirtyTableColumnRangeIndex < 0)
1707 _numberOfHiddenColumns = 0;
1709 var index = _dirtyTableColumnRangeIndex,
1711 x = index === 0 ? 0.0 :
CPMaxRange(_tableColumnRanges[index - 1]);
1713 for (; index < count; ++index)
1715 var tableColumn = _tableColumns[index];
1717 if ([tableColumn isHidden])
1719 _numberOfHiddenColumns += 1;
1724 var
width = [_tableColumns[index] width] + _intercellSpacing.width;
1726 _tableColumnRanges[index] =
CPMakeRange(x, width);
1732 _tableColumnRanges.length = count;
1742 - (CGRect)rectOfColumn:(CPInteger)aColumnIndex
1748 aColumnIndex = +aColumnIndex;
1751 return CGRectMakeZero();
1753 if ([[_tableColumns objectAtIndex:aColumnIndex] isHidden])
1754 return CGRectMakeZero();
1758 var range = _tableColumnRanges[aColumnIndex];
1760 return CGRectMake(range.location, 0.0, range.length, CGRectGetHeight([
self bounds]));
1770 - (CGRect)_rectOfRow:(CPInteger)aRowIndex checkRange:(BOOL)checkRange
1775 var lastIndex = [
self numberOfRows] - 1,
1776 validIndex = aRowIndex >= 0 && aRowIndex <= lastIndex;
1778 if (checkRange && !validIndex)
1779 return CGRectMakeZero();
1783 fixedHeightRows = 0;
1787 [
self _populateRowHeightCacheIfNeeded];
1795 heightInfo = _cachedRowHeights[aRowIndex];
1797 height = heightInfo.height + _intercellSpacing.height;
1803 if (_numberOfRows > 0)
1805 heightInfo = _cachedRowHeights[lastIndex];
1810 fixedHeightRows = aRowIndex - _numberOfRows;
1816 fixedHeightRows = aRowIndex;
1822 return CGRectMake(0.0, y, CGRectGetWidth([
self bounds]), height);
1830 - (CGRect)rectOfRow:(CPInteger)aRowIndex
1832 return [
self _rectOfRow:aRowIndex checkRange:YES];
1840 - (CPRange)rowsInRect:(CGRect)aRect
1846 if (_numberOfRows <= 0)
1849 var bounds = [
self bounds];
1852 if (!CGRectIntersectsRect(aRect, bounds))
1855 var firstRow = [
self rowAtPoint:aRect.origin];
1861 var lastRow = [
self rowAtPoint:CGPointMake(0.0, CGRectGetMaxY(aRect))];
1865 lastRow = _numberOfRows - 1;
1867 return CPMakeRange(firstRow, lastRow - firstRow + 1);
1875 - (CPRange)_exposedRowsInRect:(CGRect)aRect
1877 var rowRange = [
self rowsInRect:aRect],
1879 rectOfLastRealRow = [self _rectOfRow:lastRealRow checkRange:NO],
1880 bottomOfRealRows = CGRectGetMaxY(rectOfLastRealRow),
1881 rectBottom = CGRectGetMaxY(aRect);
1884 if (bottomOfRealRows >= rectBottom)
1887 var numberOfSynthesizedRows = CEIL((rectBottom - bottomOfRealRows) /
FULL_ROW_HEIGHT());
1889 rowRange.length += numberOfSynthesizedRows;
1899 - (
CPIndexSet)columnIndexesInRect:(CGRect)aRect
1905 var column = MAX(0, [
self columnAtPoint:CGPointMake(aRect.origin.x, 0.0)]),
1906 lastColumn = [
self columnAtPoint:CGPointMake(CGRectGetMaxX(aRect), 0.0)];
1912 if (_numberOfHiddenColumns <= 0)
1917 for (; column <= lastColumn; ++column)
1919 var tableColumn = _tableColumns[column];
1921 if (![tableColumn isHidden])
1922 [indexSet addIndex:column];
1933 - (CPInteger)columnAtPoint:(CGPoint)aPoint
1939 var bounds = [
self bounds];
1941 if (!CGRectContainsPoint(bounds, aPoint))
1948 high = _tableColumnRanges.length - 1;
1952 var middle = FLOOR(low + (high - low) / 2),
1953 range = _tableColumnRanges[middle];
1955 if (x < range.location)
1963 var numberOfColumns = _tableColumnRanges.length;
1965 while (middle < numberOfColumns && [_tableColumns[middle] isHidden])
1968 if (middle < numberOfColumns)
1983 - (CPInteger)rowAtPoint:(CGPoint)aPoint
1990 var bounds = [
self bounds];
1992 if (aPoint.x < CGRectGetMinX(bounds) || aPoint.x >= CGRectGetMaxX(bounds))
2001 var heightInfo = [_cachedRowHeights lastObject];
2006 return [_cachedRowHeights indexOfObject:aPoint
2009 usingComparator:function(aPoint, heightInfo)
2011 if (aPoint.y < heightInfo.y)
2012 return CPOrderedAscending;
2014 if (aPoint.y > ROW_BOTTOM(heightInfo))
2015 return CPOrderedDescending;
2017 return CPOrderedSame;
2024 return row >= _numberOfRows ? -1 : row;
2036 - (CPInteger)rowForView:(
CPView)aView
2038 return [
self rowNotColumn:YES forView:aView];
2049 - (CPInteger)columnForView:(
CPView)aView
2051 return [
self rowNotColumn:NO forView:aView];
2057 - (CPInteger)rowNotColumn:(BOOL)isRow forView:(
CPView)aView
2059 if (![aView isKindOfClass:[
CPView class]])
2062 var cellView = aView,
2063 contentView = [[
self window] contentView],
2068 if (!cellView || cellView === contentView)
2074 var superview = [cellView superview];
2076 if ([superview isKindOfClass:[
CPTableView class]])
2081 cellView = superview;
2085 var exposedRows = [],
2086 exposedColumns = [];
2088 [_exposedRows getIndexes:exposedRows maxCount:-1 inIndexRange:nil];
2089 [_exposedColumns getIndexes:exposedColumns maxCount:-1 inIndexRange:nil];
2091 var colcount = exposedColumns.length,
2092 countOfRows = exposedRows.length;
2096 var column = exposedColumns[colcount],
2097 tableColumnUID = [_tableColumns[column] UID],
2098 dataViewsInTableColumn = _dataViewsForTableColumns[tableColumnUID],
2099 rowcount = countOfRows;
2103 var row = exposedRows[rowcount];
2105 if (cellView == dataViewsInTableColumn[row])
2106 return isRow ? row : column;
2120 - (CGRect)frameOfDataViewAtColumn:(CPInteger)aColumn row:(CPInteger)aRow
2124 if (aColumn > [
self numberOfColumns] || aRow > [
self numberOfRows])
2125 return CGRectMakeZero();
2127 var tableColumnRange = _tableColumnRanges[aColumn],
2128 rectOfRow = [
self rectOfRow:aRow],
2129 leftInset = FLOOR(_intercellSpacing.width / 2.0),
2130 topInset = FLOOR(_intercellSpacing.height / 2.0);
2132 return CGRectMake(tableColumnRange.location + leftInset, CGRectGetMinY(rectOfRow) + topInset, tableColumnRange.length - _intercellSpacing.width, CGRectGetHeight(rectOfRow) - _intercellSpacing.height);
2138 - (void)resizeWithOldSuperviewSize:(CGSize)aSize
2140 [
super resizeWithOldSuperviewSize:aSize];
2142 if (_disableAutomaticResizing)
2145 var mask = _columnAutoResizingStyle;
2148 if (!_lastColumnShouldSnap)
2151 var superview = [
self superview];
2153 if (!superview || ![superview isKindOfClass:[
CPClipView class]])
2156 var superviewWidth = [superview bounds].size.width,
2157 lastColumnMaxX = CGRectGetMaxX([
self rectOfColumn:[
self numberOfColumns] -1]);
2160 if (lastColumnMaxX >= superviewWidth && lastColumnMaxX <= aSize.width || lastColumnMaxX <= superviewWidth && lastColumnMaxX >= aSize.width)
2161 _lastColumnShouldSnap = YES;
2162 else if (mask === CPTableViewUniformColumnAutoresizingStyle)
2166 if (mask === CPTableViewUniformColumnAutoresizingStyle)
2167 [
self _resizeAllColumnUniformlyWithOldSize:aSize];
2168 else if (mask === CPTableViewLastColumnOnlyAutoresizingStyle)
2169 [
self sizeLastColumnToFit];
2170 else if (mask === CPTableViewFirstColumnOnlyAutoresizingStyle)
2171 [
self _autoResizeFirstColumn];
2177 - (void)_autoResizeFirstColumn
2179 var superview = [
self superview];
2187 columnToResize = nil,
2191 for (; i < count; i++)
2193 var column = _tableColumns[i];
2195 if (![column isHidden])
2197 if (!columnToResize)
2198 columnToResize = column;
2199 totalWidth += [column
width] + _intercellSpacing.
width;
2206 var superviewSize = [superview bounds].size,
2207 newWidth = superviewSize.width - totalWidth;
2209 newWidth += [columnToResize
width];
2210 [columnToResize _tryToResizeToWidth:newWidth];
2213 [
self setNeedsLayout];
2221 - (void)_resizeAllColumnUniformlyWithOldSize:(CGSize)oldSize
2225 var superview = [
self superview];
2227 if (!superview || ![superview isKindOfClass:[CPClipView
class]])
2232 var superviewWidth = [superview bounds].size.width,
2235 remainingSpace = 0.0,
2240 for (; i < count; i++)
2242 var tableColumn = _tableColumns[i];
2243 if (![tableColumn isHidden] && ([tableColumn resizingMask] & CPTableColumnAutoresizingMask))
2244 [resizableColumns addIndex:i];
2247 var maxXofColumns = CGRectGetMaxX([
self rectOfColumn:[resizableColumns lastIndex]]),
2248 remainingSpace = superviewWidth - maxXofColumns,
2249 resizeableColumnsCount = [resizableColumns count],
2252 while (remainingSpace && resizeableColumnsCount)
2255 proportionate += remainingSpace / resizeableColumnsCount;
2258 remainingSpace = 0.0;
2262 while ((index = [resizableColumns indexGreaterThanIndex:index]) !==
CPNotFound)
2264 var item = _tableColumns[index],
2265 proposedWidth = [item width] + proportionate,
2266 resizeLeftovers = [item _tryToResizeToWidth:proposedWidth];
2268 if (resizeLeftovers)
2270 [resizableColumns removeIndex:index];
2272 remainingSpace += resizeLeftovers;
2281 while (count-- && [_tableColumns[count] isHidden]);
2284 var delta = superviewWidth - CGRectGetMaxX([self rectOfColumn:count]) - ([self intercellSpacing].
width || 1),
2285 newSize = [item width] + delta;
2287 [item _tryToResizeToWidth:newSize];
2301 - (void)setColumnAutoresizingStyle:(
unsigned)style
2304 _columnAutoResizingStyle = style;
2310 - (unsigned)columnAutoresizingStyle
2312 return _columnAutoResizingStyle;
2318 - (void)sizeLastColumnToFit
2320 _lastColumnShouldSnap = YES;
2322 var superview = [
self superview];
2327 var superviewSize = [superview bounds].size;
2334 while (count-- && [_tableColumns[count] isHidden]);
2339 var columnToResize = _tableColumns[count],
2340 newSize = MAX(0.0, superviewSize.width - CGRectGetMinX([
self rectOfColumn:count]) - _intercellSpacing.width);
2342 [columnToResize _tryToResizeToWidth:newSize];
2345 [
self setNeedsLayout];
2351 - (void)noteNumberOfRowsChanged
2353 var oldNumberOfRows = _numberOfRows;
2355 _numberOfRows = nil;
2356 _cachedRowHeights = [];
2364 var hangingSelections = oldNumberOfRows - _numberOfRows;
2366 if (hangingSelections > 0)
2369 var previousSelectionCount = [_selectedRowIndexes count];
2371 [_selectedRowIndexes removeIndexesInRange:CPMakeRange(_numberOfRows, hangingSelections)];
2373 if (![_selectedRowIndexes containsIndex:[
self selectedRow]])
2376 if (previousSelectionCount > [_selectedRowIndexes count])
2377 [
self _noteSelectionDidChange];
2386 - (void)_populateRowHeightCacheIfNeeded
2388 if ([
self numberOfRows] !== _cachedRowHeights.length)
2397 - (void)noteHeightOfRowsWithIndexesChanged:(
CPIndexSet)anIndexSet
2409 var y = i < _cachedRowHeights.length ? _cachedRowHeights[i].y : 0;
2411 for (var count = [
self numberOfRows]; i < count; ++i)
2415 if ([anIndexSet containsIndex:i])
2416 height = [
self _sendDelegateHeightOfRow:i];
2418 height = _cachedRowHeights[i].height || _rowHeight;
2420 _cachedRowHeights[i] = {y:y, height:height};
2421 y += height + _intercellSpacing.height;
2432 var
width = _tableColumnRanges.length > 0 ?
CPMaxRange([_tableColumnRanges lastObject]) : 0.0,
2433 superview = [self superview],
2438 else if (_numberOfRows > 0)
2440 [
self _populateRowHeightCacheIfNeeded];
2442 var heightInfo = _cachedRowHeights[_cachedRowHeights.length - 1];
2447 if ([superview isKindOfClass:[CPClipView
class]])
2449 var superviewSize = [superview bounds].size;
2451 width = MAX(superviewSize.width, width);
2452 height = MAX(superviewSize.height, height);
2455 [
self setFrameSize:CGSizeMake(width, height)];
2457 [
self setNeedsLayout];
2458 [
self setNeedsDisplay:YES];
2467 - (void)scrollRowToVisible:(
int)rowIndex
2469 var visible = [
self visibleRect],
2470 rowRect = [
self rectOfRow:rowIndex];
2472 visible.origin.y = rowRect.origin.y;
2473 visible.size.height = rowRect.size.height;
2475 [
self scrollRectToVisible:visible];
2483 - (void)scrollColumnToVisible:(
int)columnIndex
2485 var visible = [
self visibleRect],
2486 colRect = [
self rectOfColumn:columnIndex];
2488 visible.origin.x = colRect.origin.x;
2489 visible.size.width = colRect.size.width;
2491 [
self scrollRectToVisible:visible];
2492 [_headerView scrollRectToVisible:colRect];
2501 - (void)setAutosaveName:(
CPString)theAutosaveName
2503 if (_autosaveName === theAutosaveName)
2506 _autosaveName = theAutosaveName;
2508 [
self setAutosaveTableColumns:!!theAutosaveName];
2509 [
self _restoreFromAutosave];
2517 return _autosaveName;
2526 - (void)setAutosaveTableColumns:(BOOL)shouldAutosave
2528 _autosaveTableColumns = shouldAutosave;
2534 - (BOOL)autosaveTableColumns
2536 return _autosaveTableColumns;
2544 return @"CPTableView Columns " + theAutosaveName;
2550 - (BOOL)_autosaveEnabled
2552 return [
self autosaveName] && [
self autosaveTableColumns];
2563 if (![
self _autosaveEnabled])
2567 autosaveName = [
self autosaveName];
2569 var columns = [
self tableColumns],
2572 for (var i = 0; i < [columns count]; i++)
2574 var column = [columns objectAtIndex:i],
2576 @"identifier": [column identifier],
2577 @"width": [column width]
2580 [columnsSetup addObject:metaData];
2583 [userDefaults setObject:columnsSetup forKey:[
self _columnsKeyForAutosaveName:autosaveName]];
2589 - (void)_restoreFromAutosave
2591 if (![
self _autosaveEnabled])
2595 autosaveName = [
self autosaveName],
2596 tableColumns = [userDefaults objectForKey:[
self _columnsKeyForAutosaveName:autosaveName]];
2598 if ([tableColumns count] != [[
self tableColumns] count])
2601 for (var i = 0; i < [tableColumns count]; i++)
2603 var metaData = [tableColumns objectAtIndex:i],
2604 columnIdentifier = [metaData objectForKey:@"identifier"],
2605 column = [
self columnWithIdentifier:columnIdentifier],
2606 tableColumn = [
self tableColumnWithIdentifier:columnIdentifier];
2610 [
self _moveColumn:column toColumn:i];
2611 [tableColumn setWidth:[metaData objectForKey:@"width"]];
2763 - (void)setDelegate:(
id)aDelegate
2765 if (_delegate === aDelegate)
2772 if ([_delegate respondsToSelector:
@selector(tableViewColumnDidMove:)])
2774 removeObserver:_delegate
2775 name:CPTableViewColumnDidMoveNotification
2778 if ([_delegate respondsToSelector:
@selector(tableViewColumnDidResize:)])
2780 removeObserver:_delegate
2781 name:CPTableViewColumnDidResizeNotification
2784 if ([_delegate respondsToSelector:
@selector(tableViewSelectionDidChange:)])
2786 removeObserver:_delegate
2787 name:CPTableViewSelectionDidChangeNotification
2790 if ([_delegate respondsToSelector:
@selector(tableViewSelectionIsChanging:)])
2792 removeObserver:_delegate
2793 name:CPTableViewSelectionIsChangingNotification
2797 _delegate = aDelegate;
2798 _implementedDelegateMethods = 0;
2800 if ([_delegate respondsToSelector:
@selector(selectionShouldChangeInTableView:)])
2801 _implementedDelegateMethods |= CPTableViewDelegate_selectionShouldChangeInTableView_;
2803 if ([_delegate respondsToSelector:
@selector(tableView:viewForTableColumn:row:)])
2804 _implementedDelegateMethods |= CPTableViewDelegate_tableView_viewForTableColumn_row_;
2805 else if ([_delegate respondsToSelector:
@selector(tableView:dataViewForTableColumn:row:)])
2807 _implementedDelegateMethods |= CPTableViewDelegate_tableView_dataViewForTableColumn_row_;
2808 CPLog.warn(
"tableView:dataViewForTableColumn: is deprecated. You should use -tableView:viewForTableColumn: where you can request the view with -makeViewWithIdentifier:owner:");
2811 [
self _updateIsViewBased];
2813 if ([_delegate respondsToSelector:
@selector(tableView:didClickTableColumn:)])
2814 _implementedDelegateMethods |= CPTableViewDelegate_tableView_didClickTableColumn_;
2816 if ([_delegate respondsToSelector:
@selector(tableView:didDragTableColumn:)])
2817 _implementedDelegateMethods |= CPTableViewDelegate_tableView_didDragTableColumn_;
2819 if ([_delegate respondsToSelector:
@selector(tableView:heightOfRow:)])
2820 _implementedDelegateMethods |= CPTableViewDelegate_tableView_heightOfRow_;
2822 if ([_delegate respondsToSelector:
@selector(tableView:isGroupRow:)])
2823 _implementedDelegateMethods |= CPTableViewDelegate_tableView_isGroupRow_;
2825 if ([_delegate respondsToSelector:
@selector(tableView:mouseDownInHeaderOfTableColumn:)])
2826 _implementedDelegateMethods |= CPTableViewDelegate_tableView_mouseDownInHeaderOfTableColumn_;
2828 if ([_delegate respondsToSelector:
@selector(tableView:nextTypeSelectMatchFromRow:toRow:forString:)])
2829 _implementedDelegateMethods |= CPTableViewDelegate_tableView_nextTypeSelectMatchFromRow_toRow_forString_;
2831 if ([_delegate respondsToSelector:
@selector(tableView:selectionIndexesForProposedSelection:)])
2832 _implementedDelegateMethods |= CPTableViewDelegate_tableView_selectionIndexesForProposedSelection_;
2834 if ([_delegate respondsToSelector:
@selector(tableView:shouldEditTableColumn:row:)])
2835 _implementedDelegateMethods |= CPTableViewDelegate_tableView_shouldEditTableColumn_row_;
2837 if ([_delegate respondsToSelector:
@selector(tableView:shouldSelectRow:)])
2838 _implementedDelegateMethods |= CPTableViewDelegate_tableView_shouldSelectRow_;
2840 if ([_delegate respondsToSelector:
@selector(tableView:shouldSelectTableColumn:)])
2841 _implementedDelegateMethods |= CPTableViewDelegate_tableView_shouldSelectTableColumn_;
2843 if ([_delegate respondsToSelector:
@selector(tableView:shouldShowViewExpansionForTableColumn:row:)])
2844 _implementedDelegateMethods |= CPTableViewDelegate_tableView_shouldShowViewExpansionForTableColumn_row_;
2846 if ([_delegate respondsToSelector:
@selector(tableView:shouldTrackView:forTableColumn:row:)])
2847 _implementedDelegateMethods |= CPTableViewDelegate_tableView_shouldTrackView_forTableColumn_row_;
2849 if ([_delegate respondsToSelector:
@selector(tableView:shouldTypeSelectForEvent:withCurrentSearchString:)])
2850 _implementedDelegateMethods |= CPTableViewDelegate_tableView_shouldTypeSelectForEvent_withCurrentSearchString_;
2852 if ([_delegate respondsToSelector:
@selector(tableView:toolTipForView:rect:tableColumn:row:mouseLocation:)])
2853 _implementedDelegateMethods |= CPTableViewDelegate_tableView_toolTipForView_rect_tableColumn_row_mouseLocation_;
2855 if ([_delegate respondsToSelector:
@selector(tableView:typeSelectStringForTableColumn:row:)])
2856 _implementedDelegateMethods |= CPTableViewDelegate_tableView_typeSelectStringForTableColumn_row_;
2858 if ([_delegate respondsToSelector:
@selector(tableView:willDisplayView:forTableColumn:row:)])
2859 _implementedDelegateMethods |= CPTableViewDelegate_tableView_willDisplayView_forTableColumn_row_;
2861 if ([_delegate respondsToSelector:
@selector(tableView:menuForTableColumn:row:)])
2862 _implementedDelegateMethods |= CPTableViewDelegate_tableViewMenuForTableColumn_row_;
2864 if ([_delegate respondsToSelector:
@selector(tableView:shouldReorderColumn:toColumn:)])
2865 _implementedDelegateMethods |= CPTableViewDelegate_tableView_shouldReorderColumn_toColumn_;
2867 if ([_delegate respondsToSelector:
@selector(tableViewColumnDidMove:)])
2869 addObserver:_delegate
2870 selector:@selector(tableViewColumnDidMove:)
2871 name:CPTableViewColumnDidMoveNotification
2874 if ([_delegate respondsToSelector:
@selector(tableViewColumnDidResize:)])
2876 addObserver:_delegate
2877 selector:@selector(tableViewColumnDidResize:)
2878 name:CPTableViewColumnDidResizeNotification
2881 if ([_delegate respondsToSelector:
@selector(tableViewSelectionDidChange:)])
2883 addObserver:_delegate
2884 selector:@selector(tableViewSelectionDidChange:)
2885 name:CPTableViewSelectionDidChangeNotification
2888 if ([_delegate respondsToSelector:
@selector(tableViewSelectionIsChanging:)])
2890 addObserver:_delegate
2891 selector:@selector(tableViewSelectionIsChanging:)
2892 name:CPTableViewSelectionIsChangingNotification
2907 - (void)_didClickTableColumn:(CPInteger)clickedColumn modifierFlags:(
unsigned)modifierFlags
2909 [
self _changeSortDescriptorsForClickOnColumn:clickedColumn];
2911 if (_allowsColumnSelection)
2913 if ([
self _sendDelegateSelectionShouldChangeInTableView] && [
self _sendDelegateShouldSelectTableColumn:clickedColumn])
2915 [
self _noteSelectionIsChanging];
2918 if ([
self isColumnSelected:clickedColumn])
2919 [
self deselectColumn:clickedColumn];
2920 else if ([
self allowsMultipleSelection] == YES)
2928 var startColumn = MIN(clickedColumn, [_selectedColumnIndexes lastIndex]),
2929 endColumn = MAX(clickedColumn, [_selectedColumnIndexes firstIndex]);
2932 byExtendingSelection:YES];
2941 [
self _sendDelegateDidClickTableColumn:clickedColumn];
2948 - (void)_changeSortDescriptorsForClickOnColumn:(CPInteger)column
2950 var tableColumn = [_tableColumns objectAtIndex:column],
2951 newMainSortDescriptor = [tableColumn sortDescriptorPrototype];
2953 if (!newMainSortDescriptor)
2956 var oldMainSortDescriptor = nil,
2957 oldSortDescriptors = [
self sortDescriptors],
2958 newSortDescriptors = [CPArray arrayWithArray:oldSortDescriptors],
2960 e = [newSortDescriptors objectEnumerator],
2962 outdatedDescriptors = [CPArray array];
2964 if ([_sortDescriptors count] > 0)
2965 oldMainSortDescriptor = [[
self sortDescriptors] objectAtIndex: 0];
2968 while ((descriptor = [e nextObject]) !== nil)
2970 if ([[descriptor key]
isEqual: [newMainSortDescriptor key]])
2971 [outdatedDescriptors addObject:descriptor];
2975 if ([[newMainSortDescriptor key]
isEqual:[oldMainSortDescriptor key]])
2976 newMainSortDescriptor = [oldMainSortDescriptor reversedSortDescriptor];
2978 [newSortDescriptors removeObjectsInArray:outdatedDescriptors];
2979 [newSortDescriptors insertObject:newMainSortDescriptor atIndex:0];
2981 [
self setHighlightedTableColumn:tableColumn];
2982 [
self setSortDescriptors:newSortDescriptors];
2997 var headerView = [aTableColumn headerView];
2998 if ([headerView respondsToSelector:
@selector(_setIndicatorImage:)])
2999 [headerView _setIndicatorImage:anImage];
3006 - (
CPImage)_tableHeaderSortImage
3008 return [
self currentValueForThemeAttribute:@"sort-image"];
3014 - (
CPImage)_tableHeaderReverseSortImage
3016 return [
self currentValueForThemeAttribute:@"sort-image-reversed"];
3024 return _currentHighlightedTableColumn;
3030 - (void)setHighlightedTableColumn:(
CPTableColumn)aTableColumn
3032 if (_currentHighlightedTableColumn == aTableColumn)
3037 if (_currentHighlightedTableColumn != nil)
3038 [[_currentHighlightedTableColumn headerView] unsetThemeState:CPThemeStateSelected];
3040 if (aTableColumn != nil)
3041 [[aTableColumn headerView] setThemeState:CPThemeStateSelected];
3044 _currentHighlightedTableColumn = aTableColumn;
3053 - (BOOL)canDragRowsWithIndexes:(
CPIndexSet)rowIndexes atPoint:(CGPoint)mouseDownPoint
3055 return [rowIndexes
count] > 0 && [
self numberOfRows] > 0 && [
self numberOfColumns] > 0;
3068 - (
CPImage)dragImageForRowsWithIndexes:(
CPIndexSet)dragRows tableColumns:(CPArray)theTableColumns event:(
CPEvent)dragEvent offset:(CGPoint)dragImageOffset
3070 return [
self valueForThemeAttribute:@"image-generic-file"];
3085 - (CPView)dragViewForRowsWithIndexes:(
CPIndexSet)theDraggedRows tableColumns:(CPArray)theTableColumns event:(
CPEvent)theDragEvent offset:(CGPoint)dragViewOffset
3087 var bounds = [
self bounds],
3088 view = [[
CPView alloc] initWithFrame:bounds];
3090 [view setAlphaValue:0.7];
3095 var columnIndex = [theTableColumns count];
3096 while (columnIndex--)
3098 var tableColumn = [theTableColumns objectAtIndex:columnIndex],
3103 var dataView = [
self _newDataViewForRow:row tableColumn:tableColumn];
3105 [dataView setFrame:[
self frameOfDataViewAtColumn:columnIndex row:row]];
3107 [
self _setObjectValueForTableColumn:tableColumn row:row forView:dataView];
3108 [view addSubview:dataView];
3109 [_draggingViews addObject:dataView];
3115 var dragPoint = [
self convertPoint:[theDragEvent locationInWindow] fromView:nil];
3116 dragViewOffset.x = CGRectGetWidth(bounds) / 2 - dragPoint.x;
3117 dragViewOffset.y = CGRectGetHeight(bounds) / 2 - dragPoint.y;
3128 - (CPView)_dragViewForColumn:(CPInteger)theColumnIndex event:(
CPEvent)theDragEvent offset:(CGPoint)theDragViewOffset
3130 var dragView = [[_CPColumnDragView alloc] initWithLineColor:[
self gridColor]],
3131 tableColumn = [[
self tableColumns] objectAtIndex:theColumnIndex],
3132 defaultRowHeight = [
self valueForThemeAttribute:@"default-row-height"],
3133 bounds = CGRectMake(0.0, 0.0, [tableColumn
width], CGRectGetHeight([
self exposedRect]) + defaultRowHeight),
3134 columnRect = [
self rectOfColumn:theColumnIndex],
3135 headerView = [tableColumn headerView],
3136 row = [_exposedRows firstIndex];
3138 [dragView setFrame:bounds];
3142 var dataView = [
self _newDataViewForRow:row tableColumn:tableColumn],
3143 dataViewFrame = [
self frameOfDataViewAtColumn:theColumnIndex row:row];
3146 dataViewFrame.origin.x = 0.0;
3149 dataViewFrame.origin.y = ( CGRectGetMinY(dataViewFrame) - CGRectGetMinY([self exposedRect]) ) + defaultRowHeight;
3150 [dataView setFrame:dataViewFrame];
3152 [
self _setObjectValueForTableColumn:tableColumn row:row forView:dataView];
3153 [dragView addSubview:dataView];
3154 [_draggingViews addObject:dataView];
3156 row = [_exposedRows indexGreaterThanIndex:row];
3161 [dragView addSubview:columnHeaderView];
3164 [dragView setAlphaValue:0.7];
3173 - (void)setDraggingSourceOperationMask:(CPDragOperation)mask forLocal:(BOOL)isLocal
3176 _dragOperationDefaultMask = mask;
3184 - (void)setDropRow:(CPInteger)row dropOperation:(CPTableViewDropOperation)operation
3186 if (row > [
self numberOfRows] && operation === CPTableViewDropOn)
3188 var numberOfRows = [
self numberOfRows] + 1,
3189 reason =
@"Attempt to set dropRow=" + row +
3190 " dropOperation=CPTableViewDropOn when [0 - " + numberOfRows + "] is valid range of rows.";
3195 _retargetedDropRow = row;
3196 _retargetedDropOperation = operation;
3210 - (void)setDraggingDestinationFeedbackStyle:(CPTableViewDraggingDestinationFeedbackStyle)aStyle
3213 _destinationDragStyle = aStyle;
3226 - (CPTableViewDraggingDestinationFeedbackStyle)draggingDestinationFeedbackStyle
3228 return _destinationDragStyle;
3236 - (void)setVerticalMotionCanBeginDrag:(BOOL)aFlag
3238 _verticalMotionCanDrag = aFlag;
3244 - (BOOL)verticalMotionCanBeginDrag
3246 return _verticalMotionCanDrag;
3251 var tableColumns = [
self tableColumns];
3253 for (var i = 0; i < [tableColumns count]; i++)
3255 var tableColumn = [tableColumns objectAtIndex:i],
3256 sortDescriptorPrototype = [tableColumn sortDescriptorPrototype];
3258 if (!sortDescriptorPrototype)
3261 if ([sortDescriptorPrototype key] === [theSortDescriptor key]
3262 && [sortDescriptorPrototype selector] === [theSortDescriptor selector])
3276 - (void)setSortDescriptors:(CPArray)sortDescriptors
3278 var oldSortDescriptors = [[
self sortDescriptors] copy],
3279 newSortDescriptors = [CPArray array];
3281 if (sortDescriptors !== nil)
3282 [newSortDescriptors addObjectsFromArray:sortDescriptors];
3284 if ([newSortDescriptors
isEqual:oldSortDescriptors])
3287 _sortDescriptors = newSortDescriptors;
3289 var oldColumn = nil,
3292 if ([newSortDescriptors count] > 0)
3294 var newMainSortDescriptor = [newSortDescriptors objectAtIndex:0];
3295 newColumn = [
self _tableColumnForSortDescriptor:newMainSortDescriptor];
3298 if ([oldSortDescriptors count] > 0)
3300 var oldMainSortDescriptor = [oldSortDescriptors objectAtIndex:0];
3301 oldColumn = [
self _tableColumnForSortDescriptor:oldMainSortDescriptor];
3304 var image = [newMainSortDescriptor ascending] ? [
self _tableHeaderSortImage] : [
self _tableHeaderReverseSortImage];
3305 [
self setIndicatorImage:nil inTableColumn:oldColumn];
3306 [
self setIndicatorImage:image inTableColumn:newColumn];
3308 [
self _sendDataSourceSortDescriptorsDidChange:oldSortDescriptors];
3310 var binderClass = [[
self class] _binderClassForBinding:@"sortDescriptors"];
3311 [[binderClass getBinding:@"sortDescriptors" forObject:self] reverseSetValueFor:@"sortDescriptors"];
3317 - (CPArray)sortDescriptors
3319 return _sortDescriptors;
3325 - (id)_objectValueForTableColumn:(
CPTableColumn)aTableColumn row:(CPInteger)aRowIndex
3327 var tableColumnUID = [aTableColumn UID],
3328 tableColumnObjectValues = _objectValues[tableColumnUID];
3330 if (!tableColumnObjectValues)
3332 tableColumnObjectValues = [];
3333 _objectValues[tableColumnUID] = tableColumnObjectValues;
3336 var objectValue = tableColumnObjectValues[aRowIndex];
3339 if (objectValue === undefined)
3341 if ([
self _dataSourceRespondsToObjectValueForTableColumn])
3343 objectValue = [
self _sendDataSourceObjectValueForTableColumn:aTableColumn row:aRowIndex];
3344 tableColumnObjectValues[aRowIndex] = objectValue;
3346 else if (!_isViewBased && ![
self infoForBinding:
@"content"])
3348 CPLog.warn(
@"no content binding established and data source " + [_dataSource description] +
" does not implement tableView:objectValueForTableColumn:row:");
3359 - (CGRect)exposedRect
3363 var superview = [
self superview];
3367 if ([superview isKindOfClass:[CPClipView
class]])
3368 _exposedRect = [superview bounds];
3370 _exposedRect = [
self bounds];
3373 return _exposedRect;
3383 [
self _unloadDataViewsInRows:_exposedRows columns:_exposedColumns];
3388 _reloadAllRows = NO;
3391 var exposedRect = [
self exposedRect],
3393 exposedColumns = [
self columnIndexesInRect:exposedRect],
3394 obscuredRows = [_exposedRows copy],
3395 obscuredColumns = [_exposedColumns copy];
3397 [obscuredRows removeIndexes:exposedRows];
3398 [obscuredColumns removeIndexes:exposedColumns];
3400 var newlyExposedRows = [exposedRows copy],
3401 newlyExposedColumns = [exposedColumns copy];
3403 [newlyExposedRows removeIndexes:_exposedRows];
3404 [newlyExposedColumns removeIndexes:_exposedColumns];
3406 var previouslyExposedRows = [exposedRows copy],
3407 previouslyExposedColumns = [exposedColumns copy];
3409 [previouslyExposedRows removeIndexes:newlyExposedRows];
3410 [previouslyExposedColumns removeIndexes:newlyExposedColumns];
3412 [
self _unloadDataViewsInRows:previouslyExposedRows columns:obscuredColumns];
3413 [
self _unloadDataViewsInRows:obscuredRows columns:previouslyExposedColumns];
3414 [
self _unloadDataViewsInRows:obscuredRows columns:obscuredColumns];
3415 [
self _unloadDataViewsInRows:newlyExposedRows columns:newlyExposedColumns];
3417 [
self _loadDataViewsInRows:previouslyExposedRows columns:newlyExposedColumns];
3418 [
self _loadDataViewsInRows:newlyExposedRows columns:previouslyExposedColumns];
3419 [
self _loadDataViewsInRows:newlyExposedRows columns:newlyExposedColumns];
3421 _exposedRows = exposedRows;
3422 _exposedColumns = exposedColumns;
3424 [_tableDrawView setFrame:exposedRect];
3426 [
self setNeedsDisplay:YES];
3429 if ([_differedColumnDataToRemove count])
3431 for (var i = 0; i < _differedColumnDataToRemove.length; i++)
3433 var data = _differedColumnDataToRemove[i],
3434 column = data.column,
3435 tableColumnUID = [column UID],
3436 dataViews = _dataViewsForTableColumns[tableColumnUID];
3438 for (var j = 0; j < [dataViews count]; j++)
3440 [
self _enqueueReusableDataView:[dataViews objectAtIndex:j]];
3443 [_differedColumnDataToRemove removeAllObjects];
3448 for (var identifier in _cachedDataViews)
3450 var dataViews = _cachedDataViews[identifier],
3451 count = dataViews.length;
3454 [dataViews[count] removeFromSuperview];
3463 if (![rows count] || ![columns count])
3472 var columnIndex = 0,
3473 columnsCount = columnArray.length;
3475 for (; columnIndex < columnsCount; ++columnIndex)
3477 var column = columnArray[columnIndex],
3478 tableColumn = _tableColumns[column],
3479 tableColumnUID = [tableColumn UID],
3481 rowsCount = rowArray.length;
3483 for (; rowIndex < rowsCount; ++rowIndex)
3485 var row = rowArray[rowIndex],
3486 dataViews = _dataViewsForTableColumns[tableColumnUID];
3488 if (!dataViews || row >= dataViews.length)
3491 if (row === _editingRow && column === _editingColumn)
3492 [[
self window] makeFirstResponder:
self];
3494 var dataView = [dataViews objectAtIndex:row];
3496 [dataViews replaceObjectAtIndex:row withObject:nil];
3498 [
self _enqueueReusableDataView:dataView];
3508 if (![rows count] || ![columns count])
3520 var columnIndex = 0,
3521 columnsCount = columnArray.length;
3523 for (; columnIndex < columnsCount; ++columnIndex)
3525 var column = columnArray[columnIndex],
3526 tableColumn = _tableColumns[column];
3528 if ([tableColumn isHidden] || tableColumn === _draggedColumn)
3531 var tableColumnUID = [tableColumn UID];
3533 if (!_dataViewsForTableColumns[tableColumnUID])
3534 _dataViewsForTableColumns[tableColumnUID] = [];
3537 rowsCount = rowArray.length,
3538 isColumnSelected = [_selectedColumnIndexes containsIndex:column];
3540 for (; rowIndex < rowsCount; ++rowIndex)
3542 var row = rowArray[rowIndex],
3543 dataView = [
self _newDataViewForRow:row tableColumn:tableColumn],
3544 isButton = [dataView isKindOfClass:[
CPButton class]],
3545 isTextField = [dataView isKindOfClass:[
CPTextField class]];
3547 [dataView setFrame:[
self frameOfDataViewAtColumn:column row:row]];
3549 [
self _setObjectValueForTableColumn:tableColumn row:row forView:dataView];
3551 if ((_selectionHighlightStyle !== CPTableViewSelectionHighlightStyleNone) &&
3552 (isColumnSelected || [
self isRowSelected:row]))
3554 [dataView setThemeState:CPThemeStateSelectedDataView];
3557 [dataView unsetThemeState:CPThemeStateSelectedDataView];
3560 if ([
self _sendDelegateIsGroupRow:row])
3562 [_groupRows addIndex:row];
3563 [dataView setThemeState:CPThemeStateGroupRow];
3568 [_groupRows removeIndexesInRange:CPMakeRange(row, 1)];
3569 [dataView unsetThemeState:CPThemeStateGroupRow];
3572 [
self _sendDelegateWillDisplayView:dataView forTableColumn:tableColumn row:row];
3573 [
self setNeedsDisplay:YES];
3575 if ([dataView superview] !==
self)
3576 [
self addSubview:dataView];
3578 _dataViewsForTableColumns[tableColumnUID][row] = dataView;
3583 if (isButton || (_editingCellIndex && _editingCellIndex.x === column && _editingCellIndex.y === row))
3587 [dataView setEditable:YES];
3588 [dataView setSendsActionOnEndEditing:YES];
3589 [dataView setSelectable:YES];
3590 [dataView selectText:nil];
3591 [dataView setBezeled:YES];
3592 [dataView setDelegate:self];
3595 [dataView setTarget:self];
3596 [dataView setAction:@selector(_commitDataViewObjectValue:)];
3597 dataView.tableViewEditedColumnObj = tableColumn;
3598 dataView.tableViewEditedRowIndex = row;
3600 else if (isTextField)
3602 [dataView setEditable:NO];
3603 [dataView setSelectable:NO];
3609 - (void)_setObjectValueForTableColumn:(
CPTableColumn)aTableColumn row:(CPInteger)aRow forView:(CPView)aDataView
3611 if ([
self _dataSourceRespondsToObjectValueForTableColumn])
3612 [aDataView setObjectValue:[
self _objectValueForTableColumn:aTableColumn row:aRow]];
3617 if (_contentBindingExplicitlySet)
3618 [
self _prepareContentBindedDataView:aDataView forRow:aRow];
3621 [aTableColumn _prepareDataView:aDataView forRow:aRow];
3624 - (void)_prepareContentBindedDataView:(CPView)dataView forRow:(CPInteger)aRow
3627 content = [binder content],
3628 rowContent = [content objectAtIndex:aRow];
3630 [dataView setObjectValue:rowContent];
3644 var columnIndex = 0,
3645 columnsCount = columnArray.length;
3647 for (; columnIndex < columnsCount; ++columnIndex)
3649 var column = columnArray[columnIndex],
3650 tableColumn = _tableColumns[column],
3651 tableColumnUID = [tableColumn UID],
3652 dataViewsForTableColumn = _dataViewsForTableColumns[tableColumnUID],
3654 rowsCount = rowArray.length;
3656 if (dataViewsForTableColumn)
3658 for (; rowIndex < rowsCount; ++rowIndex)
3660 var row = rowArray[rowIndex],
3661 dataView = dataViewsForTableColumn[row];
3663 [dataView setFrame:[
self frameOfDataViewAtColumn:column row:row]];
3674 - (void)_commitDataViewObjectValue:(
id)sender
3681 if ([sender respondsToSelector:
@selector(sendsActionOnEndEditing)] && [sender sendsActionOnEndEditing] && _editingCellIndex === nil)
3684 _editingCellIndex = nil;
3686 [
self _sendDataSourceSetObjectValue:[sender objectValue] forTableColumn:sender.tableViewEditedColumnObj row:sender.tableViewEditedRowIndex];
3690 [sender.tableViewEditedColumnObj _reverseSetDataView:sender forRow:sender.tableViewEditedRowIndex];
3692 if ([sender respondsToSelector:
@selector(setEditable:)])
3693 [sender setEditable:NO];
3695 if ([sender respondsToSelector:
@selector(setSelectable:)])
3696 [sender setSelectable:NO];
3699 [sender setBezeled:NO];
3704 [[
self window] makeFirstResponder:self];
3715 var dataView = [theNotification
object];
3717 if ([dataView respondsToSelector:
@selector(setEditable:)])
3718 [dataView setEditable:NO];
3720 if ([dataView respondsToSelector:
@selector(setSelectable:)])
3721 [dataView setSelectable:NO];
3724 [dataView setBezeled:NO];
3726 _editingCellIndex = nil;
3732 - (CPView)_newDataViewForRow:(CPInteger)aRow tableColumn:(
CPTableColumn)aTableColumn
3736 if (_viewForTableColumnRowSelector)
3737 view = objj_msgSend(
self, _viewForTableColumnRowSelector, aTableColumn, aRow);
3741 var columnIdentifier = [aTableColumn identifier];
3744 if (!columnIdentifier)
3745 columnIdentifier = [aTableColumn UID];
3747 view = [
self makeViewWithIdentifier:columnIdentifier owner:_delegate];
3750 view = [aTableColumn _newDataView];
3752 [view setIdentifier:columnIdentifier];
3770 - (id)makeViewWithIdentifier:(
CPString)anIdentifier owner:(
id)anOwner
3777 reusableViews = _cachedDataViews[anIdentifier];
3779 if (reusableViews && reusableViews.length)
3780 view = reusableViews.pop();
3782 else if (_isViewBased)
3783 view = [
self _unarchiveViewWithIdentifier:anIdentifier owner:anOwner];
3791 - (CPView)_unarchiveViewWithIdentifier:(
CPString)anIdentifier owner:(
id)anOwner
3793 var cib = [_archivedDataViews objectForKey:anIdentifier];
3795 if (!cib && !_unavailable_custom_cibs[anIdentifier])
3798 cib = [[
CPCib alloc] initWithCibNamed:anIdentifier bundle:bundle];
3803 _unavailable_custom_cibs[anIdentifier] = YES;
3808 load = [cib instantiateCibWithOwner:anOwner topLevelObjects:objects];
3813 var count = objects.length;
3817 var obj = objects[count];
3819 if ([obj isKindOfClass:[CPView
class]])
3821 [obj setIdentifier:anIdentifier];
3822 [obj setAutoresizingMask:CPViewNotSizable];
3831 - (void)_updateIsViewBased
3833 if ([
self _delegateRespondsToViewForTableColumn])
3834 _viewForTableColumnRowSelector =
@selector(_sendDelegateViewForTableColumn:row:);
3835 else if ([
self _delegateRespondsToDataViewForTableColumn])
3836 _viewForTableColumnRowSelector =
@selector(_sendDelegateDataViewForTableColumn:row:);
3838 _isViewBased = (_viewForTableColumnRowSelector !== nil || _archivedDataViews !== nil);
3844 - (void)_enqueueReusableDataView:(CPView)aDataView
3850 var identifier = [aDataView identifier];
3852 if (!_cachedDataViews[identifier])
3853 _cachedDataViews[identifier] = [aDataView];
3855 _cachedDataViews[identifier].push(aDataView);
3862 - (void)setFrameSize:(CGSize)aSize
3864 [
super setFrameSize:aSize];
3867 [_headerView setFrameSize:CGSizeMake(CGRectGetWidth([
self frame]), CGRectGetHeight([_headerView frame]))];
3875 - (void)setFrameOrigin:(CGPoint)aPoint
3877 [
super setFrameOrigin:aPoint];
3885 - (void)setBoundsOrigin:(CGPoint)aPoint
3887 [
super setBoundsOrigin:aPoint];
3895 - (void)setBoundsSize:(CGSize)aSize
3897 [
super setBoundsSize:aSize];
3905 - (void)setNeedsDisplay:(BOOL)aFlag
3907 [
super setNeedsDisplay:aFlag];
3908 [_tableDrawView setNeedsDisplay:aFlag];
3910 [[
self headerView] setNeedsDisplay:YES];
3916 - (void)setNeedsLayout
3918 [
super setNeedsLayout];
3919 [[
self headerView] setNeedsLayout];
3927 var isEditing = _editingRow !==
CPNotFound || _editingCellIndex;
3929 return [[
self window] isKeyWindow] && ([[
self window] firstResponder] ===
self || isEditing);
3935 - (void)_drawRect:(CGRect)aRect
3940 var exposedRect = [
self exposedRect];
3942 [
self drawBackgroundInClipRect:exposedRect];
3943 [
self highlightSelectionInClipRect:exposedRect];
3944 [
self drawGridInClipRect:exposedRect];
3946 if (_implementsCustomDrawRow)
3947 [
self _drawRows:_exposedRows clipRect:exposedRect];
3955 - (void)drawBackgroundInClipRect:(CGRect)aRect
3957 if (!_usesAlternatingRowBackgroundColors)
3960 var rowColors = [
self alternatingRowBackgroundColors],
3961 colorCount = [rowColors count];
3963 if (colorCount === 0)
3968 if (colorCount === 1)
3976 var exposedRows = [
self _exposedRowsInRect:aRect],
3977 firstRow = FLOOR(exposedRows.location / colorCount) * colorCount,
3983 while (colorIndex < colorCount)
3987 for (var row = firstRow + colorIndex; row <= lastRow; row += colorCount)
3990 if (![_groupRows containsIndex:row])
3991 CGContextAddRect(context, CGRectIntersection(aRect, [
self _rectOfRow:row checkRange:NO]));
3993 groupRowRects.push(CGRectIntersection(aRect, [
self _rectOfRow:row checkRange:NO]));
4004 [
self _drawGroupRowsForRects:groupRowRects];
4011 - (void)drawGridInClipRect:(CGRect)aRect
4014 gridStyleMask = [
self gridStyleMask],
4015 lineThickness = [
self currentValueForThemeAttribute:@"grid-line-thickness"];
4017 if (!(gridStyleMask & (CPTableViewSolidHorizontalGridLineMask | CPTableViewSolidVerticalGridLineMask)))
4022 if (gridStyleMask & CPTableViewSolidHorizontalGridLineMask)
4024 var exposedRows = [
self _exposedRowsInRect:aRect],
4025 row = exposedRows.location,
4027 rowY = -lineThickness / 2,
4028 minX = CGRectGetMinX(aRect),
4029 maxX = CGRectGetMaxX(aRect);
4031 for (; row <= lastRow; ++row)
4034 var rowRect = [
self _rectOfRow:row checkRange:NO],
4035 rowY = CGRectGetMaxY(rowRect) - lineThickness / 2;
4041 if (_rowHeight > 0.0)
4044 totalHeight = CGRectGetMaxY(aRect) - lineThickness / 2;
4046 while (rowY < totalHeight)
4056 if (gridStyleMask & CPTableViewSolidVerticalGridLineMask)
4058 var exposedColumnIndexes = [
self columnIndexesInRect:aRect],
4061 [exposedColumnIndexes getIndexes:columnsArray maxCount:-1 inIndexRange:nil];
4063 var columnArrayIndex = 0,
4064 columnArrayCount = columnsArray.length,
4065 minY = CGRectGetMinY(aRect),
4066 maxY = CGRectGetMaxY(aRect);
4068 for (; columnArrayIndex < columnArrayCount; ++columnArrayIndex)
4070 var columnRect = [
self rectOfColumn:columnsArray[columnArrayIndex]],
4071 columnX = CGRectGetMaxX(columnRect) - lineThickness / 2;
4089 - (void)highlightSelectionInClipRect:(CGRect)aRect
4091 if (_selectionHighlightStyle === CPTableViewSelectionHighlightStyleNone)
4096 rectSelector =
@selector(rectOfRow:);
4098 if ([_selectedRowIndexes count] >= 1)
4101 firstRow = [exposedRows firstIndex],
4102 exposedRange =
CPMakeRange(firstRow, [exposedRows lastIndex] - firstRow + 1);
4104 [_selectedRowIndexes getIndexes:indexes maxCount:-1 inIndexRange:exposedRange];
4106 else if ([_selectedColumnIndexes count] >= 1)
4108 rectSelector =
@selector(rectOfColumn:);
4110 var exposedColumns = [
self columnIndexesInRect:aRect],
4111 firstColumn = [exposedColumns firstIndex],
4112 exposedRange =
CPMakeRange(firstColumn, [exposedColumns lastIndex] - firstColumn + 1);
4114 [_selectedColumnIndexes getIndexes:indexes maxCount:-1 inIndexRange:exposedRange];
4118 count2 = count = [indexes count];
4124 deltaHeight = 0.5 * (_gridStyleMask & CPTableViewSolidHorizontalGridLineMask),
4125 focused = [
self _isFocused];
4131 var gradientCache = focused ? [
self selectionGradientColors] : [
self unfocusedSelectionGradientColors],
4132 topLineColor = [gradientCache objectForKey:CPSourceListTopLineColor],
4133 bottomLineColor = [gradientCache objectForKey:CPSourceListBottomLineColor],
4134 gradientColor = [gradientCache objectForKey:CPSourceListGradient];
4137 var normalSelectionHighlightColor = focused ? [
self selectionHighlightColor] : [
self unfocusedSelectionHighlightColor];
4140 if ([_groupRows count])
4144 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);
4149 var currentIndex = indexes[count],
4150 rowRect = CGRectIntersection(objj_msgSend(
self, rectSelector, currentIndex), aRect);
4154 var shouldUseGroupGradient = [_groupRows containsIndex:currentIndex];
4156 if (drawGradient || shouldUseGroupGradient)
4158 var minX = CGRectGetMinX(rowRect),
4159 minY = CGRectGetMinY(rowRect),
4160 maxX = CGRectGetMaxX(rowRect),
4161 maxY = CGRectGetMaxY(rowRect) - deltaHeight;
4166 [normalSelectionHighlightColor setFill];
4174 CGContextDrawLinearGradient(context, (shouldUseGroupGradient) ? gradientGroupColor : gradientColor, rowRect.origin, CGPointMake(minX, maxY), 0);
4190 var radius = [
self currentValueForThemeAttribute:@"selection-radius"];
4194 var minX = CGRectGetMinX(rowRect),
4195 maxX = CGRectGetMaxX(rowRect),
4196 minY = CGRectGetMinY(rowRect),
4197 maxY = CGRectGetMaxY(rowRect);
4214 [normalSelectionHighlightColor setFill];
4220 var gridStyleMask = [
self gridStyleMask];
4222 for (var i = 0; i < count2; i++)
4224 var rect = objj_msgSend(
self, rectSelector, indexes[i]),
4225 minX = CGRectGetMinX(rect) - 0.5,
4226 maxX = CGRectGetMaxX(rect) - 0.5,
4227 minY = CGRectGetMinY(rect) - 0.5,
4228 maxY = CGRectGetMaxY(rect) - 0.5;
4230 if ([_selectedRowIndexes count] >= 1 && gridStyleMask & CPTableViewSolidVerticalGridLineMask)
4232 var exposedColumns = [
self columnIndexesInRect:aRect],
4233 exposedColumnIndexes = [],
4234 firstExposedColumn = [exposedColumns firstIndex],
4235 exposedRange =
CPMakeRange(firstExposedColumn, [exposedColumns lastIndex] - firstExposedColumn + 1);
4237 [exposedColumns getIndexes:exposedColumnIndexes maxCount:-1 inIndexRange:exposedRange];
4239 var exposedColumnCount = [exposedColumnIndexes count];
4241 for (var c = firstExposedColumn; c < exposedColumnCount; c++)
4243 var colRect = [
self rectOfColumn:exposedColumnIndexes[c]],
4244 colX = CGRectGetMaxX(colRect) + 0.5;
4252 if ([indexes containsObject:indexes[i] + 1])
4269 - (void)_drawGroupRowsForRects:(CPArray)rects
4279 var gradientCache = [
self selectionGradientColors],
4283 199.0 / 255.0, 199.0 / 255.0, 199.0 / 255.0, 1.0], [0, 1], 2),
4288 var rowRect = rects[i];
4294 var minX = CGRectGetMinX(rowRect),
4295 minY = CGRectGetMinY(rowRect),
4296 maxX = CGRectGetMaxX(rowRect),
4297 maxY = CGRectGetMaxY(rowRect);
4319 - (void)_drawRows:(
CPIndexSet)rowsIndexes clipRect:(CGRect)clipRect
4325 [
self drawRow:row clipRect:CGRectIntersection(clipRect, [
self rectOfRow:row])];
4336 - (void)drawRow:(CPInteger)row clipRect:(CGRect)rect
4345 - (void)layoutSubviews
4353 - (void)viewWillMoveToSuperview:(CPView)aView
4355 var superview = [
self superview],
4362 name:CPViewFrameDidChangeNotification
4367 name:CPViewBoundsDidChangeNotification
4371 if ([aView isKindOfClass:[CPClipView
class]])
4373 [aView setPostsFrameChangedNotifications:YES];
4374 [aView setPostsBoundsChangedNotifications:YES];
4378 selector:@selector(superviewFrameChanged:)
4379 name:CPViewFrameDidChangeNotification
4384 selector:@selector(superviewBoundsChanged:)
4385 name:CPViewBoundsDidChangeNotification
4397 [
self setNeedsDisplay:YES];
4398 [
self setNeedsLayout];
4414 - (BOOL)tracksMouseOutsideOfFrame
4422 - (BOOL)startTrackingAt:(CGPoint)aPoint
4425 [[
self window] makeFirstResponder:self];
4427 var row = [
self rowAtPoint:aPoint];
4430 if (row < 0 && _allowsEmptySelection)
4432 if ([
self _sendDelegateSelectionShouldChangeInTableView])
4434 var indexSet = [
self _sendDelegateSelectionIndexesForProposedSelection:[
CPIndexSet indexSet]];
4436 [
self _noteSelectionIsChanging];
4437 [
self selectRowIndexes:indexSet byExtendingSelection:NO];
4442 _selectionAnchorRow = (ABS([_selectedRowIndexes firstIndex] - row) < ABS([_selectedRowIndexes lastIndex] - row)) ?
4443 [_selectedRowIndexes firstIndex] : [_selectedRowIndexes lastIndex];
4445 _selectionAnchorRow = row;
4448 _startTrackingPoint = aPoint;
4449 _startTrackingTimestamp =
new Date();
4451 if ([
self _dataSourceRespondsToSetObjectValueForTableColumnRow])
4452 _trackingPointMovedOutOfClickSlop = NO;
4456 if (row >= 0 && !([
self _dataSourceRespondsToWriteRowsWithIndexesToPasteboard]))
4457 [
self _updateSelectionWithMouseAtRow:row];
4467 if (!([
self _delegateRespondsToMenuForTableColumnRow]))
4468 return [
super menuForEvent:theEvent];
4470 var location = [
self convertPoint:[theEvent locationInWindow] fromView:nil],
4471 row = [
self rowAtPoint:location],
4472 column = [
self columnAtPoint:location],
4473 tableColumn = [[
self tableColumns] objectAtIndex:column];
4475 return [
self _sendDelegateMenuForTableColumn:tableColumn row:row];
4481 - (void)trackMouse:(
CPEvent)anEvent
4484 if (![_draggedRowIndexes count])
4486 [
self autoscroll:anEvent];
4487 [
super trackMouse:anEvent];
4490 [CPApp sendEvent:anEvent];
4496 - (BOOL)continueTracking:(CGPoint)lastPoint at:(CGPoint)aPoint
4498 var row = [
self rowAtPoint:aPoint];
4502 if (!_isSelectingSession && [
self _dataSourceRespondsToWriteRowsWithIndexesToPasteboard])
4504 if (row >= 0 && (ABS(_startTrackingPoint.x - aPoint.x) > 3 || (_verticalMotionCanDrag && ABS(_startTrackingPoint.y - aPoint.y) > 3)) ||
4505 ([_selectedRowIndexes containsIndex:row]))
4507 if ([_selectedRowIndexes containsIndex:row])
4508 _draggedRowIndexes = [[
CPIndexSet alloc] initWithIndexSet:_selectedRowIndexes];
4515 if ([
self canDragRowsWithIndexes:_draggedRowIndexes atPoint:aPoint] && [
self _sendDataSourceWriteRowsWithIndexes:_draggedRowIndexes toPasteboard:pboard])
4517 var currentEvent = [CPApp currentEvent],
4518 offset = CGPointMakeZero(),
4519 tableColumns = [_tableColumns objectsAtIndexes:_exposedColumns];
4524 var view = [
self dragViewForRowsWithIndexes:_draggedRowIndexes
4525 tableColumns:tableColumns
4531 var image = [
self dragImageForRowsWithIndexes:_draggedRowIndexes
4532 tableColumns:tableColumns
4535 view = [[
CPImageView alloc] initWithFrame:CGRectMake(0, 0, [image size].width, [image size].height)];
4536 [view setImage:image];
4539 var bounds = [view bounds],
4540 viewLocation = CGPointMake(aPoint.x - CGRectGetWidth(bounds) / 2 + offset.x, aPoint.y - CGRectGetHeight(bounds) / 2 + offset.y);
4541 [
self dragView:view at:viewLocation offset:CGPointMakeZero() event:[CPApp currentEvent] pasteboard:pboard source:self slideBack:YES];
4542 _startTrackingPoint = nil;
4550 else if (ABS(_startTrackingPoint.x - aPoint.x) < 5 && ABS(_startTrackingPoint.y - aPoint.y) < 5)
4554 _isSelectingSession = YES;
4555 if (row >= 0 && row !== _lastTrackedRowIndex)
4557 _lastTrackedRowIndex = row;
4558 [
self _updateSelectionWithMouseAtRow:row];
4561 if ([
self _dataSourceRespondsToSetObjectValueForTableColumnRow]
4562 && !_trackingPointMovedOutOfClickSlop)
4564 var CLICK_SPACE_DELTA = 5.0;
4565 if (ABS(aPoint.x - _startTrackingPoint.x) > CLICK_SPACE_DELTA
4566 || ABS(aPoint.y - _startTrackingPoint.y) > CLICK_SPACE_DELTA)
4568 _trackingPointMovedOutOfClickSlop = YES;
4578 - (void)stopTracking:(CGPoint)lastPoint at:(CGPoint)aPoint mouseIsUp:(BOOL)mouseIsUp
4580 _isSelectingSession = NO;
4582 var CLICK_TIME_DELTA = 1000,
4588 if ([
self _dataSourceRespondsToWriteRowsWithIndexesToPasteboard])
4590 rowIndex = [
self rowAtPoint:aPoint];
4592 if (rowIndex !== -1)
4594 if ([_draggedRowIndexes count] > 0)
4600 _previouslySelectedRowIndexes = [_selectedRowIndexes copy];
4601 [
self _updateSelectionWithMouseAtRow:rowIndex];
4606 if (!_isViewBased && mouseIsUp
4607 && !_trackingPointMovedOutOfClickSlop
4608 && ([[
CPApp currentEvent] clickCount] > 1)
4609 && ([
self _dataSourceRespondsToSetObjectValueForTableColumnRow]
4610 || [
self infoForBinding:
@"content"]))
4612 columnIndex = [
self columnAtPoint:lastPoint];
4614 if (columnIndex !== -1)
4616 column = _tableColumns[columnIndex];
4618 if ([column isEditable])
4620 rowIndex = [
self rowAtPoint:aPoint];
4622 if (rowIndex !== -1)
4624 if ([
self _sendDelegateShouldEditTableColumn:column row:rowIndex])
4626 [
self editColumn:columnIndex row:rowIndex withEvent:nil select:YES];
4636 if ([[
CPApp currentEvent] clickCount] === 2 && _doubleAction)
4638 _clickedRow = [
self rowAtPoint:aPoint];
4639 _clickedColumn = [
self columnAtPoint:lastPoint];
4640 [
self sendAction:_doubleAction to:_target];
4647 - (CPDragOperation)draggingEntered:(
id)sender
4649 var location = [
self convertPoint:[sender draggingLocation] fromView:nil],
4650 dropOperation = [
self _proposedDropOperationAtPoint:location],
4651 row = [
self _proposedRowAtPoint:location];
4653 if (_retargetedDropRow !== nil)
4654 row = _retargetedDropRow;
4656 var draggedTypes = [
self registeredDraggedTypes],
4657 count = [draggedTypes count],
4660 for (; i < count; i++)
4662 if ([[[sender draggingPasteboard] types] containsObject:[draggedTypes objectAtIndex: i]])
4663 return [
self _sendDataSourceValidateDrop:sender proposedRow:row proposedDropOperation:dropOperation];
4672 - (void)draggingExited:(
id)sender
4674 [_dropOperationFeedbackView removeFromSuperview];
4680 - (void)draggingEnded:(
id)sender
4682 [
self _draggingEnded];
4688 - (void)_draggingEnded
4690 _retargetedDropOperation = nil;
4691 _retargetedDropRow = nil;
4693 [_dropOperationFeedbackView removeFromSuperview];
4694 [
self _enqueueDraggingViews];
4700 - (BOOL)wantsPeriodicDraggingUpdates
4708 - (CPTableViewDropOperation)_proposedDropOperationAtPoint:(CGPoint)theDragPoint
4710 if (_retargetedDropOperation !== nil)
4711 return _retargetedDropOperation;
4713 var row = [
self _proposedRowAtPoint:theDragPoint],
4714 rowRect = [
self rectOfRow:row];
4718 if ([
self intercellSpacing].height < 5.0)
4719 rowRect = CGRectInset(rowRect, 0.0, 5.0 - [
self intercellSpacing].height);
4724 if (CGRectContainsPoint(rowRect, theDragPoint) && row < _numberOfRows)
4725 return CPTableViewDropOn;
4727 return CPTableViewDropAbove;
4733 - (CPInteger)_proposedRowAtPoint:(CGPoint)dragPoint
4735 var row = [
self rowAtPoint:dragPoint],
4738 rect = [self rectOfRow:row],
4739 bottomPoint = CGRectGetMaxY(rect),
4740 bottomThirty = bottomPoint - ((bottomPoint - CGRectGetMinY(rect)) * 0.3),
4741 numberOfRows = [self numberOfRows];
4744 row = (CGRectGetMaxY(rect) < dragPoint.y) ? numberOfRows : row;
4745 else if (dragPoint.y > MAX(bottomThirty, bottomPoint - 6))
4748 row = MIN(numberOfRows, row);
4756 - (CGRect)_rectForDropHighlightViewOnRow:(CPInteger)theRowIndex
4758 if (theRowIndex >= [
self numberOfRows])
4759 theRowIndex = [
self numberOfRows] - 1;
4761 return [
self _rectOfRow:theRowIndex checkRange:NO];
4767 - (CGRect)_rectForDropHighlightViewBetweenUpperRow:(CPInteger)theUpperRowIndex andLowerRow:(CPInteger)theLowerRowIndex offset:(CGPoint)theOffset
4769 if (theLowerRowIndex > [
self numberOfRows])
4770 theLowerRowIndex = [
self numberOfRows];
4772 return [
self _rectOfRow:theLowerRowIndex checkRange:NO];
4778 - (CPDragOperation)draggingUpdated:(
id)sender
4780 _retargetedDropRow = nil;
4781 _retargetedDropOperation = nil;
4783 var location = [
self convertPoint:[sender draggingLocation] fromView:nil],
4784 dropOperation = [
self _proposedDropOperationAtPoint:location],
4785 numberOfRows = [
self numberOfRows],
4786 row = [
self _proposedRowAtPoint:location],
4787 dragOperation = [
self _sendDataSourceValidateDrop:sender proposedRow:row proposedDropOperation:dropOperation];
4789 if (_retargetedDropRow !== nil)
4790 row = _retargetedDropRow;
4791 if (_retargetedDropOperation !== nil)
4792 dropOperation = _retargetedDropOperation;
4795 if (dropOperation === CPTableViewDropOn && row >= numberOfRows)
4796 row = numberOfRows - 1;
4798 var rect = CGRectMakeZero();
4801 rect = [
self exposedRect];
4803 else if (dropOperation === CPTableViewDropAbove)
4804 rect = [
self _rectForDropHighlightViewBetweenUpperRow:row - 1 andLowerRow:row offset:location];
4807 rect = [
self _rectForDropHighlightViewOnRow:row];
4809 [_dropOperationFeedbackView setDropOperation:row !== -1 ? dropOperation : CPDragOperationNone];
4810 [_dropOperationFeedbackView setHidden:(dragOperation == CPDragOperationNone)];
4811 [_dropOperationFeedbackView setFrame:rect];
4812 [_dropOperationFeedbackView setCurrentRow:row];
4813 [
self addSubview:_dropOperationFeedbackView];
4815 return dragOperation;
4821 - (BOOL)prepareForDragOperation:(
id)sender
4825 [_dropOperationFeedbackView removeFromSuperview];
4827 return [
self _dataSourceRespondsToValidateDropProposedRowProposedDropOperation];
4833 - (BOOL)performDragOperation:(
id)sender
4835 var location = [
self convertPoint:[sender draggingLocation] fromView:nil],
4836 operation = [
self _proposedDropOperationAtPoint:location],
4837 row = _retargetedDropRow;
4840 var row = [
self _proposedRowAtPoint:location];
4842 return [
self _sendDataSourceAcceptDrop:sender row:row dropOperation:operation];
4848 - (void)concludeDragOperation:(
id)sender
4857 - (void)draggedView:(
CPImage)aView endedAt:(CGPoint)aLocation operation:(CPDragOperation)anOperation
4859 [
self _draggingEnded];
4860 [
self draggedImage:aView endedAt:aLocation operation:anOperation];
4863 - (void)_enqueueDraggingViews
4865 [_draggingViews enumerateObjectsUsingBlock:function(dataView, idx)
4867 [
self _enqueueReusableDataView:dataView];
4870 [_draggingViews removeAllObjects];
4876 - (void)_updateSelectionWithMouseAtRow:(CPInteger)aRow
4883 shouldExtendSelection = NO;
4888 if ([_selectedRowIndexes containsIndex:aRow])
4890 newSelection = [_selectedRowIndexes copy];
4892 [newSelection removeIndex:aRow];
4894 else if (_allowsMultipleSelection)
4896 newSelection = [_selectedRowIndexes copy];
4898 [newSelection addIndex:aRow];
4903 else if (_allowsMultipleSelection)
4906 _selectionAnchorRow = [
self numberOfRows] - 1;
4909 shouldExtendSelection = [
self mouseDownFlags] & CPShiftKeyMask &&
4910 ((_lastSelectedRow == [_selectedRowIndexes lastIndex] && aRow > _lastSelectedRow) ||
4911 (_lastSelectedRow == [_selectedRowIndexes firstIndex] && aRow < _lastSelectedRow));
4913 else if (aRow >= 0 && aRow < _numberOfRows)
4918 if ([newSelection isEqualToIndexSet:_selectedRowIndexes])
4921 if (![
self _sendDelegateSelectionShouldChangeInTableView])
4924 newSelection = [
self _sendDelegateSelectionIndexesForProposedSelection:newSelection];
4926 if (![
self _delegateRespondsToSelectionIndexesForProposedSelection] && [
self _delegateRespondsToShouldSelectRow])
4928 var indexArray = [];
4930 [newSelection getIndexes:indexArray maxCount:-1 inIndexRange:nil];
4932 var indexCount = indexArray.length;
4934 while (indexCount--)
4936 var index = indexArray[indexCount];
4938 if (![
self _sendDelegateShouldSelectRow:index])
4939 [newSelection removeIndex:index];
4943 if ([newSelection count] === 0)
4948 if (!_allowsEmptySelection && [newSelection count] === 0)
4951 if ([newSelection isEqualToIndexSet:_selectedRowIndexes])
4954 [
self _noteSelectionIsChanging];
4955 [
self selectRowIndexes:newSelection byExtendingSelection:shouldExtendSelection];
4957 _lastSelectedRow = [newSelection containsIndex:aRow] ? aRow : [newSelection lastIndex];
4963 - (void)_noteSelectionIsChanging
4974 - (void)_noteSelectionDidChange
4985 - (void)becomeKeyWindow
4987 [
self setNeedsDisplay:YES];
4993 - (void)resignKeyWindow
4995 [
self setNeedsDisplay:YES];
5001 - (BOOL)becomeFirstResponder
5003 [
self setNeedsDisplay:YES];
5010 - (BOOL)resignFirstResponder
5012 [
self setNeedsDisplay:YES];
5019 - (BOOL)acceptsFirstResponder
5027 - (BOOL)needsPanelToBecomeKey
5035 - (CPView)hitTest:(CGPoint)aPoint
5037 var hit = [
super hitTest:aPoint];
5039 if ([[
CPApp currentEvent] type] ==
CPLeftMouseDown && [hit acceptsFirstResponder] && ![
self isRowSelected:[
self rowForView:hit]])
5045 - (void)_startObservingFirstResponder
5050 - (void)_stopObservingFirstResponder
5057 var responder = [[
self window] firstResponder];
5059 if (![responder isKindOfClass:[CPView
class]] || ![responder isDescendantOf:
self])
5066 _editingRow = [
self rowForView:responder];
5067 _editingColumn = [
self columnForView:responder];
5069 if (_editingRow !==
CPNotFound && [responder isKindOfClass:[
CPTextField class]] && ![responder isBezeled])
5071 [responder setBezeled:YES];
5072 [
self _registerForEndEditingNote:responder];
5076 - (void)_registerForEndEditingNote:(CPView)aTextField
5081 - (void)_unregisterForEndEditingNote:(CPView)aTextField
5090 var textField = [aNote
object];
5092 [
self _unregisterForEndEditingNote:textField];
5093 [textField setBezeled:NO];
5095 var action = [
self _disableActionIfExists:textField];
5096 [textField resignFirstResponder];
5097 [textField setAction:action];
5100 - (SEL)_disableActionIfExists:(CPView)aView
5105 if ([aView respondsToSelector:
@selector(action)] && (action = [aView action]))
5106 [aView setAction:nil];
5114 - (void)keyDown:(
CPEvent)anEvent
5116 var character = [anEvent charactersIgnoringModifiers],
5117 modifierFlags = [anEvent modifierFlags];
5126 if ([
self numberOfRows] !== 0)
5128 [
self _moveSelectionWithEvent:anEvent upward:(character === CPUpArrowFunctionKey)];
5136 if ([
self _sendDelegateDeleteKeyPressed])
5140 [
super keyDown:anEvent];
5148 - (BOOL)_selectionIsBroken
5150 return [
self selectedRowIndexes]._ranges.length !== 1;
5158 - (void)_moveSelectionWithEvent:(
CPEvent)theEvent upward:(BOOL)shouldGoUpward
5160 if (![
self _sendDelegateSelectionShouldChangeInTableView])
5163 var selectedIndexes = [
self selectedRowIndexes];
5165 if ([selectedIndexes count] > 0)
5167 var extend = (([theEvent modifierFlags] &
CPShiftKeyMask) && _allowsMultipleSelection),
5168 i = [
self selectedRow];
5170 if ([
self _selectionIsBroken])
5172 while ([selectedIndexes containsIndex:i])
5174 shouldGoUpward ? i-- : i++;
5176 _wasSelectionBroken =
true;
5178 else if (_wasSelectionBroken && ((shouldGoUpward && i !== [selectedIndexes firstIndex]) || (!shouldGoUpward && i !== [selectedIndexes lastIndex])))
5180 shouldGoUpward ? i = [selectedIndexes firstIndex] - 1 : i = [selectedIndexes lastIndex];
5181 _wasSelectionBroken =
false;
5185 shouldGoUpward ? i-- : i++;
5192 if ([
self numberOfRows] > 0)
5193 var i = shouldGoUpward ? [
self numberOfRows] - 1 : 0;
5196 if (i >= [
self numberOfRows] || i < 0)
5199 if (![
self _delegateRespondsToSelectionIndexesForProposedSelection] && [
self _delegateRespondsToShouldSelectRow])
5201 var shouldSelect = [
self _sendDelegateShouldSelectRow:i];
5207 while (!shouldSelect && (i < [
self numberOfRows] && i > 0))
5209 shouldGoUpward ? --i : ++i;
5210 shouldSelect = [
self _sendDelegateShouldSelectRow:i];
5218 if (extend && [selectedIndexes containsIndex:i])
5221 var differedLastSelectedRow = i;
5224 shouldGoUpward ? i++ : i--;
5226 [selectedIndexes removeIndex:i];
5233 if ([selectedIndexes containsIndex:i])
5235 i = shouldGoUpward ? [selectedIndexes firstIndex] -1 : [selectedIndexes lastIndex] + 1;
5236 i = MIN(MAX(i, 0), [
self numberOfRows] - 1);
5239 [selectedIndexes addIndex:i];
5240 var differedLastSelectedRow = i;
5245 var differedLastSelectedRow = i;
5248 selectedIndexes = [
self _sendDelegateSelectionIndexesForProposedSelection:selectedIndexes];
5250 [
self selectRowIndexes:selectedIndexes byExtendingSelection:extend];
5253 _lastSelectedRow = differedLastSelectedRow;
5256 [
self scrollRowToVisible:i];
5262 @implementation CPTableView (TableViewDataSource)
5268 - (BOOL)_dataSourceRespondsToObjectValueForTableColumn
5270 return _implementedDataSourceMethods & CPTableViewDataSource_tableView_objectValueForTableColumn_row_;
5277 - (BOOL)_dataSourceRespondsToWriteRowsWithIndexesToPasteboard
5279 return _implementedDataSourceMethods & CPTableViewDataSource_tableView_writeRowsWithIndexes_toPasteboard_;
5286 - (BOOL)_dataSourceRespondsToSetObjectValueForTableColumnRow
5288 return CPTableViewDataSource_tableView_setObjectValue_forTableColumn_row_;
5295 - (BOOL)_dataSourceRespondsToValidateDropProposedRowProposedDropOperation
5297 return _implementedDataSourceMethods & CPTableViewDataSource_tableView_validateDrop_proposedRow_proposedDropOperation_;
5304 - (BOOL)_dataSourceRespondsToNumberOfRowsinTableView
5306 return _implementedDataSourceMethods & CPTableViewDataSource_numberOfRowsInTableView_;
5314 - (int)_sendDataSourceNumberOfRowsInTableView
5316 if (!(_implementedDataSourceMethods & CPTableViewDataSource_numberOfRowsInTableView_))
5319 return [_dataSource numberOfRowsInTableView:self];
5327 - (id)_sendDataSourceObjectValueForTableColumn:(
CPTableColumn)aTableColumn row:(CPInteger)aRowIndex
5329 if (!(_implementedDataSourceMethods & CPTableViewDataSource_tableView_objectValueForTableColumn_row_))
5332 return [_dataSource tableView:self objectValueForTableColumn:aTableColumn row:aRowIndex];
5339 - (void)_sendDataSourceSetObjectValue:(
id)anObject forTableColumn:(
CPTableColumn)aTableColumn row:(CPInteger)aRowIndex
5341 if (!(_implementedDataSourceMethods & CPTableViewDataSource_tableView_setObjectValue_forTableColumn_row_))
5344 [_dataSource tableView:self setObjectValue:anObject forTableColumn:aTableColumn row:aRowIndex];
5351 - (void)_sendDataSourceSortDescriptorsDidChange:(CPArray)descriptors
5353 if (!(_implementedDataSourceMethods & CPTableViewDataSource_tableView_sortDescriptorsDidChange_))
5356 [_dataSource tableView:self sortDescriptorsDidChange:descriptors];
5363 - (BOOL)_sendDataSourceAcceptDrop:(
id)info row:(CPInteger)aRowIndex dropOperation:(CPTableViewDropOperation)operation
5365 if (!(_implementedDataSourceMethods & CPTableViewDataSource_tableView_acceptDrop_row_dropOperation_))
5368 return [_dataSource tableView:self acceptDrop:info row:aRowIndex dropOperation:operation];
5375 - (CPDragOperation)_sendDataSourceValidateDrop:(
id)info proposedRow:(CPInteger)aRowIndex proposedDropOperation:(CPTableViewDropOperation)operation
5377 if (!(_implementedDataSourceMethods & CPTableViewDataSource_tableView_validateDrop_proposedRow_proposedDropOperation_))
5380 return [_dataSource tableView:self validateDrop:info proposedRow:aRowIndex proposedDropOperation:operation];
5389 if (!(_implementedDataSourceMethods & CPTableViewDataSource_tableView_writeRowsWithIndexes_toPasteboard_))
5392 return [_dataSource tableView:self writeRowsWithIndexes:rowIndexes toPasteboard:pboard];
5398 - (void)draggedImage:(
CPImage)anImage endedAt:(CGPoint)aLocation operation:(CPDragOperation)anOperation
5400 if ([_dataSource respondsToSelector:
@selector(tableView:didEndDraggedImage:atPosition:operation:)])
5401 [_dataSource tableView:self didEndDraggedImage:anImage atPosition:aLocation operation:anOperation];
5406 #pragma mark DataSource methods to implement
5412 - (CPArray)_sendDataSourceNamesOfPromisedFilesDroppedAtDestination:(
CPURL)dropDestination forDraggedRowsWithIndexes:(
CPIndexSet)indexSet
5414 if (!(_implementedDataSourceMethods & CPTableViewDataSource_tableView_namesOfPromisedFilesDroppedAtDestination_forDraggedRowsWithIndexes_))
5417 return [_dataSource tableView:self namesOfPromisedFilesDroppedAtDestination:dropDestination forDraggedRowsWithIndexes:indexSet];
5423 @implementation CPTableView (TableViewDelegate)
5429 - (BOOL)_delegateRespondsToDataViewForTableColumn
5431 return _implementedDelegateMethods & CPTableViewDelegate_tableView_dataViewForTableColumn_row_;
5438 - (BOOL)_delegateRespondsToViewForTableColumn
5440 return _implementedDelegateMethods & CPTableViewDelegate_tableView_viewForTableColumn_row_;
5447 - (BOOL)_delegateRespondsToShouldSelectRow
5449 return _implementedDelegateMethods & CPTableViewDelegate_tableView_shouldSelectRow_;
5456 - (BOOL)_delegateRespondsToSelectionShouldChangeInTableView
5458 return _implementedDelegateMethods & CPTableViewDelegate_selectionShouldChangeInTableView_;
5465 - (BOOL)_delegateRespondsToSelectionIndexesForProposedSelection
5467 return _implementedDelegateMethods & CPTableViewDelegate_tableView_selectionIndexesForProposedSelection_;
5474 - (BOOL)_delegateRespondsToMenuForTableColumnRow
5476 return _implementedDelegateMethods & CPTableViewDelegate_tableViewMenuForTableColumn_row_;
5483 - (void)_sendDelegateDidClickTableColumn:(CPInteger)column
5485 if (_implementedDelegateMethods & CPTableViewDelegate_tableView_didClickTableColumn_)
5486 [_delegate tableView:self didClickTableColumn:_tableColumns[column]];
5493 - (void)_sendDelegateDidDragTableColumn:(CPInteger)column
5495 if (_implementedDelegateMethods & CPTableViewDelegate_tableView_didDragTableColumn_)
5496 [_delegate tableView:self didDragTableColumn:_tableColumns[column]];
5503 - (void)_sendDelegateMouseDownInHeaderOfTableColumn:(CPInteger)column
5505 if (_implementedDelegateMethods & CPTableViewDelegate_tableView_mouseDownInHeaderOfTableColumn_)
5506 [_delegate tableView:self mouseDownInHeaderOfTableColumn:_tableColumns[column]];
5513 - (BOOL)_sendDelegateDeleteKeyPressed
5515 if ([_delegate respondsToSelector:
@selector(tableViewDeleteKeyPressed:)])
5517 [_delegate tableViewDeleteKeyPressed:self];
5528 - (BOOL)_sendDelegateSelectionShouldChangeInTableView
5530 if (!(_implementedDelegateMethods & CPTableViewDelegate_selectionShouldChangeInTableView_))
5533 return [_delegate selectionShouldChangeInTableView:self];
5540 - (BOOL)_sendDelegateIsGroupRow:(CPInteger)anIndex
5542 if (!(_implementedDelegateMethods & CPTableViewDelegate_tableView_isGroupRow_))
5545 return [_delegate tableView:self isGroupRow:anIndex];
5552 - (BOOL)_sendDelegateShouldSelectRow:(CPInteger)anIndex
5554 if (!(_implementedDelegateMethods & CPTableViewDelegate_tableView_shouldSelectRow_))
5557 return [_delegate tableView:self shouldSelectRow:anIndex];
5564 - (void)_sendDelegateWillDisplayView:(
id)aCell forTableColumn:(
CPTableColumn)aTableColumn row:(CPInteger)aRowIndex
5566 if (!(_implementedDelegateMethods & CPTableViewDelegate_tableView_willDisplayView_forTableColumn_row_))
5569 [_delegate tableView:self willDisplayView:aCell forTableColumn:aTableColumn row:aRowIndex];
5578 if (!(_implementedDelegateMethods & CPTableViewDelegate_tableViewMenuForTableColumn_row_))
5581 return [_delegate tableView:self menuForTableColumn:aTableColumn row:aRowIndex];
5590 - (BOOL)_sendDelegateShouldReorderColumn:(CPInteger)columnIndex toColumn:(CPInteger)newColumnIndex
5592 if ([
self allowsColumnReordering] &&
5593 _implementedDelegateMethods & CPTableViewDelegate_tableView_shouldReorderColumn_toColumn_)
5595 return [_delegate tableView:self shouldReorderColumn:columnIndex toColumn:newColumnIndex];
5598 return [
self allowsColumnReordering];
5605 - (float)_sendDelegateHeightOfRow:(CPInteger)anIndex
5607 if (!(_implementedDelegateMethods & CPTableViewDelegate_tableView_heightOfRow_))
5608 return [
self rowHeight];
5610 return [_delegate tableView:self heightOfRow:anIndex];
5617 - (BOOL)_sendDelegateShouldEditTableColumn:(
CPTableColumn)aTableColumn row:(CPInteger)aRowIndex
5619 if (!(_implementedDelegateMethods & CPTableViewDelegate_tableView_shouldEditTableColumn_row_))
5622 return [_delegate tableView:self shouldEditTableColumn:aTableColumn row:aRowIndex];
5631 if (!(_implementedDelegateMethods & CPTableViewDelegate_tableView_selectionIndexesForProposedSelection_))
5634 return [_delegate tableView:self selectionIndexesForProposedSelection:anIndexSet];
5641 - (CPView)_sendDelegateViewForTableColumn:(
CPTableColumn)aTableColumn row:(CPInteger)aRowIndex
5643 if (!(_implementedDelegateMethods & CPTableViewDelegate_tableView_viewForTableColumn_row_))
5646 return [_delegate tableView:self viewForTableColumn:aTableColumn row:aRowIndex];
5653 - (CPView)_sendDelegateDataViewForTableColumn:(
CPTableColumn)aTableColumn row:(CPInteger)aRowIndex
5655 if (!(_implementedDelegateMethods & CPTableViewDelegate_tableView_dataViewForTableColumn_row_))
5658 return [_delegate tableView:self dataViewForTableColumn:aTableColumn row:aRowIndex];
5663 #pragma mark Delegate methods to implement
5669 - (BOOL)_sendDelegateShouldSelectTableColumn:(
CPTableColumn)aTableColumn
5671 if (!(_implementedDelegateMethods & CPTableViewDelegate_tableView_shouldSelectTableColumn_))
5674 return [_delegate tableView:self shouldSelectTableColumn:aTableColumn];
5681 - (
CPString)_sendDelegateToolTipForView:(
id)aView rect:(CGRect)aRect tableColumn:(
CPTableColumn)aTableColumn row:(CPInteger)aRowIndex mouseLocation:(CGPoint)aPoint
5683 if (!(_implementedDelegateMethods & CPTableViewDelegate_tableView_toolTipForView_rect_tableColumn_row_mouseLocation_))
5686 return [_delegate tableView:self toolTipForView:aView rect:aRect tableColumn:aTableColumn row:aRowIndex mouseLocation:aPoint];
5693 - (BOOL)_sendDelegateShouldTrackView:(
id)aView forTableColumn:(
CPTableColumn)aTableColumn row:(CPInteger)aRowIndex
5695 if (!(_implementedDelegateMethods & CPTableViewDelegate_tableView_shouldTrackView_forTableColumn_row_))
5698 return [_delegate tableView:self shouldTrackView:aView forTableColumn:aTableColumn row:aRowIndex];
5705 - (BOOL)_sendDelegateShouldShowViewExpansionForTableColumn:(
CPTableColumn)aTableColumn row:(CPInteger)aRowIndex
5707 if (!(_implementedDelegateMethods & CPTableViewDelegate_tableView_shouldShowViewExpansionForTableColumn_row_))
5710 return [_delegate tableView:self shouldShowViewExpansionForTableColumn:aTableColumn row:aRowIndex];
5717 - (BOOL)_sendDelegateShouldTypeSelectForEvent:(
CPEvent)anEvent withCurrentSearchString:(
CPString)aString
5719 if (!(_implementedDelegateMethods & CPTableViewDelegate_tableView_shouldTypeSelectForEvent_withCurrentSearchString_))
5722 return [_delegate tableView:self shouldTypeSelectForEvent:anEvent withCurrentSearchString:aString];
5729 - (
CPString)_sendDelegateTypeSelectStringForTableColumn:(
CPTableColumn)aTableColumn row:(CPInteger)aRowIndex
5731 if (!(_implementedDelegateMethods & CPTableViewDelegate_tableView_typeSelectStringForTableColumn_row_))
5734 return [_delegate tableView:self typeSelectStringForTableColumn:aTableColumn row:aRowIndex];
5741 - (int)_sendDelegateNextTypeSelectMatchFromRow:(CPInteger)aRowIndex toRow:(CPInteger)aSecondRowIndex forString:(
CPString)aString
5743 if (!(_implementedDelegateMethods & CPTableViewDelegate_tableView_nextTypeSelectMatchFromRow_toRow_forString_))
5746 return [_delegate tableView:self nextTypeSelectMatchFromRow:aRowIndex toRow:aSecondRowIndex forString:aString];
5751 @implementation CPTableView (Bindings)
5753 + (Class)_binderClassForBinding:(
CPString)aBinding
5755 if (aBinding ==
@"content")
5758 return [
super _binderClassForBinding:aBinding];
5766 if (aBinding ===
@"selectionIndexes")
5767 return @"selectedRowIndexes";
5769 return [
super _replacementKeyPathForBinding:aBinding];
5775 - (void)_establishBindingsIfUnbound:(
id)destination
5777 if ([[
self infoForBinding:
@"content"] objectForKey:CPObservedObjectKey] !== destination)
5779 [
super bind:@"content" toObject:destination withKeyPath:@"arrangedObjects" options:nil];
5780 _contentBindingExplicitlySet = NO;
5784 if (!_contentBindingExplicitlySet)
5786 if ([[
self infoForBinding:
@"selectionIndexes"] objectForKey:CPObservedObjectKey] !== destination)
5787 [
self bind:@"selectionIndexes" toObject:destination withKeyPath:@"selectionIndexes" options:nil];
5789 if ([[
self infoForBinding:
@"sortDescriptors"] objectForKey:CPObservedObjectKey] !== destination)
5790 [
self bind:@"sortDescriptors" toObject:destination withKeyPath:@"sortDescriptors" options:nil];
5796 [
super bind:aBinding toObject:anObject withKeyPath:aKeyPath options:options];
5798 if (aBinding ==
@"content")
5799 _contentBindingExplicitlySet = YES;
5810 - (void)setValueFor:(
CPString)aBinding
5812 var destination = [_info objectForKey:CPObservedObjectKey],
5813 keyPath = [_info objectForKey:CPObservedKeyPathKey];
5815 _content = [destination valueForKey:keyPath];
5817 [_source reloadData];
5823 var CPTableViewDataSourceKey =
@"CPTableViewDataSourceKey",
5824 CPTableViewDelegateKey =
@"CPTableViewDelegateKey",
5825 CPTableViewHeaderViewKey =
@"CPTableViewHeaderViewKey",
5826 CPTableViewTableColumnsKey =
@"CPTableViewTableColumnsKey",
5827 CPTableViewRowHeightKey =
@"CPTableViewRowHeightKey",
5828 CPTableViewIntercellSpacingKey =
@"CPTableViewIntercellSpacingKey",
5829 CPTableViewSelectionHighlightStyleKey =
@"CPTableViewSelectionHighlightStyleKey",
5830 CPTableViewMultipleSelectionKey =
@"CPTableViewMultipleSelectionKey",
5831 CPTableViewEmptySelectionKey =
@"CPTableViewEmptySelectionKey",
5832 CPTableViewColumnReorderingKey =
@"CPTableViewColumnReorderingKey",
5833 CPTableViewColumnResizingKey =
@"CPTableViewColumnResizingKey",
5834 CPTableViewColumnSelectionKey =
@"CPTableViewColumnSelectionKey",
5835 CPTableViewColumnAutoresizingStyleKey =
@"CPTableViewColumnAutoresizingStyleKey",
5836 CPTableViewGridColorKey =
@"CPTableViewGridColorKey",
5837 CPTableViewGridStyleMaskKey =
@"CPTableViewGridStyleMaskKey",
5838 CPTableViewUsesAlternatingBackgroundKey =
@"CPTableViewUsesAlternatingBackgroundKey",
5839 CPTableViewAlternatingRowColorsKey =
@"CPTableViewAlternatingRowColorsKey",
5840 CPTableViewHeaderViewKey =
@"CPTableViewHeaderViewKey",
5841 CPTableViewCornerViewKey =
@"CPTableViewCornerViewKey",
5842 CPTableViewAutosaveNameKey =
@"CPTableViewAutosaveNameKey",
5843 CPTableViewArchivedReusableViewsKey =
@"CPTableViewArchivedReusableViewsKey";
5845 @implementation CPTableView (CPCoding)
5847 - (id)initWithCoder:(
CPCoder)aCoder
5849 self = [
super initWithCoder:aCoder];
5854 _allowsColumnReordering = [aCoder decodeBoolForKey:CPTableViewColumnReorderingKey];
5855 _allowsColumnResizing = [aCoder decodeBoolForKey:CPTableViewColumnResizingKey];
5856 _allowsMultipleSelection = [aCoder decodeBoolForKey:CPTableViewMultipleSelectionKey];
5857 _allowsEmptySelection = [aCoder decodeBoolForKey:CPTableViewEmptySelectionKey];
5858 _allowsColumnSelection = [aCoder decodeBoolForKey:CPTableViewColumnSelectionKey];
5861 _selectionHighlightStyle = [aCoder decodeIntForKey:CPTableViewSelectionHighlightStyleKey];
5862 _columnAutoResizingStyle = [aCoder decodeIntForKey:CPTableViewColumnAutoresizingStyleKey];
5864 _tableColumns = [aCoder decodeObjectForKey:CPTableViewTableColumnsKey] || [];
5865 [_tableColumns makeObjectsPerformSelector:@selector(setTableView:) withObject:self];
5867 _rowHeight = [aCoder decodeFloatForKey:CPTableViewRowHeightKey] || [
self valueForThemeAttribute:@"default-row-height"];
5868 _intercellSpacing = [aCoder decodeSizeForKey:CPTableViewIntercellSpacingKey];
5870 if (CGSizeEqualToSize(_intercellSpacing, CGSizeMakeZero()))
5871 _intercellSpacing = CGSizeMake(3.0, 2.0);
5873 [
self setGridColor:[aCoder decodeObjectForKey:CPTableViewGridColorKey]];
5874 _gridStyleMask = [aCoder decodeIntForKey:CPTableViewGridStyleMaskKey];
5876 _usesAlternatingRowBackgroundColors = [aCoder decodeObjectForKey:CPTableViewUsesAlternatingBackgroundKey];
5877 [
self setAlternatingRowBackgroundColors:[aCoder decodeObjectForKey:CPTableViewAlternatingRowColorsKey]];
5879 _headerView = [aCoder decodeObjectForKey:CPTableViewHeaderViewKey];
5880 _cornerView = [aCoder decodeObjectForKey:CPTableViewCornerViewKey];
5882 [
self setDataSource:[aCoder decodeObjectForKey:CPTableViewDataSourceKey]];
5883 [
self setDelegate:[aCoder decodeObjectForKey:CPTableViewDelegateKey]];
5887 if ([aCoder containsValueForKey:CPTableViewArchivedReusableViewsKey])
5888 _archivedDataViews = [aCoder decodeObjectForKey:CPTableViewArchivedReusableViewsKey];
5890 [
self _updateIsViewBased];
5892 [
self viewWillMoveToSuperview:[
self superview]];
5895 [
self setAutosaveName:[aCoder decodeObjectForKey:CPTableViewAutosaveNameKey]];
5901 - (void)encodeWithCoder:(
CPCoder)aCoder
5903 [
super encodeWithCoder:aCoder];
5905 [aCoder encodeObject:_dataSource forKey:CPTableViewDataSourceKey];
5906 [aCoder encodeObject:_delegate forKey:CPTableViewDelegateKey];
5908 [aCoder encodeFloat:_rowHeight forKey:CPTableViewRowHeightKey];
5909 [aCoder encodeSize:_intercellSpacing forKey:CPTableViewIntercellSpacingKey];
5911 [aCoder encodeInt:_selectionHighlightStyle forKey:CPTableViewSelectionHighlightStyleKey];
5912 [aCoder encodeInt:_columnAutoResizingStyle forKey:CPTableViewColumnAutoresizingStyleKey];
5914 [aCoder encodeBool:_allowsMultipleSelection forKey:CPTableViewMultipleSelectionKey];
5915 [aCoder encodeBool:_allowsEmptySelection forKey:CPTableViewEmptySelectionKey];
5916 [aCoder encodeBool:_allowsColumnReordering forKey:CPTableViewColumnReorderingKey];
5917 [aCoder encodeBool:_allowsColumnResizing forKey:CPTableViewColumnResizingKey];
5918 [aCoder encodeBool:_allowsColumnSelection forKey:CPTableViewColumnSelectionKey];
5920 [aCoder encodeObject:_tableColumns forKey:CPTableViewTableColumnsKey];
5922 [aCoder encodeObject:[
self gridColor] forKey:CPTableViewGridColorKey];
5923 [aCoder encodeInt:_gridStyleMask forKey:CPTableViewGridStyleMaskKey];
5925 [aCoder encodeBool:_usesAlternatingRowBackgroundColors forKey:CPTableViewUsesAlternatingBackgroundKey];
5926 [aCoder encodeObject:[
self alternatingRowBackgroundColors] forKey:CPTableViewAlternatingRowColorsKey];
5928 [aCoder encodeObject:_cornerView forKey:CPTableViewCornerViewKey];
5929 [aCoder encodeObject:_headerView forKey:CPTableViewHeaderViewKey];
5931 [aCoder encodeObject:_autosaveName forKey:CPTableViewAutosaveNameKey];
5933 if (_archivedDataViews)
5934 [aCoder encodeObject:_archivedDataViews forKey:CPTableViewArchivedReusableViewsKey];
5940 @implementation CPIndexSet (tableview)
5944 var firstindex = [
self firstIndex],
5945 index = MIN(firstindex, [otherSet firstIndex]),
5946 switchFlag = (index == firstindex);
5950 var indexSet = (switchFlag) ? otherSet :
self,
5951 otherIndex = [indexSet indexGreaterThanOrEqualToIndex:index];
5953 if (otherIndex == index)
5955 [
self removeIndex:index];
5960 switchFlag = !switchFlag;
5966 @implementation _CPDropOperationDrawingView : CPView
5968 unsigned dropOperation;
5974 - (void)drawRect:(CGRect)aRect
5976 if (tableView._destinationDragStyle === CPTableViewDraggingDestinationFeedbackStyleNone || isBlinking)
5985 if (currentRow === -1)
5987 borderColor = [tableView valueForThemeAttribute:@"dropview-on-border-color"];
5988 borderWidth = [tableView valueForThemeAttribute:@"dropview-on-border-width"];
5995 else if (dropOperation === CPTableViewDropOn)
5998 var selectedRows = [tableView selectedRowIndexes],
5999 newRect = CGRectMake(aRect.origin.x + 2, aRect.origin.y + 2, aRect.size.width - 4, aRect.size.height - 5);
6001 if ([selectedRows containsIndex:currentRow])
6003 borderRadius = [tableView valueForThemeAttribute:@"dropview-on-selected-border-radius"];
6004 borderColor = [tableView valueForThemeAttribute:@"dropview-on-selected-border-color"];
6005 borderWidth = [tableView valueForThemeAttribute:@"dropview-on-selected-border-width"];
6006 backgroundColor = [tableView valueForThemeAttribute:@"dropview-on-selected-background-color"];
6010 borderRadius = [tableView valueForThemeAttribute:@"dropview-on-border-radius"];
6011 borderColor = [tableView valueForThemeAttribute:@"dropview-on-border-color"];
6012 borderWidth = [tableView valueForThemeAttribute:@"dropview-on-border-width"];
6013 backgroundColor = [tableView valueForThemeAttribute:@"dropview-on-background-color"];
6023 else if (dropOperation === CPTableViewDropAbove)
6026 [
self setFrameOrigin:CGPointMake(_frame.origin.x, _frame.origin.y - 8)];
6028 var selectedRows = [tableView selectedRowIndexes];
6030 if ([selectedRows containsIndex:currentRow - 1] || [selectedRows containsIndex:currentRow])
6032 borderColor = [tableView valueForThemeAttribute:@"dropview-above-selected-border-color"];
6033 borderWidth = [tableView valueForThemeAttribute:@"dropview-above-selected-border-width"];
6037 borderColor = [tableView valueForThemeAttribute:@"dropview-above-border-color"];
6038 borderWidth = [tableView valueForThemeAttribute:@"dropview-above-border-width"];
6054 if (dropOperation !== CPTableViewDropOn)
6059 var showCallback =
function()
6061 objj_msgSend(
self,
"setHidden:", NO)
6065 var hideCallback = function()
6067 objj_msgSend(
self,
"setHidden:", YES)
6071 objj_msgSend(self, "setHidden:", YES);
6072 [
CPTimer scheduledTimerWithTimeInterval:0.1 callback:showCallback repeats:NO];
6073 [
CPTimer scheduledTimerWithTimeInterval:0.19 callback:hideCallback repeats:NO];
6074 [
CPTimer scheduledTimerWithTimeInterval:0.27 callback:showCallback repeats:NO];
6080 @implementation _CPColumnDragView : CPView
6085 - (id)initWithLineColor:(
CPColor)aColor
6087 self = [
super initWithFrame:CGRectMakeZero()];
6090 _lineColor = aColor;
6095 - (void)drawRect:(CGRect)aRect
6102 CGPointMake(0.5, 0),
6103 CGPointMake(0.5, aRect.size.height)
6109 CGPointMake(aRect.size.width - 0.5, 0),
6110 CGPointMake(aRect.size.width - 0.5, aRect.size.height)
6127 - (void)awakeFromCib
6129 [
self setThemeState:CPThemeStateTableDataView];
6132 - (BOOL)setThemeState:(CPThemeState)aState
6134 [
super setThemeState:aState];
6135 [
self recursivelyPerformSelector:@selector(setThemeState:) withObject:aState startingFrom:self];
6138 - (BOOL)unsetThemeState:(CPThemeState)aState
6140 [
super unsetThemeState:aState];
6141 [
self recursivelyPerformSelector:@selector(unsetThemeState:) withObject:aState startingFrom:self];
6144 - (void)recursivelyPerformSelector:(
SEL)selector withObject:(
id)anObject startingFrom:(
id)aView
6146 [[aView subviews] enumerateObjectsUsingBlock:function(view, idx)
6148 [view performSelector:selector withObject:anObject];
6150 if (![view isKindOfClass:[
self class]])
6151 [
self recursivelyPerformSelector:selector withObject:anObject startingFrom:view];
6157 return "<" + [self className] + " 0x" + [
CPString stringWithHash:[self UID]] + " identifier=" + [self identifier] + ">";
6162 @implementation CPTableView (CPSynthesizedAccessors)
6167 - (BOOL)disableAutomaticResizing
6169 return _disableAutomaticResizing;
6175 - (void)setDisableAutomaticResizing:(BOOL)aValue
6177 _disableAutomaticResizing = aValue;
6182 @implementation CPTableContentBinder (CPSynthesizedAccessors)
6195 - (void)setContent:(
id)aValue
6202 @implementation CPTableCellView (CPSynthesizedAccessors)
6209 return _objectValue;
6215 - (void)setObjectValue:(
id)aValue
6217 _objectValue = aValue;
6233 _textField = aValue;
6249 _imageView = aValue;