mirror of
https://github.com/cappuccino/cappuccino.git
synced 2026-10-18 22:41:18 +00:00
Add support for header views in table view and scroll view
This commit is contained in:
1 parent
1fecae3dc0
commit
849dda0725
5 files changed
+203
-36
No files matched your search
+77
-27
@@ -38,7 +38,8 @@
|
||||
@implementation CPScrollView : CPView
|
||||
{
|
||||
CPClipView _contentView;
|
||||
|
||||
CPClipView _headerClipView;
|
||||
|
||||
BOOL _hasVerticalScroller;
|
||||
BOOL _hasHorizontalScroller;
|
||||
BOOL _autohidesScrollers;
|
||||
@@ -57,23 +58,27 @@
|
||||
- (id)initWithFrame:(CGRect)aFrame
|
||||
{
|
||||
self = [super initWithFrame:aFrame];
|
||||
|
||||
|
||||
if (self)
|
||||
{
|
||||
_verticalLineScroll = 10.0;
|
||||
_verticalPageScroll = 10.0;
|
||||
|
||||
|
||||
_horizontalLineScroll = 10.0;
|
||||
_horizontalPageScroll = 10.0;
|
||||
|
||||
_contentView = [[CPClipView alloc] initWithFrame:[self bounds]];
|
||||
|
||||
_contentView = [[CPClipView alloc] initWithFrame:[self clipViewFrame]];
|
||||
|
||||
[self addSubview:_contentView];
|
||||
|
||||
|
||||
_headerClipView = [[CPClipView alloc] initWithFrame:[self headerClipViewFrame]];
|
||||
|
||||
[self addSubview:_headerClipView];
|
||||
|
||||
[self setHasVerticalScroller:YES];
|
||||
[self setHasHorizontalScroller:YES];
|
||||
}
|
||||
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
@@ -114,7 +119,7 @@
|
||||
|
||||
_contentView = aContentView;
|
||||
|
||||
[_contentView setFrame:CGRectMake(0.0, 0.0, size.width, size.height)];
|
||||
[_contentView setFrame:[self clipViewFrame]];
|
||||
[_contentView setDocumentView:documentView];
|
||||
|
||||
[self addSubview:_contentView];
|
||||
@@ -134,8 +139,13 @@
|
||||
*/
|
||||
- (void)setDocumentView:(CPView)aView
|
||||
{
|
||||
[_contentView setDocumentView:aView];
|
||||
[self reflectScrolledClipView:_contentView];
|
||||
[_contentView setDocumentView:aView];
|
||||
[_headerClipView setDocumentView:[self _headerView]];
|
||||
|
||||
[_contentView setFrame:[self clipViewFrame]];
|
||||
[_headerClipView setFrame:[self headerClipViewFrame]];
|
||||
|
||||
[self reflectScrolledClipView:_contentView];
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -167,17 +177,19 @@
|
||||
// [_horizontalScroller setEnabled:NO];
|
||||
}
|
||||
|
||||
[_contentView setFrame:[self bounds]];
|
||||
[_contentView setFrame:[self clipViewFrame]];
|
||||
|
||||
--_recursionCount;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
var documentFrame = [documentView frame],
|
||||
contentViewFrame = [self bounds],
|
||||
var documentFrame = [documentView frame], // the size of the whole document
|
||||
clipViewFrame = [self clipViewFrame], // the size of the visible document, within the scrollbars
|
||||
headerViewFrame = [self headerClipViewFrame],
|
||||
headerViewHeight = _CGRectGetHeight(headerViewFrame),
|
||||
scrollPoint = [_contentView bounds].origin,
|
||||
difference = _CGSizeMake(CPRectGetWidth(documentFrame) - CPRectGetWidth(contentViewFrame), CPRectGetHeight(documentFrame) - CPRectGetHeight(contentViewFrame)),
|
||||
difference = _CGSizeMake(CPRectGetWidth(documentFrame) - CPRectGetWidth(clipViewFrame), CPRectGetHeight(documentFrame) - CPRectGetHeight(clipViewFrame)),
|
||||
shouldShowVerticalScroller = (!_autohidesScrollers || difference.height > 0.0) && _hasVerticalScroller,
|
||||
shouldShowHorizontalScroller = (!_autohidesScrollers || difference.width > 0.0) && _hasHorizontalScroller,
|
||||
wasShowingVerticalScroller = ![_verticalScroller isHidden],
|
||||
@@ -203,17 +215,17 @@
|
||||
|
||||
if (shouldShowVerticalScroller)
|
||||
{
|
||||
var verticalScrollerHeight = CPRectGetHeight(contentViewFrame);
|
||||
var verticalScrollerHeight = CPRectGetHeight([self bounds]) - headerViewHeight;
|
||||
|
||||
if (shouldShowHorizontalScroller)
|
||||
verticalScrollerHeight -= horizontalScrollerHeight;
|
||||
|
||||
difference.width += verticalScrollerWidth;
|
||||
contentViewFrame.size.width -= verticalScrollerWidth;
|
||||
clipViewFrame.size.width -= verticalScrollerWidth;
|
||||
|
||||
[_verticalScroller setFloatValue:(difference.height <= 0.0) ? 0.0 : scrollPoint.y / difference.height
|
||||
knobProportion:CPRectGetHeight(contentViewFrame) / CPRectGetHeight(documentFrame)];
|
||||
[_verticalScroller setFrame:CPRectMake(CPRectGetMaxX(contentViewFrame), 0.0, verticalScrollerWidth, verticalScrollerHeight)];
|
||||
knobProportion:CPRectGetHeight(clipViewFrame) / CPRectGetHeight(documentFrame)];
|
||||
[_verticalScroller setFrame:CPRectMake(CPRectGetMaxX(clipViewFrame), headerViewHeight, verticalScrollerWidth, verticalScrollerHeight)];
|
||||
}
|
||||
else if (wasShowingVerticalScroller)
|
||||
[_verticalScroller setFloatValue:0.0 knobProportion:1.0];
|
||||
@@ -221,16 +233,17 @@
|
||||
if (shouldShowHorizontalScroller)
|
||||
{
|
||||
difference.height += horizontalScrollerHeight;
|
||||
contentViewFrame.size.height -= horizontalScrollerHeight;
|
||||
clipViewFrame.size.height -= horizontalScrollerHeight;
|
||||
|
||||
[_horizontalScroller setFloatValue:(difference.width <= 0.0) ? 0.0 : scrollPoint.x / difference.width
|
||||
knobProportion:CPRectGetWidth(contentViewFrame) / CPRectGetWidth(documentFrame)];
|
||||
[_horizontalScroller setFrame:CPRectMake(0.0, CPRectGetMaxY(contentViewFrame), CPRectGetWidth(contentViewFrame), horizontalScrollerHeight)];
|
||||
knobProportion:CPRectGetWidth(clipViewFrame) / CPRectGetWidth(documentFrame)];
|
||||
[_horizontalScroller setFrame:CPRectMake(0.0, CPRectGetMaxY(clipViewFrame), CPRectGetWidth(clipViewFrame), horizontalScrollerHeight)];
|
||||
}
|
||||
else if (wasShowingHorizontalScroller)
|
||||
[_horizontalScroller setFloatValue:0.0 knobProportion:1.0];
|
||||
|
||||
[_contentView setFrame:contentViewFrame];
|
||||
[_contentView setFrame:clipViewFrame];
|
||||
[_headerClipView setFrame:headerViewFrame];
|
||||
|
||||
--_recursionCount;
|
||||
}
|
||||
@@ -384,13 +397,47 @@
|
||||
{
|
||||
return _autohidesScrollers;
|
||||
}
|
||||
/*
|
||||
- (void)setFrameSize:(CPRect)aSize
|
||||
|
||||
|
||||
- (CGRect)insetBounds
|
||||
{
|
||||
[super setFrameSize:aSize];
|
||||
return [self bounds];
|
||||
}
|
||||
|
||||
- (CPView)_headerView
|
||||
{
|
||||
var documentView = [self documentView];
|
||||
|
||||
[self reflectScrolledClipView:_contentView];
|
||||
}*/
|
||||
if ([documentView respondsToSelector:@selector(headerView)])
|
||||
return [documentView performSelector:@selector(headerView)];
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (CGRect)headerClipViewFrame
|
||||
{
|
||||
var headerView = [self _headerView],
|
||||
bounds = [self insetBounds];
|
||||
|
||||
if (!headerView)
|
||||
return CGRectMakeZero();
|
||||
|
||||
bounds.size.height = [headerView bounds].size.height;
|
||||
bounds.size.width -= _verticalScroller ? [_verticalScroller frame].size.width : [CPScroller scrollerWidth];
|
||||
|
||||
return bounds;
|
||||
}
|
||||
|
||||
- (CGRect)clipViewFrame
|
||||
{
|
||||
var bounds = [self insetBounds],
|
||||
headerViewFrame = [self headerClipViewFrame];
|
||||
|
||||
bounds.origin.y += headerViewFrame.size.height;
|
||||
bounds.size.height -= headerViewFrame.size.height;
|
||||
|
||||
return bounds;
|
||||
}
|
||||
|
||||
/* @ignore */
|
||||
- (void)_verticalScrollerDidScroll:(CPScroller)aScroller
|
||||
@@ -448,6 +495,7 @@
|
||||
}
|
||||
|
||||
[_contentView scrollToPoint:contentBounds.origin];
|
||||
[_headerClipView scrollToPoint:CGPointMake(contentBounds.origin.x, 0.0)];
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -588,6 +636,7 @@
|
||||
contentBounds.origin.y += [anEvent deltaY] * _verticalLineScroll;
|
||||
|
||||
[_contentView scrollToPoint:contentBounds.origin];
|
||||
[_headerClipView scrollToPoint:CGPointMake(contentBounds.origin.x, 0.0)];
|
||||
}
|
||||
|
||||
- (void)keyDown:(CPEvent)anEvent
|
||||
@@ -627,6 +676,7 @@
|
||||
}
|
||||
|
||||
[_contentView scrollToPoint:contentBounds.origin];
|
||||
[_headerClipView scrollToPoint:CGPointMake(contentBounds.origin, 0)];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -1,9 +1,38 @@
|
||||
/*
|
||||
* CPTableHeaderView.j
|
||||
* AppKit
|
||||
*
|
||||
* Created by Ross Boucher.
|
||||
* Copyright 2009 280 North, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
@import <AppKit/CPView.j>
|
||||
@import "CPTableColumn.j"
|
||||
@import "CPTableView.j"
|
||||
@import "CPView.j"
|
||||
|
||||
|
||||
@implementation CPTableHeaderView : CPView
|
||||
{
|
||||
int _resizedColumn @accessors(readonly, property=resizedColumn);
|
||||
int _draggedColumn @accessors(readonly, property=draggedColumn);
|
||||
|
||||
float _draggedDistance @accessors(readonly, property=draggedDistance);
|
||||
|
||||
CPTableView _tableView @accessors(property=tableView);
|
||||
}
|
||||
|
||||
- (void)initWithFrame:(CGRect)aFrame
|
||||
@@ -11,9 +40,76 @@
|
||||
self = [super initWithFrame:aFrame];
|
||||
|
||||
if (self)
|
||||
[self setBackgroundColor:[CPColor redColor]];
|
||||
{
|
||||
_resizedColumn = CPNotFound;
|
||||
_draggedColumn = CPNotFound;
|
||||
_draggedDistance = 0.0;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
||||
- (int)columnAtPoint:(CGPoint)aPoint
|
||||
{
|
||||
if (!CGRectContainsPoint([self bounds], aPoint))
|
||||
return CPNotFound;
|
||||
|
||||
// at this point, we can essentially ignore height, because all columns have equal heights
|
||||
// and that height is equal to the height of our own bounds, which we know we are inside of
|
||||
|
||||
var index = 0,
|
||||
count = [[_tableView tableColumns] count],
|
||||
tableSpacing = [_tableView intercellSpacing],
|
||||
tableColumns = [_tableView tableColumns],
|
||||
leftOffset = 0,
|
||||
pointX = aPoint.x;
|
||||
|
||||
for (; index < count; index++)
|
||||
{
|
||||
var width = [tableColumns[index] width] + tableSpacing.width;
|
||||
|
||||
if (pointX >= leftOffset && pointX < leftOffset + width)
|
||||
return index;
|
||||
|
||||
leftOffset += width;
|
||||
}
|
||||
|
||||
return CPNotFound;
|
||||
}
|
||||
|
||||
- (CGRect)headerRectOfColumn:(int)aColumnIndex
|
||||
{
|
||||
var tableColumns = [_tableView tableColumns],
|
||||
tableSpacing = [_tableView intercellSpacing],
|
||||
bounds = [self bounds];
|
||||
|
||||
if (aColumnIndex < 0 || aColumnIndex > [tableColumns count])
|
||||
[CPException raise:"invalid" reason:"tried to get headerRectOfColumn: on invalid column"];
|
||||
|
||||
bounds.size.width = [tableColumns[aColumnIndex] width] + tableSpacing.width;
|
||||
|
||||
while (--aColumnIndex >= 0)
|
||||
bounds.origin.x += [tableColumns[aColumnIndex] width] + tableSpacing.width;
|
||||
|
||||
return bounds;
|
||||
}
|
||||
|
||||
- (void)drawRect:(CGRect)aRect
|
||||
{
|
||||
var tableColumns = [_tableView tableColumns];
|
||||
var count = [tableColumns count];
|
||||
var columnRect = [self bounds];
|
||||
var spacing = [_tableView intercellSpacing];
|
||||
|
||||
for (i = 0; i < count; ++i) {
|
||||
var column = [tableColumns objectAtIndex:i];
|
||||
var headerView = [column headerView] ;
|
||||
columnRect.size.width = [column width] + spacing.width;
|
||||
// [headerView setHighlighted:[_tableView isColumnSelected:[[_tableView tableColumns] indexOfObject:column]]];
|
||||
[headerView setFrame:columnRect];
|
||||
columnRect.origin.x += [column width] + spacing.width;
|
||||
[self addSubview:headerView] ;
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -54,7 +54,7 @@ CPTableColumnUserResizingMask = 2;
|
||||
_maxWidth = 1000000.0;
|
||||
|
||||
[self setIdentifier:anIdentifier];
|
||||
[self setHeaderView:[CPTableHeaderView new]];
|
||||
[self setHeaderView:[CPTextField new]];
|
||||
[self setDataView:[CPTextField new]];
|
||||
}
|
||||
|
||||
|
||||
@@ -79,6 +79,8 @@ CPTableViewSelectionHighlightStyleSourceList = 1;
|
||||
unsigned _currentHighlightedTableColumn;
|
||||
|
||||
unsigned _numberOfRows;
|
||||
|
||||
CPTableHeaderView _headerView;
|
||||
}
|
||||
|
||||
- (id)initWithFrame:(CGRect)aFrame
|
||||
@@ -113,6 +115,11 @@ CPTableViewSelectionHighlightStyleSourceList = 1;
|
||||
_cachedDataViews = { };
|
||||
_intercellSpacing = _CGSizeMake(0.0, 0.0);
|
||||
_rowHeight = 24.0;
|
||||
|
||||
_headerView = [[CPTableHeaderView alloc] initWithFrame:CGRectMake(0, 0, [self bounds].size.width, _rowHeight)];
|
||||
[_headerView setAutoresizingMask:CPViewWidthSizable];
|
||||
|
||||
[_headerView setTableView:self];
|
||||
}
|
||||
|
||||
return self;
|
||||
@@ -459,6 +466,18 @@ _cachedDataViews = { };
|
||||
* - setCornerView:
|
||||
* - cornerView
|
||||
*/
|
||||
|
||||
- (CPView)headerView
|
||||
{
|
||||
return _headerView;
|
||||
}
|
||||
|
||||
- (void)setHeaderView:(CPView)aHeaderView
|
||||
{
|
||||
_headerView = aHeaderView;
|
||||
[_headerView setTableView:self];
|
||||
}
|
||||
|
||||
//Layout Support
|
||||
|
||||
// Complexity:
|
||||
|
||||
@@ -38,15 +38,15 @@ CPLogRegister(CPLogConsole);
|
||||
|
||||
iconImage = [[CPImage alloc] initWithContentsOfFile:"http://cappuccino.org/images/favicon.png" size:CGSizeMake(16,16)];
|
||||
|
||||
for (var i = 1; i <= 10; i++)
|
||||
for (var i = 1; i <= 20; i++)
|
||||
{
|
||||
var column = [[NEWCPTableColumn alloc] initWithIdentifier:String(i)];
|
||||
|
||||
// [[column headerView] setStringValue:"Number"];
|
||||
// [[column headerView] sizeToFit];
|
||||
// [column setWidth:[[column headerView] frame].size.width];
|
||||
[[column headerView] setStringValue:"Number "+i];
|
||||
[[column headerView] sizeToFit];
|
||||
[column setWidth:[[column headerView] frame].size.width + 20];
|
||||
|
||||
[column setWidth:200.0];
|
||||
// [column setWidth:200.0];
|
||||
|
||||
[tableView addTableColumn:column];
|
||||
}
|
||||
@@ -58,6 +58,8 @@ CPLogRegister(CPLogConsole);
|
||||
|
||||
[view addSubview:scrollView];
|
||||
|
||||
[scrollView setAutohidesScrollers:YES];
|
||||
|
||||
[tableView setDelegate:self];
|
||||
[tableView setDataSource:self];
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user