zenilib  0.5.3.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
SDL_uikitview.m
Go to the documentation of this file.
1  /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2013 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 #include "SDL_config.h"
22 
23 #if SDL_VIDEO_DRIVER_UIKIT
24 
25 #include "SDL_uikitview.h"
26 
27 #include "../../events/SDL_keyboard_c.h"
28 #include "../../events/SDL_mouse_c.h"
29 #include "../../events/SDL_touch_c.h"
30 
31 #if SDL_IPHONE_KEYBOARD
32 #include "keyinfotable.h"
33 #endif
34 #include "SDL_uikitappdelegate.h"
35 #include "SDL_uikitmodes.h"
36 #include "SDL_uikitwindow.h"
37 
38 @implementation SDL_uikitview
39 
40 - (void)dealloc
41 {
42  [super dealloc];
43 }
44 
45 - (id)initWithFrame:(CGRect)frame
46 {
47  self = [super initWithFrame: frame];
48 
49 #if SDL_IPHONE_KEYBOARD
50  [self initializeKeyboard];
51 #endif
52 
53  self.multipleTouchEnabled = YES;
54 
55  touchId = 1;
56  SDL_AddTouch(touchId, "");
57 
58  return self;
59 
60 }
61 
62 - (CGPoint)touchLocation:(UITouch *)touch shouldNormalize:(BOOL)normalize
63 {
64  CGPoint point = [touch locationInView: self];
65 
66  /* Get the display scale and apply that to the input coordinates */
67  SDL_Window *window = self->viewcontroller.window;
69  SDL_DisplayModeData *displaymodedata = (SDL_DisplayModeData *) display->current_mode.driverdata;
70 
71  if (normalize) {
72  CGRect bounds = [self bounds];
73  point.x /= bounds.size.width;
74  point.y /= bounds.size.height;
75  } else {
76  point.x *= displaymodedata->scale;
77  point.y *= displaymodedata->scale;
78  }
79  return point;
80 }
81 
82 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
83 {
84  NSEnumerator *enumerator = [touches objectEnumerator];
85  UITouch *touch = (UITouch*)[enumerator nextObject];
86 
87  while (touch) {
88  if (!leftFingerDown) {
89  CGPoint locationInView = [self touchLocation:touch shouldNormalize:NO];
90 
91  /* send moved event */
92  SDL_SendMouseMotion(NULL, SDL_TOUCH_MOUSEID, 0, locationInView.x, locationInView.y);
93 
94  /* send mouse down event */
96 
97  leftFingerDown = touch;
98  }
99 
100  CGPoint locationInView = [self touchLocation:touch shouldNormalize:YES];
101 #ifdef IPHONE_TOUCH_EFFICIENT_DANGEROUS
102  /* FIXME: TODO: Using touch as the fingerId is potentially dangerous
103  * It is also much more efficient than storing the UITouch pointer
104  * and comparing it to the incoming event.
105  */
106  SDL_SendTouch(touchId, (SDL_FingerID)((size_t)touch),
107  SDL_TRUE, locationInView.x, locationInView.y, 1.0f);
108 #else
109  int i;
110  for(i = 0; i < MAX_SIMULTANEOUS_TOUCHES; i++) {
111  if (finger[i] == NULL) {
112  finger[i] = touch;
114  SDL_TRUE, locationInView.x, locationInView.y, 1.0f);
115  break;
116  }
117  }
118 #endif
119  touch = (UITouch*)[enumerator nextObject];
120  }
121 }
122 
123 - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
124 {
125  NSEnumerator *enumerator = [touches objectEnumerator];
126  UITouch *touch = (UITouch*)[enumerator nextObject];
127 
128  while(touch) {
129  if (touch == leftFingerDown) {
130  /* send mouse up */
132  leftFingerDown = nil;
133  }
134 
135  CGPoint locationInView = [self touchLocation:touch shouldNormalize:YES];
136 #ifdef IPHONE_TOUCH_EFFICIENT_DANGEROUS
137  SDL_SendTouch(touchId, (long)touch,
138  SDL_FALSE, locationInView.x, locationInView.y, 1.0f);
139 #else
140  int i;
141  for (i = 0; i < MAX_SIMULTANEOUS_TOUCHES; i++) {
142  if (finger[i] == touch) {
144  SDL_FALSE, locationInView.x, locationInView.y, 1.0f);
145  finger[i] = NULL;
146  break;
147  }
148  }
149 #endif
150  touch = (UITouch*)[enumerator nextObject];
151  }
152 }
153 
154 - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
155 {
156  /*
157  this can happen if the user puts more than 5 touches on the screen
158  at once, or perhaps in other circumstances. Usually (it seems)
159  all active touches are canceled.
160  */
161  [self touchesEnded: touches withEvent: event];
162 }
163 
164 - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
165 {
166  NSEnumerator *enumerator = [touches objectEnumerator];
167  UITouch *touch = (UITouch*)[enumerator nextObject];
168 
169  while (touch) {
170  if (touch == leftFingerDown) {
171  CGPoint locationInView = [self touchLocation:touch shouldNormalize:NO];
172 
173  /* send moved event */
174  SDL_SendMouseMotion(NULL, SDL_TOUCH_MOUSEID, 0, locationInView.x, locationInView.y);
175  }
176 
177  CGPoint locationInView = [self touchLocation:touch shouldNormalize:YES];
178 #ifdef IPHONE_TOUCH_EFFICIENT_DANGEROUS
179  SDL_SendTouchMotion(touchId, (long)touch,
180  locationInView.x, locationInView.y, 1.0f);
181 #else
182  int i;
183  for (i = 0; i < MAX_SIMULTANEOUS_TOUCHES; i++) {
184  if (finger[i] == touch) {
186  locationInView.x, locationInView.y, 1.0f);
187  break;
188  }
189  }
190 #endif
191  touch = (UITouch*)[enumerator nextObject];
192  }
193 }
194 
195 /*
196  ---- Keyboard related functionality below this line ----
197 */
198 #if SDL_IPHONE_KEYBOARD
199 
200 /* Is the iPhone virtual keyboard visible onscreen? */
201 - (BOOL)keyboardVisible
202 {
203  return keyboardVisible;
204 }
205 
206 /* Set ourselves up as a UITextFieldDelegate */
207 - (void)initializeKeyboard
208 {
209  textField = [[UITextField alloc] initWithFrame: CGRectZero];
210  textField.delegate = self;
211  /* placeholder so there is something to delete! */
212  textField.text = @" ";
213 
214  /* set UITextInputTrait properties, mostly to defaults */
215  textField.autocapitalizationType = UITextAutocapitalizationTypeNone;
216  textField.autocorrectionType = UITextAutocorrectionTypeNo;
217  textField.enablesReturnKeyAutomatically = NO;
218  textField.keyboardAppearance = UIKeyboardAppearanceDefault;
219  textField.keyboardType = UIKeyboardTypeDefault;
220  textField.returnKeyType = UIReturnKeyDefault;
221  textField.secureTextEntry = NO;
222 
223  textField.hidden = YES;
224  keyboardVisible = NO;
225  /* add the UITextField (hidden) to our view */
226  [self addSubview: textField];
227  [textField release];
228 }
229 
230 /* reveal onscreen virtual keyboard */
231 - (void)showKeyboard
232 {
233  keyboardVisible = YES;
234  [textField becomeFirstResponder];
235 }
236 
237 /* hide onscreen virtual keyboard */
238 - (void)hideKeyboard
239 {
240  keyboardVisible = NO;
241  [textField resignFirstResponder];
242 }
243 
244 /* UITextFieldDelegate method. Invoked when user types something. */
245 - (BOOL)textField:(UITextField *)_textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
246 {
247  if ([string length] == 0) {
248  /* it wants to replace text with nothing, ie a delete */
251  }
252  else {
253  /* go through all the characters in the string we've been sent
254  and convert them to key presses */
255  int i;
256  for (i = 0; i < [string length]; i++) {
257 
258  unichar c = [string characterAtIndex: i];
259 
260  Uint16 mod = 0;
262 
263  if (c < 127) {
264  /* figure out the SDL_Scancode and SDL_keymod for this unichar */
265  code = unicharToUIKeyInfoTable[c].code;
266  mod = unicharToUIKeyInfoTable[c].mod;
267  }
268  else {
269  /* we only deal with ASCII right now */
270  code = SDL_SCANCODE_UNKNOWN;
271  mod = 0;
272  }
273 
274  if (mod & KMOD_SHIFT) {
275  /* If character uses shift, press shift down */
277  }
278  /* send a keydown and keyup even for the character */
281  if (mod & KMOD_SHIFT) {
282  /* If character uses shift, press shift back up */
284  }
285  }
286  SDL_SendKeyboardText([string UTF8String]);
287  }
288  return NO; /* don't allow the edit! (keep placeholder text there) */
289 }
290 
291 /* Terminates the editing session */
292 - (BOOL)textFieldShouldReturn:(UITextField*)_textField
293 {
297  return YES;
298 }
299 
300 #endif
301 
302 @end
303 
304 /* iPhone keyboard addition functions */
305 #if SDL_IPHONE_KEYBOARD
306 
307 static SDL_uikitview * getWindowView(SDL_Window * window)
308 {
309  if (window == NULL) {
310  SDL_SetError("Window does not exist");
311  return nil;
312  }
313 
315  SDL_uikitview *view = data != NULL ? data->view : nil;
316 
317  if (view == nil) {
318  SDL_SetError("Window has no view");
319  }
320 
321  return view;
322 }
323 
324 SDL_bool UIKit_HasScreenKeyboardSupport(_THIS)
325 {
326  return SDL_TRUE;
327 }
328 
329 void UIKit_ShowScreenKeyboard(_THIS, SDL_Window *window)
330 {
331  SDL_uikitview *view = getWindowView(window);
332  if (view != nil) {
333  [view showKeyboard];
334  }
335 }
336 
337 void UIKit_HideScreenKeyboard(_THIS, SDL_Window *window)
338 {
339  SDL_uikitview *view = getWindowView(window);
340  if (view != nil) {
341  [view hideKeyboard];
342  }
343 }
344 
345 SDL_bool UIKit_IsScreenKeyboardShown(_THIS, SDL_Window *window)
346 {
347  SDL_uikitview *view = getWindowView(window);
348  if (view == nil) {
349  return 0;
350  }
351 
352  return view.keyboardVisible;
353 }
354 
355 #endif /* SDL_IPHONE_KEYBOARD */
356 
357 #endif /* SDL_VIDEO_DRIVER_UIKIT */
358 
359 /* vi: set ts=4 sw=4 expandtab: */
GLvoid **typedef void(GLAPIENTRY *PFNGLGETVERTEXATTRIBDVPROC)(GLuint
Definition: glew.h:1824
#define NULL
Definition: ftobjs.h:61
Sint64 SDL_FingerID
Definition: SDL_touch.h:42
SDL_bool
Definition: SDL_stdinc.h:116
SDL_Scancode code
Definition: keyinfotable.h:36
int SDL_SendTouch(SDL_TouchID id, SDL_FingerID fingerid, SDL_bool down, float x, float y, float pressure)
Definition: SDL_touch.c:213
char * display
Definition: visualinfo.c:85
#define SDL_TOUCH_MOUSEID
Definition: SDL_touch.h:53
if(!yyg->yy_init)
GLuint id
Definition: gl2ext.h:1142
int SDL_SendKeyboardKey(Uint8 state, SDL_Scancode scancode)
Definition: SDL_keyboard.c:650
int SDL_SendTouchMotion(SDL_TouchID id, SDL_FingerID fingerid, float x, float y, float pressure)
Definition: SDL_touch.c:275
DECLSPEC void SDLCALL SDL_StopTextInput(void)
Stop receiving any text input events. This function will hide the on-screen keyboard if supported...
Definition: SDL_video.c:3045
GLsizei GLsizei * length
Definition: gl2ext.h:792
int SDL_SendMouseMotion(SDL_Window *window, SDL_MouseID mouseID, int relative, int x, int y)
Definition: SDL_mouse.c:178
#define SDL_BUTTON_LEFT
Definition: SDL_mouse.h:204
#define KMOD_SHIFT
Definition: SDL_keycode.h:335
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl2ext.h:848
static UIKitKeyInfo unicharToUIKeyInfoTable[]
Definition: keyinfotable.h:41
#define _THIS
int SDL_SendKeyboardText(const char *text)
Definition: SDL_keyboard.c:784
void * driverdata
Definition: SDL_video.h:59
const GLfloat * c
Definition: glew.h:14913
SDL_DisplayMode current_mode
Definition: SDL_sysvideo.h:120
DECLSPEC int SDLCALL SDL_SetError(const char *fmt,...)
Definition: SDL_error.c:53
int SDL_AddTouch(SDL_TouchID touchID, const char *name)
Definition: SDL_touch.c:130
Definition: inftrees.h:24
SDL_VideoDisplay * SDL_GetDisplayForWindow(SDL_Window *window)
Definition: SDL_video.c:996
uint16_t Uint16
An unsigned 16-bit integer type.
Definition: SDL_stdinc.h:137
void * driverdata
Definition: SDL_sysvideo.h:99
UITouch * leftFingerDown
Definition: SDL_uikitview.h:40
#define SDL_PRESSED
Definition: SDL_events.h:50
int i
Definition: pngrutil.c:1377
SDL_TouchID touchId
Definition: SDL_uikitview.h:39
#define SDL_RELEASED
Definition: SDL_events.h:49
int SDL_SendMouseButton(SDL_Window *window, SDL_MouseID mouseID, Uint8 state, Uint8 button)
Definition: SDL_mouse.c:276
SDL_Scancode
The SDL keyboard scancode representation.
Definition: SDL_scancode.h:43
SDL_uikitopenglview * view
typedef BOOL(WINAPI *PFNWGLSETSTEREOEMITTERSTATE3DLPROC)(HDC hDC