| /* |
| * Copyright 2017 Google Inc. |
| * |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| |
| #include "tools/sk_app/ios/WindowContextFactory_ios.h" |
| #include "tools/sk_app/ios/Window_ios.h" |
| |
| #if __has_feature(objc_arc) |
| #error "File should not be compiled with ARC." |
| #endif |
| |
| @interface WindowViewController : UIViewController |
| |
| - (WindowViewController*)initWithWindow:(sk_app::Window_ios*)initWindow; |
| |
| @end |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| |
| using sk_app::Window; |
| |
| namespace sk_app { |
| |
| Window_ios* Window_ios::gWindow = nullptr; |
| |
| Window* Window::CreateNativeWindow(void*) { |
| // already have a window |
| if (Window_ios::MainWindow()) { |
| return nullptr; |
| } |
| |
| Window_ios* window = new Window_ios(); |
| if (!window->initWindow()) { |
| delete window; |
| return nullptr; |
| } |
| |
| return window; |
| } |
| |
| bool Window_ios::initWindow() { |
| // we already have a window |
| if (fWindow) { |
| return true; |
| } |
| |
| // Create a view controller to track certain events |
| WindowViewController* viewController = [[WindowViewController alloc] initWithWindow:this]; |
| if (nil == viewController) { |
| return false; |
| } |
| |
| fWindow = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; |
| if (nil == fWindow) { |
| [viewController release]; |
| return false; |
| } |
| fWindow.backgroundColor = [UIColor whiteColor]; |
| |
| viewController.view = nil; |
| [fWindow setRootViewController:viewController]; |
| [fWindow makeKeyAndVisible]; |
| |
| gWindow = this; |
| |
| return true; |
| } |
| |
| void Window_ios::closeWindow() { |
| if (nil != fWindow) { |
| gWindow = nullptr; |
| [fWindow release]; |
| fWindow = nil; |
| } |
| } |
| |
| bool Window_ios::attach(BackendType attachType) { |
| this->initWindow(); |
| |
| window_context_factory::IOSWindowInfo info; |
| info.fWindow = this; |
| info.fViewController = fWindow.rootViewController; |
| switch (attachType) { |
| #ifdef SK_METAL |
| case kMetal_BackendType: |
| fWindowContext = MakeMetalForIOS(info, fRequestedDisplayParams); |
| break; |
| #endif |
| #ifdef SK_GL |
| case kNativeGL_BackendType: |
| fWindowContext = MakeGLForIOS(info, fRequestedDisplayParams); |
| break; |
| case kRaster_BackendType: |
| fWindowContext = MakeRasterForIOS(info, fRequestedDisplayParams); |
| break; |
| #endif |
| default: |
| SkASSERT_RELEASE(false); |
| } |
| this->onBackendCreated(); |
| |
| return (SkToBool(fWindowContext)); |
| } |
| |
| void Window_ios::PaintWindow() { |
| gWindow->onPaint(); |
| } |
| |
| void Window_ios::onInval() { |
| // TODO: send expose event |
| } |
| |
| } // namespace sk_app |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| |
| @implementation WindowViewController { |
| sk_app::Window_ios* fWindow; |
| } |
| |
| - (WindowViewController*)initWithWindow:(sk_app::Window_ios *)initWindow { |
| self = [super initWithNibName:nil bundle:nil]; |
| if (self) { |
| fWindow = initWindow; |
| } |
| return self; |
| } |
| |
| - (void)viewDidLoad { |
| // nothing yet |
| } |
| |
| - (void)didReceiveMemoryWarning { |
| // nothing yet |
| } |
| |
| - (void)viewWillTransitionToSize:(CGSize)size |
| withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator { |
| // handle rotations here |
| } |
| @end |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| |
| @implementation MainView { |
| sk_app::Window_ios* fWindow; |
| } |
| |
| - (void)panGestureAction:(UIGestureRecognizer*)sender { |
| CGPoint location = [sender locationInView:self]; |
| switch (sender.state) { |
| case UIGestureRecognizerStateBegan: |
| fWindow->onMouse(location.x, location.y, |
| skui::InputState::kDown, skui::ModifierKey::kNone); |
| break; |
| case UIGestureRecognizerStateChanged: |
| fWindow->onMouse(location.x, location.y, |
| skui::InputState::kMove, skui::ModifierKey::kNone); |
| break; |
| case UIGestureRecognizerStateEnded: |
| fWindow->onMouse(location.x, location.y, |
| skui::InputState::kUp, skui::ModifierKey::kNone); |
| break; |
| case UIGestureRecognizerStateCancelled: |
| fWindow->onMouse(location.x, location.y, |
| skui::InputState::kUp, skui::ModifierKey::kNone); |
| break; |
| default: |
| break; |
| } |
| } |
| |
| - (void)tapGestureAction:(UIGestureRecognizer*)sender { |
| CGPoint location = [sender locationInView:self]; |
| switch (sender.state) { |
| case UIGestureRecognizerStateEnded: |
| fWindow->onMouse(location.x, location.y, |
| skui::InputState::kDown, skui::ModifierKey::kNone); |
| fWindow->onMouse(location.x, location.y, |
| skui::InputState::kUp, skui::ModifierKey::kNone); |
| break; |
| default: |
| break; |
| } |
| } |
| |
| - (void)pinchGestureAction:(UIGestureRecognizer*)sender { |
| CGPoint location = [sender locationInView:self]; |
| UIPinchGestureRecognizer* pinchGestureRecognizer = (UIPinchGestureRecognizer*) sender; |
| float scale = pinchGestureRecognizer.scale; |
| switch (sender.state) { |
| case UIGestureRecognizerStateBegan: |
| fWindow->onPinch(skui::InputState::kDown, scale, location.x, location.y); |
| break; |
| case UIGestureRecognizerStateChanged: |
| fWindow->onPinch(skui::InputState::kMove, scale, location.x, location.y); |
| break; |
| case UIGestureRecognizerStateEnded: |
| fWindow->onPinch(skui::InputState::kUp, scale, location.x, location.y); |
| break; |
| case UIGestureRecognizerStateCancelled: |
| fWindow->onPinch(skui::InputState::kUp, scale, location.x, location.y); |
| break; |
| default: |
| break; |
| } |
| } |
| |
| - (void)swipeRightGestureAction:(UIGestureRecognizer*)sender { |
| if (UIGestureRecognizerStateEnded == sender.state) { |
| fWindow->onFling(skui::InputState::kRight); |
| } |
| } |
| |
| - (void)swipeLeftGestureAction:(UIGestureRecognizer*)sender { |
| if (UIGestureRecognizerStateEnded == sender.state) { |
| fWindow->onFling(skui::InputState::kLeft); |
| } |
| } |
| |
| - (MainView*)initWithWindow:(sk_app::Window_ios *)initWindow { |
| self = [super init]; |
| |
| UIPanGestureRecognizer* panGestureRecognizer = [[UIPanGestureRecognizer alloc] init]; |
| panGestureRecognizer.maximumNumberOfTouches = 1; |
| [panGestureRecognizer addTarget:self action:@selector(panGestureAction:)]; |
| [self addGestureRecognizer:panGestureRecognizer]; |
| |
| UITapGestureRecognizer* tapGestureRecognizer = [[UITapGestureRecognizer alloc] init]; |
| [tapGestureRecognizer addTarget:self action:@selector(tapGestureAction:)]; |
| [self addGestureRecognizer:tapGestureRecognizer]; |
| |
| UIPinchGestureRecognizer* pinchGestureRecognizer = [[UIPinchGestureRecognizer alloc] init]; |
| [pinchGestureRecognizer addTarget:self action:@selector(pinchGestureAction:)]; |
| [self addGestureRecognizer:pinchGestureRecognizer]; |
| |
| UISwipeGestureRecognizer* swipeRightGestureRecognizer = [[UISwipeGestureRecognizer alloc] init]; |
| swipeRightGestureRecognizer.direction = UISwipeGestureRecognizerDirectionRight; |
| [swipeRightGestureRecognizer addTarget:self action:@selector(swipeRightGestureAction:)]; |
| [self addGestureRecognizer:swipeRightGestureRecognizer]; |
| |
| UISwipeGestureRecognizer* swipeLeftGestureRecognizer = [[UISwipeGestureRecognizer alloc] init]; |
| swipeLeftGestureRecognizer.direction = UISwipeGestureRecognizerDirectionLeft; |
| [swipeLeftGestureRecognizer addTarget:self action:@selector(swipeLeftGestureAction:)]; |
| [self addGestureRecognizer:swipeLeftGestureRecognizer]; |
| |
| // disable pan recognition until swipes fail |
| [panGestureRecognizer requireGestureRecognizerToFail:swipeLeftGestureRecognizer]; |
| [panGestureRecognizer requireGestureRecognizerToFail:swipeRightGestureRecognizer]; |
| |
| fWindow = initWindow; |
| |
| return self; |
| } |
| |
| @end |
| |