Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge pull request #616 from facebook/development

Release Three20 v1.0.7
  • Loading branch information...
commit 41bdb73efb660a28a6d9d73587cf70c37171f2ab 2 parents 300db17 + f963e02
@jwang jwang authored
Showing with 2,909 additions and 567 deletions.
  1. 0  Build/ignoreme
  2. +17 −5 samples/Style/TTCSSStyleSheets/Classes/StyleSheetViewController.m
  3. +30 −0 samples/Style/TTCSSStyleSheets/TTCSSStyleSheets.xcodeproj/project.pbxproj
  4. +20 −16 samples/TTCatalog/Classes/LauncherViewTestController.m
  5. +30 −0 src/Three20/Three20.xcodeproj/project.pbxproj
  6. +2 −2 src/Three20Core/Sources/Three20Version.m
  7. +1 −2  src/Three20Network/Sources/TTURLCache.m
  8. +4 −3 src/Three20Network/Sources/TTURLImageResponse.m
  9. +0 −58 src/Three20Network/Three20Network.xcodeproj/project.pbxproj
  10. +5 −0 src/Three20UI/Headers/TTImageView.h
  11. +7 −0 src/Three20UI/Headers/TTImageViewDelegate.h
  12. +21 −0 src/Three20UI/Headers/TTLauncherPersistenceMode.h
  13. +35 −0 src/Three20UI/Headers/TTLauncherView.h
  14. +44 −3 src/Three20UI/Headers/TTScrollView.h
  15. +3 −0  src/Three20UI/Headers/TTTableView.h
  16. +0 −2  src/Three20UI/Headers/TTTableViewController.h
  17. +2 −0  src/Three20UI/Headers/Three20UI.h
  18. +6 −0 src/Three20UI/Sources/TTImageView.m
  19. +45 −0 src/Three20UI/Sources/TTLauncherView.m
  20. +1 −0  src/Three20UI/Sources/TTModelViewController.m
  21. +77 −1 src/Three20UI/Sources/TTScrollView.m
  22. +9 −0 src/Three20UI/Sources/TTTableView.m
  23. +12 −4 src/Three20UI/Sources/TTTableViewController.m
  24. +4 −0 src/Three20UI/Three20UI.xcodeproj/project.pbxproj
  25. +16 −10 src/Three20UICommon/Sources/UIViewControllerAdditions.m
  26. +1 −0  src/common/Configurations/Library.xcconfig
  27. +1 −0  src/common/Configurations/Project.xcconfig
  28. +38 −0 src/extThree20CSSStyle/Headers/TTCSSApplyProtocol.h
  29. +28 −0 src/extThree20CSSStyle/Headers/TTCSSFunctions.h
  30. +28 −9 src/extThree20CSSStyle/Headers/TTCSSGlobalStyle.h
  31. +264 −0 src/extThree20CSSStyle/Headers/TTCSSRuleSet.h
  32. +57 −8 src/extThree20CSSStyle/Headers/TTCSSStyleSheet.h
  33. +55 −0 src/extThree20CSSStyle/Headers/TTCSSTextShadowModel.h
  34. +44 −0 src/extThree20CSSStyle/Headers/TTDataConverter.h
  35. +71 −0 src/extThree20CSSStyle/Headers/TTDataPopulator.h
  36. +30 −0 src/extThree20CSSStyle/Headers/TTDataPopulatorDelegate.h
  37. +68 −0 src/extThree20CSSStyle/Headers/TTDefaultCSSStyleSheet.h
  38. +3 −14 src/extThree20CSSStyle/{Sources/TTDefaultCSSStyleSheet.h → Headers/UILabel+CSSAdditions.h}
  39. +2 −11 src/extThree20CSSStyle/Headers/UILabelAdditions.h
  40. +30 −0 src/extThree20CSSStyle/Headers/UIView+CSSAdditions.h
  41. +2 −1  src/extThree20CSSStyle/Headers/extThree20CSSStyle+Additions.h
  42. +9 −0 src/extThree20CSSStyle/Headers/extThree20CSSStyle.h
  43. +69 −8 src/extThree20CSSStyle/README.mdown
  44. +268 −0 src/extThree20CSSStyle/Sources/TTCSSFunctions.m
  45. +2 −2 src/extThree20CSSStyle/Sources/TTCSSParser.m
  46. +341 −0 src/extThree20CSSStyle/Sources/TTCSSRuleSet.m
  47. +230 −278 src/extThree20CSSStyle/Sources/TTCSSStyleSheet.m
  48. +108 −0 src/extThree20CSSStyle/Sources/TTCSSTextShadowModel.m
  49. +47 −2 src/extThree20CSSStyle/Sources/TTDefaultCSSStyleSheet.m
  50. +83 −0 src/extThree20CSSStyle/Sources/UILabel+CSSAdditions.m
  51. +0 −73 src/extThree20CSSStyle/Sources/UILabelAdditions.m
  52. +103 −0 src/extThree20CSSStyle/Sources/UIView+CSSAdditions.m
  53. +57 −0 src/extThree20CSSStyle/ThirdPart/TTDataConverter.m
  54. +212 −0 src/extThree20CSSStyle/ThirdPart/TTDataPopulator.m
  55. +100 −0 src/extThree20CSSStyle/UnitTests/CssRuleSetTests.m
  56. +167 −55 src/extThree20CSSStyle/extThree20CSSStyle.xcodeproj/project.pbxproj
  57. 0  src/scripts/ttmodule.py
View
0  Build/ignoreme
No changes.
View
22 samples/Style/TTCSSStyleSheets/Classes/StyleSheetViewController.m
@@ -17,6 +17,7 @@
#import "StyleSheetViewController.h"
#import "SampleCSSStyleSheet.h"
+#import "extThree20CSSStyle/TTCSSRuleSet.h"
///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -50,23 +51,34 @@ - (void)loadView {
}
self.title = @"Three20 CSS extension";
- self.view.backgroundColor = TTCSS(@"body", backgroundColor);
+ self.view.backgroundColor = TTCSS( @"body", background_color );
// Using helper macro
UILabel* headerLabel = [[UILabel alloc] initWithFrame:CGRectZero];
headerLabel.text = @"Header text";
+
+ // When using TTCSS you specify the Rule Set Name and the CSS property.
headerLabel.font = TTCSS(@"h1", font);
headerLabel.textColor = TTCSS(@"h1", color);
- headerLabel.backgroundColor = TTCSS(@"h1", backgroundColor);
- headerLabel.shadowColor = TTCSS(@"h1", shadowColor);
- headerLabel.shadowOffset = TTCSS(@"h1", shadowOffset);
+ headerLabel.backgroundColor = TTCSS(@"h1", background_color);
+
+ // Some CSS property have sub properties.
+ headerLabel.shadowColor = TTCSS(@"h1", text_shadow).shadowColor;
+ headerLabel.shadowOffset = TTCSS(@"h1", text_shadow).shadowOffset;
+
[headerLabel sizeToFit];
[self.view addSubview:headerLabel];
// Using UILabel addition
UILabel* headerLabel2 = [[UILabel alloc] initWithFrame:CGRectZero];
headerLabel2.text = @"Header 2 text";
- [headerLabel2 applyCssSelector:@"h2"];
+
+ // Use the Helper Function TTApplyCSS and specify the Rule Set Name then the object to apply.
+ TTApplyCSS( @"h2", headerLabel2 );
+
+ // This will work too!
+ [headerLabel applyCssSelector:@"h2"];
+
[headerLabel2 sizeToFit];
CGFloat top = headerLabel.frame.size.height;
CGRect frame = headerLabel2.frame;
View
30 samples/Style/TTCSSStyleSheets/TTCSSStyleSheets.xcodeproj/project.pbxproj
@@ -33,6 +33,20 @@
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
+ 187835D313D5F7C2004600D3 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 6E3793D711B9B59D0011C497 /* Three20Network.xcodeproj */;
+ proxyType = 2;
+ remoteGlobalIDString = 662D81EF12630516005851C2;
+ remoteInfo = "Three20Network-Xcode3.2.5";
+ };
+ 187835D513D5F7C2004600D3 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 6E3793D711B9B59D0011C497 /* Three20Network.xcodeproj */;
+ proxyType = 2;
+ remoteGlobalIDString = 662D81B2126304EB005851C2;
+ remoteInfo = "Three20NetworkUnitTests-Xcode3.2.5";
+ };
6E036BCC11B38E520025E8EE /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 6E036BC711B38E520025E8EE /* extThree20CSSStyle.xcodeproj */;
@@ -355,7 +369,9 @@
isa = PBXGroup;
children = (
6E3793EF11B9B59D0011C497 /* libThree20Network.a */,
+ 187835D413D5F7C2004600D3 /* libThree20Network-Xcode3.2.5.a */,
6E3793F111B9B59D0011C497 /* NetworkUnitTests.octest */,
+ 187835D613D5F7C2004600D3 /* NetworkUnitTests-Xcode3.2.5.octest */,
);
name = Products;
sourceTree = "<group>";
@@ -546,6 +562,20 @@
/* End PBXProject section */
/* Begin PBXReferenceProxy section */
+ 187835D413D5F7C2004600D3 /* libThree20Network-Xcode3.2.5.a */ = {
+ isa = PBXReferenceProxy;
+ fileType = archive.ar;
+ path = "libThree20Network-Xcode3.2.5.a";
+ remoteRef = 187835D313D5F7C2004600D3 /* PBXContainerItemProxy */;
+ sourceTree = BUILT_PRODUCTS_DIR;
+ };
+ 187835D613D5F7C2004600D3 /* NetworkUnitTests-Xcode3.2.5.octest */ = {
+ isa = PBXReferenceProxy;
+ fileType = wrapper.cfbundle;
+ path = "NetworkUnitTests-Xcode3.2.5.octest";
+ remoteRef = 187835D513D5F7C2004600D3 /* PBXContainerItemProxy */;
+ sourceTree = BUILT_PRODUCTS_DIR;
+ };
6E036BCD11B38E520025E8EE /* libextThree20CSSStyle.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
View
36 samples/TTCatalog/Classes/LauncherViewTestController.m
@@ -28,40 +28,44 @@ - (void)loadView {
_launcherView.backgroundColor = [UIColor blackColor];
_launcherView.delegate = self;
_launcherView.columnCount = 4;
- _launcherView.pages = [NSArray arrayWithObjects:
- [NSArray arrayWithObjects:
- [[[TTLauncherItem alloc] initWithTitle:@"Button 1"
+ _launcherView.persistenceMode = TTLauncherPersistenceModeAll;
+
+ if (![_launcherView restoreLauncherItems]) {
+ _launcherView.pages = [NSArray arrayWithObjects:
+ [NSArray arrayWithObjects:
+ [[[TTLauncherItem alloc] initWithTitle:@"Button 1"
image:@"bundle://Icon.png"
URL:nil canDelete:YES] autorelease],
- [[[TTLauncherItem alloc] initWithTitle:@"Button 2"
+ [[[TTLauncherItem alloc] initWithTitle:@"Button 2"
image:@"bundle://Icon.png"
URL:nil canDelete:YES] autorelease],
- [[[TTLauncherItem alloc] initWithTitle:@"Button 3"
+ [[[TTLauncherItem alloc] initWithTitle:@"Button 3"
image:@"bundle://Icon.png"
URL:@"fb://item3" canDelete:YES] autorelease],
- [[[TTLauncherItem alloc] initWithTitle:@"Button 4"
+ [[[TTLauncherItem alloc] initWithTitle:@"Button 4"
image:@"bundle://Icon.png"
URL:@"fb://item4" canDelete:YES] autorelease],
- [[[TTLauncherItem alloc] initWithTitle:@"Button 5"
+ [[[TTLauncherItem alloc] initWithTitle:@"Button 5"
image:@"bundle://Icon.png"
URL:@"fb://item5" canDelete:YES] autorelease],
- [[[TTLauncherItem alloc] initWithTitle:@"Button 6"
+ [[[TTLauncherItem alloc] initWithTitle:@"Button 6"
image:@"bundle://Icon.png"
URL:@"fb://item6" canDelete:YES] autorelease],
- [[[TTLauncherItem alloc] initWithTitle:@"Button 7"
+ [[[TTLauncherItem alloc] initWithTitle:@"Button 7"
image:@"bundle://Icon.png"
URL:@"fb://item7" canDelete:YES] autorelease],
- nil],
- [NSArray arrayWithObjects:
- [[[TTLauncherItem alloc] initWithTitle:@"Button 8"
+ nil],
+ [NSArray arrayWithObjects:
+ [[[TTLauncherItem alloc] initWithTitle:@"Button 8"
image:@"bundle://Icon.png"
URL:nil canDelete:YES] autorelease],
- [[[TTLauncherItem alloc] initWithTitle:@"Button 9"
+ [[[TTLauncherItem alloc] initWithTitle:@"Button 9"
image:@"bundle://Icon.png"
URL:nil canDelete:YES] autorelease],
- nil],
- nil
- ];
+ nil],
+ nil
+ ];
+ }
[self.view addSubview:_launcherView];
TTLauncherItem* item = [_launcherView itemWithURL:@"fb://item3"];
View
30 src/Three20/Three20.xcodeproj/project.pbxproj
@@ -20,6 +20,20 @@
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
+ 18C011EC13D5EE01006DFF7A /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 6EE7389D1184ADB400A35176 /* Three20Network.xcodeproj */;
+ proxyType = 2;
+ remoteGlobalIDString = 662D81EF12630516005851C2;
+ remoteInfo = "Three20Network-Xcode3.2.5";
+ };
+ 18C011EE13D5EE01006DFF7A /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 6EE7389D1184ADB400A35176 /* Three20Network.xcodeproj */;
+ proxyType = 2;
+ remoteGlobalIDString = 662D81B2126304EB005851C2;
+ remoteInfo = "Three20NetworkUnitTests-Xcode3.2.5";
+ };
66FC2E291265264C00F56B19 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
@@ -362,7 +376,9 @@
isa = PBXGroup;
children = (
6EE738A31184ADB400A35176 /* libThree20Network.a */,
+ 18C011ED13D5EE01006DFF7A /* libThree20Network-Xcode3.2.5.a */,
6EE738A51184ADB400A35176 /* NetworkUnitTests.octest */,
+ 18C011EF13D5EE01006DFF7A /* NetworkUnitTests-Xcode3.2.5.octest */,
);
name = Products;
sourceTree = "<group>";
@@ -487,6 +503,20 @@
/* End PBXProject section */
/* Begin PBXReferenceProxy section */
+ 18C011ED13D5EE01006DFF7A /* libThree20Network-Xcode3.2.5.a */ = {
+ isa = PBXReferenceProxy;
+ fileType = archive.ar;
+ path = "libThree20Network-Xcode3.2.5.a";
+ remoteRef = 18C011EC13D5EE01006DFF7A /* PBXContainerItemProxy */;
+ sourceTree = BUILT_PRODUCTS_DIR;
+ };
+ 18C011EF13D5EE01006DFF7A /* NetworkUnitTests-Xcode3.2.5.octest */ = {
+ isa = PBXReferenceProxy;
+ fileType = wrapper.cfbundle;
+ path = "NetworkUnitTests-Xcode3.2.5.octest";
+ remoteRef = 18C011EE13D5EE01006DFF7A /* PBXContainerItemProxy */;
+ sourceTree = BUILT_PRODUCTS_DIR;
+ };
6E6454A71184D42800F08CB1 /* libThree20Style.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
View
4 src/Three20Core/Sources/Three20Version.m
@@ -18,6 +18,6 @@
/*! \mainpage Three20 API Documentation
*
- * Generated from Three20 Release <a href="http://three20.info/roadmap/1.0.5">1.0.5</a>.
+ * Generated from Three20 Release <a href="http://three20.info/roadmap/1.0.7">1.0.7</a>.
*/
-NSString* const Three20Version = @"1.0.6.2";
+NSString* const Three20Version = @"1.0.7";
View
3  src/Three20Network/Sources/TTURLCache.m
@@ -264,8 +264,7 @@ - (UIImage*)loadImageFromBundle:(NSString*)URL {
///////////////////////////////////////////////////////////////////////////////////////////////////
- (UIImage*)loadImageFromDocuments:(NSString*)URL {
NSString* path = TTPathForDocumentsResource([URL substringFromIndex:12]);
- NSData* data = [NSData dataWithContentsOfFile:path];
- return [UIImage imageWithData:data];
+ return [UIImage imageWithContentsOfFile:path];
}
View
7 src/Three20Network/Sources/TTURLImageResponse.m
@@ -61,12 +61,13 @@ - (NSError*)request:(TTURLRequest*)request processResponse:(NSHTTPURLResponse*)r
// TODO(jverkoey Feb 10, 2010): This logic doesn't entirely make sense. Why don't we just store
// the data in the cache if there was a cache miss, and then just retain the image data we
// downloaded? This needs to be tested in production.
- UIImage* image = [[TTURLCache sharedCache] imageForURL:request.urlPath fromDisk:NO];
-
+ UIImage* image = nil;
+ if(!(request.cachePolicy | TTURLRequestCachePolicyNoCache)) {
+ image = [[TTURLCache sharedCache] imageForURL:request.urlPath fromDisk:NO];
+ }
if (nil == image) {
image = [UIImage imageWithData:data];
}
-
if (nil != image) {
if (!request.respondedFromCache) {
// XXXjoe Working on option to scale down really large images to a smaller size to save memory
View
58 src/Three20Network/Three20Network.xcodeproj/project.pbxproj
@@ -42,7 +42,6 @@
664B29C212848AAD0008D569 /* TTErrorCodes.m in Sources */ = {isa = PBXBuildFile; fileRef = 664B29C012848AAD0008D569 /* TTErrorCodes.m */; };
664B29C312848AAD0008D569 /* TTErrorCodes.m in Sources */ = {isa = PBXBuildFile; fileRef = 664B29C012848AAD0008D569 /* TTErrorCodes.m */; };
66C16B1C1263059A00A7825A /* libThree20Network-Xcode3.2.5.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 662D81EF12630516005851C2 /* libThree20Network-Xcode3.2.5.a */; };
- 66C16B21126305AB00A7825A /* libThree20Core-Xcode3.2.5.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 66C16AC31263027400A7825A /* libThree20Core-Xcode3.2.5.a */; };
66F955B0126662E300BEF6F0 /* NetworkURLCacheTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 66F955AF126662E300BEF6F0 /* NetworkURLCacheTests.m */; };
66F955B1126662E300BEF6F0 /* NetworkURLCacheTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 66F955AF126662E300BEF6F0 /* NetworkURLCacheTests.m */; };
66F955BA1266647A00BEF6F0 /* both.png in Resources */ = {isa = PBXBuildFile; fileRef = 66F955B71266647A00BEF6F0 /* both.png */; };
@@ -87,34 +86,6 @@
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
- 662D824C12630805005851C2 /* PBXContainerItemProxy */ = {
- isa = PBXContainerItemProxy;
- containerPortal = 6EE7366611849C5800A35176 /* Three20Core.xcodeproj */;
- proxyType = 1;
- remoteGlobalIDString = 664961541262EE5000C2C80E;
- remoteInfo = "UnitTests-Xcode3.2.5";
- };
- 662D82E012639FCA005851C2 /* PBXContainerItemProxy */ = {
- isa = PBXContainerItemProxy;
- containerPortal = 6EE7366611849C5800A35176 /* Three20Core.xcodeproj */;
- proxyType = 1;
- remoteGlobalIDString = 664961541262EE5000C2C80E;
- remoteInfo = "UnitTests-Xcode3.2.5";
- };
- 66C16AC21263027400A7825A /* PBXContainerItemProxy */ = {
- isa = PBXContainerItemProxy;
- containerPortal = 6EE7366611849C5800A35176 /* Three20Core.xcodeproj */;
- proxyType = 2;
- remoteGlobalIDString = 6650CAA21262F6E2003FF804;
- remoteInfo = "Three20Core-Xcode3.2.5";
- };
- 66C16AC61263027400A7825A /* PBXContainerItemProxy */ = {
- isa = PBXContainerItemProxy;
- containerPortal = 6EE7366611849C5800A35176 /* Three20Core.xcodeproj */;
- proxyType = 2;
- remoteGlobalIDString = 664961641262EE5000C2C80E;
- remoteInfo = "UnitTests-Xcode3.2.5";
- };
66C16B26126305F500A7825A /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
@@ -214,7 +185,6 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
- 66C16B21126305AB00A7825A /* libThree20Core-Xcode3.2.5.a in Frameworks */,
66C16B1C1263059A00A7825A /* libThree20Network-Xcode3.2.5.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -439,9 +409,7 @@
isa = PBXGroup;
children = (
6EE7366C11849C5800A35176 /* libThree20Core.a */,
- 66C16AC31263027400A7825A /* libThree20Core-Xcode3.2.5.a */,
6EE7366E11849C5800A35176 /* CoreUnitTests.octest */,
- 66C16AC71263027400A7825A /* CoreUnitTests-Xcode3.2.5.octest */,
);
name = Products;
sourceTree = "<group>";
@@ -522,7 +490,6 @@
buildRules = (
);
dependencies = (
- 662D824D12630805005851C2 /* PBXTargetDependency */,
66C16B27126305F500A7825A /* PBXTargetDependency */,
);
name = "Three20NetworkUnitTests-Xcode3.2.5";
@@ -542,7 +509,6 @@
buildRules = (
);
dependencies = (
- 662D82E112639FCA005851C2 /* PBXTargetDependency */,
);
name = "Three20Network-Xcode3.2.5";
productName = Three20;
@@ -625,20 +591,6 @@
/* End PBXProject section */
/* Begin PBXReferenceProxy section */
- 66C16AC31263027400A7825A /* libThree20Core-Xcode3.2.5.a */ = {
- isa = PBXReferenceProxy;
- fileType = archive.ar;
- path = "libThree20Core-Xcode3.2.5.a";
- remoteRef = 66C16AC21263027400A7825A /* PBXContainerItemProxy */;
- sourceTree = BUILT_PRODUCTS_DIR;
- };
- 66C16AC71263027400A7825A /* CoreUnitTests-Xcode3.2.5.octest */ = {
- isa = PBXReferenceProxy;
- fileType = wrapper.cfbundle;
- path = "CoreUnitTests-Xcode3.2.5.octest";
- remoteRef = 66C16AC61263027400A7825A /* PBXContainerItemProxy */;
- sourceTree = BUILT_PRODUCTS_DIR;
- };
6EE7366C11849C5800A35176 /* libThree20Core.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
@@ -798,16 +750,6 @@
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
- 662D824D12630805005851C2 /* PBXTargetDependency */ = {
- isa = PBXTargetDependency;
- name = "UnitTests-Xcode3.2.5";
- targetProxy = 662D824C12630805005851C2 /* PBXContainerItemProxy */;
- };
- 662D82E112639FCA005851C2 /* PBXTargetDependency */ = {
- isa = PBXTargetDependency;
- name = "UnitTests-Xcode3.2.5";
- targetProxy = 662D82E012639FCA005851C2 /* PBXContainerItemProxy */;
- };
66C16B27126305F500A7825A /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 662D81C912630516005851C2 /* Three20Network-Xcode3.2.5 */;
View
5 src/Three20UI/Headers/TTImageView.h
@@ -77,6 +77,11 @@
@property (nonatomic, assign) id<TTImageViewDelegate> delegate;
/**
+ * The TTURLRequest requester used to load this image.
+ */
+@property (nonatomic, readonly) TTURLRequest* request;
+
+/**
* Cancel any pending request, remove the image, and redraw the view.
*/
- (void)unsetImage;
View
7 src/Three20UI/Headers/TTImageViewDelegate.h
@@ -38,4 +38,11 @@
*/
- (void)imageView:(TTImageView*)imageView didFailLoadWithError:(NSError*)error;
+/**
+ * Called before the image view send a network request.
+ * At this point we have the opportunity to configure the requester
+ * with some custom options (to use ETAGs, for example).
+ */
+- (void)imageView:(TTImageView*)imageView willSendARequest:(TTURLRequest*)requester;
+
@end
View
21 src/Three20UI/Headers/TTLauncherPersistenceMode.h
@@ -0,0 +1,21 @@
+//
+// Copyright 2009-2011 Facebook
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License 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.
+//
+
+typedef enum {
+ TTLauncherPersistenceModeNone, // no persistence
+ TTLauncherPersistenceModeAll, // persists all pages & buttons
+} TTLauncherPersistenceMode;
+
View
35 src/Three20UI/Headers/TTLauncherView.h
@@ -17,6 +17,9 @@
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
+// UI
+#import "Three20UI/TTLauncherPersistenceMode.h"
+
@protocol TTLauncherViewDelegate;
@class TTPageControl;
@class TTLauncherButton;
@@ -51,6 +54,9 @@
BOOL _springing;
BOOL _editable;
+ NSString* _persistenceKey;
+ TTLauncherPersistenceMode _persistenceMode;
+
id<TTLauncherViewDelegate> _delegate;
}
@@ -71,6 +77,20 @@
@property (nonatomic, readonly) BOOL editing;
@property (nonatomic, assign) BOOL editable;
+/**
+ * The key to use for storing persistence information.
+ *
+ * @default launcherViewPages
+ */
+@property (nonatomic, copy) NSString* persistenceKey;
+
+/**
+ * How buttons are automatically persisted on termination and restored on launch.
+ *
+ * @default TTLauncherPersistenceModeNone
+ */
+@property (nonatomic) TTLauncherPersistenceMode persistenceMode;
+
- (void)addItem:(TTLauncherItem*)item animated:(BOOL)animated;
- (void)removeItem:(TTLauncherItem*)item animated:(BOOL)animated;
@@ -86,6 +106,21 @@
- (void)endEditing;
/**
+ * Persists all pages & buttons to user defaults.
+ */
+- (void)persistLauncherItems;
+
+/**
+ * Restores all pages & button from user defaults and returns if sucess
+ */
+- (BOOL)restoreLauncherItems;
+
+/**
+ * Erases all data stored in user defaults.
+ */
+- (void)resetDefaults;
+
+/**
* Dims the launcher view except for a transparent circle around the given item. The given text
* will also be shown center-aligned below or above the circle, as appropriate. The item can be
* tapped while the overlay is up; tapping anywhere else on the overlay simply dismisses the
View
47 src/Three20UI/Headers/TTScrollView.h
@@ -77,6 +77,11 @@
NSUInteger _touchCount;
CGFloat _overshoot;
+ // Scroll animation.
+ // Set the engine to animate the next relayout.
+ BOOL _nextLayoutAnimated;
+ NSTimeInterval _centerPageAnimationDuration;
+
// The first touch in this view.
UITouch* _touch1;
@@ -91,11 +96,23 @@
}
/**
- * The current page index.
+ * Retrieve or set the current page index.
+ * If you inform anew value for this page, the Scroll View will
+ * load this page on the center of the view.
+ * This operatin is not animated, you should use <tt>setCenterPageIndex:animated:</tt>
+ * if you want to control the animation.
*/
@property (nonatomic) NSInteger centerPageIndex;
/**
+ * Set the duration for the animation performed by the <tt>setCenterPageIndex:animated:</tt>
+ * method.
+ *
+ * @default Is the value setted on the <tt>TT_TRANSITION_DURATION</tt> constant.
+ */
+@property (assign) NSTimeInterval centerPageAnimationDuration;
+
+/**
* Whether or not the current page is zoomed.
*/
@property (nonatomic, readonly) BOOL zoomed;
@@ -105,10 +122,19 @@
* out. (read-only)
*
* The value of this property is YES if user is making a zoom gesture, otherwise it is NO
- *
*/
@property (nonatomic, readonly) BOOL zooming;
+/**
+ * A Boolean value that indicates whether the user is scrolling the
+ * view with his finger. If the scroll is scrolling by animation this
+ * value is NO. (read-only)
+ */
+@property (readonly) BOOL isDragging;
+
+/**
+ * The scroller is performing an "hold" action.
+ */
@property (nonatomic, readonly) BOOL holding;
/**
@@ -118,21 +144,29 @@
@property (nonatomic,readonly,getter=isDecelerating) BOOL decelerating;
/**
+ * A Boolean value that determines whether scrolling is enabled.
+ *
* @default YES
*/
@property (nonatomic) BOOL scrollEnabled;
-/**
+/*
+ * A Boolean value that determines whether zooming is enabled.
+ *
* @default YES
*/
@property (nonatomic) BOOL zoomEnabled;
/**
+ * A Boolean value that determines whether rotation is enabled.
+ *
* @default YES
*/
@property (nonatomic) BOOL rotateEnabled;
/**
+ * A <tt>CGFloat</tt> value that determines the gap between the pages.
+ *
* @default 40
*/
@property (nonatomic) CGFloat pageSpacing;
@@ -215,6 +249,13 @@
- (void)zoomToDistance:(CGFloat)distance;
/**
+ * Set the current center page and optionally animate the transition.
+ * <b>Only animate if the distance between the actual page and the informed
+ * is one. Example: If is one page 1 and you inform page 3, will not animate.</b>
+ */
+- (void)setCenterPageIndex:(NSInteger)centerPageIndex animated:(BOOL)animated;
+
+/**
* Cancels any active touches and resets everything to an untouched state.
*/
- (void)cancelTouches;
View
3  src/Three20UI/Headers/TTTableView.h
@@ -49,4 +49,7 @@
- (void)tableView:(UITableView*)tableView touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event;
- (void)tableView:(UITableView*)tableView touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event;
+@optional
+- (void)tableView:(UITableView*)tableView touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event;
+
@end
View
2  src/Three20UI/Headers/TTTableViewController.h
@@ -28,8 +28,6 @@
UIView* _errorView;
UIView* _emptyView;
- NSTimer* _bannerTimer;
-
UIView* _menuView;
UITableViewCell* _menuCell;
View
2  src/Three20UI/Headers/Three20UI.h
@@ -46,9 +46,11 @@
#import "Three20UI/TTScrollViewDelegate.h"
#import "Three20UI/TTScrollViewDataSource.h"
+// Launcher
#import "Three20UI/TTLauncherView.h"
#import "Three20UI/TTLauncherViewDelegate.h"
#import "Three20UI/TTLauncherItem.h"
+#import "Three20UI/TTLauncherPersistenceMode.h"
#import "Three20UI/TTLabel.h"
#import "Three20UI/TTStyledTextLabel.h"
View
6 src/Three20UI/Sources/TTImageView.m
@@ -44,6 +44,7 @@ @implementation TTImageView
@synthesize image = _image;
@synthesize defaultImage = _defaultImage;
@synthesize autoresizesToImage = _autoresizesToImage;
+@synthesize request = _request;
@synthesize delegate = _delegate;
@@ -209,6 +210,11 @@ - (void)reload {
TTURLRequest* request = [TTURLRequest requestWithURL:_urlPath delegate:self];
request.response = [[[TTURLImageResponse alloc] init] autorelease];
+ // Give the delegate one chance to configure the requester.
+ if ([_delegate respondsToSelector:@selector(imageView:willSendARequest:)]) {
+ [_delegate imageView:self willSendARequest:request];
+ }
+
if (![request send]) {
// Put the default image in place while waiting for the request to load
if (_defaultImage && nil == self.image) {
View
45 src/Three20UI/Sources/TTLauncherView.m
@@ -23,6 +23,7 @@
#import "Three20UI/TTPageControl.h"
#import "Three20UI/UIViewAdditions.h"
+
// UI (private)
#import "Three20UI/private/TTLauncherScrollView.h"
#import "Three20UI/private/TTLauncherHighlightView.h"
@@ -69,6 +70,8 @@ @implementation TTLauncherView
@synthesize editing = _editing;
@synthesize delegate = _delegate;
@synthesize editable = _editable;
+@synthesize persistenceMode = _persistenceMode;
+@synthesize persistenceKey = _persistenceKey;
///////////////////////////////////////////////////////////////////////////////////////////////////
- (id)initWithFrame:(CGRect)frame {
@@ -99,6 +102,9 @@ - (id)initWithFrame:(CGRect)frame {
self.autoresizesSubviews = YES;
self.columnCount = kDefaultColumnCount;
self.editable = YES;
+ self.persistenceKey = @"launcherViewPages";
+ self.persistenceMode = TTLauncherPersistenceModeNone;
+
}
return self;
@@ -985,11 +991,50 @@ - (void)endEditing {
[self layoutButtons];
+ if (self.persistenceMode == TTLauncherPersistenceModeAll) {
+ [self persistLauncherItems];
+ }
+
if ([_delegate respondsToSelector:@selector(launcherViewDidEndEditing:)]) {
[_delegate launcherViewDidEndEditing:self];
}
}
+///////////////////////////////////////////////////////////////////////////////////////////////////
+- (void)persistLauncherItems {
+ NSData* pagesData = [NSKeyedArchiver archivedDataWithRootObject:self.pages];
+ [[NSUserDefaults standardUserDefaults] setValue:pagesData forKey:self.persistenceKey];
+}
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+- (BOOL)restoreLauncherItems {
+ if (self.persistenceMode == TTLauncherPersistenceModeAll) {
+ NSData* pagesData = [[NSUserDefaults standardUserDefaults] objectForKey:self.persistenceKey];
+
+ NSObject* pages;
+ if (pagesData!=nil) {
+ pages = [NSKeyedUnarchiver unarchiveObjectWithData:pagesData];
+ }
+
+ if (pagesData!=nil && pages!=nil && [pages isKindOfClass:[NSArray class]]) {
+ self.pages = (NSArray*)pages;
+ return YES;
+ }
+ }
+
+ return NO;
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+- (void)resetDefaults {
+ NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
+
+ [defaults removeObjectForKey:_persistenceKey];
+ [defaults synchronize];
+}
+
+
///////////////////////////////////////////////////////////////////////////////////////////////////
- (void)beginHighlightItem:(TTLauncherItem*)item withText:(NSString*)text {
View
1  src/Three20UI/Sources/TTModelViewController.m
@@ -210,6 +210,7 @@ - (void)viewWillAppear:(BOOL)animated {
- (void)didReceiveMemoryWarning {
if (_hasViewAppeared && !_isViewAppearing) {
[super didReceiveMemoryWarning];
+ [self resetViewStates];
[self refresh];
} else {
View
78 src/Three20UI/Sources/TTScrollView.m
@@ -64,6 +64,10 @@ @implementation TTScrollView
@synthesize zoomScale = _zoomScale;
@synthesize zooming = _executingZoomGesture;
+@synthesize isDragging = _dragging;
+
+@synthesize centerPageAnimationDuration = _centerPageAnimationDuration;
+
///////////////////////////////////////////////////////////////////////////////////////////////////
- (id)initWithFrame:(CGRect)frame {
@@ -84,6 +88,7 @@ - (id)initWithFrame:(CGRect)frame {
_orientation = UIDeviceOrientationPortrait;
_decelerationRate = 0.9; // Inertia, how faster slow the residual movement.
_maximumZoomScale = 4.0; // Maximum zoom scale default value.
+ _centerPageAnimationDuration = TT_TRANSITION_DURATION;
for (NSInteger i = 0; i < _maxPages; ++i) {
[_pages addObject:[NSNull null]];
@@ -485,7 +490,7 @@ - (void)adjustPageEdgesForPageAtIndex:(NSInteger)pageIndex {
///////////////////////////////////////////////////////////////////////////////////////////////////
-- (void)moveToPageAtIndex:(NSInteger)pageIndex resetEdges:(BOOL)resetEdges {
+- (void)moveToPageAtIndex:(NSInteger)pageIndex resetEdges:(BOOL)resetEdges animated:(BOOL)animated {
if (resetEdges) {
_pageEdges = _pageStartEdges = UIEdgeInsetsZero;
_zooming = NO;
@@ -521,13 +526,22 @@ - (void)moveToPageAtIndex:(NSInteger)pageIndex resetEdges:(BOOL)resetEdges {
_pageArrayIndex = [self arrayIndexForPageIndex:pageIndex relativeToIndex:_centerPageIndex];
_centerPageIndex = pageIndex;
[self setNeedsLayout];
+
+ // Should animate the next relayout?
+ _nextLayoutAnimated = animated;
}
}
+///////////////////////////////////////////////////////////////////////////////////////////////////
+- (void)moveToPageAtIndex:(NSInteger)pageIndex resetEdges:(BOOL)resetEdges {
+ [self moveToPageAtIndex:pageIndex resetEdges:resetEdges animated:NO];
+}
///////////////////////////////////////////////////////////////////////////////////////////////////
- (void)layoutPage {
UIView* page = [self pageAtIndex:_centerPageIndex create:YES];
+
+ // Layout.
if (nil != page) {
CGAffineTransform rotation = TTRotateTransformForOrientation(_orientation);
CGPoint offset = [self offsetForOrientation:_pageEdges.left y:_pageEdges.top];
@@ -538,13 +552,37 @@ - (void)layoutPage {
page.transform = [self rotateTransform:CGAffineTransformScale(
CGAffineTransformMakeTranslation(offset.x, offset.y), zoom, zoom)];
+
+ // Should animate the relayout?
+ if ( _nextLayoutAnimated ) {
+ [UIView beginAnimations:@"pageAnimation" context:nil];
+ [UIView setAnimationDuration:_centerPageAnimationDuration];
+ }
page.frame = CGRectMake(offset.x + frame.origin.x*zoom, offset.y + frame.origin.y*zoom,
frame.size.width*zoom, frame.size.height*zoom);
+ // Should animate the relayout?
+ if ( _nextLayoutAnimated ) {
+ [UIView commitAnimations];
+ }
+
} else {
+
page.transform = rotation;
+
+ // Should animate the relayout?
+ if ( _nextLayoutAnimated ) {
+ [UIView beginAnimations:@"pageAnimation" context:nil];
+ [UIView setAnimationDuration:_centerPageAnimationDuration];
+ }
+
page.frame = CGRectMake(offset.x + frame.origin.x, offset.y + frame.origin.y,
frame.size.width, frame.size.height);
+
+ // Should animate the relayout?
+ if ( _nextLayoutAnimated ) {
+ [UIView commitAnimations];
+ }
}
}
}
@@ -559,6 +597,9 @@ - (void)layoutAdjacentPages {
NSInteger minPageIndex = _centerPageIndex - kOffscreenPages;
NSInteger maxPageIndex = _centerPageIndex + kOffscreenPages;
+ // Determine the direction.
+ BOOL isGoingLeft = _centerPageIndex < _visiblePageIndex;
+
CGRect centerFrame = [self frameOfPageAtIndex:_centerPageIndex];
CGFloat centerPageOverflow = [self overflowForFrame:centerFrame] * self.zoomFactor;
@@ -576,9 +617,21 @@ - (void)layoutAdjacentPages {
CGPoint offset = [self offsetForOrientation:x y:0];
page.transform = rotation;
+
+ // Should animate the the "going right" relayout?
+ if ( _nextLayoutAnimated && !isGoingLeft ) {
+ [UIView beginAnimations:@"pageAnimation" context:nil];
+ [UIView setAnimationDuration:_centerPageAnimationDuration];
+ }
+
page.frame = CGRectMake(offset.x + frame.origin.x, offset.y + frame.origin.y,
frame.size.width, frame.size.height);
page.hidden = pinched;
+
+ // Should animate the the "going right" relayout?
+ if ( _nextLayoutAnimated && !isGoingLeft) {
+ [UIView commitAnimations];
+ }
}
}
@@ -597,9 +650,22 @@ - (void)layoutAdjacentPages {
CGPoint offset = [self offsetForOrientation:x y:0];
page.transform = rotation;
+
+ // Should animate the "going left" relayout?
+ if ( _nextLayoutAnimated && isGoingLeft ) {
+ [UIView beginAnimations:@"pageAnimation" context:nil];
+ [UIView setAnimationDuration:_centerPageAnimationDuration];
+ }
+
page.frame = CGRectMake(offset.x + frame.origin.x, offset.y + frame.origin.y,
frame.size.width, frame.size.height);
page.hidden = pinched;
+
+ // Should animate the "going left" relayout?
+ if ( _nextLayoutAnimated && isGoingLeft) {
+ [UIView commitAnimations];
+ }
+
}
}
}
@@ -1541,6 +1607,9 @@ - (void)layoutSubviews {
_visiblePageIndex = _centerPageIndex;
[_delegate scrollView:self didMoveToPageAtIndex:_centerPageIndex];
}
+
+ // Reset the layout animated flag.
+ _nextLayoutAnimated = NO;
}
@@ -1588,6 +1657,13 @@ - (void)setDataSource:(id<TTScrollViewDataSource>)dataSource {
[self reloadData];
}
+///////////////////////////////////////////////////////////////////////////////////////////////////
+- (void)setCenterPageIndex:(NSInteger)centerPageIndex animated:(BOOL)animated {
+ // TODO: Fix limitation, for now only animate the distance of one page .. :(
+ animated = ( _centerPageIndex-centerPageIndex >= -1 || _centerPageIndex+centerPageIndex <= 1 );
+
+ [self moveToPageAtIndex:centerPageIndex resetEdges:!_touchCount animated:animated];
+}
///////////////////////////////////////////////////////////////////////////////////////////////////
- (void)setCenterPageIndex:(NSInteger)centerPageIndex {
View
9 src/Three20UI/Sources/TTTableView.m
@@ -102,6 +102,15 @@ - (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event {
// }
}
+///////////////////////////////////////////////////////////////////////////////////////////////////
+- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
+ [super touchesMoved:touches withEvent:event];
+
+ if ([self.delegate respondsToSelector:@selector(tableView:touchesMoved:withEvent:)]) {
+ id<TTTableViewDelegate> delegate = (id<TTTableViewDelegate>)self.delegate;
+ [delegate tableView:self touchesMoved:touches withEvent:event];
+ }
+}
///////////////////////////////////////////////////////////////////////////////////////////////////
- (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event {
View
16 src/Three20UI/Sources/TTTableViewController.m
@@ -229,6 +229,15 @@ - (void)hideMenuAnimationDidStop:(NSString*)animationID finished:(NSNumber*)fini
- (void)loadView {
[super loadView];
self.tableView;
+
+ // If this view was unloaded and is now being reloaded, and it was previously
+ // showing a table banner, then redisplay that banner now.
+ if (_tableBannerView) {
+ UIView* savedTableBannerView = [_tableBannerView retain];
+ [self setTableBannerView:nil animated:NO];
+ [self setTableBannerView:savedTableBannerView animated:NO];
+ [savedTableBannerView release];
+ }
}
@@ -239,8 +248,6 @@ - (void)viewDidUnload {
_tableView.dataSource = nil;
TT_RELEASE_SAFELY(_tableDelegate);
TT_RELEASE_SAFELY(_tableView);
- [_tableBannerView removeFromSuperview];
- TT_RELEASE_SAFELY(_tableBannerView);
[_tableOverlayView removeFromSuperview];
TT_RELEASE_SAFELY(_tableOverlayView);
[_loadingView removeFromSuperview];
@@ -253,6 +260,9 @@ - (void)viewDidUnload {
TT_RELEASE_SAFELY(_menuView);
[_menuCell removeFromSuperview];
TT_RELEASE_SAFELY(_menuCell);
+
+ // Do not release _tableBannerView, because we have no way to recreate it on demand if
+ // this view gets reloaded.
}
@@ -687,7 +697,6 @@ - (void)setTableBannerView:(UIView*)tableBannerView {
///////////////////////////////////////////////////////////////////////////////////////////////////
- (void)setTableBannerView:(UIView*)tableBannerView animated:(BOOL)animated {
- TT_INVALIDATE_TIMER(_bannerTimer);
if (tableBannerView != _tableBannerView) {
if (_tableBannerView) {
if (animated) {
@@ -705,7 +714,6 @@ - (void)setTableBannerView:(UIView*)tableBannerView animated:(BOOL)animated {
self.tableView.contentInset = UIEdgeInsetsMake(0, 0, TTSTYLEVAR(tableBannerViewHeight), 0);
self.tableView.scrollIndicatorInsets = self.tableView.contentInset;
_tableBannerView.frame = [self rectForBannerView];
- _tableBannerView.userInteractionEnabled = NO;
_tableBannerView.autoresizingMask = (UIViewAutoresizingFlexibleWidth
| UIViewAutoresizingFlexibleTopMargin);
[self addSubviewOverTableView:_tableBannerView];
View
4 src/Three20UI/Three20UI.xcodeproj/project.pbxproj
@@ -17,6 +17,7 @@
66F2E85712D426AF006FB485 /* TTTableFooterInfiniteScrollView.m in Sources */ = {isa = PBXBuildFile; fileRef = 66F2E85512D426AF006FB485 /* TTTableFooterInfiniteScrollView.m */; };
66F2E85F12D426DA006FB485 /* TTTableViewNetworkEnabledDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 66F2E85D12D426DA006FB485 /* TTTableViewNetworkEnabledDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; };
66F2E86512D426EF006FB485 /* TTTableViewNetworkEnabledDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 66F2E86312D426EF006FB485 /* TTTableViewNetworkEnabledDelegate.m */; };
+ 6DB1E37D13CA885B00A72466 /* TTLauncherPersistenceMode.h in Headers */ = {isa = PBXBuildFile; fileRef = 6DB1E37C13CA885B00A72466 /* TTLauncherPersistenceMode.h */; settings = {ATTRIBUTES = (Public, ); }; };
6E60820111B0C31400C93CD4 /* TTNavigationController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6E6081FF11B0C31400C93CD4 /* TTNavigationController.m */; };
6E60820311B0C32600C93CD4 /* TTNavigationController.h in Headers */ = {isa = PBXBuildFile; fileRef = 6E60820211B0C32600C93CD4 /* TTNavigationController.h */; settings = {ATTRIBUTES = (Public, ); }; };
6E6454741184D2CD00F08CB1 /* Three20UI.h in Headers */ = {isa = PBXBuildFile; fileRef = 6E6454731184D2CD00F08CB1 /* Three20UI.h */; settings = {ATTRIBUTES = (Public, ); }; };
@@ -443,6 +444,7 @@
66F2E85512D426AF006FB485 /* TTTableFooterInfiniteScrollView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TTTableFooterInfiniteScrollView.m; path = Sources/TTTableFooterInfiniteScrollView.m; sourceTree = "<group>"; };
66F2E85D12D426DA006FB485 /* TTTableViewNetworkEnabledDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TTTableViewNetworkEnabledDelegate.h; path = Headers/TTTableViewNetworkEnabledDelegate.h; sourceTree = "<group>"; };
66F2E86312D426EF006FB485 /* TTTableViewNetworkEnabledDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TTTableViewNetworkEnabledDelegate.m; path = Sources/TTTableViewNetworkEnabledDelegate.m; sourceTree = "<group>"; };
+ 6DB1E37C13CA885B00A72466 /* TTLauncherPersistenceMode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TTLauncherPersistenceMode.h; path = Headers/TTLauncherPersistenceMode.h; sourceTree = "<group>"; };
6E6081FF11B0C31400C93CD4 /* TTNavigationController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TTNavigationController.m; path = Sources/TTNavigationController.m; sourceTree = "<group>"; };
6E60820211B0C32600C93CD4 /* TTNavigationController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TTNavigationController.h; path = Headers/TTNavigationController.h; sourceTree = "<group>"; };
6E64543D1184BE1B00F08CB1 /* Project.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Project.xcconfig; path = Configurations/Project.xcconfig; sourceTree = "<group>"; };
@@ -1561,6 +1563,7 @@
6E64583E1184E26500F08CB1 /* Launcher */ = {
isa = PBXGroup;
children = (
+ 6DB1E37C13CA885B00A72466 /* TTLauncherPersistenceMode.h */,
6E6454D61184D4C500F08CB1 /* TTLauncherView.h */,
6E6456121184D4DA00F08CB1 /* TTLauncherView.m */,
6E6454D71184D4C500F08CB1 /* TTLauncherViewDelegate.h */,
@@ -1859,6 +1862,7 @@
666E18F51294543F001C1D97 /* TTSplitViewController.h in Headers */,
66F2E85412D426A5006FB485 /* TTTableFooterInfiniteScrollView.h in Headers */,
66F2E85F12D426DA006FB485 /* TTTableViewNetworkEnabledDelegate.h in Headers */,
+ 6DB1E37D13CA885B00A72466 /* TTLauncherPersistenceMode.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
View
26 src/Three20UICommon/Sources/UIViewControllerAdditions.m
@@ -299,16 +299,22 @@ - (void)delayDidEnd {
///////////////////////////////////////////////////////////////////////////////////////////////////
- (void)showBars:(BOOL)show animated:(BOOL)animated {
-#ifdef __IPHONE_3_2
- if ([[UIApplication sharedApplication]
- respondsToSelector:@selector(setStatusBarHidden:withAnimation:)])
- [[UIApplication sharedApplication] setStatusBarHidden:!show
- withAnimation:(animated
- ? UIStatusBarAnimationFade
- : UIStatusBarAnimationNone)];
- else
-#endif
- [[UIApplication sharedApplication] setStatusBarHidden:!show animated:animated];
+
+ BOOL statusBarHidden = [[[[NSBundle mainBundle] infoDictionary]
+ objectForKey:@"UIStatusBarHidden"] boolValue];
+
+ if (!statusBarHidden) {
+ #ifdef __IPHONE_3_2
+ if ([[UIApplication sharedApplication]
+ respondsToSelector:@selector(setStatusBarHidden:withAnimation:)])
+ [[UIApplication sharedApplication] setStatusBarHidden:!show
+ withAnimation:(animated
+ ? UIStatusBarAnimationFade
+ :UIStatusBarAnimationNone)];
+ else
+ #endif
+ [[UIApplication sharedApplication] setStatusBarHidden:!show animated:animated];
+ }
if (animated) {
[UIView beginAnimations:nil context:NULL];
View
1  src/common/Configurations/Library.xcconfig
@@ -38,6 +38,7 @@ IPHONEOS_DEPLOYMENT_TARGET = 3.0
SDKROOT = iphoneos
// Required for older iOS devices (iPhone 3G)
ARCHS = $(ARCHS_STANDARD_32_BIT)
+ARCHS[sdk=iphoneos*] = armv6 armv7
// Linker Flags
View
1  src/common/Configurations/Project.xcconfig
@@ -21,3 +21,4 @@ IPHONEOS_DEPLOYMENT_TARGET = 3.0
SDKROOT = iphoneos
// Required for older iOS devices (iPhone 3G)
ARCHS = $(ARCHS_STANDARD_32_BIT)
+ARCHS[sdk=iphoneos*] = armv6 armv7
View
38 src/extThree20CSSStyle/Headers/TTCSSApplyProtocol.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2011 - SEQOY.org and Paulo Oliveira ( http://www.seqoy.org )
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License 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 "extThree20CSSStyle/TTCSSRuleSet.h"
+
+/**
+ * TTCSSApplyProtocol defines an common interface to classes that style itself
+ * using CSS readed properties. This classes should implement this protocol
+ * and his appropriate methods.
+ */
+@protocol TTCSSApplyProtocol
+@required
+
+/**
+ * Receive an Set of Rules from some CSS selector to apply. This method
+ * receive an TTCSSRuleSet with all properties ready to be set.
+ */
+-(void)applyCssRules:(TTCSSRuleSet*)anRuleSet;
+
+/**
+ * Set a CSS stylesheet selector.
+ */
+- (void)applyCssSelector:(NSString *)selector;
+
+@end
View
28 src/extThree20CSSStyle/Headers/TTCSSFunctions.h
@@ -0,0 +1,28 @@
+//
+// Copyright 2009-2011 Facebook
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License 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 <Foundation/Foundation.h>
+#import <UIKit/UIKit.h>
+
+/**
+ * Helper function to convert an CSS readed colors to UIColor.
+ */
+UIColor* TTColorFromCssValues( NSArray* cssValues );
+
+/**
+ * Helper function to convert an CSS readed size to CGFloat.
+ */
+CGFloat TTValueFromCssValues( NSString* value );
View
37 src/extThree20CSSStyle/Headers/TTCSSGlobalStyle.h
@@ -20,26 +20,45 @@
#define TTCSSSTYLESHEET ([[TTDefaultCSSStyleSheet globalCSSStyleSheet] styleSheet])
#define TTCSS_color(_SELECTOR, _STATE) \
-([TTCSSSTYLESHEET colorWithCssSelector:_SELECTOR forState:_STATE])
+ ([TTCSSSTYLESHEET colorWithCssSelector:_SELECTOR forState:_STATE])
#define TTCSS_backgroundColor(_SELECTOR, _STATE) \
-([TTCSSSTYLESHEET backgroundColorWithCssSelector:_SELECTOR forState:_STATE])
+ ([TTCSSSTYLESHEET backgroundColorWithCssSelector:_SELECTOR forState:_STATE])
#define TTCSS_font(_SELECTOR, _STATE) \
-([TTCSSSTYLESHEET fontWithCssSelector:_SELECTOR forState:_STATE])
+ ([TTCSSSTYLESHEET fontWithCssSelector:_SELECTOR forState:_STATE])
#define TTCSS_shadowColor(_SELECTOR, _STATE) \
-([TTCSSSTYLESHEET textShadowColorWithCssSelector:_SELECTOR forState:_STATE])
+ ([TTCSSSTYLESHEET textShadowColorWithCssSelector:_SELECTOR forState:_STATE])
#define TTCSS_shadowOffset(_SELECTOR, _STATE) \
-([TTCSSSTYLESHEET textShadowOffsetWithCssSelector:_SELECTOR forState:_STATE])
+ ([TTCSSSTYLESHEET textShadowOffsetWithCssSelector:_SELECTOR forState:_STATE])
#define TTCSS_shadowRadius(_SELECTOR, _STATE) \
-([TTCSSSTYLESHEET textShadowRadiusWithCssSelector:_SELECTOR forState:_STATE])
+ ([TTCSSSTYLESHEET textShadowRadiusWithCssSelector:_SELECTOR forState:_STATE])
// _VARNAME must be one of: color, backgroundColor, font, shadowColor, shadowOffset, shadowRadius
#define TTCSSSTATE(_SELECTOR, _VARNAME, _STATE) \
-TTCSS_##_VARNAME(_SELECTOR, _STATE)
+ TTCSS_##_VARNAME(_SELECTOR, _STATE)
-#define TTCSS(_SELECTOR, _VARNAME) \
-TTCSSSTATE(_SELECTOR, _VARNAME, UIControlStateNormal)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Retrieve a Full CSS Rule (TTCSSRuleSet) for specified selector.
+ */
+#define TTCSSRule(selector) (TTCSSRuleSet*)[[TTDefaultCSSStyleSheet\
+ globalCSSStyleSheet] css:selector]
+
+/**
+ * Retrieve an value for a property of an Rule Set (TTCSSRuleSet) for specified selector.
+ */
+#define TTCSS(selector,property) [TTCSSRule(selector) property]
+
+/**
+ * Apply an CSS style to specified object.
+ * The object must conform with the TTCSSApplyProtocol.
+ */
+#define TTApplyCSS(selector,object) [[TTDefaultCSSStyleSheet globalCSSStyleSheet]\
+ applyCssFromSelector:selector\
+ toObject:object]
View
264 src/extThree20CSSStyle/Headers/TTCSSRuleSet.h
@@ -0,0 +1,264 @@
+//
+// Copyright 2009-2011 Facebook
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License 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 <Foundation/Foundation.h>
+#import <UIKit/UIKit.h>
+
+#import "TTCSSTextShadowModel.h"
+
+@interface TTCSSRuleSet : NSObject {
+ NSString *selector;
+
+ // Colors.
+ UIColor *color;
+ UIColor *background_color;
+
+ // Font properties.
+ NSString *font_family;
+ NSString *font_weight;
+ NSNumber *font_size;
+
+ // Alignment and Justification.
+ NSString *text_align;
+
+ // Text Shadow.
+ TTCSSTextShadowModel* text_shadow;
+ NSNumber* text_shadow_opacity;
+
+ // Background properties.
+ NSString *background_image;
+
+ // Visibility.
+ NSString *visibility;
+
+ // Positioning and size.
+ NSString *width;
+ NSString *height;
+ NSString *top;
+ NSString *left;
+ NSString *right;
+ NSString *bottom;
+
+ // Object alignment.
+ NSString *vertical_align;
+
+ // Margins.
+ NSString *margin_right;
+ NSString *margin_left;
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+#pragma mark -
+#pragma mark Properties.
+
+/**
+ * The identifier for this rule set. Also knowed as <tt>selector</tt>
+ */
+@property (copy) NSString *selector;
+
+/**
+ * A font family name only specifies a name given to a set of font faces,
+ * it does not specify an individual face.
+ * You can call <tt>[UIFont familyNames]</tt> to retrieve a list of
+ * available fonts on your system. Font family name is case-sensitive,
+ * make sure to inform correctly.
+ * See <a href="http://www.w3.org/TR/css3-fonts/#font-family-prop">CSS3 Font Family</a>
+ * for more information.<br>
+ * Default value is the first <b>Default Font Family</b>.
+ */
+@property (copy) NSString *font_family;
+
+/**
+ * The ‘font-weight’ property specifies weight of glyphs in the font.
+ * In iOS each font has different font weight descriptions (such as Medium, Light, Oblique, etc.).
+ * You can call <tt>[UIFont familyNames]</tt> to retrieve a list of available fonts on your system.
+ * Default value is <tt>nil</tt>.<br>
+ * <br>
+ * <b>Example:</b><br>
+ * To use the font <tt>Helvetica-BoldOblique</tt> you should
+ * inform <tt>BoldOblique</tt> as font-weight and <tt>Helvetica</tt> as font_family.
+ * <br>
+ * Font weight name is case-sensitive, make sure to inform correctly.
+ */
+@property (copy) NSString *font_weight;
+
+/**
+ * This property indicates the desired height of glyphs from the font.
+ * This value is always interpreted in points, regardless of what you specify.
+ * This is due to the tricky nature of varying DPI on the various iPhone OS devices.
+ * Default value is the <b>Default System Font Size</b> (<tt>[UIFont systemFontSize]</tt>).
+ */
+@property (copy) NSNumber *font_size;
+
+/**
+ * This property describes how inline contents of a block are horizontally
+ * aligned. Values have the following meanings:<br>
+ * - <tt>left</tt>: Align text along the left edge.<br>
+ * - <tt>center</tt>: Align text equally along both sides of the center line.<br>
+ * - <tt>right</tt>: Align text along the right edge.<br>
+ * <br>
+ * Use the textAlign method to retrieve an iOS formatted UITextAlignment
+ * based on this values.
+ */
+@property (copy) NSString* text_align;
+
+/**
+ * This property specifies the size of an element’s rendering box.
+ * Possible Values:<br>
+ * - <tt>auto</tt>: The width is determinant on the values of other properties.
+ * - <tt>length</tt>: Refers to an absolute measurement for the computed
+ * element box width. Negative values are not allowed.
+ * - <tt>percentage</tt>: Refers to a percentage of the width of the containing
+ * element block.<br>
+ * Examples:<br>
+ * <tt>"75px", "50%"</tt>
+ */
+@property (copy) NSString* width;
+
+/**
+ * /copydef width
+ */
+@property (copy) NSString* height;
+
+@property (copy) NSString* top;
+@property (copy) NSString* left;
+@property (copy) NSString* right;
+@property (copy) NSString* bottom;
+
+/**
+ * The visibility property specifies whether or not an element is visible.
+ * Possible Values:<br>
+ * - <tt>visible</tt>: The element is visible. <b>This is default.</b>
+ * - <tt>hidden</tt>: The element is invisible.
+ */
+@property (copy) NSString* visibility;
+
+/**
+ * An TTCSSTextShadowModel object that define a text shadow properties.
+ */
+@property (retain) TTCSSTextShadowModel* text_shadow;
+
+/**
+ * Specifies the opacity of the receiver’s text shadow.
+ * The default value is 0.
+ */
+@property (copy) NSNumber* text_shadow_opacity;
+
+/**
+ * This property describes the foreground color of an element.
+ * Default value is a transparent color.
+ */
+@property (retain) id color;
+
+/**
+ * This property describes the background color of an element.
+ * Default value is a transparent color.
+ */
+@property (retain) id background_color;
+
+/**
+ * This property sets the background image(s) of an element.
+ * Default value is <tt>nil</tt>.
+ */
+@property (copy) NSString *background_image;
+
+/**
+ * This property sets the vertical alignment of an element.
+ * Values have the following meanings:<br>
+ * - <tt>top</tt>: The top of the element is aligned with the top of the
+ * tallest element on the line.<br>
+ * - <tt>middle</tt>: The element is placed in the middle of the parent element.<br>
+ * - <tt>bottom</tt>: The bottom of the element is aligned with the lowest element on the line.<br>
+ * <br>
+ * Use the contentVerticalAlignment method to retrieve an iOS formatted
+ * UIControlContentVerticalAlignment based on this values.
+ */
+@property (copy) NSString* vertical_align;
+
+/**
+ * This property specifies the left margin of an element.
+ * Possible Values:<br>
+ * - <tt>auto</tt>: The left margin is calculated automatically.
+ * - <tt>length</tt>: Specifies a fixed left margin in px.
+ * - <tt>percentage</tt>: Specifies a left margin in percent.
+ * Examples:<br>
+ * <tt>"75px", "50%"</tt>
+ */
+@property (copy) NSString* margin_left;
+
+/**
+ * This property specifies the right margin of an element.
+ * Possible Values:<br>
+ * - <tt>auto</tt>: The right margin is calculated automatically.
+ * - <tt>length</tt>: Specifies a fixed right margin in px.
+ * - <tt>percentage</tt>: Specifies a left margin in percent.
+ * Examples:<br>
+ * <tt>"75px", "50%"</tt>
+ */
+@property (copy) NSString* margin_right;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+#pragma mark -
+#pragma mark Init Methods.
++(id)initWithSelectorName:(NSString*)anRuleSetName;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+#pragma mark -
+#pragma mark Data Methods.
+
+/**
+ * Return an formatted UIFont object based on the defined properties.
+ * Will return <tt>nil</tt> if can't format.
+ */
+-(UIFont*)font;
+
+/**
+ * Return an formatted UITextAlignment based on the defined <tt>'text_align'</tt> property.
+ * If isn't setted return default left alignment.
+ */
+-(UITextAlignment)textAlign;
+
+/**
+ * Return an formatted CGSize based on the defined <tt>'width'</tt>
+ * and <tt>'height'</tt> properties.
+ */
+-(CGSize)size;
+
+/**
+ * Return an formatted CGPoint based on the defined <tt>'top'</tt>
+ * and <tt>'left'</tt> properties.
+ */
+-(CGPoint)origin;
+
+/**
+ * Return an Boolean value that determines whether the receiver is hidden based
+ * on the <tt>'visibility'</tt> property.
+ */
+-(BOOL)hidden;
+
+/**
+ * Return an formatted UIControlContentVerticalAlignment based on the defined
+ * <tt>'vertical_align'</tt> property. If isn't setted return default top alignment.
+ */
+-(UIControlContentVerticalAlignment)contentVerticalAlignment;
+
+/**
+ * Return an formatted UIControlContentHorizontalAlignment based on the defined
+ * <tt>'margin-left'</tt> and <tt>margin-right</tt> properties.
+ * If isn't setted return default left alignment.
+ */
+-(UIControlContentHorizontalAlignment)contentHorizontalAlignment;
+@end
View
65 src/extThree20CSSStyle/Headers/TTCSSStyleSheet.h
@@ -16,6 +16,7 @@
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
+#import "extThree20CSSStyle/TTDataPopulatorDelegate.h"
/**
* A general purpose CSS style sheet object for accessing a CSS style sheet's properties.
@@ -25,17 +26,26 @@
*
* Example apps: three20/samples/Style/TTCSSStyleSheets
*/
-@interface TTCSSStyleSheet : NSObject {
+@class TTCSSRuleSet;
+@interface TTCSSStyleSheet : NSObject <TTDataPopulatorDelegate> {
@private
+
+ // The "crude" Styles readed from CSS file.
NSDictionary* _cssStyles;
- NSMutableDictionary* _cachedCssStyles;
+ // An collection of loaded TTCSSRuleSet.
+ NSDictionary* _cssRulesSet;
- NSDictionary* _colorLookupTable;
+ // CSS mapped properties.
+ NSDictionary* _propertiesMap;
}
@property (nonatomic, readonly) NSDictionary* cssStyles;
+/**
+ * An collection of loaded TTCSSRuleSet.
+ */
+@property (readonly) NSDictionary* cssRulesSet;
/**
* Load the style sheet into memory from disk.
@@ -51,35 +61,74 @@
/**
- * Get (text) color from a specific rule set.
+ * Get (text) color from a specific rule set, also accept an specific state.
*/
- (UIColor*)colorWithCssSelector:(NSString*)selector forState:(UIControlState)state;
/**
- * Get background-color from a specific rule set.
+ * Get (text) color from a specific rule set.
+ */
+- (UIColor*)colorWithCssSelector:(NSString*)selector;
+
+/**
+ * Get background-color from a specific rule set, also accept an specific state.
*/
- (UIColor*)backgroundColorWithCssSelector:(NSString*)selector forState:(UIControlState)state;
/**
- * Get font from a specific rule set.
+ * Get background-color from a specific rule set.
+ */
+- (UIColor*)backgroundColorWithCssSelector:(NSString*)selector;
+
+/**
+ * Get font from a specific rule set, also accept an specific state.
*/
- (UIFont*)fontWithCssSelector:(NSString*)selector forState:(UIControlState)state;
/**
- * Get text shadow color from a specific rule set.
+ * Get font from a specific rule set and 'normal' state.
+ */
+- (UIFont*)fontWithCssSelector:(NSString*)selector;
+
+/**
+ * Get text shadow color from a specific rule set, also accept an specific state.
*/
- (UIColor*)textShadowColorWithCssSelector:(NSString*)selector forState:(UIControlState)state;
/**
- * Get text shadow offset from a specific rule set.
+ * Get text shadow color from a specific rule set.
+ */
+- (UIColor*)textShadowColorWithCssSelector:(NSString*)selector;
+
+/**
+ * Get text shadow offset from a specific rule set, also accept an specific state.
*/
- (CGSize)textShadowOffsetWithCssSelector:(NSString*)selector forState:(UIControlState)state;
/**
+ * Get text shadow offset from a specific rule set.
+ */
+- (CGSize)textShadowOffsetWithCssSelector:(NSString*)selector;
+
+/**
* Get text shadow radius from a specific rule set.
*/
+- (CGFloat)textShadowRadiusWithCssSelector:(NSString*)selector;
+
+/**
+ * Get text shadow radius from a specific rule set, also accept an specific state.
+ */
- (CGFloat)textShadowRadiusWithCssSelector:(NSString*)selector forState:(UIControlState)state;
+/**
+ * CSS Rule Set.
+ */
+-(TTCSSRuleSet*)css:(NSString*)selectorName;
+
+/**
+ * CSS Rule Set, also accept an specific state.
+ */
+-(TTCSSRuleSet*)css:(NSString*)selectorName forState:(UIControlState)state;
/**
* Release all cached data.
View
55 src/extThree20CSSStyle/Headers/TTCSSTextShadowModel.h
@@ -0,0 +1,55 @@
+//
+// Copyright 2009-2011 Facebook
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License 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 <UIKit/UIKit.h>
+
+@interface TTCSSTextShadowModel : NSObject {
+
+ UIColor* shadowColor;
+ NSNumber* shadowBlur;
+ CGSize shadowOffset;
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+#pragma mark -
+#pragma mark Properties.
+
+/**
+ * This is given as a pair of length values indicating x- and y- distances to use as offset.
+ * The default offset size is (0, -1), which indicates a shadow one point above the text.
+ */
+@property (assign) CGSize shadowOffset;
+
+/**
+ * The shadowBlur specifies the blur radius used to render the receiver’s shadow.
+ * This value coud not be rendered on iOS older than 3.2.
+ * The default value is 3.0.
+ */
+@property (copy) NSNumber* shadowBlur;
+
+/*
+ * Define the color to create the shadow effect.
+ * The default value for this property is transparent,
+ * which indicates that no shadow is drawn.
+ */
+@property (retain) id shadowColor;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+#pragma mark -
+#pragma mark Init Methods.
++(id)initWithShadowColor:(id)anColor andShadowOffset:(CGSize)anOffset;
++(id)initWithShadowColor:(id)anColor andShadowOffset:(CGSize)anOffset andShadowBlur:(NSNumber*)blur;
+
+@end
View
44 src/extThree20CSSStyle/Headers/TTDataConverter.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2011 - SEQOY.org and Paulo Oliveira ( http://www.seqoy.org )
+ * JUMP GIT Repository: https://github.com/seqoy/jump
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License 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 <Foundation/Foundation.h>
+
+/**
+ * \nosubgrouping
+ * This class contains an collection of methods to convert different Objective C objects.
+ * This is a little versio of this class with a small subset of useful methods to
+ * use with 'TTCSS' Classes. See JUMP Framework to retrieve the full version.
+ */
+@interface TTDataConverter : NSObject {}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+#pragma mark -
+#pragma mark Convert Methods.
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/** @name Convert Methods
+ */
+///@{
+
+/**
+ * Take an <b>NSString</b> Object and try to convert to <b>NSNumber</b>.
+ * @param anObject An <b>NSString</b> to try to convert.
+ * @return Converted object or if an conversion isn't possible will return <b>nil</b>.
+ */
++(NSNumber*)convertToNSNumberThisObject:(id)anObject;
+
+///@}
+@end
+
View
71 src/extThree20CSSStyle/Headers/TTDataPopulator.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2011 - SEQOY.org and Paulo Oliveira ( http://www.seqoy.org )
+ * JUMP GIT Repository: https://github.com/seqoy/jump
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License 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 <objc/runtime.h>
+#import <Foundation/Foundation.h>
+#import "extThree20CSSStyle/TTDataConverter.h"
+#import "extThree20CSSStyle/TTDataPopulatorDelegate.h"
+
+/**
+ * \nosubgrouping
+ * TTDataPopulator is used to populate Model Objects with Data contained in dictionaries.
+ * This is a little versio of this class with a small subset of useful methods to
+ * use with 'TTCSS' Classes. See JUMP Framework to retrieve the full version.
+ */
+@interface TTDataPopulator : NSObject {
+ id<TTDataPopulatorDelegate> delegate;
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+#pragma mark -
+#pragma mark Properties.
+@property (assign) id<TTDataPopulatorDelegate> delegate;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#pragma mark -
+#pragma mark Populate Methods.
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+//// //// //// //// //// //// //// //// //// //// //// //// //// //// ////
+/** @name Populate Methods
+ */
+///@{
+
+/**
+ * Populate the informed object with data.
+ * @param anObject The object to populate.
+ * @param withData An <tt>NSDictionary</tt> with data.
+ * @param usingMap An <tt>NSDictionary</tt> that represent an map that describe
+ * how to populate the object.
+ */
++(id)populateObject:(id)anObject withData:(NSDictionary*)anDictionary usingMap:(NSDictionary*)anMap;
+
+/**
+ * Populate the informed object with data.
+ * @param anObject The object to populate.
+ * @param withData An <tt>NSDictionary</tt> with data.
+ * @param usingMap An <tt>NSDictionary</tt> that represent an map that describe
+ * how to populate the object.
+ * @param anDelegate to extend the TTDataPopulator class. See TTDataPopulatorDelegate
+ * documentation for more information.
+ */
++(id)populateObject:(id)anObject withData:(NSDictionary*)anDictionary usingMap:(NSDictionary*)anMap
+ withDelegate:(id<TTDataPopulatorDelegate>)anDelegate;
+
+///@}
+@end
+
View
30 src/extThree20CSSStyle/Headers/TTDataPopulatorDelegate.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2011 - SEQOY.org and Paulo Oliveira ( http://www.seqoy.org )
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License 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.
+ */
+
+@protocol TTDataPopulatorDelegate
+@optional
+
+/**
+ * When the Data Populator can't automatically convert some specific type. He will call this method
+ * and let you extend the class converting you specific type.
+ * @param firstObject is original object that we need to convert.
+ * @param firstObjectClass is the class of the original object.
+ * @param convertToClass is the class that we need to receive whe converted.
+ * @return Should return converted object or <tt>nil</tt> if can't convert.
+ */
+-(id)tryToConvert:(id)object ofClass:(Class)objectClass toClass:(Class)convertToClass;
+
+@end
View
68 src/extThree20CSSStyle/Headers/TTDefaultCSSStyleSheet.h
@@ -0,0 +1,68 @@
+//
+// Copyright 2009-2011 Facebook
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License 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 "Three20Style/TTDefaultStyleSheet.h"
+
+@class TTCSSStyleSheet;
+@class TTCSSRuleSet;
+@protocol TTCSSApplyProtocol;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+@interface TTDefaultCSSStyleSheet : TTDefaultStyleSheet {
+@private
+ TTCSSStyleSheet* _styleSheet;
+
+ // Maintain an control of CSS Files already loaded and cached.
+ NSMutableSet* _cachedCssFiles;
+
+}
+
+@property (nonatomic, readonly) TTCSSStyleSheet* styleSheet;
+
+/**
+ * Load an CSS Style Sheet from disk and cache his data.
+ * If the file is already cached no data will be loaded again,
+ * if you need to reload the file use addStyleSheetFromDisk:ignoreCache:
+ */
+- (BOOL)addStyleSheetFromDisk:(NSString*)filename;
+
+/**
+ * Load an CSS Style Sheet from disk and cache his data.
+ * @param cache YES will ignore if is already cached and reload the data if needed.
+ */
+- (BOOL)addStyleSheetFromDisk:(NSString*)filename ignoreCache:(BOOL)cache;
+
++ (TTDefaultCSSStyleSheet*)globalCSSStyleSheet;
+
+/**
+ * CSS Rule Set.
+ */
+-(TTCSSRuleSet*)css:(NSString*)selectorName;
+
+/**
+ * CSS Rule Set, also accept an specific state.
+ */
+-(TTCSSRuleSet*)css:(NSString*)selectorName forState:(UIControlState)state;
+
+/**
+ * Apply the rules for the specified selector to the informed object. This object
+ * must conform with the TTCSSApplyProtocol to read and properly apply the CSS rules.
+ */
+-(void)applyCssFromSelector:(NSString*)selectorName toObject:(id<TTCSSApplyProtocol>)anObject;
+
+@end
View
17 ...CSSStyle/Sources/TTDefaultCSSStyleSheet.h → ...20CSSStyle/Headers/UILabel+CSSAdditions.h
@@ -13,20 +13,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.
//
+#import <UIKit/UIKit.h>
-#import "Three20Style/TTDefaultStyleSheet.h"
-
-@class TTCSSStyleSheet;
-
-@interface TTDefaultCSSStyleSheet : TTDefaultStyleSheet {
-@private
- TTCSSStyleSheet* _styleSheet;
-}
-
-@property (nonatomic, readonly) TTCSSStyleSheet* styleSheet;
-
-- (BOOL)addStyleSheetFromDisk:(NSString*)filename;
-
-+ (TTDefaultCSSStyleSheet*)globalCSSStyleSheet;
+#import "extThree20CSSStyle/UIView+CSSAdditions.h"
+@interface UILabel(TTCSSAdditions)
@end
View
13 src/extThree20CSSStyle/Headers/UILabelAdditions.h
@@ -14,14 +14,5 @@
// limitations under the License.
//
-#import <Foundation/Foundation.h>
-#import <UIKit/UIKit.h>
-
-@interface UILabel (TTCSSCategory)
-
-/**
- * Set a css stylesheet selector, will set font, colors and shadow.
- */
-- (void)applyCssSelector:(NSString *)selector;
-
-@end
+// For compatibility issues we import the UILabel additions.
+#import "extThree20CSSStyle/UILabel+CSSAdditions.h"
View
30 src/extThree20CSSStyle/Headers/UIView+CSSAdditions.h
@@ -0,0 +1,30 @@
+//
+// Copyright 2009-2011 Facebook
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License 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 <UIKit/UIKit.h>
+
+#import "extThree20CSSStyle/TTCSSRuleSet.h"
+#import "extThree20CSSStyle/TTCSSApplyProtocol.h"
+
+@interface UIView(TTCSSAdditions) <TTCSSApplyProtocol>
+
+/**
+ * Convenient Init method to create an UIView and apply
+ * an CSS Rule Set on one pass.
+ */
+-(id)initWithFrame:(CGRect)anFrame andApplyCssFromSelector:(NSString*)anSelector;
+
+
+@end
View
3  src/extThree20CSSStyle/Headers/extThree20CSSStyle+Additions.h
@@ -18,6 +18,7 @@
#import "extThree20CSSStyle/extThree20CSSStyle.h"
// Additions
-#import "extThree20CSSStyle/UILabelAdditions.h"
+#import "extThree20CSSStyle/UIView+CSSAdditions.h"
+#import "extThree20CSSStyle/UILabel+CSSAdditions.h"
#import "extThree20CSSStyle/TTTextStyleAdditions.h"
#import "extThree20CSSStyle/TTShadowStyleAdditions.h"
View
9 src/extThree20CSSStyle/Headers/extThree20CSSStyle.h
@@ -21,3 +21,12 @@
#import "extThree20CSSStyle/TTCSSGlobalStyle.h"
#import "extThree20CSSStyle/TTCSSStyleSheet.h"
#import "extThree20CSSStyle/TTDefaultCSSStyleSheet.h"
+
+// CSS Models
+#import "extThree20CSSStyle/TTCSSTextShadowModel.h"
+#import "extThree20CSSStyle/TTCSSRuleSet.h"
+
+// Data Processing
+#import "extThree20CSSStyle/TTDataConverter.h"
+#import "extThree20CSSStyle/TTDataPopulator.h"
+#import "extThree20CSSStyle/TTDataPopulatorDelegate.h"
View
77 src/extThree20CSSStyle/README.mdown
@@ -83,15 +83,37 @@ style sheet with all of the default TTDefaultStyleSheet values. You can then com
style sheet upon this one using addStyleSheetFromDisk:. For an example of this in action,
see TTFacebook in the `three20/samples` directory.
+### The Rule Set Object
+
+The Rule Set Object is an model that store data for each CSS Selector parsed. This object
+contains the CSS properties as Objective-C objects ready to use on your application.
+See the documentation for TTCSSRuleSet and TTCSSTextShadowModel for more information.
+
Known Limitations
-----------------
+### Font families and font weights.
+You need to always use iOS font family names and iOS font weights. For example, to use Helvetica
+Bold on iOS you should create your CSS like this:
+
+ .font {
+ font-family: Helvetica;
+ font-weight: Bold;
+ }
+
+This names are case-sensitive, you must make sure to respect the iOS font names.
+
### Font Sizes
Font-size is always interpreted in points, regardless of what you specify. This is due to
the tricky nature of varying DPI on the various iPhone OS devices.
+### Text Shadows
+
+In iOS older the 3.2 the "blur" property always interpreted as "0". This is due to the technical limitations
+of specifying blur for text shadows for UILabels.
+
Supported CSS Properties and Values
-----------------------------------
@@ -103,8 +125,8 @@ Supported CSS Properties and Values
<color> #FFF or #FF00FF or rgb(255, 0, 255)
or rgba(0, 255, 255, 0.5) or <color-name>
- <color-name> Any of the standard names found in the W3C for css3.
- http://www.w3.org/TR/css3-color/
+ <color-name> Any of the Extended color keywords found in the W3C for css3.
+ http://www.w3.org/TR/css3-color/#svg-color
Also, iPhone OS standard colors:
lightTextColor
darkTextColor
@@ -134,13 +156,34 @@ Fonts are defined with a set of properties that collectively create the final UI
### Text Shadow
- text-shadow: <number>px <number>px <number>px <color>
+ text-shadow-opacity: <number>
+ text-shadow: <number>px <number>px <ignored> <color>
textShadowColorWithCssSelector
textShadowOffsetWithCssSelector
- textShadowRadiusWithCssSelector
The `text-shadow` property is defined in one chunk, but read using two distinct methods.
+The third parameter could be ignored on older iOS versions, see "Text Shadows" in the
+`Known Limitations` section for the technical reasons.
+
+
+### Alignment and Justification
+
+ text-align: (left|center|right)
+
+This property describes how inline contents of a block are horizontally aligned.
+
+### Positioning and Size
+
+ top: <number>px
+ left: <number>px
+ width: <number>px
+ height: <number>px
+
+### Visibilty
+
+ visibilty: (visible|hidden)
+
Examples
--------
@@ -166,7 +209,25 @@ Add the following code in your app delegate's `applicationDidFinishLaunching`.
TT_RELEASE_SAFELY(styleSheet);
-Now you can freely customize the styles of your app using `stylesheet.css`. You can freely
-add new styles to the CSS, but with the current design you will also need to add an accessor
-to a custom object that inherits from `TTDefaultCSSStyleSheet`. See the source for
-`TTDefaultCSSStyleSheet` for examples of how to interact with the style sheet object.
+Now you can freely customize the styles of your app using `stylesheet.css`. You can access
+the CSS rules and his properties using two convenient functions:
+
+### TTCSS function
+
+Allows you to retrieve the selector and some specific property.
+
+ // Read the color from the CSS 'headerFont'.
+ UIColor *headerFontColor = TTCSS( @"headerFont", color );
+
+### TTCSSRule function
+
+Retrieve an TTCSSRuleSet object for specified property. So you can access every property directly.
+
+ // Read the color rule set 'headerFont'.
+ TTCSSRuleSet *headerFont = TTCSSRuleSet( @"headerFont" );
+
+ UIColor *headerFontColor = headerFont.color;
+
+
+You also could add an accessor to a custom object that inherits from `TTDefaultCSSStyleSheet`. See the source for
+`TTDefaultCSSStyleSheet` for an example.
View
268 src/extThree20CSSStyle/Sources/TTCSSFunctions.m
@@ -0,0 +1,268 @@
+//
+// Copyright 2009-2011 Facebook
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License 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