API 0.9.5
AppKit/CPTableHeaderView.j
Go to the documentation of this file.
00001 /*
00002  * CPTableHeaderView.j
00003  * AppKit
00004  *
00005  * Created by Ross Boucher.
00006  * Copyright 2009 280 North, Inc.
00007  *
00008  * This library is free software; you can redistribute it and/or
00009  * modify it under the terms of the GNU Lesser General Public
00010  * License as published by the Free Software Foundation; either
00011  * version 2.1 of the License, or (at your option) any later version.
00012  *
00013  * This library is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00016  * Lesser General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU Lesser General Public
00019  * License along with this library; if not, write to the Free Software
00020  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00021  */
00022 
00023 
00024 
00025 
00026 @implementation _CPTableColumnHeaderView : CPView
00027 {
00028     _CPImageAndTextView     _textField;
00029 }
00030 
00031 + (CPString)defaultThemeClass
00032 {
00033     return @"columnHeader";
00034 }
00035 
00036 + (id)themeAttributes
00037 {
00038     return [CPDictionary dictionaryWithObjects:[[CPNull null], [CPNull null], CGInsetMakeZero(), [CPNull null], [CPNull null], [CPNull null], CGSizeMakeZero()]
00039                                        forKeys:[@"background-color", @"text-alignment", @"text-inset", @"text-color", @"text-font", @"text-shadow-color", @"text-shadow-offset"]];
00040 }
00041 
00042 - (void)initWithFrame:(CGRect)frame
00043 {
00044     self = [super initWithFrame:frame];
00045     if (self)
00046         [self _init];
00047 
00048     return self;
00049 }
00050 
00051 - (void)_init
00052 {
00053     _textField = [[_CPImageAndTextView alloc] initWithFrame:_CGRectMakeZero()];
00054 
00055     [_textField setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
00056 
00057     [_textField setLineBreakMode:CPLineBreakByTruncatingTail];
00058     [_textField setAlignment:CPLeftTextAlignment];
00059     [_textField setVerticalAlignment:CPCenterVerticalTextAlignment];
00060 
00061     [self addSubview:_textField];
00062 }
00063 
00064 - (void)layoutSubviews
00065 {
00066     [self setBackgroundColor:[self currentValueForThemeAttribute:@"background-color"]];
00067 
00068     var inset = [self currentValueForThemeAttribute:@"text-inset"],
00069         bounds = [self bounds];
00070 
00071     [_textField setFrame:_CGRectMake(inset.right, inset.top, bounds.size.width - inset.right - inset.left, bounds.size.height - inset.top - inset.bottom)];
00072     [_textField setTextColor:[self currentValueForThemeAttribute:@"text-color"]];
00073     [_textField setFont:[self currentValueForThemeAttribute:@"text-font"]];
00074     [_textField setTextShadowColor:[self currentValueForThemeAttribute:@"text-shadow-color"]];
00075     [_textField setTextShadowOffset:[self currentValueForThemeAttribute:@"text-shadow-offset"]];
00076     [_textField setAlignment:[self currentValueForThemeAttribute:@"text-alignment"]];
00077 }
00078 
00079 - (void)setStringValue:(CPString)string
00080 {
00081     [_textField setText:string];
00082 }
00083 
00084 - (CPString)stringValue
00085 {
00086     return [_textField text];
00087 }
00088 
00089 - (void)textField
00090 {
00091     return _textField;
00092 }
00093 
00094 - (void)sizeToFit
00095 {
00096     [_textField sizeToFit];
00097 }
00098 
00099 - (void)setFont:(CPFont)aFont
00100 {
00101     [self setValue:aFont forThemeAttribute:"text-font"];
00102 }
00103 
00104 - (void)_setIndicatorImage:(CPImage)anImage
00105 {
00106     if (anImage)
00107     {
00108         [_textField setImage:anImage];
00109         [_textField setImagePosition:CPImageRight];
00110     }
00111     else
00112     {
00113         [_textField setImagePosition:CPNoImage];
00114     }
00115 }
00116 
00117 @end
00118 
00119 var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringValueKey",
00120     _CPTableColumnHeaderViewFontKey = @"_CPTableColumnHeaderViewFontKey",
00121     _CPTableColumnHeaderViewImageKey = @"_CPTableColumnHeaderViewImageKey";
00122 
00123 @implementation _CPTableColumnHeaderView (CPCoding)
00124 
00125 - (id)initWithCoder:(CPCoder)aCoder
00126 {
00127     if (self = [super initWithCoder:aCoder])
00128     {
00129         [self _init];
00130         [self _setIndicatorImage:[aCoder decodeObjectForKey:_CPTableColumnHeaderViewImageKey]];
00131         [self setStringValue:[aCoder decodeObjectForKey:_CPTableColumnHeaderViewStringValueKey]];
00132         [self setFont:[aCoder decodeObjectForKey:_CPTableColumnHeaderViewFontKey]];
00133     }
00134 
00135     return self;
00136 }
00137 
00138 - (void)encodeWithCoder:(CPCoder)aCoder
00139 {
00140     [super encodeWithCoder:aCoder];
00141 
00142     [aCoder encodeObject:[_textField text] forKey:_CPTableColumnHeaderViewStringValueKey];
00143     [aCoder encodeObject:[_textField image] forKey:_CPTableColumnHeaderViewImageKey];
00144     [aCoder encodeObject:[_textField font] forKey:_CPTableColumnHeaderViewFontKey];
00145 }
00146 
00147 @end
00148 
00149 @implementation CPTableHeaderView : CPView
00150 {
00151     CGPoint                 _mouseDownLocation;
00152     CGPoint                 _previousTrackingLocation;
00153     int                     _activeColumn;
00154     int                     _pressedColumn;
00155 
00156     BOOL                    _isResizing;
00157     BOOL                    _isDragging;
00158     BOOL                    _isTrackingColumn;
00159     BOOL                    _drawsColumnLines;
00160 
00161     float                   _columnOldWidth;
00162 
00163     CPTableView             _tableView;
00164 }
00165 
00166 + (CPString)defaultThemeClass
00167 {
00168     return @"tableHeaderRow";
00169 }
00170 
00171 + (id)themeAttributes
00172 {
00173     return [CPDictionary dictionaryWithObjects:[[CPNull null], [CPColor grayColor]]
00174                                        forKeys:[@"background-color", @"divider-color"]];
00175 }
00176 
00177 - (void)_init
00178 {
00179     _mouseDownLocation = _CGPointMakeZero();
00180     _previousTrackingLocation = _CGPointMakeZero();
00181     _activeColumn = -1;
00182     _pressedColumn = -1;
00183 
00184     _isResizing = NO;
00185     _isDragging = NO;
00186     _isTrackingColumn = NO;
00187     _drawsColumnLines = YES;
00188 
00189     _columnOldWidth = 0.0;
00190 
00191     [self setBackgroundColor:[self currentValueForThemeAttribute:@"background-color"]];
00192 }
00193 
00194 - (id)initWithFrame:(CGRect)aFrame
00195 {
00196     self = [super initWithFrame:aFrame];
00197 
00198     if (self)
00199         [self _init];
00200 
00201     return self;
00202 }
00203 
00204 - (int)columnAtPoint:(CGPoint)aPoint
00205 {
00206     return [_tableView columnAtPoint:CGPointMake(aPoint.x, aPoint.y)];
00207 }
00208 
00209 - (CGRect)headerRectOfColumn:(int)aColumnIndex
00210 {
00211     var headerRect = CGRectMakeCopy([self bounds]),
00212         columnRect = [_tableView rectOfColumn:aColumnIndex];
00213 
00214     headerRect.origin.x = _CGRectGetMinX(columnRect);
00215     headerRect.size.width = _CGRectGetWidth(columnRect);
00216 
00217     return headerRect;
00218 }
00219 
00220 - (void)setDrawsColumnLines:(BOOL)aFlag
00221 {
00222     _drawsColumnLines = aFlag;
00223 }
00224 
00225 - (BOOL)drawsColumnLines
00226 {
00227     return _drawsColumnLines;
00228 }
00229 
00230 - (CGRect)_cursorRectForColumn:(int)column
00231 {
00232     if (column == -1 || !([_tableView._tableColumns[column] resizingMask] & CPTableColumnUserResizingMask))
00233         return _CGRectMakeZero();
00234 
00235     var rect = [self headerRectOfColumn:column];
00236 
00237     rect.origin.x = _CGRectGetMaxX(rect) - 5;
00238     rect.size.width = 20;
00239 
00240     return rect;
00241 }
00242 
00243 - (void)_setPressedColumn:(CPInteger)column
00244 {
00245     if (_pressedColumn != -1)
00246     {
00247         var headerView = [_tableView._tableColumns[_pressedColumn] headerView];
00248         [headerView unsetThemeState:CPThemeStateHighlighted];
00249     }
00250 
00251     if (column != -1)
00252     {
00253         var headerView = [_tableView._tableColumns[column] headerView];
00254         [headerView setThemeState:CPThemeStateHighlighted];
00255     }
00256 
00257     _pressedColumn = column;
00258 }
00259 
00260 - (void)mouseDown:(CPEvent)theEvent
00261 {
00262     [self trackMouse:theEvent];
00263 }
00264 
00265 - (void)trackMouse:(CPEvent)theEvent
00266 {
00267     var type = [theEvent type],
00268         currentLocation = [self convertPoint:[theEvent locationInWindow] fromView:nil];
00269 
00270     // Take the right columns resize tracking area into account
00271     currentLocation.x -= 5.0;
00272 
00273     var columnIndex = [self columnAtPoint:currentLocation],
00274         shouldResize = [self shouldResizeTableColumn:columnIndex at:_CGPointMake(currentLocation.x + 5.0, currentLocation.y)];
00275 
00276     if (type === CPLeftMouseUp)
00277     {
00278         if (shouldResize)
00279             [self stopResizingTableColumn:_activeColumn at:currentLocation];
00280         else if ([self _shouldStopTrackingTableColumn:columnIndex at:currentLocation])
00281         {
00282             [_tableView _didClickTableColumn:columnIndex modifierFlags:[theEvent modifierFlags]];
00283             [self stopTrackingTableColumn:columnIndex at:currentLocation];
00284 
00285             _isTrackingColumn = NO;
00286         }
00287 
00288         [self _updateResizeCursor:[CPApp currentEvent]];
00289 
00290         _activeColumn = CPNotFound;
00291         return;
00292     }
00293 
00294     if (type === CPLeftMouseDown)
00295     {
00296         if (columnIndex === -1)
00297             return;
00298 
00299         _mouseDownLocation = currentLocation;
00300         _activeColumn = columnIndex;
00301 
00302         [_tableView _sendDelegateDidMouseDownInHeader:columnIndex];
00303 
00304         if (shouldResize)
00305             [self startResizingTableColumn:columnIndex at:currentLocation];
00306         else
00307         {
00308             [self startTrackingTableColumn:columnIndex at:currentLocation];
00309             _isTrackingColumn = YES;
00310         }
00311     }
00312     else if (type === CPLeftMouseDragged)
00313     {
00314         if (shouldResize)
00315             [self continueResizingTableColumn:_activeColumn at:currentLocation];
00316         else
00317         {
00318             if (_activeColumn === columnIndex && _CGRectContainsPoint([self headerRectOfColumn:columnIndex], currentLocation))
00319             {
00320                 if (_isTrackingColumn && _pressedColumn !== -1)
00321                 {
00322                     if (![self continueTrackingTableColumn:columnIndex at:currentLocation])
00323                         return; // Stop tracking the column, because it's being dragged
00324                 } else
00325                     [self startTrackingTableColumn:columnIndex at:currentLocation];
00326 
00327             } else if (_isTrackingColumn && _pressedColumn !== -1)
00328                 [self stopTrackingTableColumn:_activeColumn at:currentLocation];
00329         }
00330     }
00331 
00332     _previousTrackingLocation = currentLocation;
00333     [CPApp setTarget:self selector:@selector(trackMouse:) forNextEventMatchingMask:CPLeftMouseDraggedMask | CPLeftMouseUpMask untilDate:nil inMode:nil dequeue:YES];
00334 }
00335 
00336 - (void)startTrackingTableColumn:(int)aColumnIndex at:(CGPoint)aPoint
00337 {
00338     [self _setPressedColumn:aColumnIndex];
00339 }
00340 
00341 - (BOOL)continueTrackingTableColumn:(int)aColumnIndex at:(CGPoint)aPoint
00342 {
00343     if ([self _shouldDragTableColumn:aColumnIndex at:aPoint])
00344     {
00345         var columnRect = [self headerRectOfColumn:aColumnIndex],
00346             offset = _CGPointMakeZero(),
00347             view = [_tableView _dragViewForColumn:aColumnIndex event:[CPApp currentEvent] offset:offset],
00348             viewLocation = _CGPointMakeZero();
00349 
00350         viewLocation.x = ( _CGRectGetMinX(columnRect) + offset.x ) + ( aPoint.x - _mouseDownLocation.x );
00351         viewLocation.y = _CGRectGetMinY(columnRect) + offset.y;
00352 
00353         [self dragView:view at:viewLocation offset:_CGSizeMakeZero() event:[CPApp currentEvent]
00354             pasteboard:[CPPasteboard pasteboardWithName:CPDragPboard] source:self slideBack:YES];
00355 
00356         return NO;
00357     }
00358 
00359     return YES;
00360 }
00361 
00362 - (BOOL)_shouldStopTrackingTableColumn:(int)aColumnIndex at:(CGPoint)aPoint
00363 {
00364     return _isTrackingColumn && _activeColumn === aColumnIndex &&
00365         _CGRectContainsPoint([self headerRectOfColumn:aColumnIndex], aPoint);
00366 }
00367 
00368 - (void)stopTrackingTableColumn:(int)aColumnIndex at:(CGPoint)aPoint
00369 {
00370     [self _setPressedColumn:CPNotFound];
00371     [self _updateResizeCursor:[CPApp currentEvent]];
00372 }
00373 
00374 - (BOOL)_shouldDragTableColumn:(int)aColumnIndex at:(CGPoint)aPoint
00375 {
00376     return [_tableView allowsColumnReordering] && ABS(aPoint.x - _mouseDownLocation.x) >= 10.0;
00377 }
00378 
00379 - (CGRect)_headerRectOfLastVisibleColumn
00380 {
00381     var tableColumns = [_tableView tableColumns],
00382         columnIndex = [tableColumns count];
00383 
00384     while (columnIndex--)
00385     {
00386         var tableColumn = [tableColumns objectAtIndex:columnIndex];
00387 
00388         if (![tableColumn isHidden])
00389             return [self headerRectOfColumn:columnIndex];
00390     }
00391 
00392     return nil;
00393 }
00394 
00395 - (void)_constrainDragView:(CPView)theDragView at:(CGPoint)aPoint
00396 {
00397     var tableColumns = [_tableView tableColumns],
00398         lastColumnRect = [self _headerRectOfLastVisibleColumn],
00399         activeColumnRect = [self headerRectOfColumn:_activeColumn],
00400         dragWindow = [theDragView window],
00401         frame = [dragWindow frame];
00402 
00403     // Convert the frame origin from the global coordinate system to the windows' coordinate system
00404     frame.origin = [[self window] convertGlobalToBase:frame.origin];
00405     // the from the window to the view
00406     frame.origin = [self convertPoint:frame.origin fromView:nil];
00407 
00408     // This effectively clamps the value between the minimum and maximum
00409     frame.origin.x = MAX(0.0, MIN(_CGRectGetMinX(frame), _CGRectGetMaxX(lastColumnRect) - _CGRectGetWidth(activeColumnRect)));
00410 
00411     // Make sure the column cannot move vertically
00412     frame.origin.y = _CGRectGetMinY(lastColumnRect);
00413 
00414     // Convert the calculated origin back to the window coordinate system
00415     frame.origin = [self convertPoint:frame.origin toView:nil];
00416     // Then back to the global coordinate system
00417     frame.origin = [[self window] convertBaseToGlobal:frame.origin];
00418 
00419     [dragWindow setFrame:frame];
00420 }
00421 
00422 - (void)_moveColumn:(int)aFromIndex toColumn:(int)aToIndex
00423 {
00424     [_tableView moveColumn:aFromIndex toColumn:aToIndex];
00425     _activeColumn = aToIndex;
00426     _pressedColumn = _activeColumn;
00427 }
00428 
00429 - (void)draggedView:(CPView)aView beganAt:(CGPoint)aPoint
00430 {
00431     _isDragging = YES;
00432 
00433     var column = [[_tableView tableColumns] objectAtIndex:_activeColumn];
00434 
00435     [[column headerView] setHidden:YES];
00436     [_tableView _setDraggedColumn:column];
00437 
00438     [self setNeedsDisplay:YES];
00439 }
00440 
00441 - (void)draggedView:(CPView)aView movedTo:(CGPoint)aPoint
00442 {
00443     [self _constrainDragView:aView at:aPoint];
00444 
00445     var dragWindow = [aView window],
00446         dragWindowFrame = [dragWindow frame];
00447 
00448     var hoverPoint = CGPointCreateCopy(aPoint);
00449 
00450     if (aPoint.x < _previousTrackingLocation.x)
00451         hoverPoint = _CGPointMake(_CGRectGetMinX(dragWindowFrame), _CGRectGetMinY(dragWindowFrame));
00452     else if (aPoint.x > _previousTrackingLocation.x)
00453         hoverPoint = _CGPointMake(_CGRectGetMaxX(dragWindowFrame), _CGRectGetMinY(dragWindowFrame));
00454 
00455     // Convert the hover point from the global coordinate system to windows' coordinate system
00456     hoverPoint = [[self window] convertGlobalToBase:hoverPoint];
00457     // then to the view
00458     hoverPoint = [self convertPoint:hoverPoint fromView:nil];
00459 
00460     var hoveredColumn = [self columnAtPoint:hoverPoint];
00461 
00462     if (hoveredColumn !== -1)
00463     {
00464         var columnRect = [self headerRectOfColumn:hoveredColumn],
00465             columnCenterPoint = [self convertPoint:CGPointMake(_CGRectGetMidX(columnRect), _CGRectGetMidY(columnRect)) fromView:self];
00466         if (hoveredColumn < _activeColumn && hoverPoint.x < columnCenterPoint.x)
00467             [self _moveColumn:_activeColumn toColumn:hoveredColumn];
00468         else if (hoveredColumn > _activeColumn && hoverPoint.x > columnCenterPoint.x)
00469             [self _moveColumn:_activeColumn toColumn:hoveredColumn];
00470     }
00471 
00472     _previousTrackingLocation = aPoint;
00473 }
00474 
00475 - (void)draggedView:(CPImage)aView endedAt:(CGPoint)aLocation operation:(CPDragOperation)anOperation
00476 {
00477     _isDragging = NO;
00478     _isTrackingColumn = NO; // We need to do this explicitly because the mouse up section of trackMouse is never reached
00479 
00480     [_tableView _setDraggedColumn:nil];
00481     [[[[_tableView tableColumns] objectAtIndex:_activeColumn] headerView] setHidden:NO];
00482     [self stopTrackingTableColumn:_activeColumn at:aLocation];
00483 
00484     [self setNeedsDisplay:YES];
00485 }
00486 
00487 - (BOOL)shouldResizeTableColumn:(int)aColumnIndex at:(CGPoint)aPoint
00488 {
00489     if (_isResizing)
00490         return YES;
00491 
00492     if (_isTrackingColumn)
00493         return NO;
00494 
00495     return [_tableView allowsColumnResizing] && _CGRectContainsPoint([self _cursorRectForColumn:aColumnIndex], aPoint);
00496 }
00497 
00498 - (void)startResizingTableColumn:(int)aColumnIndex at:(CGPoint)aPoint
00499 {
00500     _isResizing = YES;
00501 
00502     var tableColumn = [[_tableView tableColumns] objectAtIndex:aColumnIndex];
00503 
00504     [tableColumn setDisableResizingPosting:YES];
00505     [_tableView setDisableAutomaticResizing:YES];
00506 }
00507 
00508 - (void)continueResizingTableColumn:(int)aColumnIndex at:(CGPoint)aPoint
00509 {
00510     var tableColumn = [[_tableView tableColumns] objectAtIndex:aColumnIndex],
00511         newWidth = [tableColumn width] + aPoint.x - _previousTrackingLocation.x;
00512 
00513     if (newWidth < [tableColumn minWidth])
00514         [[CPCursor resizeRightCursor] set];
00515     else if (newWidth > [tableColumn maxWidth])
00516         [[CPCursor resizeLeftCursor] set];
00517     else
00518     {
00519         _tableView._lastColumnShouldSnap = NO;
00520         [tableColumn setWidth:newWidth];
00521 
00522         [[CPCursor resizeLeftRightCursor] set];
00523         [self setNeedsLayout];
00524         [self setNeedsDisplay:YES];
00525     }
00526 }
00527 
00528 - (void)stopResizingTableColumn:(int)aColumnIndex at:(CGPoint)aPoint
00529 {
00530     var tableColumn = [[_tableView tableColumns] objectAtIndex:aColumnIndex];
00531     [tableColumn _postDidResizeNotificationWithOldWidth:_columnOldWidth];
00532     [tableColumn setDisableResizingPosting:NO];
00533     [_tableView setDisableAutomaticResizing:NO];
00534 
00535     _isResizing = NO;
00536 }
00537 
00538 - (void)_updateResizeCursor:(CPEvent)theEvent
00539 {
00540     // never get stuck in resize cursor mode (FIXME take out when we turn on tracking rects)
00541     if (![_tableView allowsColumnResizing] || ([theEvent type] === CPLeftMouseUp && ![[self window] acceptsMouseMovedEvents]))
00542     {
00543         [[CPCursor arrowCursor] set];
00544         return;
00545     }
00546 
00547     var mouseLocation = [self convertPoint:[theEvent locationInWindow] fromView:nil],
00548         mouseOverLocation = CGPointMake(mouseLocation.x - 5, mouseLocation.y),
00549         overColumn = [self columnAtPoint:mouseOverLocation];
00550 
00551     if (overColumn >= 0 && _CGRectContainsPoint([self _cursorRectForColumn:overColumn], mouseLocation))
00552     {
00553         var tableColumn = [[_tableView tableColumns] objectAtIndex:overColumn],
00554             width = [tableColumn width];
00555 
00556         if (width == [tableColumn minWidth])
00557             [[CPCursor resizeRightCursor] set];
00558         else if (width == [tableColumn maxWidth])
00559             [[CPCursor resizeLeftCursor] set];
00560         else
00561             [[CPCursor resizeLeftRightCursor] set];
00562     }
00563     else
00564         [[CPCursor arrowCursor] set];
00565 }
00566 
00567 - (void)mouseEntered:(CPEvent)theEvent
00568 {
00569     [self _updateResizeCursor:theEvent];
00570 }
00571 
00572 - (void)mouseMoved:(CPEvent)theEvent
00573 {
00574     [self _updateResizeCursor:theEvent];
00575 }
00576 
00577 - (void)mouseExited:(CPEvent)theEvent
00578 {
00579     // FIXME: we should use CPCursor push/pop (if previous currentCursor != arrow).
00580     [[CPCursor arrowCursor] set];
00581 }
00582 
00583 - (void)layoutSubviews
00584 {
00585     var tableColumns = [_tableView tableColumns],
00586         count = [tableColumns count];
00587 
00588     for (var i = 0; i < count; i++)
00589     {
00590         var column = [tableColumns objectAtIndex:i],
00591             headerView = [column headerView],
00592             frame = [self headerRectOfColumn:i];
00593 
00594         // Make space for the gridline on the right.
00595         frame.origin.x -= 0.5;
00596         frame.size.width -= 1.0;
00597         frame.size.height -= 0.5;
00598         // Note: we're not adding in intercell spacing here. This setting only affects the regular
00599         // table cell data views, not the header. Verified in Cocoa on March 29th, 2011.
00600 
00601         [headerView setFrame:frame];
00602 
00603         if ([headerView superview] != self)
00604             [self addSubview:headerView];
00605     }
00606 
00607     [self setBackgroundColor:[self currentValueForThemeAttribute:@"background-color"]];
00608 }
00609 
00610 - (void)drawRect:(CGRect)aRect
00611 {
00612     if (!_tableView || ![self drawsColumnLines])
00613         return;
00614 
00615     var context = [[CPGraphicsContext currentContext] graphicsPort],
00616         exposedColumnIndexes = [_tableView columnIndexesInRect:aRect],
00617         columnsArray = [],
00618         tableColumns = [_tableView tableColumns],
00619         exposedTableColumns = _tableView._exposedColumns,
00620         firstIndex = [exposedTableColumns firstIndex],
00621         exposedRange = CPMakeRange(firstIndex, [exposedTableColumns lastIndex] - firstIndex + 1);
00622 
00623     CGContextSetLineWidth(context, 1);
00624     CGContextSetStrokeColor(context, [self currentValueForThemeAttribute:@"divider-color"]);
00625 
00626     [exposedColumnIndexes getIndexes:columnsArray maxCount:-1 inIndexRange:exposedRange];
00627 
00628     var columnArrayIndex = 0,
00629         columnArrayCount = columnsArray.length,
00630         columnMaxX;
00631 
00632     CGContextBeginPath(context);
00633     for (; columnArrayIndex < columnArrayCount; columnArrayIndex++)
00634     {
00635         // grab each column rect and add vertical lines
00636         var columnIndex = columnsArray[columnArrayIndex],
00637             columnToStroke = [self headerRectOfColumn:columnIndex];
00638 
00639         columnMaxX = _CGRectGetMaxX(columnToStroke);
00640 
00641         CGContextMoveToPoint(context, FLOOR(columnMaxX) - 0.5, ROUND(_CGRectGetMinY(columnToStroke)));
00642         CGContextAddLineToPoint(context, FLOOR(columnMaxX) - 0.5, ROUND(_CGRectGetMaxY(columnToStroke)));
00643     }
00644     CGContextClosePath(context);
00645     CGContextStrokePath(context);
00646 
00647     /*if (_isDragging)
00648     {
00649         CGContextSetFillColor(context, [CPColor grayColor]);
00650         CGContextFillRect(context, [self headerRectOfColumn:_activeColumn])
00651     }*/
00652 }
00653 
00654 @end
00655 
00656 var CPTableHeaderViewTableViewKey = @"CPTableHeaderViewTableViewKey",
00657     CPTableHeaderViewDrawsColumnLines = @"CPTableHeaderViewDrawsColumnLines";
00658 
00659 @implementation CPTableHeaderView (CPCoding)
00660 
00661 - (id)initWithCoder:(CPCoder)aCoder
00662 {
00663     if (self = [super initWithCoder:aCoder])
00664     {
00665         [self _init];
00666         _tableView = [aCoder decodeObjectForKey:CPTableHeaderViewTableViewKey];
00667 
00668         // FIX ME: Take this out before 1.0
00669         if ([aCoder containsValueForKey:CPTableHeaderViewDrawsColumnLines])
00670             _drawsColumnLines = [aCoder decodeBoolForKey:CPTableHeaderViewDrawsColumnLines];
00671         else
00672         {
00673             _drawsColumnLines = YES;
00674             CPLog.warn("The tableview header being decoded is using an old cib. Please run Nib2Cib.");
00675         }
00676     }
00677 
00678     return self;
00679 }
00680 
00681 - (void)encodeWithCoder:(CPCoder)aCoder
00682 {
00683     [super encodeWithCoder:aCoder];
00684     [aCoder encodeObject:_tableView forKey:CPTableHeaderViewTableViewKey];
00685     [aCoder encodeBool:_drawsColumnLines forKey:CPTableHeaderViewDrawsColumnLines];
00686 }
00687 
00688 @end
00689 
00690 @implementation CPTableHeaderView (CPSynthesizedAccessors)
00691 
00695 - (CPTableView)tableView
00696 {
00697     return _tableView;
00698 }
00699 
00703 - (void)setTableView:(CPTableView)aValue
00704 {
00705     _tableView = aValue;
00706 }
00707 
00708 @end
 All Classes Files Functions Variables Defines