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