{"id":231,"date":"2011-09-28T14:03:35","date_gmt":"2011-09-28T14:03:35","guid":{"rendered":"http:\/\/www.drmop.com\/?p=231"},"modified":"2011-10-03T20:39:38","modified_gmt":"2011-10-03T20:39:38","slug":"marmalade-sdk-tutorial-handling-key-inputs-and-the-on-screen-keyboard","status":"publish","type":"post","link":"http:\/\/www.drmop.com\/index.php\/2011\/09\/28\/marmalade-sdk-tutorial-handling-key-inputs-and-the-on-screen-keyboard\/","title":{"rendered":"Marmalade SDK Tutorial \u2013 Handling key inputs and the on screen keyboard"},"content":{"rendered":"<p>This tutorial is part of the Marmalade SDK tutorials collection. To see the tutorials index\u00a0<a title=\"Marmalade SDK tutorials index\" href=\"http:\/\/www.drmop.com\/?page_id=91\">click here<\/a><\/p>\n<p>In today\u2019s tutorial we are going to cover key input and on the on screen keyboard (OSK).<\/p>\n<p>As usual if you just want the associated article source code then you can <a href=\"http:\/\/www.drmop.com\/wp-content\/uploads\/2011\/09\/Keys.zip\">Download it from here<\/a>. If you want the details on the updated CInput class then please feel free to read on.<\/p>\n<h2>Keys and Key States<\/h2>\n<p>Marmalade maps device keys to an enum called s3eKey. if you take a look at the Marmalade SDK header file s3eKeyboard.h you will see that the list of mapped keys is quite extensive.<\/p>\n<p>Marmalade uses key states to let us know what is currently happening to all the available keys on the device, for example we make queries such as \u201cis the back key pressed\u201d or \u201cis the menu key up or down\u201d. The following states are supported:<\/p>\n<ul>\n<li>S3E_KEY_STATE_DOWN \u2013 The user is holding down the key<\/li>\n<li>S3E_KEY_STATE_UP \u2013 The key is up and not being held down by the user<\/li>\n<li>S3E_KEY_STATE_PRESSED \u2013 The user has just pressed their finger on the key<\/li>\n<li>S3E_KEY_STATE_RELEASED \u2013 The user has just released the key<\/li>\n<\/ul>\n<p>To query the state of a particular key we need to call s3eKeyboardGetState(key), which returns the states of the specified key. Note that its possible that a key can have more than one state. For example, if the user has just pressed the key then it would have both the S3E_KEY_STATE_DOWN and the S3E_KEY_STATE_PRESSED states.<\/p>\n<h2>On Screen Keyboard<\/h2>\n<p>The on screen keyboard is a software based keyboard that is available to phones and tablets that support a touch sensitive screen (You can call s3eOSReadStringAvailable() to determine if it is supported). You can bring up the OS specific on screen keyboard quite easily using Marmalade\u2019s s3eOSReadStringUTF8() and s3eOSReadStringUTF8WithDefault(). These blocking functions display the operating system specific keyboard and then return any entered text. Its possible to suggest to the system (by passing a flag to these functions) what kind of keyboard you want the user to be presented with to cater for different types of input. The following types are available:<\/p>\n<ul>\n<li>No flags \u2013 Standard keyboard<\/li>\n<li>S3E_OSREADSTRING_FLAG_PASSWORD \u2013 A password entry keyboard<\/li>\n<li>S3E_OSREADSTRING_FLAG_EMAIL \u2013 An email address entry keyboard<\/li>\n<li>S3E_OSREADSTRING_FLAG_URL \u2013 A URL entry keyboard<\/li>\n<li>S3E_OSREADSTRING_FLAG_NUMBER \u2013 A number entry keyboard<\/li>\n<\/ul>\n<h2>CInput Changes<\/h2>\n<p>Ok, now that the basics are out the way lets take a look at the changes to the CInput class. If you haven\u2019t read the previous article that introduced this class then you can <a title=\"Marmalade SDK Tutorial - Touch and Multi-touch\" href=\"http:\/\/www.drmop.com\/?p=200\">check it out here<\/a><\/p>\n<p>If you take a look at CInput.h, you will notice a few major additions. The first few additions include header files required by the key and on screen keyboard systems:<\/p>\n<pre>\r\n<blockquote>\r\n\r\n#include \"s3eKeyboard.h\"\r\n#include \"s3eOSReadString.h\"<\/blockquote>\r\n<\/pre>\n<p>Switching over to the CInput.cpp class source file you will notice that we have added a few extra checks into CInput::Init()<\/p>\n<pre>\r\n<blockquote>\r\n\r\n    <span style=\"color: #008000;\">\/\/ Check to see if the device that we are running on supports the keyboard<\/span>\r\n    KeysAvailable = (s3eKeyboardGetInt(S3E_KEYBOARD_HAS_KEYPAD) || s3eKeyboardGetInt(S3E_KEYBOARD_HAS_ALPHA));\r\n\r\n    <span style=\"color: #008000;\">\/\/ Check to see if the device that we are running on supports the on screen keyboard<\/span>\r\n    OSKeyboardAvailable = s3eOSReadStringAvailable() == S3E_TRUE;<\/blockquote>\r\n<\/pre>\n<p>This code basically ensures that the modules we are wanting to use are available on the device that we are running on.<\/p>\n<p>Next we add the following code to CInput::Update() to ensure that the system updates key states<\/p>\n<pre>\r\n<blockquote>\r\n\r\n<span style=\"color: #008000;\">\/\/ Update key system if it is available<\/span>\r\nif (KeysAvailable)\r\n    s3eKeyboardUpdate();<\/blockquote>\r\n<\/pre>\n<p>Lastly, we add code to query key states and show the on screen keyboard:<\/p>\n<pre>\r\n<blockquote>\r\n\r\nbool CInput::isKeyDown(s3eKey key) const\r\n{\r\n    if (!KeysAvailable)\r\n        return false;\r\n\r\n    <span style=\"color: #008000;\">\/\/ Return down state of queried key<\/span>\r\n    return (s3eKeyboardGetState(key) &amp; S3E_KEY_STATE_DOWN) == S3E_KEY_STATE_DOWN;\r\n}\r\n\r\nbool CInput::isKeyUp(s3eKey key) const\r\n{\r\n    if (!KeysAvailable)\r\n        return false;\r\n\r\n    <span style=\"color: #008000;\">\/\/ Return up state of queried key<\/span>\r\n    return (s3eKeyboardGetState(key) &amp; S3E_KEY_STATE_UP) == S3E_KEY_STATE_UP;\r\n}\r\n\r\nbool CInput::wasKeyPressed(s3eKey key) const\r\n{\r\n    if (!KeysAvailable)\r\n        return false;\r\n\r\n    <span style=\"color: #008000;\">\/\/ Return pressed state of queried key<\/span>\r\n    return (s3eKeyboardGetState(key) &amp; S3E_KEY_STATE_PRESSED) == S3E_KEY_STATE_PRESSED;\r\n}\r\n\r\nbool CInput::wasKeyReleased(s3eKey key) const\r\n{\r\n    if (!KeysAvailable)\r\n        return false;\r\n\r\n    <span style=\"color: #008000;\">\/\/ Return released state of queried key<\/span>\r\n    return (s3eKeyboardGetState(key) &amp; S3E_KEY_STATE_RELEASED) == S3E_KEY_STATE_RELEASED;\r\n}\r\n\r\nconst char* CInput::showOnScreenKeyboard(const char* prompt, int flags, const char* default_text)\r\n{\r\n    if (!OSKeyboardAvailable)\r\n        return NULL;\r\n\r\n    <span style=\"color: #008000;\">\/\/ Show on screen keyboard and return the input string<\/span>\r\n    if (default_text != NULL)\r\n        return s3eOSReadStringUTF8WithDefault(prompt, default_text, flags);\r\n    else\r\n        return s3eOSReadStringUTF8(prompt, flags);\r\n}<\/blockquote>\r\n<\/pre>\n<h2>Using the new CInput features<\/h2>\n<p>If we now turn our attention towards Main.cpp, we can take a quick look at what has changed from our previous Touch example.<\/p>\n<p>Firstly note that we got rid of s3eKeyboardUpdate(); as this is now handled by g_Input.Update()<\/p>\n<p>We have also replaced the following code:<\/p>\n<pre>\r\n<blockquote>\r\n\r\nif (s3eKeyboardGetState(s3eKeyAbsBSK) &amp; S3E_KEY_STATE_DOWN)    <span style=\"color: #008000;\">\/\/ Back key is used to exit on some platforms<\/span>\r\n    break;<\/blockquote>\r\n<\/pre>\n<p>With this code:<\/p>\n<pre>\r\n<blockquote>\r\n\r\nif (g_Input.isKeyDown(s3eKeyAbsBSK))    <span style=\"color: #008000;\">\/\/ Back key is used to exit on some platforms<\/span>\r\n    break;<\/blockquote>\r\n<\/pre>\n<p>Not a great deal but a little more readable.<\/p>\n<p>Now, we add a check into our main loop to see if the user has tapped the top of the screen. If they have then we show the on screen keyboard<\/p>\n<pre>\r\n<blockquote>\r\n\r\n<span style=\"color: #008000;\">\/\/ if user taps at top of screen then activate on screen keyboard<\/span>\r\nif (touch-&gt;y &lt; 50)\r\n{\r\n    <span style=\"color: #008000;\">\/\/ Show on screen keyboard then print out the returned text to the debug trace<\/span>\r\n    const char* text = g_Input.showOnScreenKeyboard(\"Enter Text\");\r\n    if (text != NULL)\r\n        s3eDebugOutputString(text);\r\n}<\/blockquote>\r\n<\/pre>\n<p>If the user enters some text then we display the entered text to the debug console using s3eDebugOutputString()<\/p>\n<h2>Handling Android Back and Menu Buttons<\/h2>\n<p>Its worth noting that we\u2019ve come across a number of Android app stores that require special handling of home and menu buttons as part of their certification process. These buttons should be implemented as follows:<\/p>\n<ul>\n<li>Back Button \u2013 Navigate backwards in your application to the previous screen \/ menu<\/li>\n<li>Home Button \u2013 Bring up the in-app or in-game menu<\/li>\n<\/ul>\n<p>Well that concludes this tutorial. I hope you all find it of some use. You can download the associated <a href=\"http:\/\/www.drmop.com\/wp-content\/uploads\/2011\/09\/Keys.zip\">Keys project source code from here<\/a><\/p>\n<p>Happy coding and don\u2019t sit on two legged chairs!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This tutorial is part of the Marmalade SDK tutorials collection. To see the tutorials index\u00a0click here In today\u2019s tutorial we are going to cover key input and on the on screen keyboard (OSK). As usual if you just want the associated article source code then you can Download it from here. If you want the [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4,13,29,43,44,42,28,3,45],"tags":[63,718,60,61],"class_list":["post-231","post","type-post","status-publish","format-standard","hentry","category-airplay-sdk","category-android-app-development","category-blackberry-playbook","category-blackberry-playbook-app-development","category-game-and-app-development","category-ios-app-development","category-marmalade-sdk","category-programming","category-samsung-bada-development","tag-handling-android-back-and-menu-buttons","tag-marmalade-sdk","tag-reading-key-states","tag-showing-on-screen-keyboard"],"_links":{"self":[{"href":"http:\/\/www.drmop.com\/index.php\/wp-json\/wp\/v2\/posts\/231","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/www.drmop.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.drmop.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.drmop.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.drmop.com\/index.php\/wp-json\/wp\/v2\/comments?post=231"}],"version-history":[{"count":8,"href":"http:\/\/www.drmop.com\/index.php\/wp-json\/wp\/v2\/posts\/231\/revisions"}],"predecessor-version":[{"id":237,"href":"http:\/\/www.drmop.com\/index.php\/wp-json\/wp\/v2\/posts\/231\/revisions\/237"}],"wp:attachment":[{"href":"http:\/\/www.drmop.com\/index.php\/wp-json\/wp\/v2\/media?parent=231"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.drmop.com\/index.php\/wp-json\/wp\/v2\/categories?post=231"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.drmop.com\/index.php\/wp-json\/wp\/v2\/tags?post=231"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}