src/video/uikit/SDL_uikitview.m
author Holmes Futrell <hfutrell@umail.ucsb.edu>
Wed, 13 Aug 2008 23:14:36 +0000
branchgsoc2008_iphone
changeset 2419 ab89ff6e97af
parent 2405 3d0b3a7d3bea
child 2425 491958a6c881
permissions -rw-r--r--
Originally keyboard support was in the form of a category of the class SDL_uikitview. It turns out this can cause problems with compilation where the code is not actually included and doesn't fail until dynamic dispatch. This is just awful, so I've moved to the code into the SDL_uikitview class itself.
     1 /*
     2  SDL - Simple DirectMedia Layer
     3  Copyright (C) 1997-2006 Sam Lantinga
     4  
     5  This library is free software; you can redistribute it and/or
     6  modify it under the terms of the GNU Lesser General Public
     7  License as published by the Free Software Foundation; either
     8  version 2.1 of the License, or (at your option) any later version.
     9  
    10  This library is distributed in the hope that it will be useful,
    11  but WITHOUT ANY WARRANTY; without even the implied warranty of
    12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    13  Lesser General Public License for more details.
    14  
    15  You should have received a copy of the GNU Lesser General Public
    16  License along with this library; if not, write to the Free Software
    17  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    18  
    19  Sam Lantinga
    20  slouken@libsdl.org
    21  */
    22 
    23 #import "SDL_uikitview.h"
    24 
    25 #if SDL_IPHONE_KEYBOARD
    26 #import "SDL_keyboard_c.h"
    27 #import "keyinfotable.h"
    28 #import "SDL_uikitappdelegate.h"
    29 #import "SDL_uikitwindow.h"
    30 #endif
    31 
    32 @implementation SDL_uikitview
    33 
    34 - (void)dealloc {
    35 #if SDL_IPHONE_KEYBOARD
    36 	[textField release];
    37 #endif
    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 	int i;
    50 	for (i=0; i<MAX_SIMULTANEOUS_TOUCHES; i++) {
    51 		mice[i].driverdata = NULL;
    52 		SDL_AddMouse(&(mice[i]), i);
    53 	}
    54 	self.multipleTouchEnabled = YES;
    55 			
    56 	return self;
    57 
    58 }
    59 
    60 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    61 
    62 	NSEnumerator *enumerator = [touches objectEnumerator];
    63 	UITouch *touch=(UITouch*)[enumerator nextObject];
    64 	
    65 	// associate touches with mice, so long as we have slots
    66 	int i;
    67 	int found = 0;
    68 	for(i=0; touch && i < MAX_SIMULTANEOUS_TOUCHES; i++) {
    69 	
    70 		// check if this mouse is already tracking a touch
    71 		if (mice[i].driverdata != NULL) {
    72 			continue;
    73 		}
    74 		
    75 		found = 1;
    76 		
    77 		int oldMouse = SDL_SelectMouse(-1);
    78 		SDL_SelectMouse(i);
    79 		CGPoint locationInView = [touch locationInView: self];
    80 		mice[i].driverdata = [touch retain];
    81 		SDL_SendMouseMotion(i, 0, locationInView.x, locationInView.y);
    82 		SDL_SendMouseButton(i, SDL_PRESSED, SDL_BUTTON_LEFT);
    83 		SDL_GetRelativeMouseState(NULL, NULL);
    84 		touch = (UITouch*)[enumerator nextObject]; 
    85 		
    86 		SDL_SelectMouse(oldMouse);
    87 		
    88 	}	
    89 }
    90 
    91 - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    92 	
    93 	NSEnumerator *enumerator = [touches objectEnumerator];
    94 	UITouch *touch=nil;
    95 	
    96 	while(touch = (UITouch *)[enumerator nextObject]) {
    97 		int i, found = NO;
    98 		for (i=0; i<MAX_SIMULTANEOUS_TOUCHES && !found; i++) {
    99 			if (mice[i].driverdata == touch) {
   100 				[(UITouch*)(mice[i].driverdata) release];
   101 				mice[i].driverdata = NULL;
   102 				SDL_SendMouseButton(i, SDL_RELEASED, SDL_BUTTON_LEFT);
   103 
   104 				found = YES;
   105 			}
   106 		}
   107 	}
   108 }
   109 
   110 - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
   111 	/*
   112 		this can happen if the user puts more than 5 touches on the screen
   113 		at once, or perhaps in other circumstances.  Usually (it seems)
   114 		all active touches are canceled.
   115 	*/
   116 	[self touchesEnded: touches withEvent: event];
   117 }
   118 
   119 - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
   120 	
   121 	NSEnumerator *enumerator = [touches objectEnumerator];
   122 	UITouch *touch=nil;
   123 	
   124 	while(touch = (UITouch *)[enumerator nextObject]) {
   125 		int i, found = NO;
   126 		for (i=0; i<MAX_SIMULTANEOUS_TOUCHES && !found; i++) {
   127 			if (mice[i].driverdata == touch) {
   128 				CGPoint locationInView = [touch locationInView: self];
   129 				SDL_SendMouseMotion(i, 0, locationInView.x, locationInView.y);
   130 				found = YES;
   131 			}
   132 		}
   133 	}
   134 }
   135 
   136 /*
   137 	---- Keyboard related functionality below this line ----
   138 */
   139 #if SDL_IPHONE_KEYBOARD
   140 
   141 - (BOOL)keyboardVisible {
   142 	return keyboardVisible;
   143 }
   144 
   145 /* UITextFieldDelegate related methods */
   146 - (void)initializeKeyboard {
   147 	
   148 	NSLog(@"Text field init");
   149 	
   150 	textField = [[UITextField alloc] initWithFrame: CGRectZero];
   151 	textField.delegate = self;
   152 	/* placeholder so there is something to delete! */
   153 	textField.text = @" ";	
   154 	
   155 	/* set UITextInputTrait properties, mostly to defaults */
   156 	textField.autocapitalizationType = UITextAutocapitalizationTypeNone;
   157 	textField.autocorrectionType = UITextAutocorrectionTypeNo;
   158 	textField.enablesReturnKeyAutomatically = NO;
   159 	textField.keyboardAppearance = UIKeyboardAppearanceDefault;
   160 	textField.keyboardType = UIKeyboardTypeDefault;
   161 	textField.returnKeyType = UIReturnKeyDefault;
   162 	textField.secureTextEntry = NO;	
   163 	
   164 	textField.hidden = YES;
   165 	keyboardVisible = NO;
   166 	[self addSubview: textField];
   167 	
   168 	/*
   169 	 SDL makes a copy of our keyboard.
   170 	 */
   171 	
   172 	SDL_Keyboard keyboard;
   173 	SDL_zero(keyboard);
   174 	//data->keyboard = SDL_AddKeyboard(&keyboard, -1);
   175 	/* 
   176 	 We'll need to delete this keyboard ...
   177 	 */
   178 	SDL_AddKeyboard(&keyboard, 0);
   179 	SDLKey keymap[SDL_NUM_SCANCODES];
   180 	SDL_GetDefaultKeymap(keymap);
   181 	SDL_SetKeymap(0, 0, keymap, SDL_NUM_SCANCODES);
   182 	
   183 }
   184 
   185 - (void)showKeyboard {
   186 	keyboardVisible = YES;
   187 	[textField becomeFirstResponder];
   188 }
   189 
   190 - (void)hideKeyboard {
   191 	keyboardVisible = NO;
   192 	[textField resignFirstResponder];
   193 }
   194 
   195 - (BOOL)textField:(UITextField *)_textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
   196 	
   197 	if ([string length] == 0) {
   198 		/* it wants to replace text with nothing, ie a delete */
   199 		SDL_SendKeyboardKey( 0, SDL_PRESSED, SDL_SCANCODE_DELETE);
   200 		SDL_SendKeyboardKey( 0, SDL_RELEASED, SDL_SCANCODE_DELETE);
   201 	}
   202 	else {
   203 		
   204 		int i;
   205 		for (i=0; i<[string length]; i++) {
   206 			
   207 			unichar c = [string characterAtIndex: i];
   208 			
   209 			Uint16 mod = 0;
   210 			SDL_scancode code;
   211 			
   212 			if (c < 127) {
   213 				code = unicharToUIKeyInfoTable[c].code;
   214 				mod  = unicharToUIKeyInfoTable[c].mod;
   215 			}
   216 			else {
   217 				code = SDL_SCANCODE_UNKNOWN;
   218 				mod = 0;
   219 			}
   220 			
   221 			if (mod & KMOD_SHIFT) {
   222 				SDL_SendKeyboardKey( 0, SDL_PRESSED, SDL_SCANCODE_LSHIFT);
   223 			}
   224 			SDL_SendKeyboardKey( 0, SDL_PRESSED, code);
   225 			SDL_SendKeyboardKey( 0, SDL_RELEASED, code);
   226 			if (mod & KMOD_SHIFT) {
   227 				SDL_SendKeyboardKey( 0, SDL_RELEASED, SDL_SCANCODE_LSHIFT);
   228 			}			
   229 			
   230 		}
   231 		
   232 	}
   233 	return NO; /* don't allow the edit(!) */
   234 }
   235 
   236 /* Terminates the editing session */
   237 - (BOOL)textFieldShouldReturn:(UITextField*)_textField {
   238 	[self hideKeyboard];
   239 	return YES;
   240 }
   241 
   242 #endif
   243 
   244 @end
   245 
   246 
   247 
   248 /* iPhone keyboard addition functions */
   249 #if SDL_IPHONE_KEYBOARD
   250 
   251 int SDL_iPhoneKeyboardShow(SDL_WindowID windowID) {
   252 	
   253 	SDL_Window *window = SDL_GetWindowFromID(windowID);
   254 	SDL_WindowData *data;
   255 	SDL_uikitview *view;
   256 	
   257 	if (NULL == window) {
   258 		SDL_SetError("Window does not exist");
   259 		return -1;
   260 	}
   261 	
   262 	data = (SDL_WindowData *)window->driverdata;
   263 	view = data->view;
   264 	
   265 	if (nil == view) {
   266 		SDL_SetError("Window has no view");
   267 		return -1;
   268 	}
   269 	else {
   270 		[view showKeyboard];
   271 		return 0;
   272 	}
   273 }
   274 
   275 int SDL_iPhoneKeyboardHide(SDL_WindowID windowID) {
   276 	
   277 	SDL_Window *window = SDL_GetWindowFromID(windowID);
   278 	SDL_WindowData *data;
   279 	SDL_uikitview *view;
   280 	
   281 	if (NULL == window) {
   282 		SDL_SetError("Window does not exist");
   283 		return -1;
   284 	}	
   285 	
   286 	data = (SDL_WindowData *)window->driverdata;
   287 	view = data->view;
   288 	
   289 	if (NULL == view) {
   290 		SDL_SetError("Window has no view");
   291 		return -1;
   292 	}
   293 	else {
   294 		[view hideKeyboard];
   295 		return 0;
   296 	}
   297 }
   298 
   299 SDL_bool SDL_iPhoneKeyboardIsShown(SDL_WindowID windowID) {
   300 	
   301 	SDL_Window *window = SDL_GetWindowFromID(windowID);
   302 	SDL_WindowData *data;
   303 	SDL_uikitview *view;
   304 	
   305 	if (NULL == window) {
   306 		SDL_SetError("Window does not exist");
   307 		return -1;
   308 	}	
   309 	
   310 	data = (SDL_WindowData *)window->driverdata;
   311 	view = data->view;
   312 	
   313 	if (NULL == view) {
   314 		SDL_SetError("Window has no view");
   315 		return 0;
   316 	}
   317 	else {
   318 		return view.keyboardVisible;
   319 	}
   320 }
   321 
   322 int SDL_iPhoneKeyboardToggle(SDL_WindowID windowID) {
   323 	
   324 	SDL_Window *window = SDL_GetWindowFromID(windowID);
   325 	SDL_WindowData *data;
   326 	SDL_uikitview *view;
   327 	
   328 	if (NULL == window) {
   329 		SDL_SetError("Window does not exist");
   330 		return -1;
   331 	}	
   332 	
   333 	data = (SDL_WindowData *)window->driverdata;
   334 	view = data->view;
   335 	
   336 	if (NULL == view) {
   337 		SDL_SetError("Window has no view");
   338 		return -1;
   339 	}
   340 	else {
   341 		if (SDL_iPhoneKeyboardIsShown(windowID)) {
   342 			SDL_iPhoneKeyboardHide(windowID);
   343 		}
   344 		else {
   345 			SDL_iPhoneKeyboardShow(windowID);
   346 		}
   347 		return 0;
   348 	}
   349 }
   350 
   351 #else
   352 
   353 int SDL_iPhoneKeyboardShow(SDL_WindowID windowID) {
   354 	SDL_SetError("Not compiled with keyboard support");
   355 	return -1;
   356 }
   357 
   358 int SDL_iPhoneKeyboardHide(SDL_WindowID windowID) {
   359 	SDL_SetError("Not compiled with keyboard support");
   360 	return -1;
   361 }
   362 
   363 SDL_bool SDL_iPhoneKeyboardIsShown(SDL_WindowID windowID) {
   364 	return 0;
   365 }
   366 
   367 int SDL_iPhoneKeyboardToggle(SDL_WindowID windowID) {
   368 	SDL_SetError("Not compiled with keyboard support");
   369 	return -1;
   370 }
   371 
   372 
   373 #endif /* SDL_IPHONE_KEYBOARD */