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