25 @global CPTableViewColumnDidResizeNotification
27 @class _CPTableColumnHeaderView
29 CPTableColumnNoResizing = 0;
30 CPTableColumnAutoresizingMask = 1 << 0;
31 CPTableColumnUserResizingMask = 1 << 1;
54 unsigned _resizingMask;
62 BOOL _disableResizingPosting;
70 return [
self initWithIdentifier:@""];
77 - (id)initWithIdentifier:(
id)anIdentifier
87 _maxWidth = 1000000.0;
88 _resizingMask = CPTableColumnAutoresizingMask | CPTableColumnUserResizingMask;
89 _disableResizingPosting = NO;
91 [
self setIdentifier:anIdentifier];
93 var header = [[_CPTableColumnHeaderView alloc] initWithFrame:CGRectMakeZero()];
94 [
self setHeaderView:header];
107 _tableView = aTableView;
128 - (int)_tryToResizeToWidth:(
int)width
130 var min = [
self minWidth],
131 max = [
self maxWidth],
132 newWidth = ROUND(MIN(MAX(
width, min), max));
134 [
self setWidth:newWidth];
136 return newWidth -
width;
146 - (void)setWidth:(
float)aWidth
150 if (_width === aWidth)
153 var newWidth = MIN(MAX(aWidth, [
self minWidth]), [
self maxWidth]);
155 if (_width === newWidth)
158 var oldWidth = _width;
162 var tableView = [
self tableView];
166 var index = [[tableView tableColumns] indexOfObjectIdenticalTo:self],
167 dirtyTableColumnRangeIndex = tableView._dirtyTableColumnRangeIndex;
169 if (dirtyTableColumnRangeIndex < 0)
170 tableView._dirtyTableColumnRangeIndex = index;
172 tableView._dirtyTableColumnRangeIndex = MIN(index, tableView._dirtyTableColumnRangeIndex);
174 var rows = tableView._exposedRows,
178 [tableView _layoutDataViewsInRows:rows columns:columns];
181 if (!_disableResizingPosting)
182 [
self _postDidResizeNotificationWithOldWidth:oldWidth];
198 - (void)setMinWidth:(
float)aMinWidth
200 aMinWidth = +aMinWidth;
202 if (_minWidth === aMinWidth)
205 _minWidth = aMinWidth;
207 var
width = [
self width],
208 newWidth = MAX(width, [
self minWidth]);
210 if (width !== newWidth)
211 [
self setWidth:newWidth];
226 - (void)setMaxWidth:(
float)aMaxWidth
228 aMaxWidth = +aMaxWidth;
230 if (_maxWidth === aMaxWidth)
233 _maxWidth = aMaxWidth;
235 var
width = [
self width],
236 newWidth = MIN(width, [
self maxWidth]);
238 if (width !== newWidth)
239 [
self setWidth:newWidth];
261 - (void)setResizingMask:(
unsigned)aResizingMask
263 _resizingMask = aResizingMask;
270 - (unsigned)resizingMask
272 return _resizingMask;
280 var
width = CGRectGetWidth([_headerView
frame]);
282 if (width < [
self minWidth])
283 [
self setMinWidth:width];
284 else if (width > [
self maxWidth])
285 [
self setMaxWidth:width]
287 if (_width !== width)
288 [
self setWidth:width];
301 - (void)setHeaderView:(
CPView)aView
304 [
CPException raise:CPInvalidArgumentException
reason:@"Attempt to set nil header view on " + [
self description]];
308 var tableHeaderView = [_tableView headerView];
310 [tableHeaderView setNeedsLayout];
311 [tableHeaderView setNeedsDisplay:YES];
389 - (void)setDataView:(
CPView)aView
394 [aView setThemeState:CPThemeStateTableDataView];
413 - (id)dataViewForRow:(CPInteger)aRowIndex
415 return [
self dataView];
427 [newDataView setAutoresizingMask:CPViewNotSizable];
437 - (void)setIdentifier:(
id)anIdentifier
439 _identifier = anIdentifier;
455 - (void)setEditable:(BOOL)shouldBeEditable
457 _isEditable = shouldBeEditable;
474 _sortDescriptorPrototype = aSortDescriptor;
482 if (_sortDescriptorPrototype)
483 return _sortDescriptorPrototype;
485 var binderClass = [[
self class] _binderClassForBinding:CPValueBinding],
486 binding = [binderClass getBinding:CPValueBinding forObject:self];
488 return [binding _defaultSortDescriptorPrototype];
495 - (void)setHidden:(BOOL)shouldBeHidden
497 shouldBeHidden = !!shouldBeHidden
499 if (_isHidden === shouldBeHidden)
502 _isHidden = shouldBeHidden;
504 [[
self headerView] setHidden:shouldBeHidden];
505 [[
self tableView] _tableColumnVisibilityDidChange:self];
522 - (void)setHeaderToolTip:(
CPString)aToolTip
524 _headerToolTip = aToolTip;
532 return _headerToolTip;
538 - (void)_postDidResizeNotificationWithOldWidth:(
float)oldWidth
540 [[
self tableView] _didResizeTableColumn:self];
545 userInfo:@{ @"CPTableColumn": self, @"CPOldWidth": oldWidth }];
554 - (void)setValueFor:(
CPString)aBinding
556 var tableView = [_source tableView],
557 column = [[tableView tableColumns] indexOfObjectIdenticalTo:_source],
561 [tableView reloadDataForRowIndexes:rowIndexes columnIndexes:columnIndexes];
566 if (![
self createsSortDescriptor])
569 var keyPath = [_info objectForKey:CPObservedKeyPathKey],
570 dotIndex = keyPath.indexOf(
".");
575 var firstPart = keyPath.substring(0, dotIndex),
576 key = keyPath.substring(dotIndex + 1);
581 - (BOOL)createsSortDescriptor
583 var options = [_info objectForKey:CPOptionsKey],
584 optionValue = [options objectForKey:CPCreatesSortDescriptorBindingOption];
585 return optionValue === nil ? YES : [optionValue boolValue];
590 @implementation CPTableColumn (Bindings)
592 + (Class)_binderClassForBinding:(
CPString)aBinding
594 if (aBinding == CPValueBinding)
597 return [
super _binderClassForBinding:aBinding];
610 [
super bind:aBinding toObject:anObject withKeyPath:aKeyPath options:options];
612 if (![aBinding
isEqual:
@"someListOfExceptedBindings(notAcceptedBindings)"])
618 var acIndex = aKeyPath.lastIndexOf(
"arrangedObjects."),
619 arrayController = anObject;
623 var firstPart = aKeyPath.substring(0, acIndex - 1);
624 arrayController = [anObject valueForKeyPath:firstPart];
627 [[
self tableView] _establishBindingsIfUnbound:arrayController];
634 - (void)_prepareDataView:(
CPView)aDataView forRow:(
unsigned)aRow
636 var bindingsDictionary = [
CPBinder allBindingsForObject:self],
637 keys = [bindingsDictionary allKeys];
639 for (var i = 0, count = [keys count]; i < count; i++)
641 var bindingName = keys[i],
642 bindingPath = [aDataView _replacementKeyPathForBinding:bindingName],
643 binding = [bindingsDictionary objectForKey:bindingName],
644 bindingInfo = binding._info,
645 destination = [bindingInfo objectForKey:CPObservedObjectKey],
646 keyPath = [bindingInfo objectForKey:CPObservedKeyPathKey],
647 dotIndex = keyPath.lastIndexOf(
"."),
651 value = [[destination valueForKeyPath:keyPath] objectAtIndex:aRow];
665 var firstPart = keyPath.substring(0, dotIndex),
666 secondPart = keyPath.substring(dotIndex + 1),
667 firstValue = [destination valueForKeyPath:firstPart];
669 if ([firstValue isKindOfClass:CPArray])
670 value = [[firstValue objectAtIndex:aRow] valueForKeyPath:secondPart];
672 value = [[firstValue valueForKeyPath:secondPart] objectAtIndex:aRow];
675 value = [binding transformValue:value withOptions:[bindingInfo objectForKey:CPOptionsKey]];
676 [aDataView setValue:value forKey:@"objectValue"];
683 - (void)_reverseSetDataView:(
CPView)aDataView forRow:(
unsigned)aRow
685 var bindingsDictionary = [
CPBinder allBindingsForObject:self],
686 keys = [bindingsDictionary allKeys],
687 newValue = [aDataView valueForKey:@"objectValue"];
689 for (var i = 0, count = [keys count]; i < count; i++)
691 var bindingName = keys[i],
692 bindingPath = [aDataView _replacementKeyPathForBinding:bindingName],
693 binding = [bindingsDictionary objectForKey:bindingName],
694 bindingInfo = binding._info,
695 destination = [bindingInfo objectForKey:CPObservedObjectKey],
696 keyPath = [bindingInfo objectForKey:CPObservedKeyPathKey],
697 options = [bindingInfo objectForKey:CPOptionsKey],
698 dotIndex = keyPath.lastIndexOf(
".");
700 newValue = [binding reverseTransformValue:newValue withOptions:options];
703 [[destination valueForKeyPath:keyPath] replaceObjectAtIndex:aRow withObject:newValue];
706 var firstPart = keyPath.substring(0, dotIndex),
707 secondPart = keyPath.substring(dotIndex + 1),
708 firstValue = [destination valueForKeyPath:firstPart];
710 if ([firstValue isKindOfClass:CPArray])
711 [[firstValue objectAtIndex:aRow] setValue:newValue forKeyPath:secondPart];
713 [[firstValue valueForKeyPath:secondPart] replaceObjectAtIndex:aRow withObject:newValue];
720 var CPTableColumnIdentifierKey =
@"CPTableColumnIdentifierKey",
721 CPTableColumnHeaderViewKey =
@"CPTableColumnHeaderViewKey",
722 CPTableColumnDataViewKey =
@"CPTableColumnDataViewKey",
723 CPTableColumnWidthKey =
@"CPTableColumnWidthKey",
724 CPTableColumnMinWidthKey =
@"CPTableColumnMinWidthKey",
725 CPTableColumnMaxWidthKey =
@"CPTableColumnMaxWidthKey",
726 CPTableColumnResizingMaskKey =
@"CPTableColumnResizingMaskKey",
727 CPTableColumnIsHiddenKey =
@"CPTableColumnIsHiddenKey",
728 CPSortDescriptorPrototypeKey =
@"CPSortDescriptorPrototypeKey",
729 CPTableColumnIsEditableKey =
@"CPTableColumnIsEditableKey";
731 @implementation CPTableColumn (CPCoding)
736 - (id)initWithCoder:(
CPCoder)aCoder
744 _width = [aCoder decodeFloatForKey:CPTableColumnWidthKey];
745 _minWidth = [aCoder decodeFloatForKey:CPTableColumnMinWidthKey];
746 _maxWidth = [aCoder decodeFloatForKey:CPTableColumnMaxWidthKey];
748 [
self setIdentifier:[aCoder decodeObjectForKey:CPTableColumnIdentifierKey]];
749 [
self setHeaderView:[aCoder decodeObjectForKey:CPTableColumnHeaderViewKey]];
750 [
self setDataView:[aCoder decodeObjectForKey:CPTableColumnDataViewKey]];
752 _resizingMask = [aCoder decodeIntForKey:CPTableColumnResizingMaskKey];
753 _isHidden = [aCoder decodeBoolForKey:CPTableColumnIsHiddenKey];
754 _isEditable = [aCoder decodeBoolForKey:CPTableColumnIsEditableKey];
756 _sortDescriptorPrototype = [aCoder decodeObjectForKey:CPSortDescriptorPrototypeKey];
765 - (void)encodeWithCoder:(
CPCoder)aCoder
767 [aCoder encodeObject:_identifier forKey:CPTableColumnIdentifierKey];
769 [aCoder encodeFloat:_width forKey:CPTableColumnWidthKey];
770 [aCoder encodeFloat:_minWidth forKey:CPTableColumnMinWidthKey];
771 [aCoder encodeFloat:_maxWidth forKey:CPTableColumnMaxWidthKey];
773 [aCoder encodeObject:_headerView forKey:CPTableColumnHeaderViewKey];
774 [aCoder encodeObject:_dataView forKey:CPTableColumnDataViewKey];
776 [aCoder encodeObject:_resizingMask forKey:CPTableColumnResizingMaskKey];
777 [aCoder encodeBool:_isHidden forKey:CPTableColumnIsHiddenKey];
778 [aCoder encodeBool:_isEditable forKey:CPTableColumnIsEditableKey];
780 [aCoder encodeObject:_sortDescriptorPrototype forKey:CPSortDescriptorPrototypeKey];
785 @implementation CPTableColumn (NSInCompatibility)
789 - (void)setHeaderCell:(
CPView)aView
792 reason:@"setHeaderCell: is not supported. Use -setHeaderView:aView instead."];
801 reason:@"headCell is not supported. Use -headerView instead."];
807 - (void)setDataCell:(
CPView)aView
810 reason:@"setDataCell: is not supported. Use -setDataView:aView instead."];
819 reason:@"dataCell is not supported. Use -dataView instead."];
825 - (id)dataCellForRow:(CPInteger)row
828 reason:@"dataCellForRow: is not supported. Use -dataViewForRow:row instead."];
833 @implementation CPTableColumn (CPSynthesizedAccessors)
838 - (BOOL)disableResizingPosting
840 return _disableResizingPosting;
846 - (void)setDisableResizingPosting:(BOOL)aValue
848 _disableResizingPosting = aValue;