src/video/uikit/SDL_uikitview.m
author Alex Szpakowski <slime73@gmail.com>
Wed, 09 Sep 2015 19:08:52 -0300
changeset 9861 2117766ff8d2
parent 9727 b845f659e015
child 9998 f67cf37e9cd4
permissions -rw-r--r--
iOS: Added support for force-touch on capable devices.
slouken@6079
     1
 /*
slouken@5535
     2
  Simple DirectMedia Layer
slouken@9619
     3
  Copyright (C) 1997-2015 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@9727
    65
    /* Remove ourself from the old window. */
slime73@9532
    66
    if (sdlwindow) {
slime73@9532
    67
        SDL_uikitview *view = nil;
slime73@9532
    68
        data = (__bridge SDL_WindowData *) sdlwindow->driverdata;
slime73@9532
    69
slime73@9532
    70
        [data.views removeObject:self];
slime73@9532
    71
slime73@9532
    72
        [self removeFromSuperview];
slime73@9532
    73
slime73@9532
    74
        /* Restore the next-oldest view in the old window. */
slime73@9727
    75
        view = data.views.lastObject;
slime73@9532
    76
slime73@9532
    77
        data.viewcontroller.view = view;
slime73@9532
    78
slime73@9551
    79
        data.uiwindow.rootViewController = nil;
slime73@9551
    80
        data.uiwindow.rootViewController = data.viewcontroller;
slime73@9532
    81
slime73@9532
    82
        [data.uiwindow layoutIfNeeded];
slime73@9532
    83
    }
slime73@9532
    84
slime73@9727
    85
    /* Add ourself to the new window. */
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
slime73@9861
   126
- (float)pressureForTouch:(UITouch *)touch
slime73@9861
   127
{
slime73@9861
   128
#ifdef __IPHONE_9_0
slime73@9861
   129
    if ([touch respondsToSelector:@selector(force)]) {
slime73@9861
   130
        return (float) touch.force;
slime73@9861
   131
    }
slime73@9861
   132
#endif
slime73@9861
   133
slime73@9861
   134
    return 1.0f;
slime73@9861
   135
}
slime73@9861
   136
kees@6003
   137
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
kees@6003
   138
{
slime73@9487
   139
    for (UITouch *touch in touches) {
slime73@9861
   140
        float pressure = [self pressureForTouch:touch];
slime73@9861
   141
slime73@9532
   142
        if (!firstFingerDown) {
slouken@6597
   143
            CGPoint locationInView = [self touchLocation:touch shouldNormalize:NO];
kees@6001
   144
slime73@9532
   145
            /* send mouse moved event */
slime73@9529
   146
            SDL_SendMouseMotion(sdlwindow, SDL_TOUCH_MOUSEID, 0, locationInView.x, locationInView.y);
slouken@4488
   147
slouken@6597
   148
            /* send mouse down event */
slime73@9529
   149
            SDL_SendMouseButton(sdlwindow, SDL_TOUCH_MOUSEID, SDL_PRESSED, SDL_BUTTON_LEFT);
jim@4660
   150
slime73@9532
   151
            firstFingerDown = touch;
slouken@6597
   152
        }
slouken@6597
   153
slouken@6436
   154
        CGPoint locationInView = [self touchLocation:touch shouldNormalize:YES];
icculus@7050
   155
        SDL_SendTouch(touchId, (SDL_FingerID)((size_t)touch),
slime73@9861
   156
                      SDL_TRUE, locationInView.x, locationInView.y, pressure);
slouken@5131
   157
    }
slouken@2765
   158
}
slouken@2765
   159
kees@6003
   160
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
kees@6003
   161
{
slime73@9487
   162
    for (UITouch *touch in touches) {
slime73@9861
   163
        float pressure = [self pressureForTouch:touch];
slime73@9861
   164
slime73@9532
   165
        if (touch == firstFingerDown) {
slouken@6597
   166
            /* send mouse up */
slime73@9529
   167
            SDL_SendMouseButton(sdlwindow, SDL_TOUCH_MOUSEID, SDL_RELEASED, SDL_BUTTON_LEFT);
slime73@9532
   168
            firstFingerDown = nil;
slouken@6597
   169
        }
slouken@4661
   170
slouken@6436
   171
        CGPoint locationInView = [self touchLocation:touch shouldNormalize:YES];
slime73@9501
   172
        SDL_SendTouch(touchId, (SDL_FingerID)((size_t)touch),
slime73@9861
   173
                      SDL_FALSE, locationInView.x, locationInView.y, pressure);
slouken@5131
   174
    }
slouken@2765
   175
}
slouken@2765
   176
kees@6003
   177
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
kees@6003
   178
{
slime73@9524
   179
    [self touchesEnded:touches withEvent:event];
slouken@2765
   180
}
slouken@2765
   181
kees@6003
   182
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
kees@6003
   183
{
slime73@9487
   184
    for (UITouch *touch in touches) {
slime73@9861
   185
        float pressure = [self pressureForTouch:touch];
slime73@9861
   186
slime73@9532
   187
        if (touch == firstFingerDown) {
slouken@6597
   188
            CGPoint locationInView = [self touchLocation:touch shouldNormalize:NO];
slouken@4488
   189
slouken@6597
   190
            /* send moved event */
slime73@9529
   191
            SDL_SendMouseMotion(sdlwindow, SDL_TOUCH_MOUSEID, 0, locationInView.x, locationInView.y);
slouken@6597
   192
        }
jim@4660
   193
slouken@6436
   194
        CGPoint locationInView = [self touchLocation:touch shouldNormalize:YES];
slime73@9501
   195
        SDL_SendTouchMotion(touchId, (SDL_FingerID)((size_t)touch),
slime73@9861
   196
                            locationInView.x, locationInView.y, pressure);
slouken@5131
   197
    }
slouken@2765
   198
}
slouken@2765
   199
slouken@2765
   200
@end
slouken@2765
   201
slouken@6044
   202
#endif /* SDL_VIDEO_DRIVER_UIKIT */
slouken@6044
   203
slouken@5132
   204
/* vi: set ts=4 sw=4 expandtab: */