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