00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 @import <Foundation/CPDictionary.j>
00024 @import <Foundation/CPObject.j>
00025 @import <Foundation/CPSortDescriptor.j>
00026 @import <Foundation/CPString.j>
00027
00028 @import "CPTableHeaderView.j"
00029
00030 #include "CoreGraphics/CGGeometry.h"
00031
00032 CPTableColumnNoResizing = 0;
00033 CPTableColumnAutoresizingMask = 1 << 0;
00034 CPTableColumnUserResizingMask = 1 << 1;
00035
00036 @implementation CPTableColumn : CPObject
00037 {
00038 CPTableView _tableView;
00039 CPView _headerView;
00040 CPView _dataView;
00041 Object _dataViewData;
00042
00043 float _width;
00044 float _minWidth;
00045 float _maxWidth;
00046 unsigned _resizingMask;
00047
00048 id _identifier;
00049 BOOL _isEditable;
00050 CPSortDescriptor _sortDescriptorPrototype;
00051 BOOL _isHidden;
00052 CPString _headerToolTip;
00053
00054 BOOL _disableResizingPosting @accessors(property=disableResizingPosting);
00055 }
00056
00057 - (id)init
00058 {
00059 return [self initWithIdentifier:@""];
00060 }
00061
00062 - (id)initWithIdentifier:(id)anIdentifier
00063 {
00064 self = [super init];
00065
00066 if (self)
00067 {
00068 _dataViewData = { };
00069
00070 _width = 100.0;
00071 _minWidth = 10.0;
00072 _maxWidth = 1000000.0;
00073 _resizingMask = CPTableColumnAutoresizingMask | CPTableColumnUserResizingMask;
00074 _disableResizingPosting = NO;
00075
00076 [self setIdentifier:anIdentifier];
00077
00078 var header = [[_CPTableColumnHeaderView alloc] initWithFrame:CGRectMakeZero()];
00079 [self setHeaderView:header];
00080
00081 var textDataView = [CPTextField new];
00082 [textDataView setLineBreakMode:CPLineBreakByTruncatingTail];
00083 [textDataView setValue:[CPColor colorWithHexString:@"333333"] forThemeAttribute:@"text-color"];
00084 [textDataView setValue:[CPColor whiteColor] forThemeAttribute:@"text-color" inState:CPThemeStateSelected];
00085 [textDataView setValue:[CPFont boldSystemFontOfSize:12] forThemeAttribute:@"font" inState:CPThemeStateSelected];
00086 [textDataView setValue:CPCenterVerticalTextAlignment forThemeAttribute:@"vertical-alignment"];
00087 [self setDataView:textDataView];
00088 }
00089
00090 return self;
00091 }
00092
00093
00094 - (void)setTableView:(CPTableView)aTableView
00095 {
00096 _tableView = aTableView;
00097 }
00098
00099 - (CPTableView)tableView
00100 {
00101 return _tableView;
00102 }
00103
00104 - (void)setWidth:(float)aWidth
00105 {
00106 aWidth = +aWidth;
00107
00108 if (_width === aWidth)
00109 return;
00110
00111 var newWidth = MIN(MAX(aWidth, [self minWidth]), [self maxWidth]);
00112
00113 if (_width === newWidth)
00114 return;
00115
00116 var oldWidth = _width;
00117
00118 _width = newWidth;
00119
00120 var tableView = [self tableView];
00121
00122 if (tableView)
00123 {
00124 var index = [[tableView tableColumns] indexOfObjectIdenticalTo:self],
00125 dirtyTableColumnRangeIndex = tableView._dirtyTableColumnRangeIndex;
00126
00127 if (dirtyTableColumnRangeIndex < 0)
00128 tableView._dirtyTableColumnRangeIndex = index;
00129 else
00130 tableView._dirtyTableColumnRangeIndex = MIN(index, tableView._dirtyTableColumnRangeIndex);
00131
00132 var rows = tableView._exposedRows,
00133 columns = [CPIndexSet indexSetWithIndexesInRange:CPMakeRange(index, [tableView._exposedColumns lastIndex] - index + 1)];
00134
00135
00136 [tableView _layoutDataViewsInRows:rows columns:columns];
00137 [tableView tile];
00138
00139 if (!_disableResizingPosting)
00140 [self _postDidResizeNotificationWithOldWidth:oldWidth];
00141 }
00142 }
00143
00144 - (float)width
00145 {
00146 return _width;
00147 }
00148
00149 - (void)setMinWidth:(float)aMinWidth
00150 {
00151 aMinWidth = +aMinWidth;
00152
00153 if (_minWidth === aMinWidth)
00154 return;
00155
00156 _minWidth = aMinWidth;
00157
00158 var width = [self width],
00159 newWidth = MAX(width, [self minWidth]);
00160
00161 if (width !== newWidth)
00162 [self setWidth:newWidth];
00163 }
00164
00165 - (float)minWidth
00166 {
00167 return _minWidth;
00168 }
00169
00170 - (void)setMaxWidth:(float)aMaxWidth
00171 {
00172 aMaxWidth = +aMaxWidth;
00173
00174 if (_maxWidth === aMaxWidth)
00175 return;
00176
00177 _maxWidth = aMaxWidth;
00178
00179 var width = [self width],
00180 newWidth = MIN(width, [self maxWidth]);
00181
00182 if (width !== newWidth)
00183 [self setWidth:newWidth];
00184 }
00185
00186 - (float)maxWidth
00187 {
00188 return _maxWidth;
00189 }
00190
00191 - (void)setResizingMask:(unsigned)aResizingMask
00192 {
00193 _resizingMask = aResizingMask;
00194 }
00195
00196 - (unsigned)resizingMask
00197 {
00198 return _resizingMask;
00199 }
00200
00201 - (void)sizeToFit
00202 {
00203 var width = _CGRectGetWidth([_headerView frame]);
00204
00205 if (width < [self minWidth])
00206 [self setMinWidth:width];
00207 else if (width > [self maxWidth])
00208 [self setMaxWidth:width]
00209
00210 if (_width !== width)
00211 [self setWidth:width];
00212 }
00213
00214
00215 - (void)setHeaderView:(CPView)aView
00216 {
00217 if (!aView)
00218 [CPException raise:CPInvalidArgumentException reason:@"Attempt to set nil header view on " + [self description]];
00219
00220 _headerView = aView;
00221
00222 var tableHeaderView = [_tableView headerView];
00223
00224 [tableHeaderView setNeedsLayout];
00225 [tableHeaderView setNeedsDisplay:YES];
00226 }
00227
00228 - (CPView)headerView
00229 {
00230 return _headerView;
00231 }
00232
00249 - (void)setDataView:(CPView)aView
00250 {
00251 if (_dataView === aView)
00252 return;
00253
00254 if (_dataView)
00255 _dataViewData[[_dataView UID]] = nil;
00256
00257 _dataView = aView;
00258 _dataViewData[[aView UID]] = [CPKeyedArchiver archivedDataWithRootObject:aView];
00259 }
00260
00261 - (CPView)dataView
00262 {
00263 return _dataView;
00264 }
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274 - (id)dataViewForRow:(int)aRowIndex
00275 {
00276 return [self dataView];
00277 }
00278
00279 - (id)_newDataViewForRow:(int)aRowIndex
00280 {
00281 var dataView = [self dataViewForRow:aRowIndex],
00282 dataViewUID = [dataView UID];
00283
00284 var x = [self tableView]._cachedDataViews[dataViewUID];
00285 if (x && x.length)
00286 return x.pop();
00287
00288
00289 if (!_dataViewData[dataViewUID])
00290 _dataViewData[dataViewUID] = [CPKeyedArchiver archivedDataWithRootObject:dataView];
00291
00292
00293 var newDataView = [CPKeyedUnarchiver unarchiveObjectWithData:_dataViewData[dataViewUID]];
00294 newDataView.identifier = dataViewUID;
00295
00296 return newDataView;
00297 }
00298
00299
00300
00301
00302
00303
00304 - (void)setIdentifier:(id)anIdentifier
00305 {
00306 _identifier = anIdentifier;
00307 }
00308
00309
00310
00311
00312 - (id)identifier
00313 {
00314 return _identifier;
00315 }
00316
00317
00318
00319
00320
00321
00322 - (void)setEditable:(BOOL)shouldBeEditable
00323 {
00324 _isEditable = shouldBeEditable;
00325 }
00326
00327
00328
00329
00330
00331 - (BOOL)isEditable
00332 {
00333 return _isEditable;
00334 }
00335
00336
00337 - (void)setSortDescriptorPrototype:(CPSortDescriptor)aSortDescriptor
00338 {
00339 _sortDescriptorPrototype = aSortDescriptor;
00340 }
00341
00342 - (CPSortDescriptor)sortDescriptorPrototype
00343 {
00344 return _sortDescriptorPrototype;
00345 }
00346
00347
00348
00349 - (void)setHidden:(BOOL)shouldBeHidden
00350 {
00351 _isHidden = shouldBeHidden;
00352 }
00353
00354 - (BOOL)isHidden
00355 {
00356 return _isHidden;
00357 }
00358
00359
00360
00361
00362
00363
00364
00365 - (void)setHeaderToolTip:(CPString)aToolTip
00366 {
00367 _headerToolTip = aToolTip;
00368 }
00369
00370 - (CPString)headerToolTip
00371 {
00372 return _headerToolTip;
00373 }
00374
00375 - (void)_postDidResizeNotificationWithOldWidth:(float)oldWidth
00376 {
00377 [[CPNotificationCenter defaultCenter]
00378 postNotificationName:CPTableViewColumnDidResizeNotification
00379 object:[self tableView]
00380 userInfo:[CPDictionary dictionaryWithObjects:[self, oldWidth] forKeys:[@"CPTableColumn", "CPOldWidth"]]];
00381 }
00382
00383 @end
00384
00385 var CPTableColumnIdentifierKey = @"CPTableColumnIdentifierKey",
00386 CPTableColumnHeaderViewKey = @"CPTableColumnHeaderViewKey",
00387 CPTableColumnDataViewKey = @"CPTableColumnDataViewKey",
00388 CPTableColumnWidthKey = @"CPTableColumnWidthKey",
00389 CPTableColumnMinWidthKey = @"CPTableColumnMinWidthKey",
00390 CPTableColumnMaxWidthKey = @"CPTableColumnMaxWidthKey",
00391 CPTableColumnResizingMaskKey = @"CPTableColumnResizingMaskKey";
00392
00393 @implementation CPTableColumn (CPCoding)
00394
00395 - (id)initWithCoder:(CPCoder)aCoder
00396 {
00397 self = [super init];
00398
00399 if (self)
00400 {
00401 _dataViewData = { };
00402
00403 _width = [aCoder decodeFloatForKey:CPTableColumnWidthKey];
00404 _minWidth = [aCoder decodeFloatForKey:CPTableColumnMinWidthKey];
00405 _maxWidth = [aCoder decodeFloatForKey:CPTableColumnMaxWidthKey];
00406
00407 [self setIdentifier:[aCoder decodeObjectForKey:CPTableColumnIdentifierKey]];
00408 [self setHeaderView:[aCoder decodeObjectForKey:CPTableColumnHeaderViewKey]];
00409 [self setDataView:[aCoder decodeObjectForKey:CPTableColumnDataViewKey]];
00410 [self setHeaderView:[aCoder decodeObjectForKey:CPTableColumnHeaderViewKey]];
00411
00412 _resizingMask = [aCoder decodeBoolForKey:CPTableColumnResizingMaskKey];
00413 }
00414
00415 return self;
00416 }
00417
00418 - (void)encodeWithCoder:(CPCoder)aCoder
00419 {
00420 [aCoder encodeObject:_identifier forKey:CPTableColumnIdentifierKey];
00421
00422 [aCoder encodeObject:_width forKey:CPTableColumnWidthKey];
00423 [aCoder encodeObject:_minWidth forKey:CPTableColumnMinWidthKey];
00424 [aCoder encodeObject:_maxWidth forKey:CPTableColumnMaxWidthKey];
00425
00426 [aCoder encodeObject:_headerView forKey:CPTableColumnHeaderViewKey];
00427 [aCoder encodeObject:_dataView forKey:CPTableColumnDataViewKey];
00428
00429 [aCoder encodeObject:_resizingMask forKey:CPTableColumnResizingMaskKey];
00430 }
00431
00432 @end
00433
00434 @implementation CPTableColumn (NSInCompatibility)
00435
00436 - (void)setHeaderCell:(CPView)aView
00437 {
00438 [CPException raise:CPUnsupportedMethodException
00439 reason:@"setHeaderCell: is not supported. -setHeaderCell:aView instead."];
00440 }
00441
00442 - (CPView)headerCell
00443 {
00444 [CPException raise:CPUnsupportedMethodException
00445 reason:@"headCell is not supported. -headerView instead."];
00446 }
00447
00448 - (void)setDataCell:(CPView)aView
00449 {
00450 [CPException raise:CPUnsupportedMethodException
00451 reason:@"setDataCell: is not supported. Use -setHeaderCell:aView instead."];
00452 }
00453
00454 - (CPView)dataCell
00455 {
00456 [CPException raise:CPUnsupportedMethodException
00457 reason:@"dataCell is not supported. Use -dataCell instead."];
00458 }
00459
00460 - (id)dataCellForRow:(int)row
00461 {
00462 [CPException raise:CPUnsupportedMethodException
00463 reason:@"dataCellForRow: is not supported. Use -dataViewForRow:row instead."];
00464 }
00465
00466 @end