├── .gitignore ├── CONTRIBUTING ├── ExampleView.png ├── LICENSE ├── README.md ├── SampleApp ├── AppDelegate.h ├── AppDelegate.m ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json ├── Base.lproj │ └── LaunchScreen.storyboard ├── Info.plist ├── SampleViewController.h ├── SampleViewController.m ├── Templates │ ├── ActivityIndicatorExample.h │ ├── ActivityIndicatorExample.m │ ├── AdapterExample.h │ ├── AdapterExample.m │ ├── FirstExample.h │ ├── FirstExample.m │ ├── LabelExample.h │ ├── LabelExample.m │ ├── LayerExample.h │ ├── LayerExample.m │ ├── PosteditExample.h │ ├── PosteditExample.m │ ├── RTLExample.h │ ├── RTLExample.m │ ├── SpaceExample.h │ └── SpaceExample.m ├── duck.png └── main.m ├── TemplateKit.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ └── contents.xcworkspacedata └── xcshareddata │ └── xcschemes │ ├── SampleApp.xcscheme │ └── TemplateKit.xcscheme ├── TemplateKit ├── Internal │ ├── Core │ │ ├── TPLAccessibility.m │ │ ├── TPLBenchmark.h │ │ ├── TPLBenchmark.m │ │ ├── TPLContentViewDescriptor.h │ │ ├── TPLCoreMacros.h │ │ ├── TPLCoreMacros.m │ │ ├── TPLDebugger.m │ │ ├── TPLRootView+Internal.h │ │ ├── TPLRootView.m │ │ ├── TPLRootViewDescriptor.h │ │ ├── TPLRootViewDescriptor.m │ │ ├── TPLSettings.m │ │ ├── TPLUtils.m │ │ ├── TPLValueProvider.h │ │ ├── TPLValueProvider.m │ │ ├── TPLViewDescriptor.h │ │ ├── TPLViewDescriptor.m │ │ ├── TPLViewModel+Internal.h │ │ └── TPLViewModel.m │ ├── DSL │ │ ├── TPLBuilder+Internal.h │ │ ├── TPLBuilder.m │ │ ├── TPLBuilderFactoryExtension.m │ │ ├── TPLBuilderUtil.h │ │ ├── TPLBuilderUtil.m │ │ ├── TPLDSLMacros.m │ │ ├── TPLView.m │ │ ├── TPLViewtemplate+Internal.h │ │ └── TPLViewtemplate.m │ └── DescriptorImpls │ │ ├── TPLActivityIndicatorDescriptor.h │ │ ├── TPLActivityIndicatorDescriptor.m │ │ ├── TPLClientDataViewDescriptor.h │ │ ├── TPLClientDataViewDescriptor.m │ │ ├── TPLClientImmutableDataViewDescriptor.h │ │ ├── TPLClientImmutableDataViewDescriptor.m │ │ ├── TPLClientSimpleViewDescriptor.h │ │ ├── TPLClientSimpleViewDescriptor.m │ │ ├── TPLColumnLayout.h │ │ ├── TPLColumnLayout.m │ │ ├── TPLCompositeViewDescriptor.h │ │ ├── TPLCompositeViewDescriptor.m │ │ ├── TPLContainerViewDescriptor.h │ │ ├── TPLContainerViewDescriptor.m │ │ ├── TPLContextualSpaceSelector.h │ │ ├── TPLContextualSpaceSelector.m │ │ ├── TPLDataViewDescriptor.h │ │ ├── TPLDataViewDescriptor.m │ │ ├── TPLDescriptorImplsMacros.h │ │ ├── TPLGridDescriptor.h │ │ ├── TPLGridDescriptor.m │ │ ├── TPLImageDescriptor.h │ │ ├── TPLImageDescriptor.m │ │ ├── TPLLabelDescriptor.h │ │ ├── TPLLabelDescriptor.m │ │ ├── TPLLayerLayout.h │ │ ├── TPLLayerLayout.m │ │ ├── TPLLayoutConfig.m │ │ ├── TPLMultiplexerViewDescriptor.h │ │ ├── TPLMultiplexerViewDescriptor.m │ │ ├── TPLRepeatedDescriptor.h │ │ ├── TPLRepeatedDescriptor.m │ │ ├── TPLRowLayout.h │ │ ├── TPLRowLayout.m │ │ ├── TPLSelectViewDescriptor.h │ │ ├── TPLSelectViewDescriptor.m │ │ ├── TPLSpaceDescriptor.h │ │ └── TPLSpaceDescriptor.m ├── Public │ ├── Core │ │ ├── TPLAccessibility.h │ │ ├── TPLConstants.h │ │ ├── TPLDebugger.h │ │ ├── TPLRootView.h │ │ ├── TPLSettings.h │ │ ├── TPLUtils.h │ │ ├── TPLViewModel.h │ │ └── TPLViewModifier.h │ ├── DSL │ │ ├── TPLBuilder.h │ │ ├── TPLBuilderFactoryExtension.h │ │ ├── TPLDSLDeclarationMacros.h │ │ ├── TPLDSLMacros.h │ │ ├── TPLView.h │ │ └── TPLViewTemplate.h │ └── DescriptorImpls │ │ ├── TPLActivityIndicatorData.h │ │ ├── TPLDataViewAdapter.h │ │ ├── TPLGridConfig.h │ │ ├── TPLImmutableDataViewAdapter.h │ │ ├── TPLLabelData.h │ │ ├── TPLLayoutConfig.h │ │ └── TPLSimpleViewAdapter.h ├── TemplateKit.h ├── TemplateKitDeclarations.h └── TemplateKit_Sources.m └── Tests ├── DescriptorImpls ├── TPLColumnLayoutTest.m ├── TPLCompositeDesriptorTest.m ├── TPLContextualSpaceSelectorTest.m ├── TPLLabelDescriptorTest.m ├── TPLMultiplexerViewDescriptorTest.m └── TPLRowLayoutTest.m ├── Info.plist ├── TPLTestingUtil.h └── TPLTestingUtil.m /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | .DS_Store 3 | TemplateKit.xcodeproj/project.xcworkspace/xcuserdata 4 | TemplateKit.xcodeproj/xcuserdata 5 | -------------------------------------------------------------------------------- /CONTRIBUTING: -------------------------------------------------------------------------------- 1 | Want to contribute? Great! First, read this page (including the small print at the end). 2 | 3 | ### Before you contribute 4 | Before we can use your code, you must sign the 5 | [Google Individual Contributor License Agreement] 6 | (https://cla.developers.google.com/about/google-individual) 7 | (CLA), which you can do online. The CLA is necessary mainly because you own the 8 | copyright to your changes, even after your contribution becomes part of our 9 | codebase, so we need your permission to use and distribute your code. We also 10 | need to be sure of various other things—for instance that you'll tell us if you 11 | know that your code infringes on other people's patents. You don't have to sign 12 | the CLA until after you've submitted your code for review and a member has 13 | approved it, but you must do it before we can put your code into our codebase. 14 | Before you start working on a larger contribution, you should get in touch with 15 | us first through the issue tracker with your idea so that we can help out and 16 | possibly guide you. Coordinating up front makes it much easier to avoid 17 | frustration later on. 18 | 19 | ### Code reviews 20 | All submissions, including submissions by project members, require review. We 21 | use Github pull requests for this purpose. 22 | 23 | ### The small print 24 | Contributions made by corporations are covered by a different agreement than 25 | the one above, the 26 | [Software Grant and Corporate Contributor License Agreement] 27 | (https://cla.developers.google.com/about/google-corporate). 28 | -------------------------------------------------------------------------------- /ExampleView.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/templatekit/3fd5bfcdc0bd7c5cd2feccd44c2aeb292322eba5/ExampleView.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | #TemplateKit 2 | 3 | *This software is still in alpha. Backward-incompatible changes will 4 | be made without notice.* 5 | 6 | TemplateKit is a framework for iOS view programming. Its goal is to 7 | become a default tool for implementing complex custom views with 8 | abstractions optimized for the most common cases. 9 | 10 | TemplateKit provides an intuitive and efficient DSL to perform common 11 | tasks in view programming such as view hierarchy construction, data 12 | population, and layout. View code written with TemplateKit is much 13 | shorter and more readable than code written with the raw UIView API. 14 | 15 | For example, to implement a classic table view cell with an image on 16 | the left and two stacked texts on the right like this: 17 | 18 |


19 | 20 | you would just write: 21 | 22 | // From SampleApp/Templates/FirstExample.m. 23 | 24 | TPL_DEFINE_VIEW_TEMPLATE(first_example, FirstExampleView) { 25 | return row(image($(thumbnail)), 26 | margin(@10), 27 | column(label($(title)), 28 | label($(subtitle)), 29 | nil), 30 | nil) 31 | .padding(TPLEdgeInsetsMake(10, 10, 10, 10)); 32 | } 33 | 34 | These seven lines of template code in the block is enough to tell the framework to 35 | construct a view hierarchy with one UIImageView instance and two UILabel instances, 36 | populate them with runtime data, and lay out the view hierarchy with the specified 37 | margin and paddings. Even a very simple view like this would take several dozens of 38 | lines if it were implemented with the raw UIView API. 39 | 40 | ##Usage 41 | Find examples in SampleApp/Templates. 42 | 43 | ##Discussion Forum 44 | https://groups.google.com/forum/#!forum/templatekit 45 | 46 | ##Disclaimer 47 | This is not an official Google product. 48 | -------------------------------------------------------------------------------- /SampleApp/AppDelegate.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import 18 | 19 | @interface AppDelegate : UIResponder 20 | 21 | @property (strong, nonatomic) UIWindow *window; 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /SampleApp/AppDelegate.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import "AppDelegate.h" 18 | 19 | #import "SampleViewController.h" 20 | #import "Templates/ActivityIndicatorExample.h" 21 | #import "Templates/AdapterExample.h" 22 | #import "Templates/FirstExample.h" 23 | #import "Templates/LayerExample.h" 24 | #import "Templates/PosteditExample.h" 25 | #import "Templates/RTLExample.h" 26 | #import "Templates/SpaceExample.h" 27 | #import "TemplateKit.h" 28 | 29 | @implementation AppDelegate 30 | 31 | - (BOOL)application:(UIApplication *)application 32 | didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 33 | self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 34 | self.window.backgroundColor = [UIColor whiteColor]; 35 | [self.window makeKeyAndVisible]; 36 | TPLView *view = [[FirstExampleView alloc] init]; 37 | TPLViewModel *viewModel = [[FirstExampleViewModel alloc] init]; 38 | view.viewModel = viewModel; 39 | view.backgroundColor = [UIColor whiteColor]; 40 | SampleViewController *rootViewController = 41 | [[SampleViewController alloc] initWithContentView:view]; 42 | self.window.rootViewController = rootViewController; 43 | return YES; 44 | } 45 | 46 | @end 47 | -------------------------------------------------------------------------------- /SampleApp/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "ipad", 35 | "size" : "29x29", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "ipad", 40 | "size" : "29x29", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "40x40", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "40x40", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "76x76", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "76x76", 61 | "scale" : "2x" 62 | } 63 | ], 64 | "info" : { 65 | "version" : 1, 66 | "author" : "xcode" 67 | } 68 | } -------------------------------------------------------------------------------- /SampleApp/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /SampleApp/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /SampleApp/SampleViewController.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import 18 | 19 | 20 | @interface SampleViewController : UIViewController 21 | 22 | - (instancetype)initWithContentView:(UIView *)contentView; 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /SampleApp/SampleViewController.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import "SampleViewController.h" 18 | 19 | #import "TemplateKit.h" 20 | 21 | @implementation SampleViewController { 22 | UIView *_contentView; 23 | } 24 | 25 | - (instancetype)initWithContentView:(UIView *)contentView { 26 | self = [super init]; 27 | if (self) { 28 | _contentView = contentView; 29 | } 30 | return self; 31 | } 32 | 33 | - (void)viewDidLoad { 34 | [super viewDidLoad]; 35 | self.view.backgroundColor = [UIColor lightGrayColor]; 36 | CGSize maxSize = CGSizeMake(CGRectGetWidth(self.view.bounds) - 40, CGFLOAT_MAX); 37 | CGSize size = [_contentView sizeThatFits:maxSize]; 38 | _contentView.frame = CGRectMake(20, 20, size.width, size.height); 39 | _contentView.autoresizingMask = 40 | UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleBottomMargin; 41 | [self.view addSubview:_contentView]; 42 | } 43 | 44 | @end 45 | -------------------------------------------------------------------------------- /SampleApp/Templates/ActivityIndicatorExample.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import "TemplateKitDeclarations.h" 18 | 19 | 20 | @interface ActivityIndicatorExampleViewModel : TPLViewModel 21 | 22 | @property(nonatomic) TPLActivityIndicatorData *activityIndicator0; 23 | @property(nonatomic) TPLActivityIndicatorData *activityIndicator1; 24 | @property(nonatomic) TPLActivityIndicatorData *activityIndicator2; 25 | 26 | @end 27 | 28 | 29 | @interface ActivityIndicatorExampleView : TPLView 30 | @end 31 | -------------------------------------------------------------------------------- /SampleApp/Templates/ActivityIndicatorExample.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import "ActivityIndicatorExample.h" 18 | 19 | #import "TemplateKit.h" 20 | 21 | 22 | @implementation ActivityIndicatorExampleViewModel 23 | 24 | - (instancetype)init { 25 | self = [super init]; 26 | if (self) { 27 | _activityIndicator0 = [[TPLActivityIndicatorData alloc] init]; 28 | _activityIndicator0.style = UIActivityIndicatorViewStyleWhite; 29 | _activityIndicator0.animating = YES; 30 | _activityIndicator0.hidesWhenStopped = NO; 31 | 32 | _activityIndicator1 = [[TPLActivityIndicatorData alloc] init]; 33 | _activityIndicator1.style = UIActivityIndicatorViewStyleGray; 34 | _activityIndicator1.animating = YES; 35 | _activityIndicator1.hidesWhenStopped = NO; 36 | 37 | _activityIndicator2 = [[TPLActivityIndicatorData alloc] init]; 38 | _activityIndicator2.style = UIActivityIndicatorViewStyleWhiteLarge; 39 | _activityIndicator2.animating = NO; 40 | _activityIndicator2.hidesWhenStopped = NO; 41 | } 42 | return self; 43 | } 44 | 45 | - (BOOL)handleEvent:(TPLEvent *)event { 46 | UIActivityIndicatorView *indicator = (UIActivityIndicatorView *)event.view; 47 | if (indicator.isAnimating) { 48 | [indicator stopAnimating]; 49 | } else { 50 | [indicator startAnimating]; 51 | } 52 | return YES; 53 | } 54 | 55 | @end 56 | 57 | 58 | @implementation ActivityIndicatorExampleView 59 | @end 60 | 61 | 62 | TPL_DEFINE_VIEW_TEMPLATE(activity_indicator_example, ActivityIndicatorExampleView) { 63 | return column(activity_indicator($(activityIndicator0)) 64 | .tappable(), 65 | activity_indicator($(activityIndicator1)) 66 | .tappable(), 67 | activity_indicator($(activityIndicator2)) 68 | .tappable(), 69 | nil); 70 | } 71 | -------------------------------------------------------------------------------- /SampleApp/Templates/AdapterExample.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import "TemplateKitDeclarations.h" 18 | 19 | 20 | @interface MutableDataViewData : NSObject 21 | @property(nonatomic) UIColor *color; 22 | @end 23 | 24 | 25 | @interface ImmutableDataViewData : NSObject 26 | @property(nonatomic) UIColor *color; 27 | @end 28 | 29 | 30 | @interface AdapterExampleViewModel : TPLViewModel 31 | @property(nonatomic) MutableDataViewData *mutableViewData; 32 | @property(nonatomic) ImmutableDataViewData *immutableViewData; 33 | @end 34 | 35 | 36 | @interface AdapterExampleView : TPLView 37 | @end 38 | -------------------------------------------------------------------------------- /SampleApp/Templates/AdapterExample.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import "AdapterExample.h" 18 | 19 | #import "TemplateKit.h" 20 | 21 | @interface NoDataView : UIView 22 | @end 23 | 24 | @implementation NoDataView 25 | 26 | - (instancetype)initWithFrame:(CGRect)frame { 27 | self = [super initWithFrame:frame]; 28 | if (self) { 29 | self.backgroundColor = [UIColor yellowColor]; 30 | } 31 | return self; 32 | } 33 | 34 | @end 35 | 36 | @interface NoDataViewAdapter : NSObject 37 | @end 38 | 39 | @implementation NoDataViewAdapter 40 | 41 | - (UIView *)view { 42 | return [[NoDataView alloc] initWithFrame:CGRectMake(0, 0, 100, 40)]; 43 | } 44 | 45 | @end 46 | 47 | TPL_DEFINE_SIMPLE_VIEW_ADAPTER(my_no_data_view, NoDataViewAdapter); 48 | 49 | @implementation MutableDataViewData 50 | @end 51 | 52 | @interface MutableDataView : UIView 53 | @end 54 | 55 | @implementation MutableDataView 56 | @end 57 | 58 | @interface MutableDataViewAdapter : NSObject 59 | @end 60 | 61 | @implementation MutableDataViewAdapter 62 | 63 | - (UIView *)view { 64 | return [[MutableDataView alloc] initWithFrame:CGRectMake(0, 0, 100, 40)]; 65 | } 66 | 67 | - (void)setData:(id)data toView:(UIView *)view { 68 | view.backgroundColor = ((MutableDataViewData *)data).color; 69 | } 70 | 71 | @end 72 | 73 | TPL_DEFINE_DATA_VIEW_ADAPTER(my_mutable_data_view, MutableDataViewAdapter); 74 | 75 | @implementation ImmutableDataViewData 76 | @end 77 | 78 | @interface ImmutableDataView : UIView 79 | 80 | - (instancetype)initWithData:(ImmutableDataViewData *)data NS_DESIGNATED_INITIALIZER; 81 | - (instancetype)initWithFrame:(CGRect)frame NS_UNAVAILABLE; 82 | - (instancetype)init NS_UNAVAILABLE; 83 | 84 | @end 85 | 86 | @implementation ImmutableDataView 87 | 88 | - (instancetype)initWithData:(ImmutableDataViewData *)data { 89 | self = [super initWithFrame:CGRectZero]; 90 | if (self) { 91 | self.backgroundColor = data.color; 92 | } 93 | return self; 94 | } 95 | 96 | - (instancetype)initWithCoder:(NSCoder *)aDecoder { 97 | return [self initWithData:nil]; 98 | } 99 | 100 | @end 101 | 102 | @interface ImmutableDataViewAdapter : NSObject 103 | @end 104 | 105 | @implementation ImmutableDataViewAdapter 106 | 107 | - (UIView *)viewWithData:(id)data { 108 | return [[ImmutableDataView alloc] initWithData:data]; 109 | } 110 | 111 | - (CGSize)viewSizeThatFits:(CGSize)size withData:(id)data { 112 | return CGSizeMake(100, 40); 113 | } 114 | 115 | @end 116 | 117 | TPL_DEFINE_IMMUTABLE_DATA_VIEW_ADAPTER(my_immutable_data_view, ImmutableDataViewAdapter); 118 | 119 | 120 | @implementation AdapterExampleViewModel 121 | 122 | - (instancetype)init { 123 | self = [super init]; 124 | if (self) { 125 | _mutableViewData = [[MutableDataViewData alloc] init]; 126 | _mutableViewData.color = [UIColor greenColor]; 127 | _immutableViewData = [[ImmutableDataViewData alloc] init]; 128 | _immutableViewData.color = [UIColor blueColor]; 129 | } 130 | return self; 131 | } 132 | 133 | @end 134 | 135 | 136 | @implementation AdapterExampleView 137 | @end 138 | 139 | TPL_DEFINE_VIEW_TEMPLATE(adapter_example, AdapterExampleView) { 140 | return column(ext.my_no_data_view(), 141 | ext.my_mutable_data_view($(mutableViewData)), 142 | ext.my_immutable_data_view($(immutableViewData)), 143 | nil); 144 | } 145 | -------------------------------------------------------------------------------- /SampleApp/Templates/FirstExample.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import "TemplateKitDeclarations.h" 18 | 19 | 20 | @interface FirstExampleViewModel : TPLViewModel 21 | 22 | @property(nonatomic) UIImage *thumbnail; 23 | @property(nonatomic) TPLLabelData *title; 24 | @property(nonatomic) TPLLabelData *subtitle; 25 | 26 | @end 27 | 28 | 29 | @interface FirstExampleView : TPLView 30 | @end 31 | -------------------------------------------------------------------------------- /SampleApp/Templates/FirstExample.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import "FirstExample.h" 18 | 19 | #import "TemplateKit.h" 20 | 21 | 22 | @implementation FirstExampleView 23 | @end 24 | 25 | 26 | @implementation FirstExampleViewModel 27 | 28 | - (instancetype)init { 29 | self = [super init]; 30 | if (self) { 31 | _title = [[TPLLabelData alloc] init]; 32 | _title.text = @"The great duck"; 33 | _subtitle = [[TPLLabelData alloc] init]; 34 | _subtitle.text = @"Osaka trip, Dec 2014"; 35 | _subtitle.textColor = [UIColor darkGrayColor]; 36 | _subtitle.font = [UIFont systemFontOfSize:14]; 37 | _thumbnail = [UIImage imageNamed:@"duck"]; 38 | } 39 | return self; 40 | } 41 | 42 | @end 43 | 44 | 45 | TPL_DEFINE_VIEW_TEMPLATE(first_example, FirstExampleView) { 46 | return row(image($(thumbnail)), 47 | margin(@10), 48 | column(label($(title)), 49 | label($(subtitle)), 50 | nil), 51 | nil) 52 | .padding(TPLEdgeInsetsMake(10, 10, 10, 10)); 53 | } 54 | -------------------------------------------------------------------------------- /SampleApp/Templates/LabelExample.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import "TemplateKitDeclarations.h" 18 | 19 | 20 | @interface LabelExampleViewModel : TPLViewModel 21 | @end 22 | 23 | @interface LabelExampleView : TPLView 24 | @end 25 | -------------------------------------------------------------------------------- /SampleApp/Templates/LabelExample.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import "LabelExample.h" 18 | 19 | #import "TemplateKit.h" 20 | 21 | 22 | @implementation LabelExampleViewModel 23 | @end 24 | 25 | 26 | @implementation LabelExampleView 27 | @end 28 | 29 | TPL_DEFINE_VIEW_TEMPLATE(label_example, LabelExampleView) { 30 | // TODO: add an example with dynamic type. 31 | // http://qiita.com/koogawa/items/1011962b444420b854d7 32 | // http://stackoverflow.com/questions/20510094/how-to-use-a-custom-font-with-dynamic-text-sizes-in-ios7 33 | return label(@"hoge"); 34 | } 35 | -------------------------------------------------------------------------------- /SampleApp/Templates/LayerExample.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import "TemplateKitDeclarations.h" 18 | 19 | 20 | @interface LayerExampleViewModel : TPLViewModel 21 | @end 22 | 23 | 24 | @interface LayerExampleView : TPLView 25 | @end 26 | -------------------------------------------------------------------------------- /SampleApp/Templates/LayerExample.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import "LayerExample.h" 18 | 19 | #import "TemplateKit.h" 20 | 21 | 22 | @implementation LayerExampleViewModel 23 | @end 24 | 25 | 26 | @implementation LayerExampleView 27 | @end 28 | 29 | TPL_DEFINE_VIEW_TEMPLATE(layer_example, LayerExampleView) { 30 | return layer(layer(label(@"front text") 31 | .background_color([UIColor whiteColor]) 32 | .position(left), 33 | label(@"back text") 34 | .position(right), 35 | nil) 36 | .size(TPLSizeMake(120, 80)) 37 | .background_color([UIColor redColor]) 38 | .position(top_left), 39 | layer(label(@"front text") 40 | .background_color([UIColor whiteColor]) 41 | .position(right), 42 | label(@"back text") 43 | .position(left), 44 | nil) 45 | .size(TPLSizeMake(120, 80)) 46 | .background_color([UIColor greenColor]) 47 | .position(bottom_right), 48 | label(@"") 49 | .size(TPLSizeMake(240, 240)) 50 | .background_color([UIColor blueColor]), 51 | nil); 52 | } 53 | -------------------------------------------------------------------------------- /SampleApp/Templates/PosteditExample.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import "TemplateKitDeclarations.h" 18 | 19 | 20 | @interface PosteditExampleViewModel : TPLViewModel 21 | @end 22 | 23 | 24 | @interface PosteditExampleView : TPLView 25 | @end 26 | -------------------------------------------------------------------------------- /SampleApp/Templates/PosteditExample.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import "PosteditExample.h" 18 | 19 | #import "TemplateKit.h" 20 | 21 | static const NSInteger kTagThumbnail; 22 | static const NSInteger kTagTitle; 23 | 24 | @implementation PosteditExampleViewModel 25 | @end 26 | 27 | 28 | @implementation PosteditExampleView 29 | 30 | - (void)didLayoutSubviews { 31 | UIImageView *thumbnail = [self viewWithTag:kTagThumbnail]; 32 | CGRect thumbnailFrame = [thumbnail.superview convertRect:thumbnail.frame toView:self]; 33 | NSLog(@"thumbnail: %@ -> %@", 34 | NSStringFromCGRect(thumbnail.frame), 35 | NSStringFromCGRect(thumbnailFrame)); 36 | UILabel *title = [self viewWithTag:kTagTitle]; 37 | CGRect titleFrame = [title.superview convertRect:title.frame toView:self]; 38 | NSLog(@"title: %@ -> %@", 39 | NSStringFromCGRect(title.frame), 40 | NSStringFromCGRect(titleFrame)); 41 | } 42 | 43 | @end 44 | 45 | TPL_DEFINE_VIEW_TEMPLATE(postedit_example, PosteditExampleView) { 46 | options.postedit(YES); 47 | 48 | return row(column(image([UIImage imageNamed:@"duck"]) 49 | .tag(@(kTagThumbnail)), 50 | nil), 51 | column(label(@"First Line") 52 | .tag(@(kTagTitle)), 53 | margin(@10), 54 | label(@"Second Line"), 55 | nil), 56 | nil) 57 | .padding(TPLEdgeInsetsMake(5, 5, 5, 5)); 58 | } 59 | -------------------------------------------------------------------------------- /SampleApp/Templates/RTLExample.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import "TemplateKitDeclarations.h" 18 | 19 | 20 | @interface RTLExampleViewModel : TPLViewModel 21 | @end 22 | 23 | 24 | @interface RTLExampleView : TPLView 25 | @end 26 | -------------------------------------------------------------------------------- /SampleApp/Templates/RTLExample.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import "RTLExample.h" 18 | 19 | #import "TemplateKit.h" 20 | 21 | static const NSInteger kTagSwitch = 100; 22 | 23 | 24 | @interface MySwitchAdapter : NSObject 25 | @end 26 | 27 | @implementation MySwitchAdapter 28 | 29 | - (UIView *)view { 30 | return [[UISwitch alloc] init]; 31 | } 32 | 33 | - (UIControlEvents)activatedControlEvents { 34 | return UIControlEventValueChanged; 35 | } 36 | 37 | @end 38 | 39 | TPL_DEFINE_SIMPLE_VIEW_ADAPTER(my_switch, MySwitchAdapter); 40 | 41 | 42 | @implementation RTLExampleViewModel 43 | 44 | - (BOOL)handleEvent:(TPLEvent *)event { 45 | if (event.view.tag == kTagSwitch && event.controlEvent == UIControlEventValueChanged) { 46 | [TPLSettings setIsRTLOverride:[(UISwitch *)event.view isOn]]; 47 | [event.rootView reloadViewModel]; 48 | return YES; 49 | } else { 50 | return NO; 51 | } 52 | } 53 | 54 | @end 55 | 56 | 57 | @implementation RTLExampleView 58 | @end 59 | 60 | TPL_DEFINE_VIEW_TEMPLATE(rtl_example, RTLExampleView) { 61 | return column(label(@"aa") 62 | .position(left), 63 | label(@"bb") 64 | .position(center), 65 | label(@"cc") 66 | .position(right), 67 | label(@"aa") 68 | .position(left) 69 | .no_rtl(), 70 | label(@"bb") 71 | .position(center) 72 | .no_rtl(), 73 | label(@"cc") 74 | .position(right) 75 | .no_rtl(), 76 | ext.my_switch() 77 | .tag(@(kTagSwitch)), 78 | nil); 79 | } 80 | -------------------------------------------------------------------------------- /SampleApp/Templates/SpaceExample.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import "TemplateKitDeclarations.h" 18 | 19 | 20 | @interface SpaceExampleViewModel : TPLViewModel 21 | 22 | @property(nonatomic) UIImage *nonnilImage; 23 | @property(nonatomic) UIImage *nilImage; 24 | 25 | @end 26 | 27 | 28 | @interface SpaceExampleView : TPLView 29 | @end 30 | -------------------------------------------------------------------------------- /SampleApp/Templates/SpaceExample.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import "SpaceExample.h" 18 | 19 | #import "TemplateKit.h" 20 | 21 | 22 | @implementation SpaceExampleViewModel 23 | 24 | - (instancetype)init { 25 | self = [super init]; 26 | if (self) { 27 | _nonnilImage = [UIImage imageNamed:@"duck"]; 28 | } 29 | return self; 30 | } 31 | 32 | @end 33 | 34 | 35 | @implementation SpaceExampleView 36 | @end 37 | 38 | TPL_DEFINE_VIEW_TEMPLATE(space_example, SpaceExampleView) { 39 | UIColor *ultralighGray = [UIColor colorWithWhite:0.8 alpha:1]; 40 | UIColor *white = [UIColor whiteColor]; 41 | 42 | return column(row(image($(nonnilImage)), 43 | margin(@20), 44 | image($(nonnilImage)), 45 | margin(@20), 46 | image($(nonnilImage)), 47 | nil) 48 | .background_color(white), 49 | margin(@20), 50 | 51 | row(image($(nilImage)), 52 | margin(@20), 53 | image($(nonnilImage)), 54 | margin(@20), 55 | image($(nonnilImage)), 56 | nil) 57 | .background_color(white), 58 | margin(@20), 59 | 60 | row(image($(nonnilImage)), 61 | margin(@20), 62 | image($(nilImage)), 63 | margin(@20), 64 | image($(nonnilImage)), 65 | nil) 66 | .background_color(white), 67 | margin(@20), 68 | 69 | row(image($(nonnilImage)), 70 | margin(@20), 71 | image($(nonnilImage)), 72 | margin(@20), 73 | image($(nilImage)), 74 | nil) 75 | .background_color(white), 76 | margin(@20), 77 | 78 | row(row(image($(nonnilImage)), 79 | margin(@20), 80 | image($(nonnilImage)), 81 | nil) 82 | .background_color(white), 83 | margin(@20), 84 | row(image($(nilImage)), 85 | margin(@20), 86 | image($(nilImage)), 87 | nil) 88 | .background_color(white), 89 | nil) 90 | .background_color([UIColor redColor]), 91 | 92 | nil) 93 | .background_color(ultralighGray); 94 | } 95 | -------------------------------------------------------------------------------- /SampleApp/duck.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/templatekit/3fd5bfcdc0bd7c5cd2feccd44c2aeb292322eba5/SampleApp/duck.png -------------------------------------------------------------------------------- /SampleApp/main.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import 18 | #import "AppDelegate.h" 19 | 20 | int main(int argc, char * argv[]) { 21 | @autoreleasepool { 22 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /TemplateKit.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /TemplateKit.xcodeproj/xcshareddata/xcschemes/SampleApp.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /TemplateKit.xcodeproj/xcshareddata/xcschemes/TemplateKit.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 49 | 50 | 51 | 52 | 53 | 54 | 64 | 65 | 71 | 72 | 73 | 74 | 75 | 76 | 82 | 83 | 89 | 90 | 91 | 92 | 94 | 95 | 98 | 99 | 100 | -------------------------------------------------------------------------------- /TemplateKit/Internal/Core/TPLAccessibility.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import "Public/Core/TPLAccessibility.h" 18 | 19 | 20 | @implementation TPLAccessibility 21 | 22 | - (instancetype)init { 23 | self = [super init]; 24 | if (self) { 25 | _accessible = YES; 26 | } 27 | return self; 28 | } 29 | 30 | + (instancetype)notAccessible { 31 | TPLAccessibility *accessibility = [[TPLAccessibility alloc] init]; 32 | accessibility.accessible = NO; 33 | return accessibility; 34 | } 35 | 36 | @end 37 | -------------------------------------------------------------------------------- /TemplateKit/Internal/Core/TPLBenchmark.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | 19 | #import 20 | 21 | #ifndef TPL_BENCHMARK_LEVEL 22 | #define TPL_BENCHMARK_LEVEL 0 23 | #endif 24 | 25 | #if TPL_BENCHMARK_LEVEL > 0 26 | BOOL TPLLogBenchmark(int level, uint64_t start, uint64_t end, Class aClass, NSString *message); 27 | #define TPL_BENCHMARK_TIME(l____) (TPL_BENCHMARK_LEVEL >= l____ ? mach_absolute_time() : 1) 28 | #define TPL_BENCHMARK(l__, m__, o__) for (uint64_t c__ = 0, e__ = 0, s__ = TPL_BENCHMARK_TIME(l__); c__ < 1; ++c__ && (e__ = TPL_BENCHMARK_TIME(l__)) && (TPL_BENCHMARK_LEVEL >= l__) && TPLLogBenchmark(l__, s__, e__, [o__ class], @#m__)) 29 | #else 30 | #define TPL_BENCHMARK(...) 31 | #endif 32 | -------------------------------------------------------------------------------- /TemplateKit/Internal/Core/TPLBenchmark.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import "Internal/Core/TPLBenchmark.h" 18 | 19 | #if TPL_BENCHMARK_LEVEL > 0 20 | BOOL TPLLogBenchmark(int level, uint64_t start, uint64_t end, Class aClass, NSString *message) { 21 | uint64_t elapsed = end - start; 22 | mach_timebase_info_data_t timeBaseInfo; 23 | mach_timebase_info(&timeBaseInfo); 24 | uint64_t elapsedNanoSeconds = elapsed * timeBaseInfo.numer / timeBaseInfo.denom; 25 | NSLog(@"TemplateKit benchmark: %@ %@ took %0.3f ms", 26 | aClass, message, elapsedNanoSeconds / 1000000.0); 27 | return YES; 28 | } 29 | #endif 30 | -------------------------------------------------------------------------------- /TemplateKit/Internal/Core/TPLContentViewDescriptor.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import 18 | 19 | @class TPLViewModel; 20 | 21 | 22 | @protocol TPLContentViewDescriptor 23 | 24 | - (void)setData:(id)data toView:(UIView *)view; 25 | 26 | - (CGSize)viewSizeThatFits:(CGSize)size withData:(id)data; 27 | 28 | - (id)dataWithViewModel:(TPLViewModel *)viewModel; 29 | 30 | @end 31 | -------------------------------------------------------------------------------- /TemplateKit/Internal/Core/TPLCoreMacros.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import 18 | 19 | 20 | #if DEBUG 21 | id CheckInheritance(id obj, Class aClass); 22 | #define DOWNCAST(obj__, class__) ((class__ *)CheckInheritance(obj__, [class__ class])) 23 | #else 24 | #define DOWNCAST(obj__, class__) ((class__ *)obj__) 25 | #endif 26 | 27 | #if DEBUG 28 | id CheckProtocolConformance(id obj, Protocol *proto); 29 | #define DOWNCAST_P(obj__, proto__) ((id)CheckProtocolConformance(obj__, @protocol(proto__))) 30 | #else 31 | #define DOWNCAST_P(obj__, proto__) ((id)obj__) 32 | #endif 33 | 34 | 35 | #if DEBUG 36 | void CheckNonnull(id obj); 37 | #define CHECK_NONNULL(obj__) CheckNonnull(obj__) 38 | #else 39 | #define CHECK_NONNULL(obj__) 40 | #endif 41 | -------------------------------------------------------------------------------- /TemplateKit/Internal/Core/TPLCoreMacros.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import "Internal/Core/TPLCoreMacros.h" 18 | 19 | #import "Internal/Core/TPLRootViewDescriptor.h" 20 | #import "Internal/Core/TPLViewDescriptor.h" 21 | #import "Internal/Core/TPLViewModel+Internal.h" 22 | 23 | 24 | id CheckInheritance(id obj, Class aClass) { 25 | if (obj && ![obj isKindOfClass:aClass]) { 26 | NSString *reason = 27 | [NSString stringWithFormat:@"Expected %@ but actually is %@", 28 | NSStringFromClass(aClass), NSStringFromClass([obj class])]; 29 | NSException* exception = 30 | [NSException exceptionWithName:@"TPLDowncastFailureException" 31 | reason:reason 32 | userInfo:nil]; 33 | @throw exception; 34 | } 35 | return obj; 36 | } 37 | 38 | id CheckProtocolConformance(id obj, Protocol *proto) { 39 | if (obj && ![obj conformsToProtocol:proto]) { 40 | NSString *reason = 41 | [NSString stringWithFormat:@"Expected id<%@> but actually is not", 42 | NSStringFromProtocol(proto)]; 43 | NSException* exception = 44 | [NSException exceptionWithName:@"TPLDowncastFailureException" 45 | reason:reason 46 | userInfo:nil]; 47 | @throw exception; 48 | } 49 | return obj; 50 | } 51 | 52 | void CheckNonnull(id obj) { 53 | if (!obj) { 54 | NSException* exception = [NSException exceptionWithName:@"TPLNullPointerException" 55 | reason:@"Unexpected null pointer" 56 | userInfo:nil]; 57 | @throw exception; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /TemplateKit/Internal/Core/TPLDebugger.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import "Public/Core/TPLDebugger.h" 18 | 19 | #if TPL_ENABLE_DEBUGGING 20 | 21 | static NSMutableSet *g_debugTags = nil; 22 | static BOOL g_bordering = NO; 23 | 24 | @implementation TPLDebugger 25 | 26 | + (void)enableDebuggingForTag:(NSInteger)tag { 27 | static dispatch_once_t once; 28 | dispatch_once(&once, ^{ 29 | g_debugTags = [[NSMutableSet alloc] init]; 30 | }); 31 | [g_debugTags addObject:@(tag)]; 32 | } 33 | 34 | + (void)disableDebuggingForTag:(NSInteger)tag { 35 | [g_debugTags removeObject:@(tag)]; 36 | } 37 | 38 | + (BOOL)isDebuggingEnabledForView:(UIView *)view { 39 | return [g_debugTags containsObject:@(view.tag)]; 40 | } 41 | 42 | + (void)enableBordering { 43 | g_bordering = YES; 44 | } 45 | 46 | + (void)disableBordering { 47 | g_bordering = NO; 48 | } 49 | 50 | + (BOOL)isBorderingEnabled { 51 | return g_bordering; 52 | } 53 | 54 | @end 55 | 56 | #endif // TPL_ENABLE_DEBUGGING 57 | -------------------------------------------------------------------------------- /TemplateKit/Internal/Core/TPLRootView+Internal.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import "Public/Core/TPLRootView.h" 18 | 19 | 20 | @interface TPLRootView () { 21 | @public 22 | TPLViewModel *_viewModel; 23 | } 24 | 25 | @property(nonatomic) UIView *contentView; 26 | 27 | @end 28 | 29 | TPLRootView *TPLRootViewWithView(UIView *view); 30 | -------------------------------------------------------------------------------- /TemplateKit/Internal/Core/TPLRootView.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import "Internal/Core/TPLRootView+Internal.h" 18 | 19 | #import "Internal/Core/TPLBenchmark.h" 20 | #import "Internal/Core/TPLCoreMacros.h" 21 | #import "Internal/Core/TPLViewDescriptor.h" 22 | 23 | 24 | @implementation TPLRootView 25 | 26 | - (CGSize)sizeThatFits:(CGSize)size { 27 | CGSize result = CGSizeZero; 28 | TPL_BENCHMARK(1, size_calculation, self) { 29 | result = [_contentView.tpl_descriptor viewSizeThatFits:size 30 | withViewModel:_viewModel]; 31 | } 32 | return result; 33 | } 34 | 35 | - (void)setContentView:(UIView *)contentView { 36 | if (_contentView) { 37 | [_contentView removeFromSuperview]; 38 | _contentView = nil; 39 | } 40 | _contentView = contentView; 41 | _contentView.frame = self.bounds; 42 | _contentView.autoresizingMask = 43 | UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; 44 | [self addSubview:_contentView]; 45 | } 46 | 47 | - (void)setViewModel:(TPLViewModel *)viewModel { 48 | TPL_BENCHMARK(1, view_population, self) { 49 | _viewModel = viewModel; 50 | [self.tpl_descriptor populateView:self withViewModel:_viewModel]; 51 | } 52 | } 53 | 54 | @end 55 | 56 | TPLRootView *TPLRootViewWithView(UIView *view) { 57 | UIView *current = [view superview]; 58 | while (current) { 59 | if ([current isKindOfClass:[TPLRootView class]]) { 60 | return DOWNCAST(current, TPLRootView); 61 | } 62 | current = [current superview]; 63 | } 64 | return nil; 65 | } 66 | -------------------------------------------------------------------------------- /TemplateKit/Internal/Core/TPLRootViewDescriptor.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import 18 | 19 | #import "Internal/Core/TPLContentViewDescriptor.h" 20 | #import "Internal/Core/TPLViewDescriptor.h" 21 | 22 | @class TPLValueProvider; 23 | 24 | 25 | @interface TPLRootViewDescriptor : TPLViewDescriptor 26 | 27 | @property(nonatomic) TPLViewDescriptor *subdescriptor; 28 | 29 | @property(nonatomic) Class viewClass; 30 | 31 | @property(nonatomic) TPLValueProvider *submodel; 32 | 33 | @property(nonatomic, getter=isPosteditEnabled) BOOL posteditEnabled; 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /TemplateKit/Internal/Core/TPLRootViewDescriptor.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import "Internal/Core/TPLRootViewDescriptor.h" 18 | 19 | #import "Internal/Core/TPLCoreMacros.h" 20 | #import "Internal/Core/TPLRootView+Internal.h" 21 | #import "Internal/Core/TPLValueProvider.h" 22 | #import "Internal/Core/TPLViewModel+Internal.h" 23 | 24 | 25 | @implementation TPLRootViewDescriptor 26 | 27 | - (instancetype)init { 28 | self = [super init]; 29 | if (self) { 30 | _viewClass = [TPLRootView class]; 31 | } 32 | return self; 33 | } 34 | 35 | - (UIView *)uninitializedView { 36 | return [[_viewClass alloc] init]; 37 | } 38 | 39 | - (void)populateView:(UIView *)view withViewModel:(TPLViewModel *)viewModel { 40 | TPLRootView *rootView = DOWNCAST(view, TPLRootView); 41 | if (_submodel) { 42 | // This is the root of a subtree. 43 | TPLViewModel *submodel = [self submodelWithViewModel:viewModel]; 44 | rootView->_viewModel = submodel; 45 | } 46 | 47 | [super populateView:view withViewModel:viewModel]; 48 | 49 | if (!rootView.contentView) { 50 | rootView.contentView = [_subdescriptor view]; 51 | } 52 | if (_submodel) { 53 | // This is the root of a subtree. 54 | TPLViewModel *submodel = [self submodelWithViewModel:viewModel]; 55 | [_subdescriptor populateView:rootView.contentView withViewModel:submodel]; 56 | } else { 57 | // This is the root of the entire tree that might be comprised of more than one subtree. 58 | [_subdescriptor populateView:rootView.contentView withViewModel:viewModel]; 59 | } 60 | } 61 | 62 | - (CGSize)intrinsicViewSizeThatFits:(CGSize)size 63 | withViewModel:(TPLViewModel *)viewModel { 64 | if (_submodel) { 65 | // This is the root of a subtree. 66 | TPLViewModel *submodel = [self submodelWithViewModel:viewModel]; 67 | return [_subdescriptor viewSizeThatFits:size withViewModel:submodel]; 68 | } else { 69 | // This is the root of the entire tree that might be comprised of more than one subtree. 70 | return [_subdescriptor viewSizeThatFits:size withViewModel:viewModel]; 71 | } 72 | } 73 | 74 | - (TPLViewModel *)submodelWithViewModel:(TPLViewModel *)viewModel { 75 | return [_submodel objectWithViewModel:viewModel]; 76 | } 77 | 78 | - (void)setData:(id)data toView:(UIView *)view { 79 | // This must NOT be the root of the entire tree that might be comprised of more than one subtree. 80 | assert(_submodel); 81 | TPLRootView *rootView = DOWNCAST(view, TPLRootView); 82 | rootView.contentView = [_subdescriptor view]; 83 | rootView->_viewModel = DOWNCAST(data, TPLViewModel); 84 | [_subdescriptor populateView:rootView.contentView 85 | withViewModel:DOWNCAST(data, TPLViewModel)]; 86 | } 87 | 88 | - (CGSize)viewSizeThatFits:(CGSize)size withData:(id)data { 89 | // This must NOT be the root of the entire tree that might be comprised of more than one subtree. 90 | assert(_submodel); 91 | // TODO: I think this method should be called on self. 92 | return [_subdescriptor viewSizeThatFits:size withViewModel:DOWNCAST(data, TPLViewModel)]; 93 | } 94 | 95 | - (id)dataWithViewModel:(TPLViewModel *)viewModel { 96 | // This must NOT be the root of the entire tree that might be comprised of more than one subtree. 97 | assert(_submodel); 98 | return [self submodelWithViewModel:viewModel]; 99 | } 100 | 101 | @end 102 | -------------------------------------------------------------------------------- /TemplateKit/Internal/Core/TPLSettings.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import "Public/Core/TPLSettings.h" 18 | 19 | static NSNumber *g_isRTLOverride = nil; 20 | 21 | 22 | @implementation TPLSettings 23 | 24 | + (BOOL)isRTL { 25 | if (g_isRTLOverride) { 26 | return [g_isRTLOverride boolValue]; 27 | } else { 28 | NSString *languageCode = [[NSLocale currentLocale] objectForKey:NSLocaleLanguageCode]; 29 | NSLocaleLanguageDirection characterDirection = 30 | [NSLocale characterDirectionForLanguage:languageCode]; 31 | BOOL regionLanguageDirectionIsRTL = (characterDirection == NSLocaleLanguageDirectionRightToLeft); 32 | return regionLanguageDirectionIsRTL; 33 | } 34 | } 35 | 36 | + (void)setIsRTLOverride:(BOOL)isRTLOverride { 37 | g_isRTLOverride = @(isRTLOverride); 38 | } 39 | 40 | + (void)clearIsRTLOverride { 41 | g_isRTLOverride = nil; 42 | } 43 | 44 | @end 45 | -------------------------------------------------------------------------------- /TemplateKit/Internal/Core/TPLUtils.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import "Public/Core/TPLUtils.h" 18 | 19 | NSValue *TPLSizeMake(CGFloat width, CGFloat height) { 20 | return [NSValue valueWithCGSize:CGSizeMake(width, height)]; 21 | } 22 | 23 | NSValue *TPLEdgeInsetsMake(CGFloat top, CGFloat left, CGFloat bottom, CGFloat right) { 24 | return [NSValue valueWithUIEdgeInsets:UIEdgeInsetsMake(top, left, bottom, right)]; 25 | } 26 | -------------------------------------------------------------------------------- /TemplateKit/Internal/Core/TPLValueProvider.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import 18 | 19 | @class TPLViewModel; 20 | 21 | @interface TPLValueProvider : NSObject 22 | 23 | + (instancetype)providerWithConstant:(id)constant; 24 | 25 | + (instancetype)providerWithSelector:(SEL)selector; 26 | 27 | - (id)objectWithViewModel:(TPLViewModel *)viewModel; 28 | 29 | - (BOOL)boolValueWithViewModel:(TPLViewModel *)viewModel; 30 | 31 | - (NSInteger)integerValueWithViewModel:(TPLViewModel *)viewModel; 32 | 33 | - (CGFloat)CGFloatValueWithViewModel:(TPLViewModel *)viewModel; 34 | 35 | - (CGSize)CGSizeValueWithViewModel:(TPLViewModel *)viewModel; 36 | 37 | - (UIEdgeInsets)UIEdgeInsetsValueWithViewModel:(TPLViewModel *)viewModel; 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /TemplateKit/Internal/Core/TPLValueProvider.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import "Internal/Core/TPLValueProvider.h" 18 | 19 | #import "Internal/Core/TPLCoreMacros.h" 20 | #import "Internal/Core/TPLViewModel+Internal.h" 21 | 22 | @implementation TPLValueProvider { 23 | id _constant; 24 | SEL _selector; 25 | } 26 | 27 | - (instancetype)initWithConstant:(id)constant 28 | selector:(SEL)selector { 29 | self = [super init]; 30 | if (self) { 31 | _constant = constant; 32 | _selector = selector; 33 | } 34 | return self; 35 | } 36 | 37 | + (instancetype)providerWithConstant:(id)constant { 38 | return [[self alloc] initWithConstant:constant 39 | selector:NULL]; 40 | } 41 | 42 | + (instancetype)providerWithSelector:(SEL)selector { 43 | return [[self alloc] initWithConstant:nil 44 | selector:selector]; 45 | } 46 | 47 | - (id)objectWithViewModel:(TPLViewModel *)viewModel { 48 | if (_selector) { 49 | if (viewModel) { 50 | IMP imp = [viewModel methodForSelector:_selector]; 51 | id (*func)(TPLViewModel *, SEL) = (void *)imp; 52 | return func(viewModel, _selector); 53 | } else { 54 | return nil; 55 | } 56 | } else { 57 | return _constant; 58 | } 59 | } 60 | 61 | #define POD_VALUE_WITH_OBJECT(value_type__, zero_value__, wrapper_type__, selector__) \ 62 | if (_selector) { \ 63 | if (viewModel) { \ 64 | IMP imp = [viewModel methodForSelector:_selector]; \ 65 | value_type__ (*func)(TPLViewModel *, SEL) = (void *)imp; \ 66 | return func(viewModel, _selector); \ 67 | } else { \ 68 | return zero_value__; \ 69 | } \ 70 | } else if ([_constant isKindOfClass:[wrapper_type__ class]]) { \ 71 | return [DOWNCAST(_constant, wrapper_type__) selector__]; \ 72 | } else { \ 73 | return zero_value__; \ 74 | } 75 | 76 | - (BOOL)boolValueWithViewModel:(TPLViewModel *)viewModel { 77 | POD_VALUE_WITH_OBJECT(BOOL, NO, NSNumber, boolValue); 78 | } 79 | 80 | - (NSInteger)integerValueWithViewModel:(TPLViewModel *)viewModel { 81 | POD_VALUE_WITH_OBJECT(NSInteger, 0, NSNumber, integerValue); 82 | } 83 | 84 | - (CGFloat)CGFloatValueWithViewModel:(TPLViewModel *)viewModel { 85 | #if CGFLOAT_IS_DOUBLE 86 | POD_VALUE_WITH_OBJECT(CGFloat, 0.f, NSNumber, doubleValue); 87 | #else 88 | POD_VALUE_WITH_OBJECT(CGFloat, 0.f, NSNumber, floatValue); 89 | #endif 90 | } 91 | 92 | - (CGSize)CGSizeValueWithViewModel:(TPLViewModel *)viewModel { 93 | POD_VALUE_WITH_OBJECT(CGSize, CGSizeZero, NSValue, CGSizeValue) 94 | } 95 | 96 | - (UIEdgeInsets)UIEdgeInsetsValueWithViewModel:(TPLViewModel *)viewModel { 97 | POD_VALUE_WITH_OBJECT(UIEdgeInsets, UIEdgeInsetsZero, NSValue, UIEdgeInsetsValue) 98 | } 99 | 100 | #undef POD_VALUE_WITH_OBJECT 101 | 102 | @end 103 | -------------------------------------------------------------------------------- /TemplateKit/Internal/Core/TPLViewDescriptor.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import 18 | 19 | #import "Public/Core/TPLConstants.h" 20 | #import "Public/Core/TPLViewModifier.h" 21 | 22 | @class TPLAccessibility; 23 | @class TPLValueProvider; 24 | @class TPLViewDescriptorFormatter; 25 | @class TPLViewModel; 26 | @class TPLViewModifierAndValue; 27 | 28 | 29 | @interface TPLViewDescriptor : NSObject 30 | 31 | // public, final. 32 | + (instancetype)descriptor; 33 | 34 | // public, final. 35 | - (UIView *)view; 36 | 37 | // private, pure virtual. 38 | - (UIView *)uninitializedView; 39 | 40 | // public, virtual. Overrides must call super's implementation. 41 | - (void)populateView:(UIView *)view withViewModel:(TPLViewModel *)viewModel; 42 | 43 | // public, final. 44 | - (CGSize)viewSizeThatFits:(CGSize)size 45 | withViewModel:(TPLViewModel *)viewModel; 46 | 47 | // private, pure virtual. 48 | - (CGSize)intrinsicViewSizeThatFits:(CGSize)size 49 | withViewModel:(TPLViewModel *)viewModel; 50 | 51 | // public, virtual. Overrides must respect super's decision to hide the view. 52 | - (BOOL)isViewHiddenWithViewModel:(TPLViewModel *)viewModel; 53 | 54 | // public, final. 55 | @property(nonatomic, copy) NSString *name; 56 | 57 | @property(nonatomic) UIControlEvents activatedControlEvents; 58 | 59 | @property(nonatomic, readonly) NSMutableArray *modifiers; 60 | 61 | // private, virtual. overrides must call super's implementation. 62 | - (void)addDescriptionToFormatter:(TPLViewDescriptorFormatter *)formatter; 63 | 64 | @property(nonatomic) TPLValueProvider *accessibility; // of TPLAccessibility. 65 | @property(nonatomic) TPLValueProvider *backgroundColor; // of UIColor. 66 | @property(nonatomic) TPLValueProvider *cornerRadius; // of NSNumber. 67 | @property(nonatomic) TPLValueProvider *height; // of NSNumber of CGFloat. 68 | @property(nonatomic) TPLValueProvider *hidden; // of NSNumber of BOOL. 69 | @property(nonatomic) TPLValueProvider *position; // of NSNumber of TPLAlignment. 70 | @property(nonatomic) TPLValueProvider *size; // of NSValue of CGSize. 71 | @property(nonatomic) TPLValueProvider *tag; // of NSNumber of NSInteger. 72 | @property(nonatomic) TPLValueProvider *width; // of NSNumber of CGFloat. 73 | 74 | @property(nonatomic, getter=isRTLEnabled) BOOL RTLEnabled; 75 | @property(nonatomic, getter=isTapEnabled) BOOL tapEnabled; 76 | @property(nonatomic, getter=isHorizontalShrinkEnabled) BOOL horizontalShrinkEnabled; 77 | @property(nonatomic, getter=isHorizontalStretchEnabled) BOOL horizontalStretchEnabled; 78 | @property(nonatomic, getter=isVerticalShrinkEnabled) BOOL verticalShrinkEnabled; 79 | @property(nonatomic, getter=isVerticalStretchEnabled) BOOL verticalStretchEnabled; 80 | 81 | @end 82 | 83 | 84 | @interface TPLViewModifierAndValue : NSObject 85 | 86 | @property(nonatomic) id modifier; 87 | @property(nonatomic) TPLValueProvider *value; 88 | 89 | - (instancetype)initWithModifier:(id)modifier value:(TPLValueProvider *)value; 90 | 91 | @end 92 | 93 | 94 | @interface TPLViewDescriptorFormatter : NSObject 95 | 96 | - (void)indent; 97 | - (void)unindent; 98 | - (void)wrap; 99 | - (void)appendString:(NSString *)string; 100 | - (void)appendSubdescriptorDescriptionWithBlock:(void(^)())block; 101 | - (NSString *)string; 102 | 103 | @end 104 | 105 | 106 | @interface UIView (TPLViewDescriptor) 107 | 108 | @property(nonatomic, strong) TPLViewDescriptor *tpl_descriptor; 109 | 110 | @end 111 | -------------------------------------------------------------------------------- /TemplateKit/Internal/Core/TPLViewModel+Internal.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import "Public/Core/TPLViewModel.h" 18 | 19 | 20 | @interface TPLViewModel () 21 | 22 | - (void)__didFireTouchUpInside:(id)sender; 23 | - (void)__didFireValueChanged:(id)sender; 24 | - (void)__didRecognizeTapGesture:(id)sender; 25 | 26 | @end 27 | 28 | TPLViewModel *TPLViewModelWithView(UIView *view); 29 | -------------------------------------------------------------------------------- /TemplateKit/Internal/Core/TPLViewModel.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import "Internal/Core/TPLViewModel+Internal.h" 18 | 19 | #import "Internal/Core/TPLCoreMacros.h" 20 | #import "Internal/Core/TPLRootView+Internal.h" 21 | 22 | 23 | @implementation TPLEvent 24 | @end 25 | 26 | 27 | @implementation TPLViewModel 28 | 29 | - (BOOL)handleEvent:(TPLEvent *)event { 30 | return NO; 31 | } 32 | 33 | - (void)__didFireTouchUpInside:(id)sender { 34 | TPLEvent *event = [[TPLEvent alloc] init]; 35 | event.view = DOWNCAST(sender, UIControl); 36 | event.viewModel = self; 37 | event.controlEvent = UIControlEventTouchUpInside; 38 | [self processEvent:event]; 39 | } 40 | 41 | - (void)__didFireValueChanged:(id)sender { 42 | TPLEvent *event = [[TPLEvent alloc] init]; 43 | event.view = DOWNCAST(sender, UIControl); 44 | event.viewModel = self; 45 | event.controlEvent = UIControlEventValueChanged; 46 | [self processEvent:event]; 47 | } 48 | 49 | - (void)__didRecognizeTapGesture:(id)sender { 50 | TPLEvent *event = [[TPLEvent alloc] init]; 51 | UITapGestureRecognizer *recognizer = DOWNCAST(sender, UITapGestureRecognizer); 52 | event.view = recognizer.view; 53 | event.viewModel = self; 54 | event.gestureRecognizer = recognizer; 55 | [self processEvent:event]; 56 | } 57 | 58 | - (void)processEvent:(TPLEvent *)event { 59 | TPLRootView *rootView = TPLRootViewWithView(event.view); 60 | event.rootView = (TPLView *)rootView; 61 | while (rootView) { 62 | TPLViewModel *viewModel = rootView.viewModel; 63 | if (viewModel.eventDelegate) { 64 | [viewModel.eventDelegate viewModel:viewModel didReceiveEvent:event]; 65 | return; 66 | } else if ([viewModel handleEvent:event]) { 67 | return; 68 | } 69 | rootView = TPLRootViewWithView([rootView superview]); 70 | } 71 | assert(0); 72 | } 73 | 74 | @end 75 | 76 | TPLViewModel *TPLViewModelWithView(UIView *view) { 77 | return TPLRootViewWithView(view).viewModel; 78 | } 79 | -------------------------------------------------------------------------------- /TemplateKit/Internal/DSL/TPLBuilder+Internal.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import "Public/DSL/TPLBuilder.h" 18 | 19 | @class TPLViewDescriptor; 20 | 21 | 22 | @interface TPLBuilderOptions () 23 | 24 | @property(nonatomic) BOOL posteditEnabled; 25 | 26 | @end 27 | 28 | 29 | @interface TPLBuilder () 30 | 31 | @property(nonatomic, strong) TPLViewDescriptor *descriptor; 32 | 33 | - (instancetype)initWithDescriptor:(TPLViewDescriptor *)descriptor; 34 | 35 | + (instancetype)builderWithDescriptor:(TPLViewDescriptor *)descriptor; 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /TemplateKit/Internal/DSL/TPLBuilderFactoryExtension.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import "Public/DSL/TPLBuilderFactoryExtension.h" 18 | 19 | 20 | @implementation TPLBuilderFactoryExtension 21 | @end 22 | -------------------------------------------------------------------------------- /TemplateKit/Internal/DSL/TPLBuilderUtil.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import 18 | 19 | @class TPLViewDescriptor; 20 | 21 | 22 | @interface TPLBuilderUtil : NSObject 23 | 24 | + (void)propagatePropertiesToDescriptor:(TPLViewDescriptor *)descriptor 25 | fromSubdescriptors:(NSArray *)subdescriptors; 26 | 27 | @end 28 | -------------------------------------------------------------------------------- /TemplateKit/Internal/DSL/TPLBuilderUtil.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import "Internal/DSL/TPLBuilderUtil.h" 18 | 19 | #import "Internal/Core/TPLViewDescriptor.h" 20 | 21 | 22 | @implementation TPLBuilderUtil 23 | 24 | + (void)propagatePropertiesToDescriptor:(TPLViewDescriptor *)descriptor 25 | fromSubdescriptors:(NSArray *)subdescriptors { 26 | BOOL horizontalShrinkEnabled = NO; 27 | BOOL horizontalStretchEnabled = NO; 28 | BOOL verticalStrechEnabled = NO; 29 | for (TPLViewDescriptor *subdescriptor in subdescriptors) { 30 | if (subdescriptor.horizontalShrinkEnabled) { 31 | // TODO: Row, column and repeated may want different behaviors. AND or OR? 32 | horizontalShrinkEnabled = YES; 33 | } 34 | if (subdescriptor.horizontalStretchEnabled) { 35 | // TODO: Row, column and repeated may want different behaviors. AND or OR? 36 | horizontalStretchEnabled = YES; 37 | } 38 | if (subdescriptor.verticalStretchEnabled) { 39 | verticalStrechEnabled = YES; 40 | } 41 | } 42 | descriptor.horizontalShrinkEnabled = horizontalShrinkEnabled; 43 | descriptor.horizontalStretchEnabled = horizontalStretchEnabled; 44 | descriptor.verticalStretchEnabled = verticalStrechEnabled; 45 | } 46 | 47 | @end 48 | -------------------------------------------------------------------------------- /TemplateKit/Internal/DSL/TPLDSLMacros.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import "Public/DSL/TPLDSLMacros.h" 18 | 19 | #import "Internal/Core/TPLCoreMacros.h" 20 | #import "Internal/Core/TPLRootViewDescriptor.h" 21 | #import "Internal/Core/TPLValueProvider.h" 22 | #import "Internal/DSL/TPLBuilder+Internal.h" 23 | #import "Internal/DSL/TPLBuilderUtil.h" 24 | #import "Internal/DSL/TPLViewTemplate+Internal.h" 25 | #import "Internal/DescriptorImpls/TPLClientDataViewDescriptor.h" 26 | #import "Internal/DescriptorImpls/TPLClientImmutableDataViewDescriptor.h" 27 | #import "Internal/DescriptorImpls/TPLClientSimpleViewDescriptor.h" 28 | #import "Public/Core/TPLViewModifier.h" 29 | 30 | TPLBuilderFactoryTemplateBlock 31 | TPLBuilderFactoryTemplateBlockCreate(NSString *name, 32 | Class viewClass, 33 | TPLViewTemplateDefinerPointer definer) { 34 | return ^(id arg) { 35 | TPLViewTemplate *template = TPLInstantiateViewTemplate(name, definer); 36 | TPLRootViewDescriptor *rootDescriptor = template.rootDescriptor; 37 | rootDescriptor.name = name; 38 | if ([arg isKindOfClass:[TPLSelectorWrapper class]]) { 39 | rootDescriptor.submodel = 40 | [TPLValueProvider providerWithSelector:DOWNCAST(arg, TPLSelectorWrapper).selector]; 41 | } else { 42 | rootDescriptor.submodel = [TPLValueProvider providerWithConstant:arg]; 43 | } 44 | rootDescriptor.viewClass = viewClass; 45 | return [TPLBuilder builderWithDescriptor:rootDescriptor]; 46 | }; 47 | } 48 | 49 | TPLBuilderSimpleViewBlock TPLBuilderSimpleViewBlockCreate(NSString *name, Class adapterClass) { 50 | return ^{ 51 | TPLClientSimpleViewDescriptor *descriptor = [TPLClientSimpleViewDescriptor descriptor]; 52 | descriptor.name = name; 53 | descriptor.adapter = [[adapterClass alloc] init]; 54 | return [TPLBuilder builderWithDescriptor:descriptor]; 55 | }; 56 | } 57 | 58 | TPLBuilderDataViewBlock TPLBuilderDataViewBlockCreate(NSString *name, Class adapterClass) { 59 | return ^(id arg) { 60 | TPLClientDataViewDescriptor *descriptor = [TPLClientDataViewDescriptor descriptor]; 61 | descriptor.name = name; 62 | descriptor.adapter = [[adapterClass alloc] init]; 63 | if ([arg isKindOfClass:[TPLSelectorWrapper class]]) { 64 | descriptor.data = 65 | [TPLValueProvider providerWithSelector:DOWNCAST(arg, TPLSelectorWrapper).selector]; 66 | } else { 67 | descriptor.data = [TPLValueProvider providerWithConstant:arg]; 68 | } 69 | return [TPLBuilder builderWithDescriptor:descriptor]; 70 | }; 71 | } 72 | 73 | TPLBuilderDataViewBlock TPLBuilderImmutableDataViewBlockCreate(NSString *name, Class adapterClass) { 74 | return ^(id arg) { 75 | TPLClientImmutableDataViewDescriptor *descriptor = 76 | [TPLClientImmutableDataViewDescriptor descriptor]; 77 | descriptor.name = name; 78 | descriptor.adapter = [[adapterClass alloc] init]; 79 | if ([arg isKindOfClass:[TPLSelectorWrapper class]]) { 80 | descriptor.data = 81 | [TPLValueProvider providerWithSelector:DOWNCAST(arg, TPLSelectorWrapper).selector]; 82 | } else { 83 | descriptor.data = [TPLValueProvider providerWithConstant:arg]; 84 | } 85 | return [TPLBuilder builderWithDescriptor:descriptor]; 86 | }; 87 | } 88 | 89 | TPLBuilderModifierBlock TPLBuilderModifierBlockCreate(TPLBuilder *builder, Class modifierClass) { 90 | return ^(id arg) { 91 | id modifier = [[modifierClass alloc] init]; 92 | TPLValueProvider *value; 93 | if ([arg isKindOfClass:[TPLSelectorWrapper class]]) { 94 | value = [TPLValueProvider providerWithSelector:DOWNCAST(arg, TPLSelectorWrapper).selector]; 95 | } else { 96 | value = [TPLValueProvider providerWithConstant:arg]; 97 | } 98 | TPLViewModifierAndValue *pair = 99 | [[TPLViewModifierAndValue alloc] initWithModifier:modifier value:value]; 100 | [builder.descriptor.modifiers addObject:pair]; 101 | return builder; 102 | }; 103 | } 104 | -------------------------------------------------------------------------------- /TemplateKit/Internal/DSL/TPLView.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import "Public/DSL/TPLView.h" 18 | 19 | #import "Internal/Core/TPLBenchmark.h" 20 | #import "Internal/Core/TPLCoreMacros.h" 21 | #import "Internal/Core/TPLRootViewDescriptor.h" 22 | #import "Internal/Core/TPLViewDescriptor.h" 23 | #import "Internal/DSL/TPLViewtemplate+Internal.h" 24 | 25 | 26 | @implementation TPLView 27 | 28 | - (instancetype)init { 29 | return [self initWithFrame:CGRectZero]; 30 | } 31 | 32 | - (instancetype)initWithFrame:(CGRect)frame { 33 | return [self initWithFrame:frame viewTemplate:[[self class] viewTemplate]]; 34 | } 35 | 36 | - (instancetype)initWithFrame:(CGRect)frame viewTemplate:(TPLViewTemplate *)viewTemplate { 37 | self = [super initWithFrame:frame]; 38 | if (self) { 39 | self.tpl_descriptor = viewTemplate.rootDescriptor; 40 | } 41 | return self; 42 | } 43 | 44 | - (void)layoutSubviews { 45 | [super layoutSubviews]; 46 | TPLRootViewDescriptor *rootDescriptor = DOWNCAST(self.tpl_descriptor, TPLRootViewDescriptor); 47 | if (rootDescriptor.posteditEnabled) { 48 | [self didLayoutSubviews]; 49 | } 50 | } 51 | 52 | - (void)didLayoutSubviews { 53 | // no-op. 54 | } 55 | 56 | + (CGSize)sizeThatFits:(CGSize)size withViewModel:(TPLViewModel *)viewModel { 57 | CGSize result = CGSizeZero; 58 | TPLViewTemplate *viewTemplate = [[self class] viewTemplate]; 59 | TPL_BENCHMARK(1, static_size_calculation, self) { 60 | result = [viewTemplate viewSizeThatFits:size withViewModel:viewModel]; 61 | } 62 | return result; 63 | } 64 | 65 | - (void)reloadViewModel { 66 | [self.tpl_descriptor populateView:self 67 | withViewModel:self.viewModel]; 68 | [self setNeedsLayout]; 69 | } 70 | 71 | + (Class)viewTemplateClass { 72 | [self doesNotRecognizeSelector:_cmd]; 73 | return [NSObject class]; 74 | } 75 | 76 | + (TPLViewTemplateDefinerPointer)viewTemplateDefiner { 77 | [self doesNotRecognizeSelector:_cmd]; 78 | return NULL; 79 | } 80 | 81 | + (TPLViewTemplate *)viewTemplate { 82 | TPLViewTemplate *viewTemplate; 83 | TPL_BENCHMARK(1, template_evaluation, self) { 84 | TPLViewTemplateDefinerPointer definer = [self viewTemplateDefiner]; 85 | assert(definer); 86 | // FIXME: Pass name text. 87 | viewTemplate = TPLInstantiateViewTemplate(@"", definer); 88 | assert([viewTemplate isKindOfClass:[TPLViewTemplate class]]); 89 | } 90 | return viewTemplate; 91 | } 92 | 93 | @end 94 | -------------------------------------------------------------------------------- /TemplateKit/Internal/DSL/TPLViewtemplate+Internal.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import "Public/DSL/TPLViewTemplate.h" 18 | 19 | @class TPLRootViewDescriptor; 20 | 21 | 22 | @interface TPLViewTemplate () 23 | 24 | @property(nonatomic, strong) TPLRootViewDescriptor *rootDescriptor; 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /TemplateKit/Internal/DSL/TPLViewtemplate.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import "Internal/DSL/TPLViewTemplate+Internal.h" 18 | 19 | #import "Internal/Core/TPLBenchmark.h" 20 | #import "Internal/Core/TPLRootViewDescriptor.h" 21 | #import "Internal/Core/TPLViewDescriptor.h" 22 | #import "Internal/DSL/TPLBuilder+Internal.h" 23 | #import "Internal/DSL/TPLBuilderUtil.h" 24 | #import "Public/DSL/TPLBuilderFactoryExtension.h" 25 | 26 | 27 | @implementation TPLViewTemplate 28 | 29 | - (CGSize)viewSizeThatFits:(CGSize)size withViewModel:(TPLViewModel *)viewModel { 30 | return [_rootDescriptor viewSizeThatFits:size 31 | withViewModel:viewModel]; 32 | } 33 | 34 | - (NSString *)description { 35 | return [_rootDescriptor description]; 36 | } 37 | 38 | @end 39 | 40 | TPLViewTemplate *TPLInstantiateViewTemplate(NSString *name, TPLViewTemplateDefinerPointer definer) { 41 | TPLBuilderFactory *builderFactory = [[TPLBuilderFactory alloc] init]; 42 | TPLBuilderFactoryExtension *extension = [[TPLBuilderFactoryExtension alloc] init]; 43 | TPLBuilderOptions *options = [[TPLBuilderOptions alloc] init]; 44 | TPLBuilder *builder = definer(builderFactory.activity_indicator, 45 | builderFactory.bind, 46 | @(TPLAlignmentBottom), 47 | @(TPLAlignmentBottomLeft), 48 | @(TPLAlignmentBottomRight), 49 | @(TPLAlignmentCenter), 50 | builderFactory.column, 51 | builderFactory.cond, 52 | extension, 53 | builderFactory.grid, 54 | builderFactory.image, 55 | @(TPLAlignmentJustify), 56 | builderFactory.label, 57 | builderFactory.layer, 58 | @(TPLAlignmentLeft), 59 | builderFactory.margin, 60 | options, 61 | builderFactory.repeated, 62 | @(TPLAlignmentRight), 63 | builderFactory.row, 64 | builderFactory.space, 65 | @(TPLAlignmentTop), 66 | @(TPLAlignmentTopLeft), 67 | @(TPLAlignmentTopRight)); 68 | TPLViewDescriptor *descriptor = builder.descriptor; 69 | TPLRootViewDescriptor *rootDescriptor = [[TPLRootViewDescriptor alloc] init]; 70 | rootDescriptor.subdescriptor = descriptor; 71 | rootDescriptor.posteditEnabled = options.posteditEnabled; 72 | [TPLBuilderUtil propagatePropertiesToDescriptor:rootDescriptor 73 | fromSubdescriptors:@[ descriptor ]]; 74 | 75 | TPLViewTemplate *template = [[TPLViewTemplate alloc] init]; 76 | template.rootDescriptor = rootDescriptor; 77 | return template; 78 | } 79 | -------------------------------------------------------------------------------- /TemplateKit/Internal/DescriptorImpls/TPLActivityIndicatorDescriptor.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import "Internal/DescriptorImpls/TPLDataViewDescriptor.h" 18 | 19 | 20 | @interface TPLActivityIndicatorDescriptor : TPLDataViewDescriptor 21 | @end 22 | -------------------------------------------------------------------------------- /TemplateKit/Internal/DescriptorImpls/TPLActivityIndicatorDescriptor.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import "Internal/DescriptorImpls/TPLActivityIndicatorDescriptor.h" 18 | 19 | #import "Internal/Core/TPLCoreMacros.h" 20 | #import "Public/DescriptorImpls/TPLActivityIndicatorData.h" 21 | 22 | static CGSize g_TPLActivityIndicatorSizeGray; 23 | static CGSize g_TPLActivityIndicatorSizeWhite; 24 | static CGSize g_TPLActivityIndicatorSizeWhiteLarge; 25 | 26 | @implementation TPLActivityIndicatorData 27 | 28 | - (instancetype)init { 29 | self = [super init]; 30 | if (self) { 31 | _hidesWhenStopped = YES; 32 | } 33 | return self; 34 | } 35 | 36 | @end 37 | 38 | 39 | @implementation TPLActivityIndicatorDescriptor 40 | 41 | - (UIView *)uninitializedView { 42 | return [[UIActivityIndicatorView alloc] 43 | initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite]; 44 | } 45 | 46 | - (void)setData:(id)data toView:(UIView *)view { 47 | UIActivityIndicatorView *indicator = DOWNCAST(view, UIActivityIndicatorView); 48 | TPLActivityIndicatorData *indicatorData = DOWNCAST(data, TPLActivityIndicatorData); 49 | indicator.activityIndicatorViewStyle = indicatorData.style; 50 | indicator.hidesWhenStopped = indicatorData.hidesWhenStopped; 51 | if (indicatorData.animating) { 52 | [indicator startAnimating]; 53 | } else { 54 | [indicator stopAnimating]; 55 | } 56 | } 57 | 58 | - (CGSize)viewSizeThatFits:(CGSize)size withData:(id)data { 59 | static dispatch_once_t once; 60 | dispatch_once(&once, ^{ 61 | UIActivityIndicatorView *indicator = [[UIActivityIndicatorView alloc] init]; 62 | indicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyleGray; 63 | [indicator sizeToFit]; 64 | g_TPLActivityIndicatorSizeGray = indicator.bounds.size; 65 | 66 | indicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyleWhite; 67 | [indicator sizeToFit]; 68 | g_TPLActivityIndicatorSizeWhite = indicator.bounds.size; 69 | 70 | indicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyleWhiteLarge; 71 | [indicator sizeToFit]; 72 | g_TPLActivityIndicatorSizeWhiteLarge = indicator.bounds.size; 73 | }); 74 | 75 | switch (DOWNCAST(data, TPLActivityIndicatorData).style) { 76 | case UIActivityIndicatorViewStyleGray: 77 | return g_TPLActivityIndicatorSizeGray; 78 | case UIActivityIndicatorViewStyleWhite: 79 | return g_TPLActivityIndicatorSizeWhite; 80 | case UIActivityIndicatorViewStyleWhiteLarge: 81 | return g_TPLActivityIndicatorSizeWhiteLarge; 82 | } 83 | } 84 | 85 | @end 86 | -------------------------------------------------------------------------------- /TemplateKit/Internal/DescriptorImpls/TPLClientDataViewDescriptor.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import "Internal/DescriptorImpls/TPLDataViewDescriptor.h" 18 | #import "Public/DescriptorImpls/TPLDataViewAdapter.h" 19 | 20 | 21 | @interface TPLClientDataViewDescriptor : TPLDataViewDescriptor 22 | 23 | @property(nonatomic) id adapter; 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /TemplateKit/Internal/DescriptorImpls/TPLClientDataViewDescriptor.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import "Internal/DescriptorImpls/TPLClientDataViewDescriptor.h" 18 | 19 | 20 | @implementation TPLClientDataViewDescriptor 21 | 22 | - (void)setAdapter:(id)adapter { 23 | _adapter = adapter; 24 | if ([_adapter respondsToSelector:@selector(activatedControlEvents)]) { 25 | self.activatedControlEvents = [_adapter activatedControlEvents]; 26 | } 27 | } 28 | 29 | - (UIView *)uninitializedView { 30 | return [_adapter view]; 31 | } 32 | 33 | - (void)setData:(id)data toView:(UIView *)view { 34 | [_adapter setData:data toView:view]; 35 | } 36 | 37 | - (CGSize)viewSizeThatFits:(CGSize)size withData:(id)data { 38 | CGSize result = CGSizeZero; 39 | if ([_adapter respondsToSelector:@selector(viewSizeThatFits:withData:)]) { 40 | result = [_adapter viewSizeThatFits:size withData:data]; 41 | } else { 42 | UIView *view = [self view]; 43 | [self setData:data toView:view]; 44 | result = [view sizeThatFits:size]; 45 | } 46 | return result; 47 | } 48 | 49 | @end 50 | -------------------------------------------------------------------------------- /TemplateKit/Internal/DescriptorImpls/TPLClientImmutableDataViewDescriptor.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import "Internal/DescriptorImpls/TPLDataViewDescriptor.h" 18 | #import "Public/DescriptorImpls/TPLImmutableDataViewAdapter.h" 19 | 20 | 21 | @interface TPLClientImmutableDataViewDescriptor : TPLDataViewDescriptor 22 | 23 | @property(nonatomic) id adapter; 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /TemplateKit/Internal/DescriptorImpls/TPLClientImmutableDataViewDescriptor.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import "Internal/DescriptorImpls/TPLClientImmutableDataViewDescriptor.h" 18 | 19 | 20 | @implementation TPLClientImmutableDataViewDescriptor 21 | 22 | - (void)setAdapter:(id)adapter { 23 | _adapter = adapter; 24 | if ([_adapter respondsToSelector:@selector(activatedControlEvents)]) { 25 | self.activatedControlEvents = [_adapter activatedControlEvents]; 26 | } 27 | } 28 | 29 | - (UIView *)uninitializedView { 30 | return [[UIView alloc] init]; 31 | } 32 | 33 | - (void)setData:(id)data toView:(UIView *)view { 34 | UIView *contentView = [_adapter viewWithData:data]; 35 | contentView.frame = view.bounds; 36 | contentView.autoresizingMask = 37 | UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; 38 | [view addSubview:contentView]; 39 | } 40 | 41 | - (CGSize)viewSizeThatFits:(CGSize)size withData:(id)data { 42 | return [_adapter viewSizeThatFits:size withData:data]; 43 | } 44 | 45 | @end 46 | -------------------------------------------------------------------------------- /TemplateKit/Internal/DescriptorImpls/TPLClientSimpleViewDescriptor.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import "Internal/Core/TPLViewDescriptor.h" 18 | #import "Public/DescriptorImpls/TPLSimpleViewAdapter.h" 19 | 20 | 21 | @interface TPLClientSimpleViewDescriptor : TPLViewDescriptor 22 | 23 | @property(nonatomic) id adapter; 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /TemplateKit/Internal/DescriptorImpls/TPLClientSimpleViewDescriptor.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import "Internal/DescriptorImpls/TPLClientSimpleViewDescriptor.h" 18 | 19 | 20 | @implementation TPLClientSimpleViewDescriptor 21 | 22 | - (void)setAdapter:(id)adapter { 23 | _adapter = adapter; 24 | if ([_adapter respondsToSelector:@selector(activatedControlEvents)]) { 25 | self.activatedControlEvents = [_adapter activatedControlEvents]; 26 | } 27 | } 28 | 29 | - (UIView *)uninitializedView { 30 | return [_adapter view]; 31 | } 32 | 33 | - (CGSize)intrinsicViewSizeThatFits:(CGSize)size 34 | withViewModel:(TPLViewModel *)viewModel { 35 | if ([_adapter respondsToSelector:@selector(viewSizeThatFits:)]) { 36 | return [_adapter viewSizeThatFits:size]; 37 | } else { 38 | return [_adapter view].bounds.size; 39 | } 40 | } 41 | 42 | @end 43 | -------------------------------------------------------------------------------- /TemplateKit/Internal/DescriptorImpls/TPLColumnLayout.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import "Internal/DescriptorImpls/TPLCompositeViewDescriptor.h" 18 | 19 | TPLCompositeLayoutCalculator TPLColumnLayoutCalculatorCreate(); 20 | -------------------------------------------------------------------------------- /TemplateKit/Internal/DescriptorImpls/TPLCompositeViewDescriptor.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import "Internal/Core/TPLViewDescriptor.h" 18 | #import "Internal/DescriptorImpls/TPLContainerViewDescriptor.h" 19 | 20 | @class TPLCompositeViewDescriptor; 21 | 22 | typedef void (^TPLCompositeLayoutCalculator)(TPLCompositeViewDescriptor *compositeDescriptor, 23 | TPLViewModel *viewModel, 24 | CGRect bounds, 25 | BOOL shouldLayout, 26 | CGSize *selfSize, 27 | CGRect *subviewFrames); 28 | 29 | 30 | @interface TPLCompositeViewDescriptor : TPLViewDescriptor 31 | 32 | @property(nonatomic) NSMutableArray *subdescriptors; 33 | @property(nonatomic) TPLValueProvider *layoutConfig; // of TPLLayoutConfig. 34 | @property(nonatomic) TPLValueProvider *subviewAlignment; // of Number of TPLAlignment. 35 | @property(nonatomic) TPLValueProvider *padding; // of NSValue of UIEdgeInsets. 36 | 37 | // protected, final. 38 | - (UIEdgeInsets)paddingWithViewModel:(TPLViewModel *)viewModel; 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /TemplateKit/Internal/DescriptorImpls/TPLCompositeViewDescriptor.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import "Internal/DescriptorImpls/TPLCompositeViewDescriptor.h" 18 | 19 | #import "Internal/Core/TPLCoreMacros.h" 20 | #import "Internal/Core/TPLValueProvider.h" 21 | #import "Internal/Core/TPLViewModel+Internal.h" 22 | #import "Internal/DescriptorImpls/TPLColumnLayout.h" 23 | #import "Internal/DescriptorImpls/TPLContextualSpaceSelector.h" 24 | #import "Internal/DescriptorImpls/TPLLayerLayout.h" 25 | #import "Internal/DescriptorImpls/TPLRowLayout.h" 26 | #import "Internal/DescriptorImpls/TPLSpaceDescriptor.h" 27 | #import "Public/Core/TPLSettings.h" 28 | #import "Public/DescriptorImpls/TPLLayoutConfig.h" 29 | 30 | static TPLCompositeLayoutCalculator LayoutCalculatorWithConfig(TPLLayoutConfig *config) { 31 | switch (config.layoutType) { 32 | case TPLLayoutTypeRow: 33 | return TPLRowLayoutCalculatorCreate(); 34 | case TPLLayoutTypeColumn: 35 | return TPLColumnLayoutCalculatorCreate(); 36 | case TPLLayoutTypeLayer: 37 | return TPLLayerLayoutCalculatorCreate(); 38 | default: 39 | // Defaults to row. 40 | assert(NO); 41 | return TPLRowLayoutCalculatorCreate(); 42 | } 43 | } 44 | 45 | static CGRect TPLRTLFrame(CGRect frame, CGRect containerBounds) { 46 | CGFloat rightMargin = CGRectGetWidth(containerBounds) - CGRectGetMaxX(frame); 47 | frame.origin.x = rightMargin; 48 | return frame; 49 | } 50 | 51 | 52 | @implementation TPLCompositeViewDescriptor 53 | 54 | - (instancetype)init { 55 | self = [super init]; 56 | if (self) { 57 | _subdescriptors = [[NSMutableArray alloc] init]; 58 | } 59 | return self; 60 | } 61 | 62 | - (TPLContainerView *)uninitializedView { 63 | TPLContainerView *view = [[TPLContainerView alloc] init]; 64 | for (TPLViewDescriptor *subdescriptor in _subdescriptors) { 65 | UIView *subview = [subdescriptor view]; 66 | CHECK_NONNULL(subview.tpl_descriptor); 67 | [view addSubview:subview]; 68 | [view.tpl_subviews addObject:subview]; 69 | } 70 | return view; 71 | } 72 | 73 | - (void)populateView:(UIView *)view withViewModel:(TPLViewModel *)viewModel { 74 | [super populateView:view withViewModel:viewModel]; 75 | 76 | TPLContainerView *containerView = DOWNCAST(view, TPLContainerView); 77 | NSInteger index = 0; 78 | for (TPLViewDescriptor *subdesc in _subdescriptors) { 79 | UIView *subview = containerView.tpl_subviews[index]; 80 | [subdesc populateView:subview withViewModel:viewModel]; 81 | ++index; 82 | } 83 | } 84 | 85 | - (BOOL)isViewHiddenWithViewModel:(TPLViewModel *)viewModel { 86 | if ([super isViewHiddenWithViewModel:viewModel]) { 87 | return YES; 88 | } 89 | 90 | for (TPLViewDescriptor *subdesc in self.subdescriptors) { 91 | if ([subdesc isKindOfClass:[TPLSpaceDescriptor class]] 92 | && !DOWNCAST(subdesc, TPLSpaceDescriptor).shouldAlwaysShow) { 93 | continue; 94 | } 95 | BOOL subviewHidden = [subdesc isViewHiddenWithViewModel:viewModel]; 96 | if (!subviewHidden) { 97 | return NO; 98 | } 99 | } 100 | return YES; 101 | } 102 | 103 | - (CGSize)intrinsicViewSizeThatFits:(CGSize)size 104 | withViewModel:(TPLViewModel *)viewModel { 105 | TPLCompositeLayoutCalculator layoutCalculator = 106 | LayoutCalculatorWithConfig([_layoutConfig objectWithViewModel:viewModel]); 107 | CGSize selfSize; 108 | layoutCalculator(self, 109 | viewModel, 110 | CGRectMake(0, 0, size.width, size.height), 111 | NO, 112 | &selfSize, 113 | NULL); 114 | return selfSize; 115 | } 116 | 117 | - (void)layoutSubviewsInContainerView:(TPLContainerView *)containerView { 118 | TPLViewModel *viewModel = TPLViewModelWithView(containerView); 119 | TPLCompositeLayoutCalculator layoutCalculator = 120 | LayoutCalculatorWithConfig([_layoutConfig objectWithViewModel:viewModel]); 121 | CGRect bounds = containerView.bounds; 122 | CGRect subviewFrames[self.subdescriptors.count]; 123 | layoutCalculator(self, 124 | viewModel, 125 | bounds, 126 | YES, 127 | NULL, 128 | subviewFrames); 129 | BOOL isRTL = [TPLSettings isRTL]; 130 | NSUInteger index = 0; 131 | for (UIView *subview in containerView.tpl_subviews) { 132 | if (isRTL && subview.tpl_descriptor.RTLEnabled) { 133 | subviewFrames[index] = TPLRTLFrame(subviewFrames[index], bounds); 134 | } 135 | subview.frame = subviewFrames[index]; 136 | ++index; 137 | } 138 | } 139 | 140 | - (UIEdgeInsets)paddingWithViewModel:(TPLViewModel *)viewModel { 141 | return [_padding UIEdgeInsetsValueWithViewModel:viewModel]; 142 | } 143 | 144 | - (void)addDescriptionToFormatter:(TPLViewDescriptorFormatter *)formatter { 145 | [super addDescriptionToFormatter:formatter]; 146 | [formatter appendSubdescriptorDescriptionWithBlock:^{ 147 | for (TPLViewDescriptor *subdesc in _subdescriptors) { 148 | [subdesc addDescriptionToFormatter:formatter]; 149 | if (subdesc != _subdescriptors.lastObject) { 150 | [formatter wrap]; 151 | } 152 | } 153 | }]; 154 | } 155 | 156 | @end 157 | 158 | -------------------------------------------------------------------------------- /TemplateKit/Internal/DescriptorImpls/TPLContainerViewDescriptor.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import 18 | 19 | @class TPLContainerView; 20 | 21 | 22 | @protocol TPLContainerViewDescriptor 23 | 24 | - (void)layoutSubviewsInContainerView:(TPLContainerView *)containerView; 25 | 26 | @end 27 | 28 | 29 | @interface TPLContainerView : UIView 30 | 31 | @property(nonatomic, strong, readonly) NSMutableArray *tpl_subviews; 32 | 33 | - (void)removeAllSubviews; 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /TemplateKit/Internal/DescriptorImpls/TPLContainerViewDescriptor.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import "Internal/DescriptorImpls/TPLContainerViewDescriptor.h" 18 | 19 | #import "Internal/Core/TPLBenchmark.h" 20 | #import "Internal/Core/TPLCoreMacros.h" 21 | #import "Internal/Core/TPLViewDescriptor.h" 22 | #import "Public/Core/TPLDebugger.h" 23 | 24 | @implementation TPLContainerView 25 | 26 | - (instancetype)initWithFrame:(CGRect)frame { 27 | self = [super initWithFrame:frame]; 28 | if (self) { 29 | _tpl_subviews = [[NSMutableArray alloc] init]; 30 | } 31 | return self; 32 | } 33 | 34 | - (void)removeAllSubviews { 35 | for (UIView *subview in _tpl_subviews) { 36 | [subview removeFromSuperview]; 37 | } 38 | [_tpl_subviews removeAllObjects]; 39 | } 40 | 41 | - (void)layoutSubviews { 42 | #if TPL_ENABLE_DEBUGGING 43 | if ([TPLDebugger isDebuggingEnabledForView:self]) { 44 | NSLog(@"%zd:%p layoutSubviews frame:%@", 45 | self.tag, 46 | self, 47 | NSStringFromCGRect(self.frame)); 48 | } 49 | #endif // TPL_ENABLE_DEBUGGING 50 | 51 | TPL_BENCHMARK(1, view_layout, self.tpl_descriptor) { 52 | [super layoutSubviews]; 53 | [(id)self.tpl_descriptor layoutSubviewsInContainerView:self]; 54 | } 55 | } 56 | 57 | #if TPL_ENABLE_DEBUGGING 58 | - (void)setFrame:(CGRect)frame { 59 | if ([TPLDebugger isDebuggingEnabledForView:self]) { 60 | NSLog(@"%zd:%p setFrame oldFrame:%@ newFrame:%@", 61 | self.tag, 62 | self, 63 | NSStringFromCGRect(self.frame), 64 | NSStringFromCGRect(frame)); 65 | } 66 | 67 | [super setFrame:frame]; 68 | } 69 | #endif // TPL_ENABLE_DEBUGGING 70 | 71 | #if TPL_ENABLE_DEBUGGING 72 | - (void)setBounds:(CGRect)bounds { 73 | if ([TPLDebugger isDebuggingEnabledForView:self]) { 74 | NSLog(@"%zd:%p setFrame oldBounds:%@ newBounds:%@", 75 | self.tag, 76 | self, 77 | NSStringFromCGRect(self.bounds), 78 | NSStringFromCGRect(bounds)); 79 | } 80 | 81 | [super setBounds:bounds]; 82 | } 83 | #endif // TPL_ENABLE_DEBUGGING 84 | 85 | #if TPL_ENABLE_DEBUGGING 86 | - (void)setNeedsLayout { 87 | if ([TPLDebugger isDebuggingEnabledForView:self]) { 88 | NSLog(@"%zd:%p setNeedsLayout frame:%@", 89 | self.tag, 90 | self, 91 | NSStringFromCGRect(self.frame)); 92 | } 93 | 94 | [super setNeedsLayout]; 95 | } 96 | #endif // TPL_ENABLE_DEBUGGING 97 | 98 | @end 99 | -------------------------------------------------------------------------------- /TemplateKit/Internal/DescriptorImpls/TPLContextualSpaceSelector.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import 18 | 19 | struct TPLContextualSpaceSelector; 20 | typedef struct TPLContextualSpaceSelector *TPLContextualSpaceSelectorRef; 21 | 22 | TPLContextualSpaceSelectorRef TPLContextualSpaceSelectorCreate(NSInteger numberOfViews); 23 | void TPLContextualSpaceSelectorDelete(TPLContextualSpaceSelectorRef selector); 24 | 25 | void TPLContextualSpaceSelectorAddView(TPLContextualSpaceSelectorRef selector, BOOL isHidden); 26 | void TPLContextualSpaceSelectorAddContextualSpace(TPLContextualSpaceSelectorRef selector); 27 | 28 | NSInteger TPLContextualSpaceSelectorGetSpaceToBeHiddenCount(TPLContextualSpaceSelectorRef selector); 29 | NSInteger *TPLContextualSpaceSelectorGetSpaceToBeHiddenIndexes(TPLContextualSpaceSelectorRef selector); 30 | -------------------------------------------------------------------------------- /TemplateKit/Internal/DescriptorImpls/TPLContextualSpaceSelector.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import "Internal/DescriptorImpls/TPLContextualSpaceSelector.h" 18 | 19 | static void ContextualSpaceSelectorFinalize(TPLContextualSpaceSelectorRef selector); 20 | 21 | typedef struct { 22 | BOOL isSpace; 23 | BOOL isHidden; 24 | } TPLContextualSpaceSelectorInput; 25 | 26 | typedef struct TPLContextualSpaceSelector { 27 | NSInteger inputCount; 28 | NSInteger nextInputIndex; 29 | TPLContextualSpaceSelectorInput *input; 30 | NSInteger spaceToBeHiddenCount; 31 | NSInteger *spaceToBeHiddenIndexes; 32 | } TPLContextualSpaceSelector; 33 | 34 | TPLContextualSpaceSelectorRef TPLContextualSpaceSelectorCreate(NSInteger numberOfViews) { 35 | TPLContextualSpaceSelectorRef selector = malloc(sizeof(TPLContextualSpaceSelector)); 36 | selector->inputCount = numberOfViews; 37 | selector->nextInputIndex = 0; 38 | selector->input = malloc(sizeof(TPLContextualSpaceSelectorInput) * numberOfViews); 39 | selector->spaceToBeHiddenCount = 0; 40 | selector->spaceToBeHiddenIndexes = malloc(sizeof(NSInteger) * numberOfViews); 41 | return selector; 42 | } 43 | 44 | void TPLContextualSpaceSelectorDelete(TPLContextualSpaceSelectorRef selector) { 45 | free(selector->input); 46 | free(selector->spaceToBeHiddenIndexes); 47 | free(selector); 48 | } 49 | 50 | void TPLContextualSpaceSelectorAddView(TPLContextualSpaceSelectorRef selector, BOOL isHidden) { 51 | assert(selector->nextInputIndex < selector->inputCount); 52 | 53 | TPLContextualSpaceSelectorInput *input = &selector->input[selector->nextInputIndex]; 54 | input->isSpace = NO; 55 | input->isHidden = isHidden; 56 | ++selector->nextInputIndex; 57 | 58 | if (selector->nextInputIndex == selector->inputCount) { 59 | ContextualSpaceSelectorFinalize(selector); 60 | } 61 | } 62 | 63 | void TPLContextualSpaceSelectorAddContextualSpace(TPLContextualSpaceSelectorRef selector) { 64 | assert(selector->nextInputIndex < selector->inputCount); 65 | 66 | TPLContextualSpaceSelectorInput *input = &selector->input[selector->nextInputIndex]; 67 | input->isSpace = YES; 68 | input->isHidden = NO; 69 | ++selector->nextInputIndex; 70 | 71 | if (selector->nextInputIndex == selector->inputCount) { 72 | ContextualSpaceSelectorFinalize(selector); 73 | } 74 | } 75 | 76 | NSInteger TPLContextualSpaceSelectorGetSpaceToBeHiddenCount(TPLContextualSpaceSelectorRef selector) { 77 | assert(selector->nextInputIndex == selector->inputCount); 78 | 79 | return selector->spaceToBeHiddenCount; 80 | } 81 | 82 | NSInteger *TPLContextualSpaceSelectorGetSpaceToBeHiddenIndexes(TPLContextualSpaceSelectorRef selector) { 83 | assert(selector->nextInputIndex == selector->inputCount); 84 | 85 | return selector->spaceToBeHiddenIndexes; 86 | } 87 | 88 | static void ContextualSpaceSelectorFinalize(TPLContextualSpaceSelectorRef selector) { 89 | BOOL hasPrecedingView = NO; 90 | NSInteger pendingSpaceIndex = -1; 91 | for (NSInteger index = 0; index < selector->inputCount; ++index) { 92 | TPLContextualSpaceSelectorInput *input = &selector->input[index]; 93 | if (input->isSpace) { 94 | if (hasPrecedingView) { 95 | pendingSpaceIndex = index; 96 | } else { 97 | input->isHidden = YES; 98 | } 99 | hasPrecedingView = NO; 100 | } else { 101 | if (!input->isHidden) { 102 | pendingSpaceIndex = -1; 103 | hasPrecedingView = YES; 104 | } 105 | } 106 | } 107 | if (pendingSpaceIndex >= 0) { 108 | selector->input[pendingSpaceIndex].isHidden = YES; 109 | } 110 | 111 | for (NSInteger index = 0; index < selector->inputCount; ++index) { 112 | const TPLContextualSpaceSelectorInput input = selector->input[index]; 113 | if (input.isSpace && input.isHidden) { 114 | selector->spaceToBeHiddenIndexes[selector->spaceToBeHiddenCount] = index; 115 | ++selector->spaceToBeHiddenCount; 116 | } 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /TemplateKit/Internal/DescriptorImpls/TPLDataViewDescriptor.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import "Internal/Core/TPLContentViewDescriptor.h" 18 | #import "Internal/Core/TPLViewDescriptor.h" 19 | 20 | @class TPLValueProvider; 21 | 22 | // An abstract superclass of describers for views that takes 23 | // one data object to display. 24 | @interface TPLDataViewDescriptor : TPLViewDescriptor 25 | 26 | @property(nonatomic, strong) TPLValueProvider *data; 27 | 28 | // pure virtual. 29 | - (void)setData:(id)data toView:(UIView *)view; 30 | 31 | // pure virtual. 32 | - (CGSize)viewSizeThatFits:(CGSize)size withData:(id)data; 33 | 34 | // virtual. 35 | // The default implementation returns NO. 36 | - (BOOL)isViewHiddenWithData:(id)data; 37 | 38 | - (id)dataWithViewModel:(TPLViewModel *)viewModel; 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /TemplateKit/Internal/DescriptorImpls/TPLDataViewDescriptor.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import "Internal/DescriptorImpls/TPLDataViewDescriptor.h" 18 | 19 | #import "Internal/Core/TPLValueProvider.h" 20 | #import "Internal/Core/TPLViewModel+Internal.h" 21 | 22 | 23 | @implementation TPLDataViewDescriptor 24 | 25 | - (void)setData:(id)data toView:(UIView *)view { 26 | [self doesNotRecognizeSelector:_cmd]; 27 | } 28 | 29 | - (CGSize)viewSizeThatFits:(CGSize)size withData:(id)data { 30 | [self doesNotRecognizeSelector:_cmd]; 31 | return CGSizeZero; 32 | } 33 | 34 | - (void)populateView:(UIView *)view withViewModel:(TPLViewModel *)viewModel { 35 | [super populateView:view withViewModel:viewModel]; 36 | 37 | id data = [self dataWithViewModel:viewModel]; 38 | [self setData:data toView:view]; 39 | } 40 | 41 | - (CGSize)intrinsicViewSizeThatFits:(CGSize)size 42 | withViewModel:(TPLViewModel *)viewModel { 43 | id data = [self dataWithViewModel:viewModel]; 44 | return [self viewSizeThatFits:size withData:data]; 45 | } 46 | 47 | - (BOOL)isViewHiddenWithViewModel:(TPLViewModel *)viewModel { 48 | if ([super isViewHiddenWithViewModel:viewModel]) { 49 | return YES; 50 | } 51 | id data = [self dataWithViewModel:viewModel]; 52 | if (!data) { 53 | return YES; 54 | } 55 | return [self isViewHiddenWithData:data]; 56 | } 57 | 58 | - (BOOL)isViewHiddenWithData:(id)data { 59 | return NO; 60 | } 61 | 62 | - (id)dataWithViewModel:(TPLViewModel *)viewModel { 63 | return [_data objectWithViewModel:viewModel]; 64 | } 65 | 66 | @end 67 | -------------------------------------------------------------------------------- /TemplateKit/Internal/DescriptorImpls/TPLDescriptorImplsMacros.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | 19 | #if CGFLOAT_IS_DOUBLE 20 | #define TPL_CEIL ceil 21 | #define TPL_FLOOR floor 22 | #define TPL_FMAX fmax 23 | #define TPL_FMIN fmin 24 | #else 25 | #define TPL_CEIL ceilf 26 | #define TPL_FLOOR floorf 27 | #define TPL_FMAX fmaxf 28 | #define TPL_FMIN fminf 29 | #endif 30 | -------------------------------------------------------------------------------- /TemplateKit/Internal/DescriptorImpls/TPLGridDescriptor.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import "Internal/DescriptorImpls/TPLMultiplexerViewDescriptor.h" 18 | 19 | @class TPLValueProvider; 20 | 21 | 22 | @interface TPLGridDescriptor : TPLMultiplexerViewDescriptor 23 | 24 | @property(nonatomic) TPLValueProvider *config; // of TPLGridConfig. 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /TemplateKit/Internal/DescriptorImpls/TPLGridDescriptor.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import "Internal/DescriptorImpls/TPLGridDescriptor.h" 18 | 19 | #include 20 | 21 | #import "Internal/Core/TPLCoreMacros.h" 22 | #import "Internal/Core/TPLValueProvider.h" 23 | #import "Internal/Core/TPLViewModel+Internal.h" 24 | #import "Internal/DescriptorImpls/TPLDataViewDescriptor.h" 25 | #import "Internal/DescriptorImpls/TPLDescriptorImplsMacros.h" 26 | #import "Public/DescriptorImpls/TPLGridConfig.h" 27 | 28 | 29 | @implementation TPLGridConfig 30 | 31 | - (instancetype)init { 32 | self = [super init]; 33 | if (self) { 34 | _numberOfColumns = 2; 35 | _columnMargin = 5.f; 36 | _rowMargin = 5.f; 37 | } 38 | return self; 39 | } 40 | 41 | @end 42 | 43 | 44 | @implementation TPLGridDescriptor 45 | 46 | - (instancetype)init { 47 | self = [super init]; 48 | if (self) { 49 | _config = [TPLValueProvider providerWithConstant:[[TPLGridConfig alloc] init]]; 50 | } 51 | return self; 52 | } 53 | 54 | - (CGSize)intrinsicViewSizeThatFits:(CGSize)size 55 | withViewModel:(TPLViewModel *)viewModel { 56 | NSArray *dataArray = [self dataArrayWithViewModel:viewModel]; 57 | NSInteger numberOfCells = dataArray.count; 58 | if (numberOfCells == 0) { 59 | return CGSizeZero; 60 | } 61 | TPLGridConfig *config = [_config objectWithViewModel:viewModel]; 62 | NSInteger numberOfColumns = config.numberOfColumns; 63 | NSInteger numberOfRows = (numberOfCells + numberOfColumns - 1) / numberOfColumns; 64 | CGSize firstCellMaxSize = CGSizeMake(ceil(size.width / numberOfColumns), 65 | ceil(size.height / numberOfRows)); 66 | CGSize firstCellSize = [self.subdescriptor viewSizeThatFits:firstCellMaxSize 67 | withData:dataArray[0]]; 68 | CGFloat finalWidth = 69 | ceil(firstCellSize.width) * numberOfColumns + config.columnMargin * (numberOfColumns - 1); 70 | CGFloat finalHeight = 71 | ceil(firstCellSize.height) * numberOfRows + config.rowMargin * (numberOfRows - 1); 72 | CGSize finalSize = CGSizeMake(finalWidth, finalHeight); 73 | return finalSize; 74 | } 75 | 76 | - (void)layoutSubviewsInContainerView:(TPLContainerView *)containerView { 77 | TPLViewModel *viewModel = TPLViewModelWithView(containerView); 78 | TPLGridConfig *config = [_config objectWithViewModel:viewModel]; 79 | NSArray *dataArray = [self dataArrayWithViewModel:viewModel]; 80 | NSInteger numberOfCells = dataArray.count; 81 | NSInteger numberOfColumns = config.numberOfColumns; 82 | NSInteger numberOfRows = (numberOfCells + numberOfColumns - 1) / numberOfColumns; 83 | CGRect bounds = containerView.bounds; 84 | CGFloat columnWidth = 85 | (CGRectGetWidth(bounds) - config.columnMargin * (numberOfColumns - 1)) / numberOfColumns; 86 | CGFloat rowHeight = 87 | (CGRectGetHeight(bounds) - config.rowMargin * (numberOfRows - 1)) / numberOfRows; 88 | for (NSUInteger cellIndex = 0; cellIndex < dataArray.count; ++cellIndex) { 89 | NSUInteger columnIndex = cellIndex % numberOfColumns; 90 | NSUInteger rowIndex = cellIndex / numberOfColumns; 91 | UIView *subview = containerView.tpl_subviews[cellIndex]; 92 | subview.frame = CGRectMake(TPL_CEIL((columnWidth + config.columnMargin) * columnIndex), 93 | TPL_CEIL((rowHeight + config.rowMargin) * rowIndex), 94 | TPL_CEIL(columnWidth), 95 | TPL_CEIL(rowHeight)); 96 | } 97 | } 98 | 99 | @end 100 | -------------------------------------------------------------------------------- /TemplateKit/Internal/DescriptorImpls/TPLImageDescriptor.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import "Internal/DescriptorImpls/TPLDataViewDescriptor.h" 18 | 19 | 20 | @interface TPLImageDescriptor : TPLDataViewDescriptor 21 | @end 22 | -------------------------------------------------------------------------------- /TemplateKit/Internal/DescriptorImpls/TPLImageDescriptor.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import "Internal/DescriptorImpls/TPLImageDescriptor.h" 18 | 19 | #import "Internal/Core/TPLCoreMacros.h" 20 | 21 | 22 | @implementation TPLImageDescriptor 23 | 24 | - (UIView *)uninitializedView { 25 | return [[UIImageView alloc] init]; 26 | } 27 | 28 | - (void)setData:(id)data toView:(UIView *)view { 29 | DOWNCAST(view, UIImageView).image = DOWNCAST(data, UIImage); 30 | } 31 | 32 | - (CGSize)viewSizeThatFits:(CGSize)size withData:(id)data { 33 | return DOWNCAST(data, UIImage).size; 34 | } 35 | 36 | @end 37 | -------------------------------------------------------------------------------- /TemplateKit/Internal/DescriptorImpls/TPLLabelDescriptor.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import "Internal/DescriptorImpls/TPLDataViewDescriptor.h" 18 | #import "Public/DescriptorImpls/TPLLabelData.h" 19 | 20 | 21 | @interface TPLLabelDescriptor : TPLDataViewDescriptor 22 | @end 23 | -------------------------------------------------------------------------------- /TemplateKit/Internal/DescriptorImpls/TPLLayerLayout.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import "Internal/DescriptorImpls/TPLCompositeViewDescriptor.h" 18 | 19 | TPLCompositeLayoutCalculator TPLLayerLayoutCalculatorCreate(); 20 | -------------------------------------------------------------------------------- /TemplateKit/Internal/DescriptorImpls/TPLLayerLayout.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import "Internal/DescriptorImpls/TPLLayerLayout.h" 18 | 19 | #import "Internal/Core/TPLValueProvider.h" 20 | 21 | #import 22 | 23 | static CGPoint TPLLayerLayoutSubviewOrigin(CGSize subviewSize, 24 | CGRect containerBounds, 25 | TPLAlignment position) { 26 | CGFloat widthDelta = CGRectGetWidth(containerBounds) - subviewSize.width; 27 | CGFloat xOffset = 0; 28 | switch (position) { 29 | case TPLAlignmentLeft: 30 | case TPLAlignmentTopLeft: 31 | case TPLAlignmentBottomLeft: 32 | xOffset = 0; 33 | break; 34 | case TPLAlignmentRight: 35 | case TPLAlignmentTopRight: 36 | case TPLAlignmentBottomRight: 37 | xOffset = widthDelta; 38 | break; 39 | default: 40 | xOffset = floor(widthDelta / 2); 41 | break; 42 | } 43 | 44 | CGFloat heightDelta = CGRectGetHeight(containerBounds) - subviewSize.height; 45 | CGFloat yOffset = 0; 46 | switch (position) { 47 | case TPLAlignmentTop: 48 | case TPLAlignmentTopLeft: 49 | case TPLAlignmentTopRight: 50 | yOffset = 0; 51 | break; 52 | case TPLAlignmentBottom: 53 | case TPLAlignmentBottomLeft: 54 | case TPLAlignmentBottomRight: 55 | yOffset = heightDelta; 56 | break; 57 | default: 58 | yOffset = floor(heightDelta / 2); 59 | break; 60 | } 61 | 62 | CGPoint origin = CGPointMake(CGRectGetMinX(containerBounds) + xOffset, 63 | CGRectGetMinY(containerBounds) + yOffset); 64 | return origin; 65 | } 66 | 67 | TPLCompositeLayoutCalculator TPLLayerLayoutCalculatorCreate() { 68 | static const CGFloat kVeryLargeDimention = 1000000; 69 | 70 | return ^(TPLCompositeViewDescriptor *compositeDescriptor, 71 | TPLViewModel *viewModel, 72 | CGRect bounds, 73 | BOOL shouldLayout, 74 | CGSize *selfSize, 75 | CGRect *subviewFrames) { 76 | NSArray *subdescriptors = compositeDescriptor.subdescriptors; 77 | 78 | UIEdgeInsets insets = [compositeDescriptor paddingWithViewModel:viewModel]; 79 | CGRect containerBounds = UIEdgeInsetsInsetRect(bounds, insets); 80 | CGFloat containerWidth = CGRectGetWidth(containerBounds); 81 | // CGFloat containerHeight = CGRectGetHeight(containerBounds); 82 | 83 | CGSize unlimitedSize = CGSizeMake(CGRectGetWidth(containerBounds), kVeryLargeDimention); 84 | CGFloat maxWidth = 0; 85 | CGFloat maxHeight = 0; 86 | NSInteger index = 0; 87 | for (TPLViewDescriptor *subdesc in subdescriptors) { 88 | CGSize size = [subdesc viewSizeThatFits:unlimitedSize withViewModel:viewModel]; 89 | if (size.width < containerWidth && subdesc.horizontalStretchEnabled) { 90 | size.width = containerWidth; 91 | } 92 | maxWidth = fmax(maxWidth, size.width); 93 | maxHeight = fmax(maxHeight, size.height); 94 | if (shouldLayout) { 95 | TPLAlignment position = [subdesc.position integerValueWithViewModel:viewModel]; 96 | CGPoint origin = TPLLayerLayoutSubviewOrigin(size, containerBounds, position); 97 | subviewFrames[index] = (CGRect){.origin = origin, .size = size}; 98 | } 99 | ++index; 100 | } 101 | 102 | if (!shouldLayout) { 103 | *selfSize = CGSizeMake(insets.left + maxWidth + insets.right, 104 | insets.top + maxHeight + insets.bottom); 105 | } 106 | }; 107 | } 108 | -------------------------------------------------------------------------------- /TemplateKit/Internal/DescriptorImpls/TPLLayoutConfig.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import "Public/DescriptorImpls/TPLLayoutConfig.h" 18 | 19 | @implementation TPLLayoutConfig 20 | 21 | + (instancetype)defaultRowLayoutConfig { 22 | TPLLayoutConfig *config = [[TPLLayoutConfig alloc] init]; 23 | config.layoutType = TPLLayoutTypeRow; 24 | return config; 25 | } 26 | 27 | + (instancetype)defaultColumnLayoutConfig { 28 | TPLLayoutConfig *config = [[TPLLayoutConfig alloc] init]; 29 | config.layoutType = TPLLayoutTypeColumn; 30 | return config; 31 | } 32 | 33 | + (instancetype)defaultLayerLayoutConfig { 34 | TPLLayoutConfig *config = [[TPLLayoutConfig alloc] init]; 35 | config.layoutType = TPLLayoutTypeLayer; 36 | return config; 37 | } 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /TemplateKit/Internal/DescriptorImpls/TPLMultiplexerViewDescriptor.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import "Internal/Core/TPLViewDescriptor.h" 18 | #import "Internal/DescriptorImpls/TPLContainerViewDescriptor.h" 19 | 20 | @protocol TPLContentViewDescriptor; 21 | 22 | 23 | @interface TPLMultiplexerViewDescriptor : TPLViewDescriptor 24 | 25 | @property(nonatomic, strong) TPLViewDescriptor *subdescriptor; 26 | 27 | - (NSArray *)dataArrayWithViewModel:(TPLViewModel *)viewModel; 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /TemplateKit/Internal/DescriptorImpls/TPLMultiplexerViewDescriptor.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import "Internal/DescriptorImpls/TPLMultiplexerViewDescriptor.h" 18 | 19 | #import "Internal/Core/TPLCoreMacros.h" 20 | #import "Internal/DescriptorImpls/TPLDataViewDescriptor.h" 21 | 22 | 23 | @implementation TPLMultiplexerViewDescriptor 24 | 25 | - (UIView *)uninitializedView { 26 | return [[TPLContainerView alloc] init]; 27 | } 28 | 29 | - (void)populateView:(UIView *)view withViewModel:(TPLViewModel *)viewModel { 30 | [super populateView:view withViewModel:viewModel]; 31 | 32 | TPLContainerView *containerView = DOWNCAST(view, TPLContainerView); 33 | [containerView removeAllSubviews]; 34 | 35 | NSArray *dataArray = [self dataArrayWithViewModel:viewModel]; 36 | for (id data in dataArray) { 37 | UIView *subview = [self.subdescriptor view]; 38 | CHECK_NONNULL(subview.tpl_descriptor); 39 | [self.subdescriptor setData:data toView:subview]; 40 | [containerView addSubview:subview]; 41 | [containerView.tpl_subviews addObject:subview]; 42 | } 43 | } 44 | 45 | - (BOOL)isViewHiddenWithViewModel:(TPLViewModel *)viewModel { 46 | if ([super isViewHiddenWithViewModel:viewModel]) { 47 | return YES; 48 | } 49 | 50 | NSArray *dataArray = [self dataArrayWithViewModel:viewModel]; 51 | if (!dataArray.count) { 52 | return YES; 53 | } 54 | // TODO: Call -isViewHiddenWithViewModel: with data items in the array and return YES if 55 | // all of those return YES. 56 | return NO; 57 | } 58 | 59 | - (void)layoutSubviewsInContainerView:(TPLContainerView *)containerView { 60 | [self doesNotRecognizeSelector:_cmd]; 61 | } 62 | 63 | - (NSArray *)dataArrayWithViewModel:(TPLViewModel *)viewModel { 64 | id data = [self.subdescriptor dataWithViewModel:viewModel]; 65 | return DOWNCAST(data, NSArray); 66 | } 67 | 68 | - (void)addDescriptionToFormatter:(TPLViewDescriptorFormatter *)formatter { 69 | [super addDescriptionToFormatter:formatter]; 70 | [formatter appendSubdescriptorDescriptionWithBlock:^{ 71 | [_subdescriptor addDescriptionToFormatter:formatter]; 72 | }]; 73 | } 74 | 75 | @end 76 | -------------------------------------------------------------------------------- /TemplateKit/Internal/DescriptorImpls/TPLRepeatedDescriptor.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import "Internal/DescriptorImpls/TPLMultiplexerViewDescriptor.h" 18 | 19 | @class TPLValueProvider; 20 | 21 | 22 | @interface TPLRepeatedDescriptor : TPLMultiplexerViewDescriptor 23 | 24 | @property(nonatomic, assign) TPLDirection direction; 25 | 26 | @property(nonatomic) TPLValueProvider *interval; // of NSNumber of CGFloat. 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /TemplateKit/Internal/DescriptorImpls/TPLRepeatedDescriptor.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import "Internal/DescriptorImpls/TPLRepeatedDescriptor.h" 18 | 19 | #import "Internal/Core/TPLValueProvider.h" 20 | #import "Internal/Core/TPLViewModel+Internal.h" 21 | #import "Internal/DescriptorImpls/TPLDataViewDescriptor.h" 22 | #import "Internal/DescriptorImpls/TPLDescriptorImplsMacros.h" 23 | 24 | 25 | @implementation TPLRepeatedDescriptor 26 | 27 | - (CGFloat)intervalWithViewModel:(TPLViewModel *)viewModel { 28 | return [_interval CGFloatValueWithViewModel:viewModel]; 29 | } 30 | 31 | - (CGSize)intrinsicViewSizeThatFits:(CGSize)size 32 | withViewModel:(TPLViewModel *)viewModel { 33 | NSArray *dataArray = [self dataArrayWithViewModel:viewModel]; 34 | CGSize viewSize = CGSizeZero; 35 | switch (_direction) { 36 | case TPLDirectionHorizontal: { 37 | CGFloat totalWidth = 0; 38 | CGFloat maxHeight = 0; 39 | for (id data in dataArray) { 40 | CGSize subviewSize = [self.subdescriptor viewSizeThatFits:size withData:data]; 41 | totalWidth += subviewSize.width; 42 | maxHeight = MAX(maxHeight, subviewSize.height); 43 | } 44 | totalWidth += [self intervalWithViewModel:viewModel] * (dataArray.count - 1); 45 | viewSize = CGSizeMake(totalWidth, maxHeight); 46 | break; 47 | } 48 | case TPLDirectionVertical: { 49 | CGFloat maxWidth = 0; 50 | CGFloat totalHeight = 0; 51 | for (id data in dataArray) { 52 | CGSize subviewSize = [self.subdescriptor viewSizeThatFits:size withData:data]; 53 | maxWidth = MAX(maxWidth, subviewSize.width); 54 | totalHeight += subviewSize.height; 55 | } 56 | totalHeight += [self intervalWithViewModel:viewModel] * (dataArray.count - 1); 57 | viewSize = CGSizeMake(maxWidth, totalHeight); 58 | break; 59 | } 60 | } 61 | return viewSize; 62 | } 63 | 64 | - (void)layoutSubviewsInContainerView:(TPLContainerView *)containerView { 65 | TPLViewModel *viewModel = TPLViewModelWithView(containerView); 66 | CGRect remainingBounds = containerView.bounds; 67 | NSArray *dataArray = [self dataArrayWithViewModel:viewModel]; 68 | CGFloat interval = [self intervalWithViewModel:viewModel]; 69 | NSUInteger index = 0; 70 | for (id data in dataArray) { 71 | UIView *subview = containerView.tpl_subviews[index]; 72 | CGSize size = [self.subdescriptor viewSizeThatFits:remainingBounds.size 73 | withData:data]; 74 | size = CGSizeMake(TPL_CEIL(size.width), TPL_CEIL(size.height)); 75 | switch (_direction) { 76 | case TPLDirectionHorizontal: { 77 | CGRect frame = CGRectMake(CGRectGetMinX(remainingBounds), 78 | CGRectGetMinY(remainingBounds), 79 | size.width, 80 | size.height); 81 | // TODO: Implement stretch and alignment. 82 | subview.frame = frame; 83 | remainingBounds.origin.x += (size.width + interval); 84 | remainingBounds.size.width -= (size.width + interval); 85 | break; 86 | } 87 | case TPLDirectionVertical: { 88 | CGRect frame = CGRectMake(CGRectGetMinX(remainingBounds), 89 | CGRectGetMinY(remainingBounds), 90 | size.width, 91 | size.height); 92 | if (subview.tpl_descriptor.horizontalStretchEnabled) { 93 | frame.size.width = CGRectGetWidth(remainingBounds); 94 | } 95 | // TODO: Implement alignment. 96 | subview.frame = frame; 97 | remainingBounds.origin.y += (size.height + interval); 98 | remainingBounds.size.height -= (size.height + interval); 99 | break; 100 | } 101 | } 102 | ++index; 103 | } 104 | } 105 | 106 | @end 107 | -------------------------------------------------------------------------------- /TemplateKit/Internal/DescriptorImpls/TPLRowLayout.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import "Internal/DescriptorImpls/TPLCompositeViewDescriptor.h" 18 | 19 | TPLCompositeLayoutCalculator TPLRowLayoutCalculatorCreate(); 20 | -------------------------------------------------------------------------------- /TemplateKit/Internal/DescriptorImpls/TPLSelectViewDescriptor.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import "Internal/Core/TPLViewDescriptor.h" 18 | 19 | @class TPLValueProvider; 20 | 21 | 22 | @interface TPLBinarySelectViewDescriptor : TPLViewDescriptor 23 | 24 | @property(nonatomic) TPLValueProvider *condition; // of NSNumber of BOOL. 25 | @property(nonatomic) TPLViewDescriptor *thenDescriptor; 26 | @property(nonatomic) TPLViewDescriptor *elseDescriptor; 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /TemplateKit/Internal/DescriptorImpls/TPLSelectViewDescriptor.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import "Internal/DescriptorImpls/TPLSelectViewDescriptor.h" 18 | 19 | #import "Internal/Core/TPLCoreMacros.h" 20 | #import "Internal/Core/TPLValueProvider.h" 21 | #import "Internal/DescriptorImpls/TPLDescriptorImplsMacros.h" 22 | 23 | typedef UIView *(^TPLCreateSubviewBlock)(id key); 24 | 25 | 26 | @interface TPLSelectView : UIView 27 | 28 | - (instancetype)initWithCreateSubviewBlock:(TPLCreateSubviewBlock)createBlock; 29 | 30 | - (UIView *)selectedSubview; 31 | 32 | - (void)selectSubviewForKey:(id)key; 33 | 34 | @end 35 | 36 | 37 | @implementation TPLSelectView { 38 | id _selectedSubviewKey; 39 | TPLCreateSubviewBlock _createSubviewBlock; 40 | NSMutableDictionary *_cachedSubviews; // From subview key (id) to subview (UIView). 41 | } 42 | 43 | - (instancetype)initWithCreateSubviewBlock:(TPLCreateSubviewBlock)createBlock { 44 | self = [super init]; 45 | if (self) { 46 | _selectedSubviewKey = nil; 47 | _createSubviewBlock = [createBlock copy]; 48 | _cachedSubviews = [[NSMutableDictionary alloc] init]; 49 | } 50 | return self; 51 | } 52 | 53 | - (UIView *)selectedSubview { 54 | assert(_selectedSubviewKey && _cachedSubviews[_selectedSubviewKey]); 55 | return _cachedSubviews[_selectedSubviewKey]; 56 | } 57 | 58 | - (void)selectSubviewForKey:(id)key { 59 | if ([key isEqual:_selectedSubviewKey]) { 60 | return; 61 | } 62 | 63 | if (_selectedSubviewKey) { 64 | [[self selectedSubview] removeFromSuperview]; 65 | } 66 | 67 | if (!_cachedSubviews[key]) { 68 | UIView *newView = _createSubviewBlock(key); 69 | // TODO: What is the right value for autoresizingMask? 70 | newView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; 71 | _cachedSubviews[key] = newView; 72 | } 73 | UIView *selectedSubview = _cachedSubviews[key]; 74 | // TODO: What is the right value for frame? 75 | selectedSubview.frame = self.bounds; 76 | [self addSubview:selectedSubview]; 77 | _selectedSubviewKey = key; 78 | } 79 | 80 | @end 81 | 82 | 83 | @implementation TPLBinarySelectViewDescriptor 84 | 85 | - (UIView *)uninitializedView { 86 | // TODO: Any risk of retain cycle? 87 | TPLCreateSubviewBlock createSubviewBlock = ^(id key) { 88 | if ([key isEqual:@YES]) { 89 | return [self.thenDescriptor view]; 90 | } else if ([key isEqual:@NO]) { 91 | return [self.elseDescriptor view]; 92 | } else { 93 | assert(false); 94 | return (UIView *)nil; 95 | } 96 | }; 97 | TPLSelectView *selectView = [[TPLSelectView alloc] initWithCreateSubviewBlock:createSubviewBlock]; 98 | return selectView; 99 | } 100 | 101 | - (void)populateView:(UIView *)view withViewModel:(TPLViewModel *)viewModel { 102 | [super populateView:view withViewModel:viewModel]; 103 | 104 | TPLSelectView *selectView = DOWNCAST(view, TPLSelectView); 105 | BOOL condition = [self conditionWithViewModel:viewModel]; 106 | if (condition) { 107 | [selectView selectSubviewForKey:@YES]; 108 | [_thenDescriptor populateView:[selectView selectedSubview] withViewModel:viewModel]; 109 | } else { 110 | [selectView selectSubviewForKey:@NO]; 111 | [_elseDescriptor populateView:[selectView selectedSubview] withViewModel:viewModel]; 112 | } 113 | } 114 | 115 | - (CGSize)intrinsicViewSizeThatFits:(CGSize)size 116 | withViewModel:(TPLViewModel *)viewModel { 117 | BOOL condition = [self conditionWithViewModel:viewModel]; 118 | TPLViewDescriptor *activeDescriptor = condition ? _thenDescriptor : _elseDescriptor; 119 | return [activeDescriptor viewSizeThatFits:size 120 | withViewModel:viewModel]; 121 | } 122 | 123 | - (void)addDescriptionToFormatter:(TPLViewDescriptorFormatter *)formatter { 124 | [super addDescriptionToFormatter:formatter]; 125 | [formatter appendSubdescriptorDescriptionWithBlock:^{ 126 | [_thenDescriptor addDescriptionToFormatter:formatter]; 127 | [formatter wrap]; 128 | [_elseDescriptor addDescriptionToFormatter:formatter]; 129 | }]; 130 | } 131 | 132 | - (BOOL)conditionWithViewModel:(TPLViewModel *)viewModel { 133 | return [_condition boolValueWithViewModel:viewModel]; 134 | } 135 | 136 | @end 137 | -------------------------------------------------------------------------------- /TemplateKit/Internal/DescriptorImpls/TPLSpaceDescriptor.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import "Internal/Core/TPLViewDescriptor.h" 18 | 19 | 20 | @interface TPLSpaceDescriptor : TPLViewDescriptor 21 | 22 | @property(nonatomic) TPLDirection direction; 23 | @property(nonatomic) NSNumber *length; 24 | @property(nonatomic) SEL lengthSelector; 25 | @property(nonatomic) BOOL shouldAlwaysShow; 26 | 27 | @end 28 | -------------------------------------------------------------------------------- /TemplateKit/Internal/DescriptorImpls/TPLSpaceDescriptor.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import "Internal/DescriptorImpls/TPLSpaceDescriptor.h" 18 | 19 | #import "Internal/Core/TPLViewModel+Internal.h" 20 | #import "Internal/DescriptorImpls/TPLDescriptorImplsMacros.h" 21 | 22 | 23 | @implementation TPLSpaceDescriptor 24 | 25 | - (UIView *)uninitializedView { 26 | return [[UIView alloc] init]; 27 | } 28 | 29 | - (CGSize)intrinsicViewSizeThatFits:(CGSize)size 30 | withViewModel:(TPLViewModel *)viewModel { 31 | CGFloat length = [self lengthWithViewModel:viewModel]; 32 | if (_direction == TPLDirectionHorizontal) { 33 | return CGSizeMake(length, length); 34 | } else { 35 | return CGSizeMake(length, length); 36 | } 37 | } 38 | 39 | - (CGFloat)lengthWithViewModel:(TPLViewModel *)viewModel { 40 | CGFloat length = 0; 41 | if (self.length) { 42 | length = [self.length floatValue]; 43 | } else if (self.lengthSelector) { 44 | IMP imp = [viewModel methodForSelector:self.lengthSelector]; 45 | CGFloat (*func)(id, SEL) = (void *)imp; 46 | length = func(viewModel, self.lengthSelector); 47 | } 48 | return length; 49 | } 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /TemplateKit/Public/Core/TPLAccessibility.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import 18 | 19 | 20 | @interface TPLAccessibility : NSObject 21 | 22 | // Default YES. 23 | @property(nonatomic, getter=isAccessible) BOOL accessible; 24 | 25 | @property(nonatomic, copy) NSString *label; 26 | @property(nonatomic, copy) NSString *hint; 27 | 28 | + (instancetype)notAccessible; 29 | 30 | @end 31 | -------------------------------------------------------------------------------- /TemplateKit/Public/Core/TPLConstants.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import 18 | 19 | typedef NS_ENUM(NSInteger, TPLAlignment) { 20 | TPLAlignmentUnspecified = 0, 21 | TPLAlignmentTop, 22 | TPLAlignmentTopLeft, 23 | TPLAlignmentLeft, 24 | TPLAlignmentBottomLeft, 25 | TPLAlignmentBottom, 26 | TPLAlignmentBottomRight, 27 | TPLAlignmentRight, 28 | TPLAlignmentTopRight, 29 | TPLAlignmentCenter, 30 | TPLAlignmentJustify, 31 | }; 32 | 33 | typedef NS_ENUM(NSInteger, TPLDirection) { 34 | TPLDirectionHorizontal = 0, 35 | TPLDirectionVertical = 1, 36 | }; 37 | -------------------------------------------------------------------------------- /TemplateKit/Public/Core/TPLDebugger.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import 18 | 19 | #ifndef TPL_ENABLE_DEBUGGING 20 | #if DEBUG 21 | #define TPL_ENABLE_DEBUGGING 1 22 | #else 23 | #define TPL_ENABLE_DEBUGGING 0 24 | #endif 25 | #endif 26 | 27 | #if TPL_ENABLE_DEBUGGING 28 | 29 | @interface TPLDebugger : NSObject 30 | 31 | + (void)enableDebuggingForTag:(NSInteger)tag; 32 | + (void)disableDebuggingForTag:(NSInteger)tag; 33 | + (BOOL)isDebuggingEnabledForView:(UIView *)view; 34 | 35 | + (void)enableBordering; 36 | + (void)disableBordering; 37 | + (BOOL)isBorderingEnabled; 38 | 39 | 40 | @end 41 | 42 | #endif // TPL_ENABLE_DEBUGGING 43 | -------------------------------------------------------------------------------- /TemplateKit/Public/Core/TPLRootView.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import 18 | 19 | @class TPLViewModel; 20 | 21 | 22 | @interface TPLRootView : UIView 23 | 24 | @property(nonatomic) TPLViewModel *viewModel; 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /TemplateKit/Public/Core/TPLSettings.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import 18 | 19 | 20 | @interface TPLSettings : NSObject 21 | 22 | + (BOOL)isRTL; 23 | 24 | + (void)setIsRTLOverride:(BOOL)isRTLOverride; 25 | 26 | + (void)clearIsRTLOverride; 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /TemplateKit/Public/Core/TPLUtils.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import 18 | 19 | #ifdef __cplusplus 20 | extern "C" { 21 | #endif 22 | 23 | NSValue *TPLSizeMake(CGFloat width, CGFloat height); 24 | NSValue *TPLEdgeInsetsMake(CGFloat top, CGFloat left, CGFloat bottom, CGFloat right); 25 | 26 | #ifdef __cplusplus 27 | } 28 | #endif 29 | -------------------------------------------------------------------------------- /TemplateKit/Public/Core/TPLViewModel.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import 18 | 19 | @class TPLEvent; 20 | @class TPLView; 21 | @protocol TPLViewModelEventDelegate; 22 | 23 | 24 | @interface TPLViewModel : NSObject 25 | 26 | @property(nonatomic, weak) id eventDelegate; 27 | 28 | - (BOOL)handleEvent:(TPLEvent *)event; 29 | 30 | @end 31 | 32 | 33 | @interface TPLEvent : NSObject 34 | 35 | @property(nonatomic) UIView *view; 36 | @property(nonatomic) TPLView *rootView; 37 | @property(nonatomic) TPLViewModel *viewModel; 38 | @property(nonatomic) UIControlEvents controlEvent; 39 | @property(nonatomic) UIGestureRecognizer *gestureRecognizer; 40 | 41 | @end 42 | 43 | 44 | @protocol TPLViewModelEventDelegate 45 | 46 | - (void)viewModel:(TPLViewModel *)viewModel didReceiveEvent:(TPLEvent *)event; 47 | 48 | @end 49 | -------------------------------------------------------------------------------- /TemplateKit/Public/Core/TPLViewModifier.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import 18 | 19 | 20 | @protocol TPLViewModifier 21 | 22 | @optional 23 | - (void)modifyView:(UIView *)view withValue:(id)value; 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /TemplateKit/Public/DSL/TPLBuilder.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import 18 | 19 | @class TPLBuilder; 20 | @class TPLBuilderFactoryExtension; 21 | @class TPLSelectorWrapper; 22 | 23 | typedef TPLBuilder *(^TPLBuilderBlock0)(); 24 | typedef TPLBuilder *(^TPLBuilderBlock1)(id); 25 | typedef TPLBuilder *(^TPLBuilderBlockVariadic)(id, ...); 26 | typedef TPLBuilder *(^TPLBuilderBoolBlock1)(BOOL); 27 | typedef TPLSelectorWrapper *(^TPLSelectorWrapperBlock)(SEL); 28 | typedef TPLBuilder *(^TPLBuilderCondBlock)(TPLSelectorWrapper *, TPLBuilder *, TPLBuilder *); 29 | 30 | 31 | typedef void (^TPLBuilderOptionBlock)(BOOL); 32 | @interface TPLBuilderOptions : NSObject 33 | @property(nonatomic, readonly) TPLBuilderOptionBlock postedit; 34 | @end 35 | 36 | @interface TPLBuilderFactory : NSObject 37 | 38 | @property(nonatomic, readonly) TPLBuilderBlock1 activity_indicator; 39 | @property(nonatomic, readonly) TPLSelectorWrapperBlock bind; 40 | @property(nonatomic, readonly) TPLBuilderBlockVariadic column; 41 | @property(nonatomic, readonly) TPLBuilderCondBlock cond; 42 | 43 | typedef TPLBuilder *(^TPLBuilderGridBlock)(TPLBuilder *); 44 | @property(nonatomic, readonly) TPLBuilderGridBlock grid; 45 | 46 | @property(nonatomic, readonly) TPLBuilderBlock1 image; 47 | @property(nonatomic, readonly) TPLBuilderBlock1 label; 48 | 49 | @property(nonatomic, readonly) TPLBuilderBlockVariadic layer; 50 | 51 | @property(nonatomic, readonly) TPLBuilderBlock1 margin; 52 | 53 | typedef TPLBuilder *(^TPLBuilderRepeatedBlock)(TPLBuilder *); 54 | @property(nonatomic, readonly) TPLBuilderRepeatedBlock repeated; 55 | 56 | @property(nonatomic, readonly) TPLBuilderBlockVariadic row; 57 | @property(nonatomic, readonly) TPLBuilderBlock1 space; 58 | 59 | @end 60 | 61 | 62 | @interface TPLBuilder : NSObject 63 | 64 | #define TPL_BUILTIN_VIEW_ATTRIBUTE0(name__) \ 65 | @property(nonatomic, strong, readonly) TPLBuilder *(^name__)() 66 | 67 | #define TPL_BUILTIN_VIEW_ATTRIBUTE1(name__) \ 68 | @property(nonatomic, strong, readonly) TPLBuilder *(^name__)(id) 69 | 70 | TPL_BUILTIN_VIEW_ATTRIBUTE1(accessible); 71 | TPL_BUILTIN_VIEW_ATTRIBUTE1(align); 72 | TPL_BUILTIN_VIEW_ATTRIBUTE1(background_color); 73 | TPL_BUILTIN_VIEW_ATTRIBUTE1(corner_radius); 74 | TPL_BUILTIN_VIEW_ATTRIBUTE1(grid_config); 75 | TPL_BUILTIN_VIEW_ATTRIBUTE0(h_shrinkable); 76 | TPL_BUILTIN_VIEW_ATTRIBUTE0(h_stretchable); 77 | TPL_BUILTIN_VIEW_ATTRIBUTE1(height); 78 | TPL_BUILTIN_VIEW_ATTRIBUTE1(hidden); 79 | TPL_BUILTIN_VIEW_ATTRIBUTE1(interval); 80 | TPL_BUILTIN_VIEW_ATTRIBUTE1(layout_config); 81 | TPL_BUILTIN_VIEW_ATTRIBUTE0(no_rtl); 82 | TPL_BUILTIN_VIEW_ATTRIBUTE0(not_accessible); 83 | TPL_BUILTIN_VIEW_ATTRIBUTE1(padding); 84 | TPL_BUILTIN_VIEW_ATTRIBUTE1(position); 85 | TPL_BUILTIN_VIEW_ATTRIBUTE1(size); 86 | TPL_BUILTIN_VIEW_ATTRIBUTE1(tag); 87 | TPL_BUILTIN_VIEW_ATTRIBUTE0(tappable); 88 | TPL_BUILTIN_VIEW_ATTRIBUTE0(v_stretchable); 89 | TPL_BUILTIN_VIEW_ATTRIBUTE1(width); 90 | 91 | #undef TPL_BUILTIN_VIEW_ATTRIBUTE0 92 | #undef TPL_BUILTIN_VIEW_ATTRIBUTE1 93 | 94 | @end 95 | 96 | 97 | @interface TPLSelectorWrapper : NSObject 98 | 99 | @property(nonatomic, assign, readonly) SEL selector; 100 | 101 | - (instancetype)initWithSelector:(SEL)selector; 102 | 103 | @end 104 | -------------------------------------------------------------------------------- /TemplateKit/Public/DSL/TPLBuilderFactoryExtension.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import 18 | 19 | 20 | @interface TPLBuilderFactoryExtension : NSObject 21 | @end 22 | -------------------------------------------------------------------------------- /TemplateKit/Public/DSL/TPLDSLDeclarationMacros.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import "Public/DSL/TPLBuilder.h" 18 | #import "Public/DSL/TPLBuilderFactoryExtension.h" 19 | #import "Public/DSL/TPLViewTemplate.h" 20 | 21 | #define TPL_DECLARE_VIEW_TEMPLATE(name__) \ 22 | @interface TPLBuilderFactoryExtension (template_declaration_##name__) \ 23 | - (TPLBuilder *(^)(id))name__; \ 24 | @end \ 25 | TPLViewTemplateDefiner TPLDefineViewTemplate_##name__ 26 | 27 | #define TPL_DECLARE_SIMPLE_VIEW_ADAPTER(name__) \ 28 | @interface TPLBuilderFactoryExtension (simple_adapter_declaration_##name__) \ 29 | - (TPLBuilder *(^)())name__; \ 30 | @end 31 | 32 | #define TPL_DECLARE_DATA_VIEW_ADAPTER(name__) \ 33 | @interface TPLBuilderFactoryExtension (data_adapter_declaration_##name__) \ 34 | - (TPLBuilder *(^)(id))name__; \ 35 | @end 36 | 37 | #define TPL_DECLARE_IMMUTABLE_DATA_VIEW_ADAPTER(name__) \ 38 | @interface TPLBuilderFactoryExtension (immutable_data_adapter_declaration_##name__) \ 39 | - (TPLBuilder *(^)(id))name__; \ 40 | @end 41 | 42 | #define TPL_DECLARE_VIEW_MODIFIER(name__) \ 43 | @interface TPLBuilder (modifier_declaration_##name__) \ 44 | - (TPLBuilder *(^)(id))name__; \ 45 | @end 46 | -------------------------------------------------------------------------------- /TemplateKit/Public/DSL/TPLView.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import 18 | 19 | #import "Public/Core/TPLRootView.h" 20 | 21 | @class TPLViewModel; 22 | @class TPLViewTemplate; 23 | 24 | 25 | @interface TPLView : TPLRootView 26 | 27 | - (instancetype)initWithFrame:(CGRect)frame viewTemplate:(TPLViewTemplate *)viewTemplate; 28 | 29 | - (void)reloadViewModel; 30 | 31 | + (CGSize)sizeThatFits:(CGSize)size withViewModel:(TPLViewModel *)viewModel; 32 | 33 | - (void)didLayoutSubviews; 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /TemplateKit/Public/DSL/TPLViewTemplate.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import 18 | 19 | #import "Public/Core/TPLRootView.h" 20 | #import "Public/DSL/TPLBuilder.h" 21 | 22 | @class TPLViewModel; 23 | 24 | #ifdef __cplusplus 25 | extern "C" { 26 | #endif 27 | 28 | @interface TPLViewTemplate : NSObject 29 | 30 | - (CGSize)viewSizeThatFits:(CGSize)size withViewModel:(TPLViewModel *)viewModel; 31 | 32 | @end 33 | 34 | typedef TPLBuilder *(TPLViewTemplateDefiner)(const TPLBuilderBlock1 activity_indicator, 35 | const TPLSelectorWrapperBlock bind, 36 | NSNumber *const bottom, 37 | NSNumber *const bottom_left, 38 | NSNumber *const bottom_right, 39 | NSNumber *const center, 40 | const TPLBuilderBlockVariadic column, 41 | const TPLBuilderCondBlock cond, 42 | TPLBuilderFactoryExtension *const ext, 43 | const TPLBuilderGridBlock grid, 44 | const TPLBuilderBlock1 image, 45 | NSNumber *const justify, 46 | const TPLBuilderBlock1 label, 47 | const TPLBuilderBlockVariadic layer, 48 | NSNumber *const left, 49 | const TPLBuilderBlock1 margin, 50 | TPLBuilderOptions *const options, 51 | const TPLBuilderBlock1 repeated, 52 | NSNumber *const right, 53 | const TPLBuilderBlockVariadic row, 54 | const TPLBuilderBlock1 space, 55 | NSNumber *const top, 56 | NSNumber *const top_left, 57 | NSNumber *const top_right); 58 | 59 | typedef TPLViewTemplateDefiner *TPLViewTemplateDefinerPointer; 60 | 61 | TPLViewTemplate *TPLInstantiateViewTemplate(NSString *name, TPLViewTemplateDefinerPointer definer); 62 | 63 | #ifdef __cplusplus 64 | } 65 | #endif 66 | -------------------------------------------------------------------------------- /TemplateKit/Public/DescriptorImpls/TPLActivityIndicatorData.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import 18 | 19 | @interface TPLActivityIndicatorData : NSObject 20 | 21 | @property(nonatomic) UIActivityIndicatorViewStyle style; 22 | 23 | // When YES, -startAnimating is called on the view on population and, when NO, -stopAnimating. 24 | // You can manually call these methods after population. 25 | // Default is NO. 26 | @property(nonatomic, getter=isAnimating) BOOL animating; 27 | 28 | // Default is YES. 29 | @property(nonatomic) BOOL hidesWhenStopped; 30 | 31 | @end 32 | -------------------------------------------------------------------------------- /TemplateKit/Public/DescriptorImpls/TPLDataViewAdapter.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import 18 | 19 | 20 | @protocol TPLDataViewAdapter 21 | 22 | - (UIView *)view; 23 | 24 | - (void)setData:(id)data toView:(UIView *)view; 25 | 26 | @optional 27 | - (CGSize)viewSizeThatFits:(CGSize)size withData:(id)data; 28 | 29 | @optional 30 | - (UIControlEvents)activatedControlEvents; 31 | 32 | @end 33 | -------------------------------------------------------------------------------- /TemplateKit/Public/DescriptorImpls/TPLGridConfig.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import 18 | 19 | 20 | @interface TPLGridConfig : NSObject 21 | 22 | @property(nonatomic) NSInteger numberOfColumns; 23 | @property(nonatomic) CGFloat columnMargin; 24 | @property(nonatomic) CGFloat rowMargin; 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /TemplateKit/Public/DescriptorImpls/TPLImmutableDataViewAdapter.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import 18 | 19 | 20 | @protocol TPLImmutableDataViewAdapter 21 | 22 | - (UIView *)viewWithData:(id)data; 23 | 24 | - (CGSize)viewSizeThatFits:(CGSize)size withData:(id)data; 25 | 26 | @optional 27 | - (UIControlEvents)activatedControlEvents; 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /TemplateKit/Public/DescriptorImpls/TPLLabelData.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import 18 | 19 | 20 | @interface TPLLabelData : NSObject 21 | 22 | @property(nonatomic, copy) NSString *text; 23 | @property(nonatomic, copy) NSAttributedString *attributedText; 24 | @property(nonatomic) UIColor *textColor; 25 | @property(nonatomic) UIFont *font; 26 | @property(nonatomic) NSLineBreakMode lineBreakMode; 27 | @property(nonatomic) NSInteger numberOfLines; 28 | @property(nonatomic) NSTextAlignment textAlignment; 29 | 30 | @end 31 | -------------------------------------------------------------------------------- /TemplateKit/Public/DescriptorImpls/TPLLayoutConfig.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import 18 | 19 | typedef NS_ENUM(NSInteger, TPLLayoutType) { 20 | TPLLayoutTypeRow, 21 | TPLLayoutTypeColumn, 22 | TPLLayoutTypeLayer, 23 | }; 24 | 25 | @interface TPLLayoutConfig : NSObject 26 | 27 | @property(nonatomic) TPLLayoutType layoutType; 28 | 29 | + (instancetype)defaultRowLayoutConfig; 30 | + (instancetype)defaultColumnLayoutConfig; 31 | + (instancetype)defaultLayerLayoutConfig; 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /TemplateKit/Public/DescriptorImpls/TPLSimpleViewAdapter.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import 18 | 19 | 20 | @protocol TPLSimpleViewAdapter 21 | 22 | - (UIView *)view; 23 | 24 | @optional 25 | - (CGSize)viewSizeThatFits:(CGSize)size; 26 | 27 | @optional 28 | - (UIControlEvents)activatedControlEvents; 29 | 30 | @end 31 | -------------------------------------------------------------------------------- /TemplateKit/TemplateKit.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import "TemplateKitDeclarations.h" 18 | 19 | #import "Public/Core/TPLAccessibility.h" 20 | #import "Public/Core/TPLDebugger.h" 21 | #import "Public/Core/TPLSettings.h" 22 | #import "Public/Core/TPLUtils.h" 23 | #import "Public/Core/TPLViewModifier.h" 24 | #import "Public/DescriptorImpls/TPLDataViewAdapter.h" 25 | #import "Public/DescriptorImpls/TPLGridConfig.h" 26 | #import "Public/DescriptorImpls/TPLImmutableDataViewAdapter.h" 27 | #import "Public/DescriptorImpls/TPLLayoutConfig.h" 28 | #import "Public/DescriptorImpls/TPLSimpleViewAdapter.h" 29 | #import "Public/DSL/TPLDSLMacros.h" 30 | -------------------------------------------------------------------------------- /TemplateKit/TemplateKitDeclarations.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | @class TPLActivityIndicatorData; 18 | @class TPLAccessibility; 19 | @class TPLGridConfig; 20 | @class TPLLabelData; 21 | @class TPLLayoutConfig; 22 | @protocol TPLDataViewAdapter; 23 | @protocol TPLSimpleViewAdapter; 24 | @protocol TPLViewModifier; 25 | 26 | #import "Public/Core/TPLViewModel.h" 27 | #import "Public/DescriptorImpls/TPLActivityIndicatorData.h" 28 | #import "Public/DescriptorImpls/TPLLabelData.h" 29 | #import "Public/DSL/TPLDSLDeclarationMacros.h" 30 | #import "Public/DSL/TPLView.h" 31 | -------------------------------------------------------------------------------- /TemplateKit/TemplateKit_Sources.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import "Internal/Core/TPLAccessibility.m" 18 | #import "Internal/Core/TPLBenchmark.m" 19 | #import "Internal/Core/TPLCoreMacros.m" 20 | #import "Internal/Core/TPLDebugger.m" 21 | #import "Internal/Core/TPLRootView.m" 22 | #import "Internal/Core/TPLRootViewDescriptor.m" 23 | #import "Internal/Core/TPLSettings.m" 24 | #import "Internal/Core/TPLUtils.m" 25 | #import "Internal/Core/TPLValueProvider.m" 26 | #import "Internal/Core/TPLViewDescriptor.m" 27 | #import "Internal/Core/TPLViewModel.m" 28 | #import "Internal/DescriptorImpls/TPLActivityIndicatorDescriptor.m" 29 | #import "Internal/DescriptorImpls/TPLClientDataViewDescriptor.m" 30 | #import "Internal/DescriptorImpls/TPLClientImmutableDataViewDescriptor.m" 31 | #import "Internal/DescriptorImpls/TPLClientSimpleViewDescriptor.m" 32 | #import "Internal/DescriptorImpls/TPLColumnLayout.m" 33 | #import "Internal/DescriptorImpls/TPLCompositeViewDescriptor.m" 34 | #import "Internal/DescriptorImpls/TPLContainerViewDescriptor.m" 35 | #import "Internal/DescriptorImpls/TPLContextualSpaceSelector.m" 36 | #import "Internal/DescriptorImpls/TPLDataViewDescriptor.m" 37 | #import "Internal/DescriptorImpls/TPLGridDescriptor.m" 38 | #import "Internal/DescriptorImpls/TPLImageDescriptor.m" 39 | #import "Internal/DescriptorImpls/TPLLabelDescriptor.m" 40 | #import "Internal/DescriptorImpls/TPLLayerLayout.m" 41 | #import "Internal/DescriptorImpls/TPLLayoutConfig.m" 42 | #import "Internal/DescriptorImpls/TPLMultiplexerViewDescriptor.m" 43 | #import "Internal/DescriptorImpls/TPLRepeatedDescriptor.m" 44 | #import "Internal/DescriptorImpls/TPLRowLayout.m" 45 | #import "Internal/DescriptorImpls/TPLSelectViewDescriptor.m" 46 | #import "Internal/DescriptorImpls/TPLSpaceDescriptor.m" 47 | #import "Internal/DSL/TPLBuilder.m" 48 | #import "Internal/DSL/TPLBuilderFactoryExtension.m" 49 | #import "Internal/DSL/TPLBuilderUtil.m" 50 | #import "Internal/DSL/TPLDSLMacros.m" 51 | #import "Internal/DSL/TPLView.m" 52 | #import "Internal/DSL/TPLViewTemplate.m" 53 | -------------------------------------------------------------------------------- /Tests/DescriptorImpls/TPLCompositeDesriptorTest.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import 18 | 19 | #import "Internal/Core/TPLValueProvider.h" 20 | #import "Internal/DescriptorImpls/TPLCompositeViewDescriptor.h" 21 | #import "Internal/DescriptorImpls/TPLSpaceDescriptor.h" 22 | #import "Public/Core/TPLConstants.h" 23 | #import "TPLTestingUtil.h" 24 | 25 | static TPLCompositeViewDescriptor *CreateCompositeDescriptor(NSArray *subdescriptors) { 26 | TPLCompositeViewDescriptor *composite = [TPLCompositeViewDescriptor descriptor]; 27 | [composite.subdescriptors addObjectsFromArray:subdescriptors]; 28 | return composite; 29 | } 30 | 31 | @interface TPLCompositeDesriptorTestBase : XCTestCase 32 | @end 33 | 34 | @implementation TPLCompositeDesriptorTestBase 35 | @end 36 | 37 | 38 | @interface TPLCompositeDesriptorHiddenViewsTest : TPLCompositeDesriptorTestBase 39 | @end 40 | 41 | @implementation TPLCompositeDesriptorHiddenViewsTest { 42 | TPLViewDescriptor *_subdesc0; 43 | TPLSpaceDescriptor *_subdesc1; 44 | TPLViewDescriptor *_subdesc2; 45 | TPLCompositeViewDescriptor *_desc; 46 | } 47 | 48 | - (void)setUp { 49 | [super setUp]; 50 | 51 | _subdesc0 = CreateMockViewDescriptor(20, 20); 52 | _subdesc1 = [TPLSpaceDescriptor descriptor]; 53 | _subdesc2 = CreateMockViewDescriptor(20, 20); 54 | _desc = CreateCompositeDescriptor(@[ _subdesc0, _subdesc1, _subdesc2 ]); 55 | } 56 | 57 | - (void)testNoSubviewsAreHidden { 58 | XCTAssertFalse([_desc isViewHiddenWithViewModel:nil]); 59 | } 60 | 61 | - (void)testSomeSubviewsAreHidden { 62 | _subdesc0.hidden = [TPLValueProvider providerWithConstant:@YES]; 63 | XCTAssertFalse([_desc isViewHiddenWithViewModel:nil]); 64 | } 65 | 66 | - (void)testAllSubviewsAreHiddenWithContextualSpace { 67 | _subdesc0.hidden = [TPLValueProvider providerWithConstant:@YES]; 68 | _subdesc2.hidden = [TPLValueProvider providerWithConstant:@YES]; 69 | XCTAssertTrue([_desc isViewHiddenWithViewModel:nil]); 70 | } 71 | 72 | - (void)testAllSubviewsAreHiddenWithNoncontextualSpace { 73 | _subdesc0.hidden = [TPLValueProvider providerWithConstant:@YES]; 74 | _subdesc1.shouldAlwaysShow = YES; 75 | _subdesc2.hidden = [TPLValueProvider providerWithConstant:@YES]; 76 | XCTAssertFalse([_desc isViewHiddenWithViewModel:nil]); 77 | } 78 | 79 | - (void)testNoSubviewsAtAll { 80 | _desc = CreateCompositeDescriptor(@[]); 81 | XCTAssertTrue([_desc isViewHiddenWithViewModel:nil]); 82 | } 83 | 84 | @end 85 | -------------------------------------------------------------------------------- /Tests/DescriptorImpls/TPLMultiplexerViewDescriptorTest.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import 18 | 19 | #import "Internal/Core/TPLValueProvider.h" 20 | #import "Internal/Core/TPLViewModel+Internal.h" 21 | #import "Internal/DescriptorImpls/TPLDataViewDescriptor.h" 22 | #import "Internal/DescriptorImpls/TPLMultiplexerViewDescriptor.h" 23 | #import "Public/Core/TPLConstants.h" 24 | 25 | @interface TPLMultiplexerViewDescriptorTestViewModel : TPLViewModel 26 | 27 | @property(nonatomic) NSMutableArray *dataArray; 28 | 29 | @end 30 | 31 | @implementation TPLMultiplexerViewDescriptorTestViewModel 32 | 33 | - (instancetype)init { 34 | self = [super init]; 35 | if (self) { 36 | _dataArray = [[NSMutableArray alloc] init]; 37 | } 38 | return self; 39 | } 40 | 41 | @end 42 | 43 | @interface TPLMultiplexerViewDescriptorTestBase : XCTestCase 44 | @end 45 | 46 | @implementation TPLMultiplexerViewDescriptorTestBase 47 | @end 48 | 49 | @interface TPLMultiplexerViewDescriptorHiddenViewsTest : TPLMultiplexerViewDescriptorTestBase 50 | @end 51 | 52 | @implementation TPLMultiplexerViewDescriptorHiddenViewsTest { 53 | TPLMultiplexerViewDescriptor *_desc; 54 | TPLDataViewDescriptor *_subdesc; 55 | } 56 | 57 | - (void)setUp { 58 | [super setUp]; 59 | 60 | _desc = [TPLMultiplexerViewDescriptor descriptor]; 61 | _subdesc = [TPLDataViewDescriptor descriptor]; 62 | _subdesc.data = [TPLValueProvider providerWithSelector:@selector(dataArray)]; 63 | _desc.subdescriptor = _subdesc; 64 | } 65 | 66 | - (void)testNoViewModel { 67 | XCTAssertTrue([_desc isViewHiddenWithViewModel:nil]); 68 | } 69 | 70 | - (void)testNoData { 71 | TPLMultiplexerViewDescriptorTestViewModel *viewModel = 72 | [[TPLMultiplexerViewDescriptorTestViewModel alloc] init]; 73 | XCTAssertTrue([_desc isViewHiddenWithViewModel:viewModel]); 74 | } 75 | 76 | - (void)testDataHasNotHiddenItems { 77 | TPLMultiplexerViewDescriptorTestViewModel *viewModel = 78 | [[TPLMultiplexerViewDescriptorTestViewModel alloc] init]; 79 | [viewModel.dataArray addObjectsFromArray:@[ @1, @2 ]]; 80 | XCTAssertFalse([_desc isViewHiddenWithViewModel:viewModel]); 81 | } 82 | 83 | - (void)testNoSubdescriptor { 84 | TPLMultiplexerViewDescriptorTestViewModel *viewModel = 85 | [[TPLMultiplexerViewDescriptorTestViewModel alloc] init]; 86 | [viewModel.dataArray addObjectsFromArray:@[ @1, @2 ]]; 87 | _desc.subdescriptor = nil; 88 | XCTAssertTrue([_desc isViewHiddenWithViewModel:viewModel]); 89 | } 90 | 91 | - (void)testDataHasOnlyHiddenItems { 92 | // TODO: Write tests. 93 | } 94 | 95 | @end 96 | -------------------------------------------------------------------------------- /Tests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /Tests/TPLTestingUtil.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import 18 | 19 | #import "Internal/Core/TPLViewDescriptor.h" 20 | #import "Internal/DescriptorImpls/TPLContainerViewDescriptor.h" 21 | 22 | @class MockViewDescriptor; 23 | 24 | 25 | #define ASSERT_EQUAL_POINTS(point___, x___, y___) \ 26 | do { \ 27 | XCTAssertEqualWithAccuracy(point___.x, x___, 0.00001); \ 28 | XCTAssertEqualWithAccuracy(point___.y, y___, 0.00001); \ 29 | } while (0) 30 | 31 | #define ASSERT_EQUAL_SIZES(size___, width___, height___) \ 32 | do { \ 33 | XCTAssertEqualWithAccuracy(size___.width, width___, 0.00001); \ 34 | XCTAssertEqualWithAccuracy(size___.height, height___, 0.00001); \ 35 | } while (0) 36 | 37 | #define ASSERT_EQUAL_RECTS(frame__, x__, y__, width__, height__) \ 38 | do { \ 39 | ASSERT_EQUAL_POINTS(frame__.origin, x__, y__); \ 40 | ASSERT_EQUAL_SIZES(frame__.size, width__, height__); \ 41 | } while (0) 42 | 43 | 44 | UIView *FindSubview(TPLContainerView *rootView, TPLViewDescriptor *descriptor); 45 | 46 | MockViewDescriptor *CreateMockViewDescriptor(CGFloat width, CGFloat height); 47 | 48 | @interface MockViewDescriptor : TPLViewDescriptor 49 | 50 | - (instancetype)initWithIntrinsicSize:(CGSize)size; 51 | 52 | @end 53 | 54 | @interface MockHeightAdjustingViewDescriptor : TPLViewDescriptor 55 | 56 | @property(nonatomic) CGSize defaultSize; 57 | @property(nonatomic) CGFloat adjustedHeight; 58 | 59 | - (instancetype)initWithDefaultSize:(CGSize)defaultSize adjustedHeight:(CGFloat)adjustedHeight; 60 | 61 | @end 62 | -------------------------------------------------------------------------------- /Tests/TPLTestingUtil.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #import "TPLTestingUtil.h" 18 | 19 | #import "Internal/Core/TPLCoreMacros.h" 20 | #import "Internal/Core/TPLValueProvider.h" 21 | #import "Internal/DescriptorImpls/TPLContainerViewDescriptor.h" 22 | #import "Public/Core/TPLUtils.h" 23 | 24 | UIView *FindSubview(TPLContainerView *rootView, TPLViewDescriptor *descriptor) { 25 | NSMutableArray *pendingViews = [[NSMutableArray alloc] init]; 26 | [pendingViews addObject:rootView]; 27 | while (pendingViews.count) { 28 | UIView *view = pendingViews.firstObject; 29 | [pendingViews removeObjectAtIndex:0]; 30 | if (view.tpl_descriptor == descriptor) { 31 | return view; 32 | } 33 | if ([view isKindOfClass:[TPLContainerView class]]) { 34 | TPLContainerView *container = DOWNCAST(view, TPLContainerView); 35 | [pendingViews addObjectsFromArray:container.tpl_subviews]; 36 | } 37 | } 38 | return nil; 39 | } 40 | 41 | MockViewDescriptor *CreateMockViewDescriptor(CGFloat width, CGFloat height) { 42 | return [[MockViewDescriptor alloc] initWithIntrinsicSize:CGSizeMake(width, height)]; 43 | } 44 | 45 | @implementation MockViewDescriptor { 46 | CGSize _intrinsicSize; 47 | } 48 | 49 | - (instancetype)initWithIntrinsicSize:(CGSize)size { 50 | self = [super init]; 51 | if (self) { 52 | _intrinsicSize = size; 53 | } 54 | return self; 55 | } 56 | 57 | - (UIView *)uninitializedView { 58 | return [[UIView alloc] init]; 59 | } 60 | 61 | - (CGSize)intrinsicViewSizeThatFits:(CGSize)size withViewModel:(TPLViewModel *)viewModel { 62 | return _intrinsicSize; 63 | } 64 | 65 | @end 66 | 67 | @implementation MockHeightAdjustingViewDescriptor 68 | 69 | - (instancetype)initWithDefaultSize:(CGSize)defaultSize adjustedHeight:(CGFloat)adjustedHeight { 70 | self = [super init]; 71 | if (self) { 72 | _defaultSize = defaultSize; 73 | _adjustedHeight = adjustedHeight; 74 | } 75 | return self; 76 | } 77 | 78 | - (UIView *)uninitializedView { 79 | return [[UIView alloc] init]; 80 | } 81 | 82 | - (CGSize)intrinsicViewSizeThatFits:(CGSize)size withViewModel:(TPLViewModel *)viewModel { 83 | if (size.width >= _defaultSize.width) { 84 | return _defaultSize; 85 | } else { 86 | return CGSizeMake(size.width, _adjustedHeight); 87 | } 88 | } 89 | 90 | @end 91 | --------------------------------------------------------------------------------