Game Development Community

Show iOS keyboard the moment user clicks in a field.

by Andy Hawkins · in iTorque 2D · 02/09/2013 (6:28 am) · 4 replies

*EDIT - SOLVED BY ME :D

I've been reading a few solutions and this one got me most of the way. By the way version 1.5 has all this implemented. You just need to call getiPhoneKeyboardInput() now - not all the things it says to do.
www.garagegames.com/community/forums/viewthread/85799

However I just can't get the last bit to work. I can invoke an iOS keyboard using getiPhoneKeyboardInput("Enter your name"); in TorqueScript.

But what I want to do, is show the iOS keyboard the moment the user clicks on the GuiTextEditCtrl. I understand I could probably do this on GuiTextEditCtrl::onMouseDown but that's where I'm stuck.

The getiPhoneKeyboardControl is a console function (i.e. used in TorqueScript) so how do I write the TorqueScript version of GuiTextEditCtrl::onMouseDown (or onTouchDown maybe) in TorqueScript so that at the point I can call getiPhoneKeyboardInput(); ???

#1
02/09/2013 (8:50 pm)
Hey I'm starting to think maybe I should invoke a console command from onMouseDown in C++ and ping back to the game via a callback in TorqueScript. I'll try that.

But if anyone knows the right way to extend onMouseDown so I can determine when someone has clicked on an edit box on iOS please let me know.
#2
02/09/2013 (9:45 pm)
Got it! (see additions with AH - 2013 in the comments)

1. Added this code to the end of GuiTextEditCtrl::onMouseDown in gui/controls/guiTextEditCtrl.cc
void GuiTextEditCtrl::onMouseDown( const GuiEvent &event )
{
   mDragHit = false;

   // If we have a double click, select all text.  Otherwise
   // act as before by clearing any selection.
   bool doubleClick = (event.mouseClickCount > 1);
   if(doubleClick)
   {
      selectAllText();

   } else
   {
      //undo any block function
      mBlockStart = 0;
      mBlockEnd = 0;
   }

   //find out where the cursor should be
   S32 pos = setCursorPos( event.mousePoint );

   // if the position is to the left
   if ( pos == -1 )
      mCursorPos = 0;
   else if ( pos == -2 ) //else if the position is to the right
      mCursorPos = mTextBuffer.length();
   else //else set the mCursorPos
      mCursorPos = pos;

   //save the mouseDragPos
   mMouseDragStart = mCursorPos;

   // lock the mouse
   mouseLock();

   //set the drag var
   mDragHit = true;

   //let the parent get the event
   setFirstResponder();
    
   // AH - 2013 - Added this code to callback TorqueScript when a Text Edit field
   // is tapped on an iOS device
    Con::executef(1,"onMouseDownGuiTextEditCtrl");
}
#3
02/09/2013 (10:03 pm)
2. In game/scripts/games.cs after startGame() added these functions

// -----------------------------------------------------------------
// AH - 2013 copied this code from forum entry to show iOS keyboard
// www.garagegames.com/community/forums/viewthread/85799
// -----------------------------------------------------------------
function showKeyboard() {  
    echo("showKeyboard start");  
    if (isFunction("getIphoneKeyboardInput")) {
         
        getiPhoneKeyboardInput(ProfileEntry.getValue());  
    }   
      
    echo("showKeyboard end");  
}  
// -----------------------------------------------------------------
// AH - 2013 copied this code from forum entry to read in the value
// read from the iOS text entry box
// www.garagegames.com/community/forums/viewthread/85799
// Callback for when the keyboard is disposed by the user. 
// ----------------------------------------------------------------- 
function oniPhoneKeyboardInputFinished(%result, %cancelled) {  
    echo("oniPhoneKeyboardInputFinished");  
    echo("cancelled" SPC %cancelled);  
    echo("result" SPC %result);
    ProfileEntry.text = %result;  
    saveChangesToProfile(); // my own XML saving code based on forum entry
                            // http://www.garagegames.com/community/forums/viewthread/131452
}
// ----------------------------------------------------------------- 
// AH - 2013 responding to callback invoked from guiEditTextCtrl.cc
// to show keyboard. 
// -----------------------------------------------------------------
function onMouseDownGuiTextEditCtrl()
{
   showKeyboard();
}
#4
02/09/2013 (10:05 pm)
For completeness here are the functions that are called in a file I made called manageProfiles.cs to support saving and loading to the user profile area via XML. It changes to apparently a suitable location on the iPhone, PC and Mac without me having to change that - so that's a bit of magic for me right now I need to investigate.
function SaveGame()
{
	%txml = new ScriptObject() { class = "XML"; };
	%fileFullname = "playerProfile.xml";

	if(%txml.beginWrite(%fileFullname))
	{
		%txml.writeClassBegin("SaveClass");
		
			%txml.writeClassBegin("PlayerName");
			%txml.writeValue($myName);
			%txml.writeClassEnd();	
			%txml.writeClassBegin("PlayerScore");
			%txml.writeValue($myScore);
			%txml.writeClassEnd();

			%txml.writeClassBegin("PlayerLocation");
			%txml.writeAttribute("levelid", $myLevel);
			%txml.writeAttribute("levelx", $myX);
			%txml.writeAttribute("levely", $myY);
			%txml.writeClassEnd();			
			
		%txml.writeClassEnd();
		
		%txml.endWrite();
	}	
}

function LoadGame()
{	
	%txml = new ScriptObject() { class = "XML"; };
	%fileFullname = "playerProfile.xml";
	
	if(%txml.beginRead(%fileFullname))
	{
		if ( %txml.readClassBegin("SaveClass"))
		{
			$myName = %txml.readField("PlayerName");
			$myScore = %txml.readField("PlayerScore");
			echo($myName);
			echo($myScore);
			
			%txml.readClassBegin("PlayerLocation");
			$myLevel = %txml.readAttribute("levelid");
			$myX = %txml.readAttribute("levelx");
			$myY = %txml.readAttribute("levely");
			%txml.readClassEnd();
			echo($myLevel);
			echo($myX);
			echo($myY);
			
			ProfileEntry.setValue($myName);
			ProfileLabel.setValue("Score:"@$myScore);
		}

		%txml.endRead();
	}
	else
	{
	   echo("Profile does not exist - creating one");
	   $myName = "Andy";
	   $myScore = "1000";
	   $myLevel = "1";
	   $myX = "10";
	   $myY = "20";
	   SaveGame();
	}
}
function saveChangesToProfile()
{
   $myName = ProfileEntry.getValue();
   SaveGame();
}