Files
twui/ExampleProject/Example/ExampleView.m
T
Aditya Nrusimha 3087c8428a Add TUITableViewCell default drawing and options.
Flesh out the class, as well as clean it up.
2012-10-11 20:20:55 -07:00

204 lines
7.6 KiB
Objective-C

/*
Copyright 2011 Twitter, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this work except in compliance with the License.
You may obtain a copy of the License in the LICENSE file, or at:
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#import "ExampleView.h"
#import "ExampleTableViewCell.h"
#import "ExampleSectionHeaderView.h"
#define TAB_HEIGHT 60
@implementation ExampleView
- (id)initWithFrame:(CGRect)frame
{
if((self = [super initWithFrame:frame])) {
self.backgroundColor = [NSColor colorWithCalibratedWhite:0.9 alpha:1.0];
// if you're using a font a lot, it's best to allocate it once and re-use it
exampleFont1 = [NSFont fontWithName:@"HelveticaNeue" size:15];
exampleFont2 = [NSFont fontWithName:@"HelveticaNeue-Bold" size:15];
CGRect b = self.bounds;
b.origin.y += TAB_HEIGHT;
b.size.height -= TAB_HEIGHT;
/*
Note by default scroll views (and therefore table views) don't
have clipsToBounds enabled. Set only if needed. In this case
we don't, so it could potentially save us some rendering costs.
*/
_tableView = [[TUITableView alloc] initWithFrame:b];
_tableView.alwaysBounceVertical = YES;
_tableView.autoresizingMask = TUIViewAutoresizingFlexibleSize;
_tableView.dataSource = self;
_tableView.delegate = self;
_tableView.maintainContentOffsetAfterReload = YES;
[self addSubview:_tableView];
_tabBar = [[ExampleTabBar alloc] initWithNumberOfTabs:5];
_tabBar.delegate = self;
// It'd be easier to just use .autoresizingmask, but for demonstration we'll use ^layout.
_tabBar.layout = ^(TUIView *v) { // 'v' in this case will point to the same object as 'tabs'
TUIView *superview = v.superview; // note we're using the passed-in 'v' argument, rather than referencing 'tabs' in the block, this avoids a retain cycle without jumping through hoops
CGRect rect = superview.bounds; // take the superview bounds
rect.size.height = TAB_HEIGHT; // only take up the bottom 60px
return rect;
};
[self addSubview:_tabBar];
// setup individual tabs
for(TUIView *tabView in _tabBar.tabViews) {
tabView.backgroundColor = [NSColor clearColor]; // will also set opaque=NO
// let's just teach the tabs how to draw themselves right here - no need to subclass anything
tabView.drawRect = ^(TUIView *v, CGRect rect) {
CGRect b = v.bounds;
CGContextRef ctx = TUIGraphicsGetCurrentContext();
NSImage *image = [NSImage imageNamed:@"clock"];
CGRect imageRect = ABIntegralRectWithSizeCenteredInRect([image size], b);
if([v.nsView isTrackingSubviewOfView:v]) { // simple way to check if the mouse is currently down inside of 'v'. See the other methods in TUINSView for more.
// first draw a slight white emboss below
CGContextSaveGState(ctx);
CGImageRef cgImage = [image CGImageForProposedRect:&imageRect context:nil hints:nil];
CGContextClipToMask(ctx, CGRectOffset(imageRect, 0, -1), cgImage);
CGContextSetRGBFillColor(ctx, 1, 1, 1, 0.5);
CGContextFillRect(ctx, b);
CGContextRestoreGState(ctx);
// replace image with a dynamically generated fancy inset image
// 1. use the image as a mask to draw a blue gradient
// 2. generate an inner shadow image based on the mask, then overlay that on top
image = [NSImage tui_imageWithSize:imageRect.size drawing:^(CGContextRef ctx) {
CGRect r;
r.origin = CGPointZero;
r.size = imageRect.size;
CGContextClipToMask(ctx, r, image.tui_CGImage);
CGContextDrawLinearGradientBetweenPoints(ctx, CGPointMake(0, r.size.height), (CGFloat[]){0,0,1,1}, CGPointZero, (CGFloat[]){0,0.6,1,1});
NSImage *innerShadow = [image tui_innerShadowWithOffset:CGSizeMake(0, -1) radius:3.0 color:[NSColor blackColor] backgroundColor:[NSColor cyanColor]];
CGContextSetBlendMode(ctx, kCGBlendModeOverlay);
CGContextDrawImage(ctx, r, innerShadow.tui_CGImage);
}];
}
[image drawInRect:imageRect fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0]; // draw 'image' (might be the regular one, or the dynamically generated one)
// draw the index
TUIAttributedString *s = [TUIAttributedString stringWithString:[NSString stringWithFormat:@"%ld", v.tag]];
[s ab_drawInRect:CGRectOffset(imageRect, imageRect.size.width, -15)];
};
}
}
return self;
}
- (void)tabBar:(ExampleTabBar *)tabBar didSelectTab:(NSInteger)index
{
NSLog(@"selected tab %ld", index);
if(index == [[tabBar tabViews] count] - 1){
NSLog(@"Reload table data...");
[_tableView reloadData];
}
}
- (NSInteger)numberOfSectionsInTableView:(TUITableView *)tableView
{
return 8;
}
- (NSInteger)tableView:(TUITableView *)table numberOfRowsInSection:(NSInteger)section
{
return 25;
}
- (CGFloat)tableView:(TUITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 50.0;
}
- (TUIView *)tableView:(TUITableView *)tableView headerViewForSection:(NSInteger)section
{
ExampleSectionHeaderView *view = [[ExampleSectionHeaderView alloc] initWithFrame:CGRectMake(0, 0, 100, 32)];
TUIAttributedString *title = [TUIAttributedString stringWithString:[NSString stringWithFormat:@"Example Section %d", (int)section]];
title.color = [NSColor blackColor];
title.font = exampleFont2;
view.labelRenderer.attributedString = title;
// Dragging a title can drag the window too.
[view setMoveWindowByDragging:YES];
return view;
}
- (TUITableViewCell *)tableView:(TUITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
ExampleTableViewCell *cell = reusableTableCellOfClass(tableView, ExampleTableViewCell);
TUIAttributedString *s = [TUIAttributedString stringWithString:[NSString stringWithFormat:@"example cell %d", (int)indexPath.row]];
s.color = [NSColor blackColor];
s.font = exampleFont1;
[s setFont:exampleFont2 inRange:NSMakeRange(8, 4)]; // make the word "cell" bold
cell.attributedString = s;
return cell;
}
- (void)tableView:(TUITableView *)tableView didClickRowAtIndexPath:(NSIndexPath *)indexPath withEvent:(NSEvent *)event
{
if([event clickCount] == 1) {
// do something cool
}
if(event.type == NSRightMouseUp){
// show context menu
}
}
- (BOOL)tableView:(TUITableView *)tableView shouldSelectRowAtIndexPath:(NSIndexPath *)indexPath forEvent:(NSEvent *)event{
switch (event.type) {
case NSRightMouseDown:
return NO;
}
return YES;
}
-(BOOL)tableView:(TUITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
// return TRUE to enable row reordering by dragging; don't implement this method or return
// FALSE to disable
return TRUE;
}
-(void)tableView:(TUITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath {
// update the model to reflect the changed index paths; since this example isn't backed by
// a "real" model, after dropping a cell the table will revert to it's previous state
NSLog(@"Move dragged row: %@ => %@", fromIndexPath, toIndexPath);
}
-(NSIndexPath *)tableView:(TUITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)fromPath toProposedIndexPath:(NSIndexPath *)proposedPath {
// optionally revise the drag-to-reorder drop target index path by returning a different index path
// than proposedPath. if proposedPath is suitable, return that. if this method is not implemented,
// proposedPath is used by default.
return proposedPath;
}
@end