Created
March 24, 2010 22:57
-
-
Save boucher/342932 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* AppController.j | |
* CPBrowserTest | |
* | |
* Created by Ross Boucher on March 23, 2010. | |
* Copyright 2010, Your Company All rights reserved. | |
*/ | |
@import <Foundation/CPObject.j> | |
@import "CPBrowser.j" | |
@implementation Node : CPObject | |
{ | |
id value; | |
} | |
+ (id)withValue:(id)aValue | |
{ | |
var a = [[self alloc] init]; | |
a.value = aValue; | |
return a; | |
} | |
- (id)value | |
{ | |
return value; | |
} | |
- (CPArray)children | |
{ | |
return [[Node withValue:1], | |
[Node withValue:2], | |
[Node withValue:3], | |
[Node withValue:4]]; | |
} | |
@end | |
@implementation AppController : CPObject | |
{ | |
} | |
- (void)applicationDidFinishLaunching:(CPNotification)aNotification | |
{ | |
var theWindow = [[CPWindow alloc] initWithContentRect:CGRectMakeZero() styleMask:CPBorderlessBridgeWindowMask], | |
contentView = [theWindow contentView]; | |
browser = [[CPBrowser alloc] initWithFrame:CGRectMake(0,0,500,300)]; | |
//[browser setBackgroundColor:[CPColor blueColor]]; | |
[browser setCenter:[contentView center]]; | |
[contentView addSubview:browser]; | |
[theWindow orderFront:self]; | |
[browser setDelegate:self]; | |
// Uncomment the following line to turn on the standard menu bar. | |
//[CPMenu setMenuBarVisible:YES]; | |
} | |
- (id)rootItemForBrowser:(id)aBrowser | |
{ | |
return [Node withValue:0]; | |
} | |
- (id)browser:(id)aBrowser numberOfChildrenOfItem:(id)anItem | |
{ | |
return [[anItem children] count]; | |
} | |
- (id)browser:(id)aBrowser child:(int)index ofItem:(id)anItem | |
{ | |
return [[anItem children] objectAtIndex:index]; | |
} | |
- (id)browser:(id)aBrowser objectValueOfItem:(id)anItem | |
{ | |
return [anItem value]; | |
} | |
- (id)browser:(id)aBrowser itemIsLeaf:(id)anItem | |
{ | |
return [[anItem children] count] && [anItem value] !== 4; | |
} | |
@end | |
/* | |
* CPBrowser.j | |
* AppKit | |
* | |
* Created by Ross Boucher. | |
* Copyright 2010, 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/CPControl.j> | |
CPBrowserIllegalDelegateException = "CPBrowserIllegalDelegateException"; | |
/*! | |
@ingroup appkit | |
@class CPBrowser | |
*/ | |
@implementation CPBrowser : CPControl | |
{ | |
id _delegate; | |
CPString _pathSeparator; | |
CPView _contentView; | |
CPScrollView _horizontalScrollView; | |
CPView _prototypeView; | |
CPArray _tableViews; | |
CPArray _tableDelegates; | |
id _rootItem; | |
BOOL _delegateSupportsImages; | |
} | |
+ (CPImage)branchImage | |
{ | |
return [[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:[self class]] | |
pathForResource:"browser-leaf.png"] | |
size:CGSizeMake(9,9)]; | |
} | |
+ (CPImage)highlightedBranchImage | |
{ | |
return [[CPImage alloc] initWithContentsOfFile:[[CPBundle bundleForClass:[self class]] | |
pathForResource:"browser-leaf-highlighted.png"] | |
size:CGSizeMake(9,9)]; | |
} | |
- (id)initWithFrame:(CGRect)aFrame | |
{ | |
if (self = [super initWithFrame:aFrame]) | |
{ | |
_pathSeparator = "/"; | |
_tableViews = []; | |
_tableDelegates = []; | |
_prototypeView = [[CPTextField alloc] initWithFrame:CGRectMake(0, 0, 100.0, 23.0)]; | |
_horizontalScrollView = [[CPScrollView alloc] initWithFrame:[self bounds]]; | |
[_horizontalScrollView setHasVerticalScroller:NO]; | |
[_horizontalScrollView setAutohidesScrollers:YES]; | |
[_horizontalScrollView setAutoresizingMask:CPViewWidthSizable|CPViewHeightSizable]; | |
_contentView = [[CPView alloc] initWithFrame:CGRectMake(0, 0, 0, CGRectGetHeight([self bounds]))]; | |
[_horizontalScrollView setDocumentView:_contentView]; | |
[self addSubview:_horizontalScrollView]; | |
} | |
return self; | |
} | |
- (void)setDelegate:(id)anObject | |
{ | |
_delegate = anObject; | |
_delegateSupportsImages = [_delegate respondsToSelector:@selector(browser:imageValueForItem:)]; | |
[self loadColumnZero]; | |
} | |
- (id)delegate | |
{ | |
return _delegate; | |
} | |
- (CPTableView)tableViewInColumn:(unsigned)index | |
{ | |
return _tableViews[index]; | |
} | |
- (void)loadColumnZero | |
{ | |
if ([_delegate respondsToSelector:@selector(rootItemForBrowser:)]) | |
_rootItem = [_delegate rootItemForBrowser:self]; | |
else | |
_rootItem = nil; | |
[self _loadColumn:0]; | |
} | |
- (void)_loadColumn:(int)index | |
{ | |
[_tableViews.slice(index) makeObjectsPerformSelector:@selector(removeFromSuperview)]; | |
_tableViews = _tableViews.slice(0, index); | |
_tableDelegates = _tableDelegates.slice(0, index); | |
var table = [[CPTableView alloc] initWithFrame:CGRectMake(0, 0, 150, 150)]; | |
[self _addTableColumnsToTableView:table]; | |
var delegate = [[_CPBrowserTableDelegate alloc] init]; | |
[delegate _setDelegate:_delegate]; | |
[delegate _setBrowser:self]; | |
[delegate _setIndex:index]; | |
var itemForColumn = index === 0 ? _rootItem : [_tableDelegates[index - 1] _item]; | |
[delegate _setItem:itemForColumn]; | |
_tableViews[index] = table; | |
_tableDelegates[index] = delegate; | |
//[table setDelegate:delegate]; | |
[table setDataSource:delegate]; | |
var x = CGRectGetWidth([_contentView bounds]); | |
var scrollView = [[CPScrollView alloc] initWithFrame:CGRectMake(0, x, 150.0, CGRectGetHeight([self bounds]))]; | |
[scrollView setDocumentView:table]; | |
[scrollView setHasHorizontalScroller:NO]; | |
[_contentView addSubview:scrollView]; | |
[_contentView setFrameSize:CGRectMake(x+150.0, CGRectGetHeight([_contentView bounds]))]; | |
} | |
- (void)_addTableColumnsToTableView:(CPTableView)aTableView | |
{ | |
if (_delegateSupportsImages) | |
{ | |
var column = [[CPTableColumn alloc] initWithIdentifier:@"Image"], | |
view = [[CPImageView alloc] initWithFrame:CGRectMake(0, 0, 23, 23)]; | |
[view setImageScaling:CPScaleProportionally]; | |
[column setDataView:view]; | |
[column setResizingMask:CPTableColumnNoResizing]; | |
[column setWidth:23]; | |
[aTableView addTableColumn:column]; | |
} | |
var column = [[CPTableColumn alloc] initWithIdentifier:@"Content"]; | |
[column setDataView:_prototypeView]; | |
[column setResizingMask:CPTableColumnNoResizing]; | |
[column setWidth:CGRectGetWidth([_prototypeView frame])]; | |
[aTableView addTableColumn:column]; | |
/* | |
var column = [[CPTableColumn alloc] initWithIdentifier:@"Leaf"], | |
view = [[_CPBrowserLeafView alloc] initWithFrame:CGRectMakeZero(0, 0, 23, 23)]; | |
[view setBranchImage:[[self class] branchImage]]; | |
[view setHighlightedBranchImage:[[self class] highlightedBranchImage]]; | |
[column setDataView:view]; | |
[column setResizingMask:CPTableColumnNoResizing]; | |
[column setWidth:23]; | |
[aTableView addTableColumn:column]; | |
*/ | |
} | |
@end | |
@implementation _CPBrowserTableDelegate : CPObject | |
{ | |
CPBrowser _browser @accessors; | |
unsigned _index @accessors; | |
id _delegate @accessors; | |
id _item @accessors; | |
} | |
- (unsigned)numberOfRowsInTableView:(CPTableView)aTableView | |
{ | |
console.log([aTableView tableColumns].toString()); | |
console.log("number of rows: "+aTableView+" - "+[_delegate browser:_browser numberOfChildrenOfItem:_item]); | |
return [_delegate browser:_browser numberOfChildrenOfItem:_item]; | |
} | |
- (void)tableView:(CPTableView)aTableView objectValueForTableColumn:(CPTableColumn)column row:(unsigned)row | |
{console.log("tableView: "+aTableView+" objectValueForColumn: "+column+" row: "+row); | |
if ([column identifier] === "Image") | |
return [_delegate browser:_browser imageValueForItem:[self childAtIndex:row]]; | |
else if ([column identifier] === "Leaf") | |
return [_delegate respondsToSelector:@selector(browser:isLeafItem:)] && [_delegate browser:_browser isLeafItem:[self childAtIndex:row]]; | |
else | |
return [_delegate browser:_browser objectValueForItem:[self childAtIndex:row]]; | |
} | |
- (id)childAtIndex:(unsigned)index | |
{console.log("here: "+index); | |
return [_delegate browser:_browser child:index ofItem:_item]; | |
} | |
@end | |
@implementation _CPBrowserLeafView : CPView | |
{ | |
BOOL _isLeaf @accessors(readonly, property=isLeaf); | |
CPImage _branchImage @accessors(property=branchImage); | |
CPImage _highlightedBranchImage @accessors(property=highlightedBranchImage); | |
} | |
- (BOOL)objectValue | |
{ | |
return _isLeaf; | |
} | |
- (void)setObjectValue:(id)aValue | |
{ | |
_isLeaf = !!aValue; | |
[self setNeedsLayout]; | |
} | |
- (CGRect)rectForEphemeralSubviewNamed:(CPString)aName | |
{ | |
if (aName === "image-view") | |
return CGRectInset([self bounds], 1, 1); | |
return [super rectForEphemeralSubviewNamed:aName]; | |
} | |
- (CPView)createEphemeralSubviewNamed:(CPString)aName | |
{ | |
if (aName === "image-view") | |
return [[CPImageView alloc] initWithFrame:CGRectMakeZero()]; | |
return [super createEphemeralSubviewNamed:aName]; | |
} | |
- (void)layoutSubviews | |
{ | |
var imageView = [self layoutEphemeralSubviewNamed:@"image-view" | |
positioned:CPWindowAbove | |
relativeToEphemeralSubviewNamed:nil]; | |
var isHighlighted = [self themeState] & CPThemeStateHighlighted; | |
[imageView setImage: _isLeaf ? (isHighlighted ? _highlightedBranchImage : _branchImage) : nil]; | |
[imageView setImageScaling:CPScaleNone]; | |
} | |
- (void)encodeWithCoder:(CPCoder)aCoder | |
{ | |
[super encodeWithCoder:aCoder]; | |
[aCoder encodeBool:_isLeaf forKey:"_CPBrowserLeafViewIsLeafKey"]; | |
[aCoder encodeObject:_branchImage forKey:"_CPBrowserLeafViewBranchImageKey"]; | |
[aCoder encodeObject:_highlightedBranchImage forKey:"_CPBrowserLeafViewHighlightedBranchImageKey"]; | |
} | |
- (void)initWithCoder:(CPCoder)aCoder | |
{ | |
if (self = [super initWithCoder:aCoder]) | |
{ | |
_isLeaf = [aCoder decodeBoolForKey:"_CPBrowserLeafViewIsLeafKey"]; | |
_branchImage = [aCoder decodeObjectForKey:"_CPBrowserLeafViewBranchImageKey"]; | |
_highlightedBranchImage = [aCoder decodeObjectForKey:"_CPBrowserLeafViewHighlightedBranchImageKey"]; | |
} | |
return self; | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment