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