src/video/uikit/SDL_uikitview.m
author Alex Szpakowski <slime73@gmail.com>
Fri, 10 Apr 2015 23:30:31 -0300
changeset 9551 950a1a7b4c3c
parent 9532 318042c16b76
child 9619 b94b6d0bff0f
permissions -rw-r--r--
Fixed an iOS view orientation issue when SDL_GL_CreateContext or SDL_CreateRenderer is called.
     1  /*
     2   Simple DirectMedia Layer
     3   Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
     4 
     5   This software is provided 'as-is', without any express or implied
     6   warranty.  In no event will the authors be held liable for any damages
     7   arising from the use of this software.
     8 
     9   Permission is granted to anyone to use this software for any purpose,
    10   including commercial applications, and to alter it and redistribute it
    11   freely, subject to the following restrictions:
    12 
    13   1. The origin of this software must not be misrepresented; you must not
    14      claim that you wrote the original software. If you use this software
    15      in a product, an acknowledgment in the product documentation would be
    16      appreciated but is not required.
    17   2. Altered source versions must be plainly marked as such, and must not be
    18      misrepresented as being the original software.
    19   3. This notice may not be removed or altered from any source distribution.
    20 */
    21 #include "../../SDL_internal.h"
    22 
    23 #if SDL_VIDEO_DRIVER_UIKIT
    24 
    25 #include "SDL_uikitview.h"
    26 
    27 #include "../../events/SDL_mouse_c.h"
    28 #include "../../events/SDL_touch_c.h"
    29 #include "../../events/SDL_events_c.h"
    30 
    31 #import "SDL_uikitappdelegate.h"
    32 #import "SDL_uikitmodes.h"
    33 #import "SDL_uikitwindow.h"
    34 
    35 @implementation SDL_uikitview {
    36     SDL_Window *sdlwindow;
    37 
    38     SDL_TouchID touchId;
    39     UITouch * __weak firstFingerDown;
    40 }
    41 
    42 - (instancetype)initWithFrame:(CGRect)frame
    43 {
    44     if ((self = [super initWithFrame:frame])) {
    45         self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
    46         self.autoresizesSubviews = YES;
    47 
    48         self.multipleTouchEnabled = YES;
    49 
    50         touchId = 1;
    51         SDL_AddTouch(touchId, "");
    52     }
    53 
    54     return self;
    55 }
    56 
    57 - (void)setSDLWindow:(SDL_Window *)window
    58 {
    59     SDL_WindowData *data = nil;
    60 
    61     if (window == sdlwindow) {
    62         return;
    63     }
    64 
    65     if (sdlwindow) {
    66         SDL_uikitview *view = nil;
    67         data = (__bridge SDL_WindowData *) sdlwindow->driverdata;
    68 
    69         [data.views removeObject:self];
    70 
    71         [self removeFromSuperview];
    72 
    73         /* Restore the next-oldest view in the old window. */
    74         if (data.views.count > 0) {
    75             view = data.views[data.views.count - 1];
    76         }
    77 
    78         data.viewcontroller.view = view;
    79 
    80         data.uiwindow.rootViewController = nil;
    81         data.uiwindow.rootViewController = data.viewcontroller;
    82 
    83         [data.uiwindow layoutIfNeeded];
    84     }
    85 
    86     if (window) {
    87         data = (__bridge SDL_WindowData *) window->driverdata;
    88 
    89         /* Make sure the SDL window has a strong reference to this view. */
    90         [data.views addObject:self];
    91 
    92         /* Replace the view controller's old view with this one. */
    93         [data.viewcontroller.view removeFromSuperview];
    94         data.viewcontroller.view = self;
    95 
    96         /* The root view controller handles rotation and the status bar.
    97          * Assigning it also adds the controller's view to the window. We
    98          * explicitly re-set it to make sure the view is properly attached to
    99          * the window. Just adding the sub-view if the root view controller is
   100          * already correct causes orientation issues on iOS 7 and below. */
   101         data.uiwindow.rootViewController = nil;
   102         data.uiwindow.rootViewController = data.viewcontroller;
   103 
   104         /* The view's bounds may not be correct until the next event cycle. That
   105          * might happen after the current dimensions are queried, so we force a
   106          * layout now to immediately update the bounds. */
   107         [data.uiwindow layoutIfNeeded];
   108     }
   109 
   110     sdlwindow = window;
   111 }
   112 
   113 - (CGPoint)touchLocation:(UITouch *)touch shouldNormalize:(BOOL)normalize
   114 {
   115     CGPoint point = [touch locationInView:self];
   116 
   117     if (normalize) {
   118         CGRect bounds = self.bounds;
   119         point.x /= bounds.size.width;
   120         point.y /= bounds.size.height;
   121     }
   122 
   123     return point;
   124 }
   125 
   126 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
   127 {
   128     for (UITouch *touch in touches) {
   129         if (!firstFingerDown) {
   130             CGPoint locationInView = [self touchLocation:touch shouldNormalize:NO];
   131 
   132             /* send mouse moved event */
   133             SDL_SendMouseMotion(sdlwindow, SDL_TOUCH_MOUSEID, 0, locationInView.x, locationInView.y);
   134 
   135             /* send mouse down event */
   136             SDL_SendMouseButton(sdlwindow, SDL_TOUCH_MOUSEID, SDL_PRESSED, SDL_BUTTON_LEFT);
   137 
   138             firstFingerDown = touch;
   139         }
   140 
   141         CGPoint locationInView = [self touchLocation:touch shouldNormalize:YES];
   142         SDL_SendTouch(touchId, (SDL_FingerID)((size_t)touch),
   143                       SDL_TRUE, locationInView.x, locationInView.y, 1.0f);
   144     }
   145 }
   146 
   147 - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
   148 {
   149     for (UITouch *touch in touches) {
   150         if (touch == firstFingerDown) {
   151             /* send mouse up */
   152             SDL_SendMouseButton(sdlwindow, SDL_TOUCH_MOUSEID, SDL_RELEASED, SDL_BUTTON_LEFT);
   153             firstFingerDown = nil;
   154         }
   155 
   156         CGPoint locationInView = [self touchLocation:touch shouldNormalize:YES];
   157         SDL_SendTouch(touchId, (SDL_FingerID)((size_t)touch),
   158                       SDL_FALSE, locationInView.x, locationInView.y, 1.0f);
   159     }
   160 }
   161 
   162 - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
   163 {
   164     [self touchesEnded:touches withEvent:event];
   165 }
   166 
   167 - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
   168 {
   169     for (UITouch *touch in touches) {
   170         if (touch == firstFingerDown) {
   171             CGPoint locationInView = [self touchLocation:touch shouldNormalize:NO];
   172 
   173             /* send moved event */
   174             SDL_SendMouseMotion(sdlwindow, SDL_TOUCH_MOUSEID, 0, locationInView.x, locationInView.y);
   175         }
   176 
   177         CGPoint locationInView = [self touchLocation:touch shouldNormalize:YES];
   178         SDL_SendTouchMotion(touchId, (SDL_FingerID)((size_t)touch),
   179                             locationInView.x, locationInView.y, 1.0f);
   180     }
   181 }
   182 
   183 @end
   184 
   185 #endif /* SDL_VIDEO_DRIVER_UIKIT */
   186 
   187 /* vi: set ts=4 sw=4 expandtab: */