src/video/uikit/SDL_uikitview.m
author Kees Bakker <kees@ijzerbout.nl>
Tue, 27 Sep 2011 21:02:26 +0200
changeset 6001 3ae3d1e58d59
parent 5535 96594ac5fd1a
child 6003 fddf81967e2d
permissions -rw-r--r--
Cleanup out trailing whitespace in src/video/uikit
     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     [super dealloc];
    38 }
    39 
    40 - (id)initWithFrame:(CGRect)frame {
    41 
    42     self = [super initWithFrame: frame];
    43 
    44 #if SDL_IPHONE_KEYBOARD
    45     [self initializeKeyboard];
    46 #endif
    47 
    48 #ifdef FIXED_MULTITOUCH
    49     self.multipleTouchEnabled = YES;
    50 
    51     SDL_Touch touch;
    52     touch.id = 0; //TODO: Should be -1?
    53 
    54     //touch.driverdata = SDL_malloc(sizeof(EventTouchData));
    55     //EventTouchData* data = (EventTouchData*)(touch.driverdata);
    56 
    57     touch.x_min = 0;
    58     touch.x_max = frame.size.width;
    59     touch.native_xres = touch.x_max - touch.x_min;
    60     touch.y_min = 0;
    61     touch.y_max = frame.size.height;
    62     touch.native_yres = touch.y_max - touch.y_min;
    63     touch.pressure_min = 0;
    64     touch.pressure_max = 1;
    65     touch.native_pressureres = touch.pressure_max - touch.pressure_min;
    66 
    67 
    68     touchId = SDL_AddTouch(&touch, "IPHONE SCREEN");
    69 #endif
    70 
    71     return self;
    72 
    73 }
    74 
    75 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    76 
    77     NSEnumerator *enumerator = [touches objectEnumerator];
    78     UITouch *touch = (UITouch*)[enumerator nextObject];
    79 
    80     if (touch) {
    81         CGPoint locationInView = [touch locationInView: self];
    82 
    83         /* send moved event */
    84         SDL_SendMouseMotion(NULL, 0, locationInView.x, locationInView.y);
    85 
    86         /* send mouse down event */
    87         SDL_SendMouseButton(NULL, SDL_PRESSED, SDL_BUTTON_LEFT);
    88     }
    89 
    90 #ifdef FIXED_MULTITOUCH
    91     while(touch) {
    92       CGPoint locationInView = [touch locationInView: self];
    93 
    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 
   135 #ifdef IPHONE_TOUCH_EFFICIENT_DANGEROUS
   136       SDL_SendFingerDown(touchId,(long)touch,
   137                  SDL_FALSE,locationInView.x,locationInView.y,
   138                  1);
   139 #else
   140       int i;
   141       for(i = 0;i < MAX_SIMULTANEOUS_TOUCHES;i++) {
   142         if(finger[i] == touch) {
   143           SDL_SendFingerDown(touchId,i,
   144                  SDL_FALSE,locationInView.x,locationInView.y,
   145                  1);
   146           finger[i] = NULL;
   147           break;
   148         }
   149       }
   150 #endif
   151 
   152       touch = (UITouch*)[enumerator nextObject];
   153     }
   154 #endif
   155 }
   156 
   157 - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
   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 
   183 #ifdef IPHONE_TOUCH_EFFICIENT_DANGEROUS
   184       SDL_SendTouchMotion(touchId,(long)touch,
   185                   SDL_FALSE,locationInView.x,locationInView.y,
   186                   1);
   187 #else
   188       int i;
   189       for(i = 0;i < MAX_SIMULTANEOUS_TOUCHES;i++) {
   190         if(finger[i] == touch) {
   191           SDL_SendTouchMotion(touchId,i,
   192                   SDL_FALSE,locationInView.x,locationInView.y,
   193                   1);
   194           break;
   195         }
   196       }
   197 #endif
   198 
   199       touch = (UITouch*)[enumerator nextObject];
   200     }
   201 #endif
   202 }
   203 
   204 /*
   205     ---- Keyboard related functionality below this line ----
   206 */
   207 #if SDL_IPHONE_KEYBOARD
   208 
   209 /* Is the iPhone virtual keyboard visible onscreen? */
   210 - (BOOL)keyboardVisible {
   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     keyboardVisible = YES;
   241     [textField becomeFirstResponder];
   242 }
   243 
   244 /* hide onscreen virtual keyboard */
   245 - (void)hideKeyboard {
   246     keyboardVisible = NO;
   247     [textField resignFirstResponder];
   248 }
   249 
   250 /* UITextFieldDelegate method.  Invoked when user types something. */
   251 - (BOOL)textField:(UITextField *)_textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
   252 
   253     if ([string length] == 0) {
   254         /* it wants to replace text with nothing, ie a delete */
   255         SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_DELETE);
   256         SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_DELETE);
   257     }
   258     else {
   259         /* go through all the characters in the string we've been sent
   260            and convert them to key presses */
   261         int i;
   262         for (i=0; i<[string length]; i++) {
   263 
   264             unichar c = [string characterAtIndex: i];
   265 
   266             Uint16 mod = 0;
   267             SDL_Scancode code;
   268 
   269             if (c < 127) {
   270                 /* figure out the SDL_Scancode and SDL_keymod for this unichar */
   271                 code = unicharToUIKeyInfoTable[c].code;
   272                 mod  = unicharToUIKeyInfoTable[c].mod;
   273             }
   274             else {
   275                 /* we only deal with ASCII right now */
   276                 code = SDL_SCANCODE_UNKNOWN;
   277                 mod = 0;
   278             }
   279 
   280             if (mod & KMOD_SHIFT) {
   281                 /* If character uses shift, press shift down */
   282                 SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_LSHIFT);
   283             }
   284             /* send a keydown and keyup even for the character */
   285             SDL_SendKeyboardKey(SDL_PRESSED, code);
   286             SDL_SendKeyboardKey(SDL_RELEASED, code);
   287             if (mod & KMOD_SHIFT) {
   288                 /* If character uses shift, press shift back up */
   289                 SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_LSHIFT);
   290             }
   291         }
   292         SDL_SendKeyboardText([string UTF8String]);
   293     }
   294     return NO; /* don't allow the edit! (keep placeholder text there) */
   295 }
   296 
   297 /* Terminates the editing session */
   298 - (BOOL)textFieldShouldReturn:(UITextField*)_textField {
   299     SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_RETURN);
   300     [self hideKeyboard];
   301     return YES;
   302 }
   303 
   304 #endif
   305 
   306 @end
   307 
   308 /* iPhone keyboard addition functions */
   309 #if SDL_IPHONE_KEYBOARD
   310 
   311 int SDL_iPhoneKeyboardShow(SDL_Window * window) {
   312 
   313     SDL_WindowData *data;
   314     SDL_uikitview *view;
   315 
   316     if (NULL == window) {
   317         SDL_SetError("Window does not exist");
   318         return -1;
   319     }
   320 
   321     data = (SDL_WindowData *)window->driverdata;
   322     view = data->view;
   323 
   324     if (nil == view) {
   325         SDL_SetError("Window has no view");
   326         return -1;
   327     }
   328     else {
   329         [view showKeyboard];
   330         return 0;
   331     }
   332 }
   333 
   334 int SDL_iPhoneKeyboardHide(SDL_Window * window) {
   335 
   336     SDL_WindowData *data;
   337     SDL_uikitview *view;
   338 
   339     if (NULL == window) {
   340         SDL_SetError("Window does not exist");
   341         return -1;
   342     }
   343 
   344     data = (SDL_WindowData *)window->driverdata;
   345     view = data->view;
   346 
   347     if (NULL == view) {
   348         SDL_SetError("Window has no view");
   349         return -1;
   350     }
   351     else {
   352         [view hideKeyboard];
   353         return 0;
   354     }
   355 }
   356 
   357 SDL_bool SDL_iPhoneKeyboardIsShown(SDL_Window * window) {
   358 
   359     SDL_WindowData *data;
   360     SDL_uikitview *view;
   361 
   362     if (NULL == window) {
   363         SDL_SetError("Window does not exist");
   364         return -1;
   365     }
   366 
   367     data = (SDL_WindowData *)window->driverdata;
   368     view = data->view;
   369 
   370     if (NULL == view) {
   371         SDL_SetError("Window has no view");
   372         return 0;
   373     }
   374     else {
   375         return view.keyboardVisible;
   376     }
   377 }
   378 
   379 int SDL_iPhoneKeyboardToggle(SDL_Window * window) {
   380 
   381     SDL_WindowData *data;
   382     SDL_uikitview *view;
   383 
   384     if (NULL == window) {
   385         SDL_SetError("Window does not exist");
   386         return -1;
   387     }
   388 
   389     data = (SDL_WindowData *)window->driverdata;
   390     view = data->view;
   391 
   392     if (NULL == view) {
   393         SDL_SetError("Window has no view");
   394         return -1;
   395     }
   396     else {
   397         if (SDL_iPhoneKeyboardIsShown(window)) {
   398             SDL_iPhoneKeyboardHide(window);
   399         }
   400         else {
   401             SDL_iPhoneKeyboardShow(window);
   402         }
   403         return 0;
   404     }
   405 }
   406 
   407 #else
   408 
   409 /* stubs, used if compiled without keyboard support */
   410 
   411 int SDL_iPhoneKeyboardShow(SDL_Window * window) {
   412     SDL_SetError("Not compiled with keyboard support");
   413     return -1;
   414 }
   415 
   416 int SDL_iPhoneKeyboardHide(SDL_Window * window) {
   417     SDL_SetError("Not compiled with keyboard support");
   418     return -1;
   419 }
   420 
   421 SDL_bool SDL_iPhoneKeyboardIsShown(SDL_Window * window) {
   422     return 0;
   423 }
   424 
   425 int SDL_iPhoneKeyboardToggle(SDL_Window * window) {
   426     SDL_SetError("Not compiled with keyboard support");
   427     return -1;
   428 }
   429 
   430 #endif /* SDL_IPHONE_KEYBOARD */
   431 
   432 /* vi: set ts=4 sw=4 expandtab: */