• 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/Window_ios.h"
9#include "tools/window/ios/WindowContextFactory_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    skwindow::IOSWindowInfo info;
84    info.fWindow = this;
85    info.fViewController = fWindow.rootViewController;
86    switch (attachType) {
87#ifdef SK_METAL
88        case kMetal_BackendType:
89            fWindowContext = skwindow::MakeMetalForIOS(info, fRequestedDisplayParams);
90            break;
91#if defined(SK_GRAPHITE)
92        case kGraphiteMetal_BackendType:
93            fWindowContext = MakeGraphiteMetalForIOS(info, fRequestedDisplayParams);
94            break;
95#endif
96#endif
97#ifdef SK_GL
98        case kNativeGL_BackendType:
99            fWindowContext = skwindow::MakeGLForIOS(info, fRequestedDisplayParams);
100            break;
101        case kRaster_BackendType:
102            fWindowContext = skwindow::MakeRasterForIOS(info, fRequestedDisplayParams);
103            break;
104#endif
105        default:
106            SkASSERT_RELEASE(false);
107    }
108    this->onBackendCreated();
109
110    return (SkToBool(fWindowContext));
111}
112
113void Window_ios::PaintWindow() {
114    gWindow->onPaint();
115}
116
117void Window_ios::onInval() {
118    // TODO: send expose event
119}
120
121}   // namespace sk_app
122
123///////////////////////////////////////////////////////////////////////////////
124
125@implementation WindowViewController {
126    sk_app::Window_ios* fWindow;
127}
128
129- (WindowViewController*)initWithWindow:(sk_app::Window_ios *)initWindow {
130    self = [super initWithNibName:nil bundle:nil];
131    if (self) {
132        fWindow = initWindow;
133    }
134    return self;
135}
136
137- (void)viewDidLoad {
138    // nothing yet
139}
140
141- (void)didReceiveMemoryWarning {
142    // nothing yet
143}
144
145- (void)viewWillTransitionToSize:(CGSize)size
146       withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
147    // handle rotations here
148}
149@end
150
151///////////////////////////////////////////////////////////////////////////////
152
153@implementation MainView {
154    sk_app::Window_ios* fWindow;
155}
156
157- (void)panGestureAction:(UIGestureRecognizer*)sender {
158    CGPoint location = [sender locationInView:self];
159    switch (sender.state) {
160        case UIGestureRecognizerStateBegan:
161            fWindow->onMouse(location.x, location.y,
162                             skui::InputState::kDown, skui::ModifierKey::kNone);
163            break;
164        case UIGestureRecognizerStateChanged:
165            fWindow->onMouse(location.x, location.y,
166                             skui::InputState::kMove, skui::ModifierKey::kNone);
167            break;
168        case UIGestureRecognizerStateEnded:
169            fWindow->onMouse(location.x, location.y,
170                             skui::InputState::kUp, skui::ModifierKey::kNone);
171            break;
172        case UIGestureRecognizerStateCancelled:
173            fWindow->onMouse(location.x, location.y,
174                             skui::InputState::kUp, skui::ModifierKey::kNone);
175            break;
176        default:
177            break;
178    }
179}
180
181- (void)tapGestureAction:(UIGestureRecognizer*)sender {
182    CGPoint location = [sender locationInView:self];
183    switch (sender.state) {
184        case UIGestureRecognizerStateEnded:
185            fWindow->onMouse(location.x, location.y,
186                             skui::InputState::kDown, skui::ModifierKey::kNone);
187            fWindow->onMouse(location.x, location.y,
188                             skui::InputState::kUp, skui::ModifierKey::kNone);
189            break;
190        default:
191            break;
192    }
193}
194
195- (void)pinchGestureAction:(UIGestureRecognizer*)sender {
196    CGPoint location = [sender locationInView:self];
197    UIPinchGestureRecognizer* pinchGestureRecognizer = (UIPinchGestureRecognizer*) sender;
198    float scale = pinchGestureRecognizer.scale;
199    switch (sender.state) {
200        case UIGestureRecognizerStateBegan:
201            fWindow->onPinch(skui::InputState::kDown, scale, location.x, location.y);
202            break;
203        case UIGestureRecognizerStateChanged:
204            fWindow->onPinch(skui::InputState::kMove, scale, location.x, location.y);
205            break;
206        case UIGestureRecognizerStateEnded:
207            fWindow->onPinch(skui::InputState::kUp, scale, location.x, location.y);
208            break;
209        case UIGestureRecognizerStateCancelled:
210            fWindow->onPinch(skui::InputState::kUp, scale, location.x, location.y);
211            break;
212        default:
213            break;
214    }
215}
216
217- (void)swipeRightGestureAction:(UIGestureRecognizer*)sender {
218    if (UIGestureRecognizerStateEnded == sender.state) {
219        fWindow->onFling(skui::InputState::kRight);
220    }
221}
222
223- (void)swipeLeftGestureAction:(UIGestureRecognizer*)sender {
224    if (UIGestureRecognizerStateEnded == sender.state) {
225        fWindow->onFling(skui::InputState::kLeft);
226    }
227}
228
229- (MainView*)initWithWindow:(sk_app::Window_ios *)initWindow {
230    self = [super init];
231
232    UIPanGestureRecognizer* panGestureRecognizer = [[UIPanGestureRecognizer alloc] init];
233    panGestureRecognizer.maximumNumberOfTouches = 1;
234    [panGestureRecognizer addTarget:self action:@selector(panGestureAction:)];
235    [self addGestureRecognizer:panGestureRecognizer];
236
237    UITapGestureRecognizer* tapGestureRecognizer = [[UITapGestureRecognizer alloc] init];
238    [tapGestureRecognizer addTarget:self action:@selector(tapGestureAction:)];
239    [self addGestureRecognizer:tapGestureRecognizer];
240
241    UIPinchGestureRecognizer* pinchGestureRecognizer = [[UIPinchGestureRecognizer alloc] init];
242    [pinchGestureRecognizer addTarget:self action:@selector(pinchGestureAction:)];
243    [self addGestureRecognizer:pinchGestureRecognizer];
244
245    UISwipeGestureRecognizer* swipeRightGestureRecognizer = [[UISwipeGestureRecognizer alloc] init];
246    swipeRightGestureRecognizer.direction = UISwipeGestureRecognizerDirectionRight;
247    [swipeRightGestureRecognizer addTarget:self action:@selector(swipeRightGestureAction:)];
248    [self addGestureRecognizer:swipeRightGestureRecognizer];
249
250    UISwipeGestureRecognizer* swipeLeftGestureRecognizer = [[UISwipeGestureRecognizer alloc] init];
251    swipeLeftGestureRecognizer.direction = UISwipeGestureRecognizerDirectionLeft;
252    [swipeLeftGestureRecognizer addTarget:self action:@selector(swipeLeftGestureAction:)];
253    [self addGestureRecognizer:swipeLeftGestureRecognizer];
254
255    // disable pan recognition until swipes fail
256    [panGestureRecognizer requireGestureRecognizerToFail:swipeLeftGestureRecognizer];
257    [panGestureRecognizer requireGestureRecognizerToFail:swipeRightGestureRecognizer];
258
259    fWindow = initWindow;
260
261    return self;
262}
263
264@end
265
266