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