Skip to content

Commit

Permalink
* Support mask styles
Browse files Browse the repository at this point in the history
* Improved drop shadow rendering
* Slight style changes to tabs
  • Loading branch information
joehewitt committed Apr 13, 2009
1 parent 53c1586 commit d13c574
Show file tree
Hide file tree
Showing 8 changed files with 129 additions and 31 deletions.
3 changes: 1 addition & 2 deletions samples/TTCatalog/Classes/ButtonTestController.m
Expand Up @@ -51,7 +51,6 @@ - (TTStyle*)dropButton:(UIControlState)state {
if (state == UIControlStateNormal) {
return
[TTShapeStyle styleWithShape:[TTRoundedRectangleShape shapeWithRadius:8] next:
[TTInsetStyle styleWithInset:UIEdgeInsetsMake(0, 0, 0, 0) next:
[TTShadowStyle styleWithColor:RGBACOLOR(0,0,0,0.7) blur:3 offset:CGSizeMake(2, 2) next:
[TTInsetStyle styleWithInset:UIEdgeInsetsMake(0.25, 0.25, 0.25, 0.25) next:
[TTSolidFillStyle styleWithColor:[UIColor whiteColor] next:
Expand All @@ -61,7 +60,7 @@ - (TTStyle*)dropButton:(UIControlState)state {
[TTPaddingStyle styleWithPadding:UIEdgeInsetsMake(11, 10, 9, 10) next:
[TTTextStyle styleWithFont:nil color:TTSTYLEVAR(linkTextColor)
shadowColor:[UIColor colorWithWhite:255 alpha:0.4]
shadowOffset:CGSizeMake(0, -1) next:nil]]]]]]]]]];
shadowOffset:CGSizeMake(0, -1) next:nil]]]]]]]]];
} else if (state == UIControlStateHighlighted) {
return
[TTInsetStyle styleWithInset:UIEdgeInsetsMake(3, 3, 0, 0) next:
Expand Down
8 changes: 6 additions & 2 deletions samples/TTCatalog/Classes/StyleTestController.m
Expand Up @@ -86,14 +86,18 @@ - (void)loadView {
[TTBevelBorderStyle styleWithHighlight:nil shadow:RGBACOLOR(0,0,0,0.15)
width:1 lightSource:270 next:nil]]]]]],


// Badge
[TTShapeStyle styleWithShape:[TTRoundedRectangleShape shapeWithRadius:TT_ROUNDED] next:
[TTInsetStyle styleWithInset:UIEdgeInsetsMake(1.5, 1.5, 1.5, 1.5) next:
[TTShadowStyle styleWithColor:RGBACOLOR(0,0,0,0.8) blur:2 offset:CGSizeMake(0, 5) next:
[TTShadowStyle styleWithColor:RGBACOLOR(0,0,0,0.8) blur:3 offset:CGSizeMake(0, 5) next:
[TTReflectiveFillStyle styleWithColor:[UIColor redColor] next:
[TTInsetStyle styleWithInset:UIEdgeInsetsMake(-1.5, -1.5, -1.5, -1.5) next:
[TTSolidBorderStyle styleWithColor:[UIColor whiteColor] width:3 next:nil]]]]]],

// Mask
[TTMaskStyle styleWithMask:[UIImage imageNamed:@"mask.png"] next:
[TTLinearGradientFillStyle styleWithColor1:RGBCOLOR(0, 180, 231)
color2:RGBCOLOR(0, 0, 255) next:nil]],
nil];

CGFloat padding = 10;
Expand Down
1 change: 0 additions & 1 deletion samples/TTCatalog/Classes/TabBarTestController.m
Expand Up @@ -29,7 +29,6 @@ - (void)loadView {
[self.view addSubview:_tabBar1];

_tabBar2 = [[TTTabBar alloc] initWithFrame:CGRectMake(0, _tabBar1.bottom, 320, 40)];
_tabBar2.contentMode = UIViewContentModeScaleToFill;
_tabBar2.tabItems = [NSArray arrayWithObjects:
[[[TTTabItem alloc] initWithTitle:@"Banana"] autorelease],
[[[TTTabItem alloc] initWithTitle:@"Cherry"] autorelease],
Expand Down
4 changes: 4 additions & 0 deletions samples/TTCatalog/TTCatalog.xcodeproj/project.pbxproj
Expand Up @@ -16,6 +16,7 @@
28AD73600D9D9599002E5188 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 28AD735F0D9D9599002E5188 /* MainWindow.xib */; };
28C286E10D94DF7D0034E888 /* RootViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 28C286E00D94DF7D0034E888 /* RootViewController.m */; };
BE1288310F8973CD00F65EA2 /* StyleTestController.m in Sources */ = {isa = PBXBuildFile; fileRef = BE1288300F8973CD00F65EA2 /* StyleTestController.m */; };
BE1289C20F91811E00F65EA2 /* mask.png in Resources */ = {isa = PBXBuildFile; fileRef = BE1289C10F91811E00F65EA2 /* mask.png */; };
BE1D843A0F8D104B00EC8BB8 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BE1D84390F8D104B00EC8BB8 /* QuartzCore.framework */; };
BE3188A10F822E2C00E3067D /* smiley.png in Resources */ = {isa = PBXBuildFile; fileRef = BE3188A00F822E2C00E3067D /* smiley.png */; };
BE5F25920EBA5F0400FD59A6 /* PhotoTest2Controller.m in Sources */ = {isa = PBXBuildFile; fileRef = BE5F25910EBA5F0400FD59A6 /* PhotoTest2Controller.m */; };
Expand Down Expand Up @@ -76,6 +77,7 @@
8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
BE12882F0F8973CD00F65EA2 /* StyleTestController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StyleTestController.h; sourceTree = "<group>"; };
BE1288300F8973CD00F65EA2 /* StyleTestController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = StyleTestController.m; sourceTree = "<group>"; };
BE1289C10F91811E00F65EA2 /* mask.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = mask.png; sourceTree = "<group>"; };
BE1D84390F8D104B00EC8BB8 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
BE3188A00F822E2C00E3067D /* smiley.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = smiley.png; sourceTree = "<group>"; };
BE5F25900EBA5F0400FD59A6 /* PhotoTest2Controller.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PhotoTest2Controller.h; sourceTree = "<group>"; };
Expand Down Expand Up @@ -223,6 +225,7 @@
BE6E4DBF0F46A352001CE9B4 /* tableIcon.png */,
BECB1CC10F46AE9600AE5B52 /* person.jpg */,
BE3188A00F822E2C00E3067D /* smiley.png */,
BE1289C10F91811E00F65EA2 /* mask.png */,
8D1107310486CEB800E47090 /* Info.plist */,
);
name = Resources;
Expand Down Expand Up @@ -322,6 +325,7 @@
BECB1CC20F46AE9600AE5B52 /* person.jpg in Resources */,
BEDCFBB40F4FFF820060B7D1 /* Three20.bundle in Resources */,
BE3188A10F822E2C00E3067D /* smiley.png in Resources */,
BE1289C20F91811E00F65EA2 /* mask.png in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
6 changes: 3 additions & 3 deletions src/TTDefaultStyleSheet.m
Expand Up @@ -241,16 +241,16 @@ - (TTStyle*)tabGridTab:(UIControlState)state corner:(short)corner {
[TTSolidFillStyle styleWithColor:RGBCOLOR(150, 168, 191) next:
[TTInnerShadowStyle styleWithColor:RGBACOLOR(0,0,0,0.6) blur:3 offset:CGSizeMake(0, 0) next:
[TTPaddingStyle styleWithPadding:UIEdgeInsetsMake(11, 10, 9, 10) next:
[TTTextStyle styleWithFont:[UIFont boldSystemFontOfSize:12] color:RGBCOLOR(255, 255, 255)
[TTTextStyle styleWithFont:[UIFont boldSystemFontOfSize:11] color:RGBCOLOR(255, 255, 255)
minimumFontSize:8 shadowColor:RGBACOLOR(0,0,0,0.1) shadowOffset:CGSizeMake(-1,-1)
next:nil]]]]];
} else {
return
[TTShapeStyle styleWithShape:shape next:
[TTBevelBorderStyle styleWithHighlight:highlight shadow:shadow width:1 lightSource:125 next:
[TTPaddingStyle styleWithPadding:UIEdgeInsetsMake(11, 10, 9, 10) next:
[TTTextStyle styleWithFont:[UIFont boldSystemFontOfSize:12] color:self.linkTextColor
minimumFontSize:8 shadowColor:[UIColor whiteColor]
[TTTextStyle styleWithFont:[UIFont boldSystemFontOfSize:11] color:self.linkTextColor
minimumFontSize:8 shadowColor:[UIColor colorWithWhite:255 alpha:0.9]
shadowOffset:CGSizeMake(0, -1) next:nil]]]];
}
}
Expand Down
87 changes: 75 additions & 12 deletions src/TTStyle.m
Expand Up @@ -386,6 +386,8 @@ - (void)drawText:(NSString*)text context:(TTStyleContext*)context {
CGRect rect = context.contentFrame;
CGRect titleRect = [self rectForText:text forSize:rect.size withFont:font];
[text drawInRect:CGRectOffset(titleRect, rect.origin.x, rect.origin.y) withFont:font];

CGContextRestoreGState(ctx);
}

///////////////////////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -536,6 +538,61 @@ - (CGSize)addToSize:(CGSize)size context:(TTStyleContext*)context {

@end


@implementation TTMaskStyle

@synthesize mask = _mask;

///////////////////////////////////////////////////////////////////////////////////////////////////
// class public

+ (TTMaskStyle*)styleWithMask:(UIImage*)mask next:(TTStyle*)next {
TTMaskStyle* style = [[[self alloc] initWithNext:next] autorelease];
style.mask = mask;
return style;
}


///////////////////////////////////////////////////////////////////////////////////////////////////
// NSObject

- (id)initWithNext:(TTStyle*)next {
if (self = [super initWithNext:next]) {
_mask = nil;
}
return self;
}

- (void)dealloc {
[_mask release];
[super dealloc];
}

///////////////////////////////////////////////////////////////////////////////////////////////////
// TTStyle

- (BOOL)draw:(TTStyleContext*)context {
if (_mask) {
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextSaveGState(ctx);

// Translate context upside-down to invert the clip-to-mask, which turns the mask upside down
CGContextTranslateCTM(ctx, 0, context.frame.size.height);
CGContextScaleCTM(ctx, 1.0, -1.0);

CGRect maskRect = CGRectMake(0, 0, _mask.size.width, _mask.size.height);
CGContextClipToMask(ctx, maskRect, _mask.CGImage);

BOOL ok = [self.next draw:context];
CGContextRestoreGState(ctx);
return ok;
} else {
return [self.next draw:context];
}
}

@end

///////////////////////////////////////////////////////////////////////////////////////////////////

@implementation TTSolidFillStyle
Expand Down Expand Up @@ -574,6 +631,7 @@ - (BOOL)draw:(TTStyleContext*)context {

CGContextSaveGState(ctx);
[context.shape addToPath:context.frame];

[_color setFill];
CGContextFillPath(ctx);
CGContextRestoreGState(ctx);
Expand Down Expand Up @@ -754,39 +812,44 @@ - (void)dealloc {
// TTStyle

- (BOOL)draw:(TTStyleContext*)context {
UIEdgeInsets inset = UIEdgeInsetsZero;
CGFloat blurSize = round(_blur / 2);
UIEdgeInsets inset = UIEdgeInsetsMake(blurSize, blurSize, blurSize, blurSize);
if (_offset.width < 0) {
inset.left += fabs(_offset.width) + blurSize;
inset.left += fabs(_offset.width) + blurSize*2;
inset.right -= blurSize;
} else if (_offset.width > 0) {
inset.right += fabs(_offset.width) + blurSize;
inset.right += fabs(_offset.width) + blurSize*2;
inset.left -= blurSize;
}
if (_offset.height < 0) {
inset.top += fabs(_offset.height) + blurSize;
inset.top += fabs(_offset.height) + blurSize*2;
inset.bottom -= blurSize;
} else if (_offset.height > 0) {
inset.bottom += fabs(_offset.height) + blurSize;
inset.bottom += fabs(_offset.height) + blurSize*2;
inset.top -= blurSize;
}

context.frame = TTRectInset(context.frame, inset);
context.contentFrame = TTRectInset(context.contentFrame, inset);

CGContextRef ctx = UIGraphicsGetCurrentContext();

CGContextSaveGState(ctx);

[context.shape addToPath:context.frame];
[_color setFill];
CGContextSetShadowWithColor(ctx, CGSizeMake(_offset.width, -_offset.height), _blur,
_color.CGColor);
CGContextFillPath(ctx);
CGContextBeginTransparencyLayer(ctx, nil);
BOOL ok = [self.next draw:context];
CGContextEndTransparencyLayer(ctx);

CGContextRestoreGState(ctx);

return [self.next draw:context];
return ok;
}

- (CGSize)addToSize:(CGSize)size context:(TTStyleContext*)context {
CGFloat blurSize = round(_blur / 2);
size.width += _offset.width + (_offset.width ? blurSize : 0);
size.height += _offset.height + (_offset.height ? blurSize : 0);
size.width += _offset.width + (_offset.width ? blurSize : 0) + blurSize*2;
size.height += _offset.height + (_offset.height ? blurSize : 0) + blurSize*2;

if (_next) {
return [self.next addToSize:size context:context];
Expand Down
39 changes: 28 additions & 11 deletions src/TTTabBar.m
Expand Up @@ -92,7 +92,6 @@ - (id)initWithFrame:(CGRect)frame {
_tabViews = [[NSMutableArray alloc] init];
_tabStyle = nil;

self.contentMode = UIViewContentModeLeft;
self.style = TTSTYLE(tabBar);
self.tabStyle = @"tab:";
}
Expand All @@ -106,6 +105,14 @@ - (void)dealloc {
[super dealloc];
}

///////////////////////////////////////////////////////////////////////////////////////////////////
// UIView

- (void)layoutSubviews {
[super layoutSubviews];
[self layoutTabs];
}

///////////////////////////////////////////////////////////////////////////////////////////////////
// public

Expand Down Expand Up @@ -176,7 +183,7 @@ - (void)setTabItems:(NSArray*)tabItems {
}
}

[self layoutTabs];
[self setNeedsLayout];
}

- (void)showTabAtIndex:(NSInteger)tabIndex {
Expand Down Expand Up @@ -260,7 +267,6 @@ - (id)initWithFrame:(CGRect)frame {
_scrollView.showsHorizontalScrollIndicator = NO;
[self addSubview:_scrollView];

self.contentMode = UIViewContentModeLeft;
self.style = TTSTYLE(tabStrip);
self.tabStyle = @"tabRound:";
}
Expand Down Expand Up @@ -307,8 +313,7 @@ - (NSInteger)rowCount {
return ceil((float)self.tabViews.count / [self columnCount]);
}


- (CGSize)layoutTabs {
- (void)updateTabStyles {
CGFloat columnCount = [self columnCount];
int rowCount = [self rowCount];
int cellCount = rowCount * columnCount;
Expand All @@ -328,19 +333,24 @@ - (CGSize)layoutTabs {
}
++column;
}
}

TTGridLayout* layout = [[[TTGridLayout alloc] init] autorelease];
layout.padding = 1;
layout.columnCount = columnCount;
return [layout layoutSubviews:self.tabViews forView:self];
- (CGSize)layoutTabs {
if (self.width && self.height) {
TTGridLayout* layout = [[[TTGridLayout alloc] init] autorelease];
layout.padding = 1;
layout.columnCount = [self columnCount];
return [layout layoutSubviews:self.tabViews forView:self];
} else {
return self.frame.size;
}
}

///////////////////////////////////////////////////////////////////////////////////////////////////
// NSObject

- (id)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
self.contentMode = UIViewContentModeLeft;
self.style = TTSTYLE(tabGrid);
}
return self;
Expand All @@ -353,11 +363,18 @@ - (CGSize)sizeThatFits:(CGSize)size {
CGSize styleSize = [super sizeThatFits:size];
for (TTTab* tab in self.tabViews) {
CGSize tabSize = [tab sizeThatFits:CGSizeZero];
return CGSizeMake(size.width, tabSize.height * [self rowCount] + styleSize.height);
NSInteger rowCount = [self rowCount];
return CGSizeMake(size.width,
rowCount ? tabSize.height * [self rowCount] + styleSize.height : 0);
}
return size;
}

- (void)setTabItems:(NSArray*)tabItems {
[super setTabItems:tabItems];
[self updateTabStyles];
}

@end

///////////////////////////////////////////////////////////////////////////////////////////////////
Expand Down
12 changes: 12 additions & 0 deletions src/Three20/TTStyle.h
Expand Up @@ -123,6 +123,18 @@

///////////////////////////////////////////////////////////////////////////////////////////////////

@interface TTMaskStyle : TTStyle {
UIImage* _mask;
}

@property(nonatomic,retain) UIImage* mask;

+ (TTMaskStyle*)styleWithMask:(UIImage*)mask next:(TTStyle*)next;

@end

///////////////////////////////////////////////////////////////////////////////////////////////////

@interface TTSolidFillStyle : TTStyle {
UIColor* _color;
}
Expand Down

0 comments on commit d13c574

Please sign in to comment.