• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2* Copyright 2017 Google Inc.
3*
4* Use of this source code is governed by a BSD-style license that can be
5* found in the LICENSE file.
6*/
7
8#include "tools/sk_app/ios/WindowContextFactory_ios.h"
9#include "tools/sk_app/ios/Window_ios.h"
10
11@interface WindowViewController : UIViewController
12
13- (WindowViewController*)initWithWindow:(sk_app::Window_ios*)initWindow;
14
15@end
16
17///////////////////////////////////////////////////////////////////////////////
18
19using sk_app::Window;
20
21namespace sk_app {
22
23Window_ios* Window_ios::gWindow = nullptr;
24
25Window* Window::CreateNativeWindow(void*) {
26    // already have a window
27    if (Window_ios::MainWindow()) {
28        return nullptr;
29    }
30
31    Window_ios* window = new Window_ios();
32    if (!window->initWindow()) {
33        delete window;
34        return nullptr;
35    }
36
37    return window;
38}
39
40bool Window_ios::initWindow() {
41    // we already have a window
42    if (fWindow) {
43        return true;
44    }
45
46    // Create a view controller to track certain events
47    WindowViewController* viewController = [[WindowViewController alloc] initWithWindow:this];
48    if (nil == viewController) {
49        return false;
50    }
51
52    fWindow = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
53    if (nil == fWindow) {
54        [viewController release];
55        return false;
56    }
57    fWindow.backgroundColor = [UIColor whiteColor];
58
59    viewController.view = nil;
60    [fWindow setRootViewController:viewController];
61    [fWindow makeKeyAndVisible];
62
63    gWindow = this;
64
65    return true;
66}
67
68void Window_ios::closeWindow() {
69    if (nil != fWindow) {
70        gWindow = nullptr;
71        [fWindow release];
72        fWindow = nil;
73    }
74}
75
76bool Window_ios::attach(BackendType attachType) {
77    this->initWindow();
78
79    window_context_factory::IOSWindowInfo info;
80    info.fWindow = this;
81    info.fViewController = fWindow.rootViewController;
82    switch (attachType) {
83        case kRaster_BackendType:
84            fWindowContext = MakeRasterForIOS(info, fRequestedDisplayParams);
85            break;
86#ifdef SK_METAL
87        case kMetal_BackendType:
88            fWindowContext = MakeMetalForIOS(info, fRequestedDisplayParams);
89            break;
90#endif
91        case kNativeGL_BackendType:
92        default:
93            fWindowContext = MakeGLForIOS(info, fRequestedDisplayParams);
94            break;
95    }
96    this->onBackendCreated();
97
98    return (SkToBool(fWindowContext));
99}
100
101void Window_ios::PaintWindow() {
102    gWindow->onPaint();
103}
104
105void Window_ios::onInval() {
106    // TODO: send expose event
107}
108
109}   // namespace sk_app
110
111///////////////////////////////////////////////////////////////////////////////
112
113@implementation WindowViewController {
114    sk_app::Window_ios* fWindow;
115}
116
117- (WindowViewController*)initWithWindow:(sk_app::Window_ios *)initWindow {
118    fWindow = initWindow;
119
120    return self;
121}
122
123- (void)viewDidLoad {
124    // nothing yet
125}
126
127- (void)didReceiveMemoryWarning {
128    // nothing yet
129}
130
131- (void)viewWillTransitionToSize:(CGSize)size
132       withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
133    // handle rotations here
134}
135@end
136
137///////////////////////////////////////////////////////////////////////////////
138
139@implementation MainView {
140    sk_app::Window_ios* fWindow;
141}
142
143- (IBAction)panGestureAction:(UIGestureRecognizer*)sender {
144    CGPoint location = [sender locationInView:self];
145    switch (sender.state) {
146        case UIGestureRecognizerStateBegan:
147            fWindow->onMouse(location.x, location.y,
148                             skui::InputState::kDown, skui::ModifierKey::kNone);
149            break;
150        case UIGestureRecognizerStateChanged:
151            fWindow->onMouse(location.x, location.y,
152                             skui::InputState::kMove, skui::ModifierKey::kNone);
153            break;
154        case UIGestureRecognizerStateEnded:
155            fWindow->onMouse(location.x, location.y,
156                             skui::InputState::kUp, skui::ModifierKey::kNone);
157            break;
158        case UIGestureRecognizerStateCancelled:
159            fWindow->onMouse(location.x, location.y,
160                             skui::InputState::kUp, skui::ModifierKey::kNone);
161            break;
162        default:
163            break;
164    }
165}
166
167- (IBAction)tapGestureAction:(UIGestureRecognizer*)sender {
168    CGPoint location = [sender locationInView:self];
169    switch (sender.state) {
170        case UIGestureRecognizerStateEnded:
171            fWindow->onMouse(location.x, location.y,
172                             skui::InputState::kDown, skui::ModifierKey::kNone);
173            fWindow->onMouse(location.x, location.y,
174                             skui::InputState::kUp, skui::ModifierKey::kNone);
175            break;
176        default:
177            break;
178    }
179}
180
181- (IBAction)pinchGestureAction:(UIGestureRecognizer*)sender {
182    CGPoint location = [sender locationInView:self];
183    UIPinchGestureRecognizer* pinchGestureRecognizer = (UIPinchGestureRecognizer*) sender;
184    float scale = pinchGestureRecognizer.scale;
185    switch (sender.state) {
186        case UIGestureRecognizerStateBegan:
187            fWindow->onPinch(skui::InputState::kDown, scale, location.x, location.y);
188            break;
189        case UIGestureRecognizerStateChanged:
190            fWindow->onPinch(skui::InputState::kMove, scale, location.x, location.y);
191            break;
192        case UIGestureRecognizerStateEnded:
193            fWindow->onPinch(skui::InputState::kUp, scale, location.x, location.y);
194            break;
195        case UIGestureRecognizerStateCancelled:
196            fWindow->onPinch(skui::InputState::kUp, scale, location.x, location.y);
197            break;
198        default:
199            break;
200    }
201}
202
203- (IBAction)swipeRightGestureAction:(UIGestureRecognizer*)sender {
204    if (UIGestureRecognizerStateEnded == sender.state) {
205        fWindow->onFling(skui::InputState::kRight);
206    }
207}
208
209- (IBAction)swipeLeftGestureAction:(UIGestureRecognizer*)sender {
210    if (UIGestureRecognizerStateEnded == sender.state) {
211        fWindow->onFling(skui::InputState::kLeft);
212    }
213}
214
215- (MainView*)initWithWindow:(sk_app::Window_ios *)initWindow {
216    self = [super init];
217
218    UIPanGestureRecognizer* panGestureRecognizer = [[UIPanGestureRecognizer alloc] init];
219    panGestureRecognizer.maximumNumberOfTouches = 1;
220    [panGestureRecognizer addTarget:self action:@selector(panGestureAction:)];
221    [self addGestureRecognizer:panGestureRecognizer];
222
223    UITapGestureRecognizer* tapGestureRecognizer = [[UITapGestureRecognizer alloc] init];
224    [tapGestureRecognizer addTarget:self action:@selector(tapGestureAction:)];
225    [self addGestureRecognizer:tapGestureRecognizer];
226
227    UIPinchGestureRecognizer* pinchGestureRecognizer = [[UIPinchGestureRecognizer alloc] init];
228    [pinchGestureRecognizer addTarget:self action:@selector(pinchGestureAction:)];
229    [self addGestureRecognizer:pinchGestureRecognizer];
230
231    UISwipeGestureRecognizer* swipeRightGestureRecognizer = [[UISwipeGestureRecognizer alloc] init];
232    swipeRightGestureRecognizer.direction = UISwipeGestureRecognizerDirectionRight;
233    [swipeRightGestureRecognizer addTarget:self action:@selector(swipeRightGestureAction:)];
234    [self addGestureRecognizer:swipeRightGestureRecognizer];
235
236    UISwipeGestureRecognizer* swipeLeftGestureRecognizer = [[UISwipeGestureRecognizer alloc] init];
237    swipeLeftGestureRecognizer.direction = UISwipeGestureRecognizerDirectionLeft;
238    [swipeLeftGestureRecognizer addTarget:self action:@selector(swipeLeftGestureAction:)];
239    [self addGestureRecognizer:swipeLeftGestureRecognizer];
240
241    // disable pan recognition until swipes fail
242    [panGestureRecognizer requireGestureRecognizerToFail:swipeLeftGestureRecognizer];
243    [panGestureRecognizer requireGestureRecognizerToFail:swipeRightGestureRecognizer];
244
245    fWindow = initWindow;
246
247    return self;
248}
249
250@end
251
252