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