1cb93a386Sopenharmony_ci// Copyright 2019 Google LLC. 2cb93a386Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. 3cb93a386Sopenharmony_ci 4cb93a386Sopenharmony_ci#include "tools/skottie_ios_app/SkiaContext.h" 5cb93a386Sopenharmony_ci#include "tools/skottie_ios_app/SkottieViewController.h" 6cb93a386Sopenharmony_ci 7cb93a386Sopenharmony_ci#include "include/core/SkTypes.h" 8cb93a386Sopenharmony_ci 9cb93a386Sopenharmony_ci#import <UIKit/UIKit.h> 10cb93a386Sopenharmony_ci 11cb93a386Sopenharmony_ci#include <cstdlib> 12cb93a386Sopenharmony_ci 13cb93a386Sopenharmony_ci@interface AppViewController : UIViewController 14cb93a386Sopenharmony_ci @property (strong) SkiaContext* skiaContext; 15cb93a386Sopenharmony_ci @property (strong) UIStackView* stackView; 16cb93a386Sopenharmony_ci@end 17cb93a386Sopenharmony_ci 18cb93a386Sopenharmony_ci@implementation AppViewController 19cb93a386Sopenharmony_ci 20cb93a386Sopenharmony_ci- (void)loadView { 21cb93a386Sopenharmony_ci [self setView:[[UIView alloc] init]]; 22cb93a386Sopenharmony_ci} 23cb93a386Sopenharmony_ci 24cb93a386Sopenharmony_ci- (void)viewDidLoad { 25cb93a386Sopenharmony_ci [super viewDidLoad]; 26cb93a386Sopenharmony_ci if (![self skiaContext]) { 27cb93a386Sopenharmony_ci #if (SK_SUPPORT_GPU && defined(SK_METAL) && !defined(SK_BUILD_FOR_GOOGLE3)) 28cb93a386Sopenharmony_ci [self setSkiaContext:MakeSkiaMetalContext()]; 29cb93a386Sopenharmony_ci #elif (SK_SUPPORT_GPU && defined(SK_GL) && !defined(SK_BUILD_FOR_GOOGLE3)) 30cb93a386Sopenharmony_ci [self setSkiaContext:MakeSkiaGLContext()]; 31cb93a386Sopenharmony_ci #else 32cb93a386Sopenharmony_ci [self setSkiaContext:MakeSkiaUIContext()]; 33cb93a386Sopenharmony_ci #endif 34cb93a386Sopenharmony_ci if (![self skiaContext]) { 35cb93a386Sopenharmony_ci NSLog(@"abort: failed to make skia context."); 36cb93a386Sopenharmony_ci std::abort(); 37cb93a386Sopenharmony_ci } 38cb93a386Sopenharmony_ci } 39cb93a386Sopenharmony_ci CGFloat screenWidth = [[UIScreen mainScreen] bounds].size.width; 40cb93a386Sopenharmony_ci 41cb93a386Sopenharmony_ci UIStackView* stack = [[UIStackView alloc] init]; 42cb93a386Sopenharmony_ci [stack setAxis:UILayoutConstraintAxisVertical]; 43cb93a386Sopenharmony_ci [stack setDistribution:UIStackViewDistributionEqualSpacing]; 44cb93a386Sopenharmony_ci 45cb93a386Sopenharmony_ci NSBundle* mainBundle = [NSBundle mainBundle]; 46cb93a386Sopenharmony_ci NSArray<NSString*>* paths = [mainBundle pathsForResourcesOfType:@"json" 47cb93a386Sopenharmony_ci inDirectory:@"data"]; 48cb93a386Sopenharmony_ci constexpr CGFloat kSpacing = 2; 49cb93a386Sopenharmony_ci CGFloat totalHeight = kSpacing; 50cb93a386Sopenharmony_ci for (NSUInteger i = 0; i < [paths count]; ++i) { 51cb93a386Sopenharmony_ci NSString* path = [paths objectAtIndex:i]; 52cb93a386Sopenharmony_ci NSData* content = [NSData dataWithContentsOfFile:path]; 53cb93a386Sopenharmony_ci if (!content) { 54cb93a386Sopenharmony_ci NSLog(@"'%@' not found", path); 55cb93a386Sopenharmony_ci continue; 56cb93a386Sopenharmony_ci } 57cb93a386Sopenharmony_ci SkottieViewController* controller = [[SkottieViewController alloc] init]; 58cb93a386Sopenharmony_ci if (![controller loadAnimation:content]) { 59cb93a386Sopenharmony_ci continue; 60cb93a386Sopenharmony_ci } 61cb93a386Sopenharmony_ci CGSize animSize = [controller size]; 62cb93a386Sopenharmony_ci CGFloat height = animSize.width ? (screenWidth * animSize.height / animSize.width) : 0; 63cb93a386Sopenharmony_ci CGRect frame = {{0, 0}, {screenWidth, height}}; 64cb93a386Sopenharmony_ci UIView* skiaView = [[self skiaContext] makeViewWithController:controller withFrame:frame]; 65cb93a386Sopenharmony_ci [[[skiaView heightAnchor] constraintEqualToConstant:height] setActive:true]; 66cb93a386Sopenharmony_ci [[[skiaView widthAnchor] constraintEqualToConstant:screenWidth] setActive:true]; 67cb93a386Sopenharmony_ci [skiaView setNeedsDisplay]; 68cb93a386Sopenharmony_ci [stack addArrangedSubview:skiaView]; 69cb93a386Sopenharmony_ci totalHeight += height + kSpacing; 70cb93a386Sopenharmony_ci } 71cb93a386Sopenharmony_ci [stack setFrame:{{0, 0}, {screenWidth, totalHeight}}]; 72cb93a386Sopenharmony_ci [stack setNeedsDisplay]; 73cb93a386Sopenharmony_ci 74cb93a386Sopenharmony_ci CGFloat statusBarHeight = [[UIApplication sharedApplication] statusBarFrame].size.height; 75cb93a386Sopenharmony_ci CGSize mainScreenSize = [[UIScreen mainScreen] bounds].size; 76cb93a386Sopenharmony_ci CGRect scrollViewBounds = {{0, statusBarHeight}, 77cb93a386Sopenharmony_ci {mainScreenSize.width, mainScreenSize.height - statusBarHeight}}; 78cb93a386Sopenharmony_ci UIScrollView* scrollView = [[UIScrollView alloc] initWithFrame:scrollViewBounds]; 79cb93a386Sopenharmony_ci [scrollView setContentSize:[stack frame].size]; 80cb93a386Sopenharmony_ci [scrollView addSubview:stack]; 81cb93a386Sopenharmony_ci [scrollView setBackgroundColor:[UIColor blackColor]]; 82cb93a386Sopenharmony_ci [scrollView setNeedsDisplay]; 83cb93a386Sopenharmony_ci 84cb93a386Sopenharmony_ci [self setStackView:stack]; 85cb93a386Sopenharmony_ci 86cb93a386Sopenharmony_ci UIView* mainView = [self view]; 87cb93a386Sopenharmony_ci [mainView setBounds:{{0, 0}, mainScreenSize}]; 88cb93a386Sopenharmony_ci [mainView setBackgroundColor:[UIColor whiteColor]]; 89cb93a386Sopenharmony_ci [mainView addSubview:scrollView]; 90cb93a386Sopenharmony_ci [mainView setNeedsDisplay]; 91cb93a386Sopenharmony_ci 92cb93a386Sopenharmony_ci UITapGestureRecognizer* tapGestureRecognizer = [[UITapGestureRecognizer alloc] init]; 93cb93a386Sopenharmony_ci [tapGestureRecognizer addTarget:self action:@selector(handleTap:)]; 94cb93a386Sopenharmony_ci [mainView addGestureRecognizer:tapGestureRecognizer]; 95cb93a386Sopenharmony_ci} 96cb93a386Sopenharmony_ci 97cb93a386Sopenharmony_ci- (void)handleTap:(UIGestureRecognizer*)sender { 98cb93a386Sopenharmony_ci if ([sender state] != UIGestureRecognizerStateEnded) { 99cb93a386Sopenharmony_ci return; 100cb93a386Sopenharmony_ci } 101cb93a386Sopenharmony_ci NSArray<UIView*>* subviews = [[self stackView] subviews]; 102cb93a386Sopenharmony_ci for (NSUInteger i = 0; i < [subviews count]; ++i) { 103cb93a386Sopenharmony_ci UIView* uIView = [subviews objectAtIndex:i]; 104cb93a386Sopenharmony_ci if (SkiaViewController* controller = [[self skiaContext] getViewController:uIView]) { 105cb93a386Sopenharmony_ci [controller togglePaused]; 106cb93a386Sopenharmony_ci [uIView setNeedsDisplay]; 107cb93a386Sopenharmony_ci } 108cb93a386Sopenharmony_ci } 109cb93a386Sopenharmony_ci} 110cb93a386Sopenharmony_ci@end 111cb93a386Sopenharmony_ci 112cb93a386Sopenharmony_ci@interface AppDelegate : UIResponder <UIApplicationDelegate> 113cb93a386Sopenharmony_ci @property (strong, nonatomic) UIWindow* window; 114cb93a386Sopenharmony_ci@end 115cb93a386Sopenharmony_ci 116cb93a386Sopenharmony_ci@implementation AppDelegate 117cb93a386Sopenharmony_ci 118cb93a386Sopenharmony_ci- (BOOL)application:(UIApplication*)app didFinishLaunchingWithOptions:(NSDictionary*)ops { 119cb93a386Sopenharmony_ci [self setWindow:[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]]; 120cb93a386Sopenharmony_ci [[self window] setRootViewController:[[AppViewController alloc] init]]; 121cb93a386Sopenharmony_ci [[self window] makeKeyAndVisible]; 122cb93a386Sopenharmony_ci return YES; 123cb93a386Sopenharmony_ci} 124cb93a386Sopenharmony_ci@end 125cb93a386Sopenharmony_ci 126cb93a386Sopenharmony_ciint main(int argc, char* argv[]) { 127cb93a386Sopenharmony_ci @autoreleasepool { 128cb93a386Sopenharmony_ci return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 129cb93a386Sopenharmony_ci } 130cb93a386Sopenharmony_ci} 131