27 @implementation _CPTableColumnHeaderView :
CPView 29 _CPImageAndTextView _textField;
34 return @"columnHeader";
43 @"text-inset": CGInsetMakeZero(),
47 @"text-shadow-offset": CGSizeMakeZero()
51 - (id)initWithFrame:(CGRect)frame
53 self = [
super initWithFrame:frame];
63 _textField = [[_CPImageAndTextView alloc] initWithFrame:
64 CGRectMake(5.0, 0.0, CGRectGetWidth([
self bounds]) - 10.0, CGRectGetHeight([
self bounds]))];
66 [_textField setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
68 [_textField setLineBreakMode:CPLineBreakByTruncatingTail];
71 [_textField setAlignment:CPLeftTextAlignment];
72 [_textField setVerticalAlignment:CPCenterVerticalTextAlignment];
74 [_textField setTextShadowOffset:CGSizeMake(0,1)];
76 [
self addSubview:_textField];
79 - (void)layoutSubviews
81 [
self setBackgroundColor:[
self currentValueForThemeAttribute:@"background-color"]];
83 var inset = [
self currentValueForThemeAttribute:@"text-inset"],
86 [_textField setFrame:CGRectMake(inset.right, inset.top, bounds.size.width - inset.right - inset.left, bounds.size.height - inset.top - inset.bottom)];
87 [_textField setTextColor:[
self currentValueForThemeAttribute:@"text-color"]];
88 [_textField setFont:[
self currentValueForThemeAttribute:@"font"]];
89 [_textField setTextShadowColor:[
self currentValueForThemeAttribute:@"text-shadow-color"]];
90 [_textField setTextShadowOffset:[
self currentValueForThemeAttribute:@"text-shadow-offset"]];
91 [_textField setAlignment:[
self currentValueForThemeAttribute:@"text-alignment"]];
92 [_textField setLineBreakMode:[
self currentValueForThemeAttribute:@"line-break-mode"]];
95 - (void)setStringValue:(
CPString)string
97 [_textField setText:string];
102 return [_textField text];
112 [_textField sizeToFit];
115 - (void)setFont:(
CPFont)aFont
117 [
self setValue:aFont forThemeAttribute:@"font"];
122 return [
self currentValueForThemeAttribute:@"font"];
125 - (void)setAlignment:(CPTextAlignment)alignment
127 [
self setValue:alignment forThemeAttribute:@"text-alignment"];
130 - (CPTextAlignment)alignment
132 return [
self currentValueForThemeAttribute:@"text-alignment"];
135 - (void)setLineBreakMode:(CPLineBreakMode)mode
137 [
self setValue:mode forThemeAttribute:@"line-break-mode"];
140 - (CPLineBreakMode)lineBreakMode
142 return [
self currentValueForThemeAttribute:@"line-break-mode"];
145 - (void)setTextColor:(
CPColor)aColor
147 [
self setValue:aColor forThemeAttribute:@"text-color"];
152 return [
self currentValueForThemeAttribute:@"text-color"];
155 - (void)setTextShadowColor:(
CPColor)aColor
157 [
self setValue:aColor forThemeAttribute:@"text-shadow-color"];
162 return [
self currentValueForThemeAttribute:@"text-shadow-color"];
165 - (void)_setIndicatorImage:(
CPImage)anImage
169 [_textField setImage:anImage];
170 [_textField setImagePosition:CPImageRight];
174 [_textField setImagePosition:CPNoImage];
180 return [_textField imagePosition] ===
CPNoImage ? nil : [_textField image];
183 - (void)drawRect:(CGRect)aRect
185 var
bounds = [
self bounds];
187 if (!CGRectIntersectsRect(aRect,
bounds))
191 maxX = CGRectGetMaxX(
bounds) - 0.5;
206 var _CPTableColumnHeaderViewStringValueKey =
@"_CPTableColumnHeaderViewStringValueKey",
207 _CPTableColumnHeaderViewFontKey =
@"_CPTableColumnHeaderViewFontKey",
208 _CPTableColumnHeaderViewImageKey =
@"_CPTableColumnHeaderViewImageKey",
209 _CPTableColumnHeaderViewIsDraggingKey =
@"_CPTableColumnHeaderViewIsDraggingKey";
211 @implementation _CPTableColumnHeaderView (CPCoding)
213 - (id)initWithCoder:(
CPCoder)aCoder
215 if (
self = [super initWithCoder:aCoder])
218 [
self _setIndicatorImage:[aCoder decodeObjectForKey:_CPTableColumnHeaderViewImageKey]];
219 [
self setStringValue:[aCoder decodeObjectForKey:_CPTableColumnHeaderViewStringValueKey]];
220 [
self setFont:[aCoder decodeObjectForKey:_CPTableColumnHeaderViewFontKey]];
226 - (void)encodeWithCoder:(
CPCoder)aCoder
228 [
super encodeWithCoder:aCoder];
230 [aCoder encodeObject:[_textField text] forKey:_CPTableColumnHeaderViewStringValueKey];
231 [aCoder encodeObject:[_textField image] forKey:_CPTableColumnHeaderViewImageKey];
232 [aCoder encodeObject:[_textField font] forKey:_CPTableColumnHeaderViewFontKey];
244 CGPoint _mouseDownLocation;
245 CGPoint _columnMouseDownLocation;
246 CGPoint _mouseEnterExitLocation;
247 CGPoint _previousTrackingLocation;
257 CPView _columnDragHeaderView;
258 CPView _columnDragClipView;
260 float _columnOldWidth;
267 return @"tableHeaderRow";
275 @"divider-thickness": 1.0
281 _mouseDownLocation = CGPointMakeZero();
282 _columnMouseDownLocation = CGPointMakeZero();
283 _mouseEnterExitLocation = CGPointMakeZero();
284 _previousTrackingLocation = CGPointMakeZero();
293 _columnOldWidth = 0.0;
298 - (id)initWithFrame:(CGRect)aFrame
312 - (CPInteger)draggedColumn
314 return _isDragging ? _activeColumn : -1;
317 - (float)draggedDistance
320 return (CGRectGetMinX(_columnDragClipView) - _columnMouseDownLocation.x);
325 - (CPInteger)resizedColumn
328 return _activeColumn;
335 - (CPInteger)columnAtPoint:(CGPoint)aPoint
337 return [_tableView columnAtPoint:aPoint];
340 - (CGRect)headerRectOfColumn:(CPInteger)aColumnIndex
342 var headerRect = [
self bounds],
343 columnRect = [_tableView rectOfColumn:aColumnIndex];
345 headerRect.origin.x = CGRectGetMinX(columnRect);
346 headerRect.size.width = CGRectGetWidth(columnRect);
353 - (void)viewDidMoveToWindow
360 - (void)layoutSubviews
362 var tableColumns = [_tableView tableColumns],
363 count = [tableColumns count];
365 for (var i = 0; i < count; i++)
367 var column = [tableColumns objectAtIndex:i],
368 headerView = [column headerView],
371 [headerView setFrame:frame];
373 if ([headerView superview] !=
self)
389 _mouseDownLocation = currentLocation;
391 _canDragColumn = YES;
393 [_tableView _sendDelegateMouseDownInHeaderOfTableColumn:columnIndex];
395 if ([
self _shouldResizeTableColumn:
columnIndex at:currentLocation])
396 [
self _startResizingTableColumn:columnIndex at:currentLocation];
398 [
self _setPressedColumn:columnIndex];
409 [
self _autoscroll:theEvent localLocation:currentLocation];
410 [
self _continueResizingTableColumn:_activeColumn at:currentLocation];
412 else if (_isDragging)
416 [
self _dragTableColumn:_activeColumn to:currentLocation];
420 if (CGRectContainsPoint([
self headerRectOfColumn:_activeColumn], currentLocation))
422 if ([
self _shouldDragTableColumn:
columnIndex at:currentLocation])
423 [
self _startDraggingTableColumn:columnIndex at:currentLocation];
425 [
self _setPressedColumn:_activeColumn];
428 [
self _setPressedColumn:-1];
436 [
self _stopResizingTableColumn:_activeColumn];
438 else if (_isDragging)
440 [
self _stopDraggingTableColumn:_activeColumn];
442 else if (_activeColumn != -1)
446 if (CGRectContainsPoint([
self headerRectOfColumn:_activeColumn], currentLocation))
447 [_tableView _didClickTableColumn:_activeColumn modifierFlags:[theEvent
modifierFlags]];
450 [
self _setPressedColumn:-1];
451 [
self _updateResizeCursor:[CPApp currentEvent]];
460 - (void)updateTrackingAreas
466 for (var i = 0; i < _tableView._tableColumns.length; i++)
467 [
self addTrackingArea:[[
CPTrackingArea alloc] initWithRect:[
self _cursorRectForColumn:i]
475 [
self _updateResizeCursor:anEvent];
482 - (CGRect)_cursorRectForColumn:(CPInteger)column
485 return CGRectMakeZero();
495 - (void)_setPressedColumn:(CPInteger)column
497 if (_pressedColumn === column)
500 if (_pressedColumn != -1)
502 var headerView = [_tableView._tableColumns[_pressedColumn] headerView];
503 [headerView unsetThemeState:CPThemeStateHighlighted];
508 var headerView = [_tableView._tableColumns[column] headerView];
509 [headerView setThemeState:CPThemeStateHighlighted];
517 _pressedColumn = column;
520 - (BOOL)_shouldDragTableColumn:(CPInteger)aColumnIndex at:(CGPoint)aPoint
525 - (void)_autoscroll:(
CPEvent)theEvent localLocation:(CGPoint)theLocation
528 var constrainedLocation = CGPointMake(theLocation.x, CGRectGetMinY([_tableView visibleRect])),
540 [_tableView autoscroll:constrainedEvent];
543 - (CGRect)_headerRectOfLastVisibleColumn
545 var tableColumns = [_tableView tableColumns],
550 var tableColumn = [tableColumns objectAtIndex:columnIndex];
559 - (CGPoint)_constrainDragPoint:(CGPoint)aPoint
562 var visibleRect = [_tableView visibleRect],
563 lastColumnRect = [
self _headerRectOfLastVisibleColumn],
565 maxX = CGRectGetMaxX(lastColumnRect) - CGRectGetWidth(activeColumnRect) - CGRectGetMinX(visibleRect),
566 point = CGPointMake(MAX(MIN(aPoint.x, maxX), -CGRectGetMinX(visibleRect)), aPoint.y);
571 - (void)_moveColumn:(CPInteger)aFromIndex toColumn:(CPInteger)aToIndex
573 [_tableView moveColumn:aFromIndex toColumn:aToIndex];
574 _activeColumn = aToIndex;
575 _pressedColumn = _activeColumn;
577 [_tableView _setDraggedColumn:_activeColumn];
587 - (void)_startDraggingTableColumn:(CPInteger)aColumnIndex at:(CGPoint)aPoint
590 _columnDragView = [_tableView _dragViewForColumn:aColumnIndex];
591 _previousTrackingLocation = aPoint;
594 var headerHeight = CGRectGetHeight([
self frame]),
596 contentFrame = [[scrollView contentView] frame];
598 contentFrame.origin.y -= headerHeight;
599 contentFrame.size.height += headerHeight;
601 _columnDragClipView = [[
CPView alloc] initWithFrame:contentFrame];
603 [_columnDragClipView addSubview:_columnDragView];
606 [scrollView addSubview:_columnDragClipView positioned:CPWindowAbove relativeTo:self];
609 var headerView = [[[_tableView tableColumns] objectAtIndex:aColumnIndex] headerView];
611 [[headerView subviews] makeObjectsPerformSelector:@selector(setHidden:) withObject:YES];
614 [headerView unsetThemeStates:[CPThemeStateHighlighted, CPThemeStateSelected]];
617 _columnDragHeaderView = [_columnDragView viewWithTag:CPTableHeaderViewDragColumnHeaderTag];
619 _columnMouseDownLocation = [
self convertPoint:_mouseDownLocation
toView:_columnDragHeaderView];
621 [_tableView _setDraggedColumn:aColumnIndex];
628 - (void)_dragTableColumn:(CPInteger)aColumnIndex to:(CGPoint)aPoint
630 var delta = aPoint.x - _previousTrackingLocation.x,
631 columnPoint = [_columnDragHeaderView convertPoint:aPoint fromView:self];
634 if ((delta > 0 && columnPoint.x > _columnMouseDownLocation.x) || (delta < 0 && columnPoint.x < _columnMouseDownLocation.x))
636 var dragFrame = [_columnDragView frame],
637 newOrigin = [
self _constrainDragPoint:CGPointMake(CGRectGetMinX(dragFrame) + delta, CGRectGetMinY(dragFrame))];
639 [_columnDragView setFrameOrigin:newOrigin];
642 var hoverPoint = CGPointMakeCopy(aPoint);
648 hoverPoint.x = CGRectGetMaxX(dragFrame);
650 hoverPoint.x = CGRectGetMinX(dragFrame);
654 if (hoveredColumn !== -1)
657 columnCenterPoint = CGPointMake(CGRectGetMidX(columnRect), CGRectGetMidY(columnRect));
659 if (hoveredColumn < _activeColumn && hoverPoint.x < columnCenterPoint.x)
660 [
self _moveColumn:_activeColumn toColumn:hoveredColumn];
661 else if (hoveredColumn > _activeColumn && hoverPoint.x > columnCenterPoint.x)
662 [
self _moveColumn:_activeColumn toColumn:hoveredColumn];
666 _previousTrackingLocation = aPoint;
669 - (void)_stopDraggingTableColumn:(CPInteger)aColumnIndex
673 [_columnDragClipView removeFromSuperview];
674 [_tableView _setDraggedColumn:-1];
676 var headerView = [[[_tableView tableColumns] objectAtIndex:aColumnIndex] headerView];
678 [[headerView subviews] makeObjectsPerformSelector:@selector(setHidden:) withObject:NO];
680 if (_tableView._draggedColumnIsSelected)
681 [headerView setThemeState:CPThemeStateSelected];
683 var columnRect = [_tableView rectOfColumn:aColumnIndex];
685 [_tableView _reloadDataViews];
686 [[_tableView headerView] setNeedsLayout];
692 - (BOOL)_shouldResizeTableColumn:(CPInteger)aColumnIndex at:(CGPoint)aPoint
697 return [_tableView allowsColumnResizing] && CGRectContainsPoint([
self _cursorRectForColumn:aColumnIndex], aPoint);
700 - (void)_startResizingTableColumn:(CPInteger)aColumnIndex at:(CGPoint)aPoint
703 _previousTrackingLocation = aPoint;
704 _activeColumn = aColumnIndex;
706 var tableColumn = [[_tableView tableColumns] objectAtIndex:aColumnIndex];
708 _columnOldWidth = [tableColumn width];
710 [tableColumn setDisableResizingPosting:YES];
711 [_tableView setDisableAutomaticResizing:YES];
714 - (void)_continueResizingTableColumn:(CPInteger)aColumnIndex at:(CGPoint)aPoint
716 var tableColumn = [[_tableView tableColumns] objectAtIndex:aColumnIndex],
717 delta = aPoint.x - _previousTrackingLocation.x,
718 spacing = [_tableView intercellSpacing].width,
719 newWidth = [tableColumn width] + spacing + delta,
720 minWidth = [tableColumn minWidth] + spacing,
721 maxWidth = [tableColumn maxWidth] + spacing;
723 if (newWidth <= minWidth)
725 else if (newWidth >= maxWidth)
730 var columnRect = [_tableView rectOfColumn:aColumnIndex],
731 columnWidth = CGRectGetWidth(columnRect);
733 if ((delta > 0 && columnWidth == maxWidth) || (delta < 0 && columnWidth == minWidth))
736 var columnMinX = CGRectGetMinX(columnRect),
737 columnMaxX = CGRectGetMaxX(columnRect);
739 if ((delta > 0 && aPoint.x > columnMaxX) || (delta < 0 && aPoint.x < columnMaxX))
741 [tableColumn setWidth:newWidth - spacing];
747 _previousTrackingLocation = aPoint;
750 - (void)_stopResizingTableColumn:(CPInteger)aColumnIndex
752 var tableColumn = [[_tableView tableColumns] objectAtIndex:aColumnIndex];
754 if ([tableColumn
width] != _columnOldWidth)
756 [_tableView _didResizeTableColumn:tableColumn oldWidth:_columnOldWidth];
760 [tableColumn setDisableResizingPosting:NO];
761 [_tableView setDisableAutomaticResizing:NO];
766 - (void)_updateResizeCursor:(
CPEvent)theEvent
772 if (overColumn >= 0 && CGRectContainsPoint([
self _cursorRectForColumn:overColumn], mouseLocation))
774 var tableColumn = [[_tableView tableColumns] objectAtIndex:overColumn],
775 spacing = [_tableView intercellSpacing].width,
776 width = [tableColumn width];
778 if (
width <= [tableColumn minWidth])
780 else if (
width >= [tableColumn maxWidth])
797 if (
self = [super initWithCoder:aCoder])
800 _tableView = [aCoder decodeObjectForKey:CPTableHeaderViewTableViewKey];
809 [aCoder encodeObject:_tableView forKey:CPTableHeaderViewTableViewKey];
id initWithFrame:(CGRect aFrame)
id mouseEventWithType:location:modifierFlags:timestamp:windowNumber:context:eventNumber:clickCount:pressure:(CPEventType anEventType, [location] CGPoint aPoint, [modifierFlags] unsigned modifierFlags, [timestamp] CPTimeInterval aTimestamp, [windowNumber] int aWindowNumber, [context] CPGraphicsContext aGraphicsContext, [eventNumber] int anEventNumber, [clickCount] int aClickCount, [pressure] float aPressure)
void addSubview:(CPView aSubview)
CPGraphicsContext currentContext()
An object representation of nil.
CPTableColumnUserResizingMask
CPCursor resizeRightCursor()
BOOL autoscroll:(CPEvent anEvent)
function CGContextSetStrokeColor(aContext, aColor)
CGPoint locationInWindow()
CPTrackingActiveInKeyWindow
function CGContextAddLineToPoint(aContext, x, y)
void setAcceptsMouseMovedEvents:(BOOL shouldAcceptMouseMovedEvents)
function CGContextStrokePath(aContext)
A mutable key-value pair collection.
CPScrollView enclosingScrollView()
function CGContextSetLineWidth(aContext, aLineWidth)
CPCursor closedHandCursor()
An immutable string (collection of characters).
CGPoint convertPoint:fromView:(CGPoint aPoint, [fromView] CPView aView)
CPCellImagePosition CPNoImage
CPColor colorWithRed:green:blue:alpha:(float red, [green] float green, [blue] float blue, [alpha] float alpha)
void viewDidMoveToWindow()
CPCursor resizeLeftRightCursor()
void setNeedsDisplay:(BOOL aFlag)
void encodeWithCoder:(CPCoder aCoder)
CGPoint convertPoint:toView:(CGPoint aPoint, [toView] CPView aView)
function CGContextBeginPath(aContext)
CPLineBreakByTruncatingTail
CPTimeInterval timestamp()
CPFont boldSystemFontOfSize:(CGSize aSize)
CGRect convertRect:fromView:(CGRect aRect, [fromView] CPView aView)
Defines methods for use when archiving & restoring (enc/decoding).
CPTextAlignment CPLeftTextAlignment
void setBackgroundColor:(CPColor aColor)
void removeAllTrackingAreas()
function CGContextMoveToPoint(aContext, x, y)
CPCursor resizeLeftCursor()