src/video/uikit/SDL_uikitview.m
author Kees Bakker <kees@ijzerbout.nl>
Tue, 27 Sep 2011 22:51:26 +0200
changeset 6003 fddf81967e2d
parent 6001 3ae3d1e58d59
child 6010 508aa078acc0
permissions -rw-r--r--
Use a consistent source code format in src/video/uikit

For example:
* Opening bracket of a method/function on a new line at column 0
* space after "if", "while", etc
     1 /*
     2   Simple DirectMedia Layer
     3   Copyright (C) 1997-2011 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 
    22 #import "SDL_uikitview.h"
    23 
    24 #include "../../events/SDL_keyboard_c.h"
    25 #include "../../events/SDL_mouse_c.h"
    26 #include "../../events/SDL_touch_c.h"
    27 
    28 #if SDL_IPHONE_KEYBOARD
    29 #import "keyinfotable.h"
    30 #import "SDL_uikitappdelegate.h"
    31 #import "SDL_uikitwindow.h"
    32 #endif
    33 
    34 @implementation SDL_uikitview
    35 
    36 - (void)dealloc
    37 {
    38     [super dealloc];
    39 }
    40 
    41 - (id)initWithFrame:(CGRect)frame
    42 {
    43     self = [super initWithFrame: frame];
    44 
    45 #if SDL_IPHONE_KEYBOARD
    46     [self initializeKeyboard];
    47 #endif
    48 
    49 #ifdef FIXED_MULTITOUCH
    50     self.multipleTouchEnabled = YES;
    51 
    52     SDL_Touch touch;
    53     touch.id = 0; //TODO: Should be -1?
    54 
    55     //touch.driverdata = SDL_malloc(sizeof(EventTouchData));
    56     //EventTouchData* data = (EventTouchData*)(touch.driverdata);
    57 
    58     touch.x_min = 0;
    59     touch.x_max = frame.size.width;
    60     touch.native_xres = touch.x_max - touch.x_min;
    61     touch.y_min = 0;
    62     touch.y_max = frame.size.height;
    63     touch.native_yres = touch.y_max - touch.y_min;
    64     touch.pressure_min = 0;
    65     touch.pressure_max = 1;
    66     touch.native_pressureres = touch.pressure_max - touch.pressure_min;
    67 
    68 
    69     touchId = SDL_AddTouch(&touch, "IPHONE SCREEN");
    70 #endif
    71 
    72     return self;
    73 
    74 }
    75 
    76 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
    77 {
    78     NSEnumerator *enumerator = [touches objectEnumerator];
    79     UITouch *touch = (UITouch*)[enumerator nextObject];
    80 
    81     if (touch) {
    82         CGPoint locationInView = [touch locationInView: self];
    83 
    84         /* send moved event */
    85         SDL_SendMouseMotion(NULL, 0, locationInView.x, locationInView.y);
    86 
    87         /* send mouse down event */
    88         SDL_SendMouseButton(NULL, SDL_PRESSED, SDL_BUTTON_LEFT);
    89     }
    90 
    91 #ifdef FIXED_MULTITOUCH
    92     while(touch) {
    93         CGPoint locationInView = [touch locationInView: self];
    94 
    95 #ifdef IPHONE_TOUCH_EFFICIENT_DANGEROUS
    96         //FIXME: TODO: Using touch as the fingerId is potentially dangerous
    97         //It is also much more efficient than storing the UITouch pointer
    98         //and comparing it to the incoming event.
    99         SDL_SendFingerDown(touchId, (long)touch,
   100                            SDL_TRUE, locationInView.x, locationInView.y,
   101                            1);
   102 #else
   103         int i;
   104         for(i = 0; i < MAX_SIMULTANEOUS_TOUCHES; i++) {
   105             if (finger[i] == NULL) {
   106                 finger[i] = touch;
   107                 SDL_SendFingerDown(touchId, i,
   108                                    SDL_TRUE, locationInView.x, locationInView.y,
   109                                    1);
   110                 break;
   111             }
   112         }
   113 #endif
   114 
   115         touch = (UITouch*)[enumerator nextObject];
   116     }
   117 #endif
   118 }
   119 
   120 - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
   121 {
   122     NSEnumerator *enumerator = [touches objectEnumerator];
   123     UITouch *touch = (UITouch*)[enumerator nextObject];
   124 
   125     if (touch) {
   126         /* send mouse up */
   127         SDL_SendMouseButton(NULL, SDL_RELEASED, SDL_BUTTON_LEFT);
   128     }
   129 
   130 #ifdef FIXED_MULTITOUCH
   131     while(touch) {
   132         CGPoint locationInView = [touch locationInView: self];
   133 
   134 #ifdef IPHONE_TOUCH_EFFICIENT_DANGEROUS
   135         SDL_SendFingerDown(touchId, (long)touch,
   136                            SDL_FALSE, locationInView.x, locationInView.y,
   137                            1);
   138 #else
   139         int i;
   140         for (i = 0; i < MAX_SIMULTANEOUS_TOUCHES; i++) {
   141             if (finger[i] == touch) {
   142                 SDL_SendFingerDown(touchId, i,
   143                                    SDL_FALSE, locationInView.x, locationInView.y,
   144                                    1);
   145                 finger[i] = NULL;
   146                 break;
   147             }
   148         }
   149 #endif
   150 
   151         touch = (UITouch*)[enumerator nextObject];
   152     }
   153 #endif
   154 }
   155 
   156 - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
   157 {
   158     /*
   159         this can happen if the user puts more than 5 touches on the screen
   160         at once, or perhaps in other circumstances.  Usually (it seems)
   161         all active touches are canceled.
   162     */
   163     [self touchesEnded: touches withEvent: event];
   164 }
   165 
   166 - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
   167 {
   168     NSEnumerator *enumerator = [touches objectEnumerator];
   169     UITouch *touch = (UITouch*)[enumerator nextObject];
   170 
   171     if (touch) {
   172         CGPoint locationInView = [touch locationInView: self];
   173 
   174         /* send moved event */
   175         SDL_SendMouseMotion(NULL, 0, locationInView.x, locationInView.y);
   176     }
   177 
   178 #ifdef FIXED_MULTITOUCH
   179     while(touch) {
   180         CGPoint locationInView = [touch locationInView: self];
   181 
   182 #ifdef IPHONE_TOUCH_EFFICIENT_DANGEROUS
   183         SDL_SendTouchMotion(touchId, (long)touch,
   184                             SDL_FALSE, locationInView.x, locationInView.y,
   185                             1);
   186 #else
   187         int i;
   188         for (i = 0; i < MAX_SIMULTANEOUS_TOUCHES; i++) {
   189             if (finger[i] == touch) {
   190                 SDL_SendTouchMotion(touchId, i,
   191                                     SDL_FALSE, locationInView.x, locationInView.y,
   192                                     1);
   193                 break;
   194             }
   195         }
   196 #endif
   197 
   198         touch = (UITouch*)[enumerator nextObject];
   199     }
   200 #endif
   201 }
   202 
   203 /*
   204     ---- Keyboard related functionality below this line ----
   205 */
   206 #if SDL_IPHONE_KEYBOARD
   207 
   208 /* Is the iPhone virtual keyboard visible onscreen? */
   209 - (BOOL)keyboardVisible
   210 {
   211     return keyboardVisible;
   212 }
   213 
   214 /* Set ourselves up as a UITextFieldDelegate */
   215 - (void)initializeKeyboard
   216 {
   217     textField = [[UITextField alloc] initWithFrame: CGRectZero];
   218     textField.delegate = self;
   219     /* placeholder so there is something to delete! */
   220     textField.text = @" ";
   221 
   222     /* set UITextInputTrait properties, mostly to defaults */
   223     textField.autocapitalizationType = UITextAutocapitalizationTypeNone;
   224     textField.autocorrectionType = UITextAutocorrectionTypeNo;
   225     textField.enablesReturnKeyAutomatically = NO;
   226     textField.keyboardAppearance = UIKeyboardAppearanceDefault;
   227     textField.keyboardType = UIKeyboardTypeDefault;
   228     textField.returnKeyType = UIReturnKeyDefault;
   229     textField.secureTextEntry = NO;
   230 
   231     textField.hidden = YES;
   232     keyboardVisible = NO;
   233     /* add the UITextField (hidden) to our view */
   234     [self addSubview: textField];
   235     [textField release];
   236 }
   237 
   238 /* reveal onscreen virtual keyboard */
   239 - (void)showKeyboard
   240 {
   241     keyboardVisible = YES;
   242     [textField becomeFirstResponder];
   243 }
   244 
   245 /* hide onscreen virtual keyboard */
   246 - (void)hideKeyboard
   247 {
   248     keyboardVisible = NO;
   249     [textField resignFirstResponder];
   250 }
   251 
   252 /* UITextFieldDelegate method.  Invoked when user types something. */
   253 - (BOOL)textField:(UITextField *)_textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
   254 {
   255     if ([string length] == 0) {
   256         /* it wants to replace text with nothing, ie a delete */
   257         SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_DELETE);
   258         SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_DELETE);
   259     }
   260     else {
   261         /* go through all the characters in the string we've been sent
   262            and convert them to key presses */
   263         int i;
   264         for (i = 0; i < [string length]; i++) {
   265 
   266             unichar c = [string characterAtIndex: i];
   267 
   268             Uint16 mod = 0;
   269             SDL_Scancode code;
   270 
   271             if (c < 127) {
   272                 /* figure out the SDL_Scancode and SDL_keymod for this unichar */
   273                 code = unicharToUIKeyInfoTable[c].code;
   274                 mod  = unicharToUIKeyInfoTable[c].mod;
   275             }
   276             else {
   277                 /* we only deal with ASCII right now */
   278                 code = SDL_SCANCODE_UNKNOWN;
   279                 mod = 0;
   280             }
   281 
   282             if (mod & KMOD_SHIFT) {
   283                 /* If character uses shift, press shift down */
   284                 SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_LSHIFT);
   285             }
   286             /* send a keydown and keyup even for the character */
   287             SDL_SendKeyboardKey(SDL_PRESSED, code);
   288             SDL_SendKeyboardKey(SDL_RELEASED, code);
   289             if (mod & KMOD_SHIFT) {
   290                 /* If character uses shift, press shift back up */
   291                 SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_LSHIFT);
   292             }
   293         }
   294         SDL_SendKeyboardText([string UTF8String]);
   295     }
   296     return NO; /* don't allow the edit! (keep placeholder text there) */
   297 }
   298 
   299 /* Terminates the editing session */
   300 - (BOOL)textFieldShouldReturn:(UITextField*)_textField
   301 {
   302     SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_RETURN);
   303     [self hideKeyboard];
   304     return YES;
   305 }
   306 
   307 #endif
   308 
   309 @end
   310 
   311 /* iPhone keyboard addition functions */
   312 #if SDL_IPHONE_KEYBOARD
   313 
   314 int SDL_iPhoneKeyboardShow(SDL_Window * window)
   315 {
   316     SDL_WindowData *data;
   317     SDL_uikitview *view;
   318 
   319     if (NULL == window) {
   320         SDL_SetError("Window does not exist");
   321         return -1;
   322     }
   323 
   324     data = (SDL_WindowData *)window->driverdata;
   325     view = data->view;
   326 
   327     if (nil == view) {
   328         SDL_SetError("Window has no view");
   329         return -1;
   330     }
   331     else {
   332         [view showKeyboard];
   333         return 0;
   334     }
   335 }
   336 
   337 int SDL_iPhoneKeyboardHide(SDL_Window * window)
   338 {
   339     SDL_WindowData *data;
   340     SDL_uikitview *view;
   341 
   342     if (NULL == window) {
   343         SDL_SetError("Window does not exist");
   344         return -1;
   345     }
   346 
   347     data = (SDL_WindowData *)window->driverdata;
   348     view = data->view;
   349 
   350     if (NULL == view) {
   351         SDL_SetError("Window has no view");
   352         return -1;
   353     }
   354     else {
   355         [view hideKeyboard];
   356         return 0;
   357     }
   358 }
   359 
   360 SDL_bool SDL_iPhoneKeyboardIsShown(SDL_Window * window)
   361 {
   362     SDL_WindowData *data;
   363     SDL_uikitview *view;
   364 
   365     if (NULL == window) {
   366         SDL_SetError("Window does not exist");
   367         return -1;
   368     }
   369 
   370     data = (SDL_WindowData *)window->driverdata;
   371     view = data->view;
   372 
   373     if (NULL == view) {
   374         SDL_SetError("Window has no view");
   375         return 0;
   376     }
   377     else {
   378         return view.keyboardVisible;
   379     }
   380 }
   381 
   382 int SDL_iPhoneKeyboardToggle(SDL_Window * window)
   383 {
   384     SDL_WindowData *data;
   385     SDL_uikitview *view;
   386 
   387     if (NULL == window) {
   388         SDL_SetError("Window does not exist");
   389         return -1;
   390     }
   391 
   392     data = (SDL_WindowData *)window->driverdata;
   393     view = data->view;
   394 
   395     if (NULL == view) {
   396         SDL_SetError("Window has no view");
   397         return -1;
   398     }
   399     else {
   400         if (SDL_iPhoneKeyboardIsShown(window)) {
   401             SDL_iPhoneKeyboardHide(window);
   402         }
   403         else {
   404             SDL_iPhoneKeyboardShow(window);
   405         }
   406         return 0;
   407     }
   408 }
   409 
   410 #else
   411 
   412 /* stubs, used if compiled without keyboard support */
   413 
   414 int SDL_iPhoneKeyboardShow(SDL_Window * window)
   415 {
   416     SDL_SetError("Not compiled with keyboard support");
   417     return -1;
   418 }
   419 
   420 int SDL_iPhoneKeyboardHide(SDL_Window * window)
   421 {
   422     SDL_SetError("Not compiled with keyboard support");
   423     return -1;
   424 }
   425 
   426 SDL_bool SDL_iPhoneKeyboardIsShown(SDL_Window * window)
   427 {
   428     return 0;
   429 }
   430 
   431 int SDL_iPhoneKeyboardToggle(SDL_Window * window)
   432 {
   433     SDL_SetError("Not compiled with keyboard support");
   434     return -1;
   435 }
   436 
   437 #endif /* SDL_IPHONE_KEYBOARD */
   438 
   439 /* vi: set ts=4 sw=4 expandtab: */