Android soft keyboard solution

New to Moai? Get started here with our best tips and tutorials.

Android soft keyboard solution

Postby lancew » Thu Oct 11, 2012 10:25 am

I couldn't wait any longer for a moai android keyboard, so I decided to implement my own, hopefully as just a temporary solution. This is just my first implementation, but it seems to do the trick so far. It is developed using the moaigui package, but only requires that the main gui object be passed in.

Here is the keyboard 'class':

Code: Select all
  1.  

  2.  

  3. --utility function

  4. function distance ( x1, y1, x2, y2 )

  5.         return math.sqrt ((( x2 - x1 ) ^ 2 ) + (( y2 - y1 ) ^ 2 ))

  6. end

  7.  

  8. k = {}

  9.  

  10. local kboard = nil

  11. local keysWide = 1

  12. local keySize = 5

  13. local boardHeight = keySize

  14. local left = 50 - keySize/2

  15. local top = 100

  16. local xpos = left

  17. local ypos = top

  18. local rowCount = 0

  19. local speed = 1000

  20. local textbox = nil

  21.  

  22. --release all gui objects

  23. k.destroyKeyboard = function (self, gui)

  24.         if kboard ~= nil then

  25.                 for k, v in pairs(kboard) do

  26.                         gui:destroyWindow(v)

  27.                 end

  28.                 kboard = nil

  29.         end

  30. end

  31.  

  32. --setup a new keyboard, starting with only 1 row

  33. k.createKeyboard = function (self, gui, charsWide)

  34.         if kboard ~= nil then destroyKeyboard(gui) end

  35.         kboard = {}

  36.         keysWide = charsWide

  37.         boardHeight = keySize

  38.         left = 50 - keySize*charsWide/2

  39.         xpos = left

  40.         top = 100

  41.         ypos = top

  42.         rowCount = 0

  43. end

  44.  

  45. local function keyClick(event, data)

  46.         --give focus to selected textbox so that it receives the keypress

  47.         if textbox ~= nil then data.g:setFocus(textbox) end

  48.         --pass keypress to gui

  49.         data.g:injectKeyDown(data.character)

  50.         data.g:injectKeyUp(data.character)

  51. end

  52.  

  53. k.addKey = function (self, gui, char)

  54.         if kboard == nil then return end

  55.         --empty string indicates skipping a key slot

  56.         if char ~= "" then

  57.                 kboard[char] = gui:createButton()

  58.                 kboard[char]:setPos(xpos, ypos)

  59.                 kboard[char]:setDim(keySize, keySize)

  60.                 kboard[char]:setText(char)

  61.                 data = {}

  62.                 data.g = gui

  63.                 if char == "<" then

  64.                         data.character = 8 --backspace

  65.                 else

  66.                         data.character = string.byte(char) --ascii value of character

  67.                 end

  68.                 kboard[char]:registerEventHandler(kboard[char].EVENT_BUTTON_CLICK, nil, keyClick, data)

  69.         end

  70.         --increment to next key in row

  71.         rowCount = rowCount + 1

  72.         xpos = xpos + keySize

  73.         if rowCount >= keysWide then

  74.                 --new row

  75.                 xpos = left

  76.                 ypos = ypos + keySize

  77.                 boardHeight = boardHeight + keySize

  78.                 rowCount = 0

  79.         end

  80. end

  81.  

  82. --moves the key to its place at the bottom of the screen (or off the screen if show=false).

  83. --NOTE: only returns once the move has finished

  84. local function moveKey(key, show)

  85.         local x, y = key:getPos()

  86.         --move onto the screen

  87.         local newy = y - boardHeight

  88.         --move off the screen

  89.         if not show then newy = y + boardHeight end

  90.         --not really the best way of getting the target location, but the easiest/quickest solution

  91.         key:setPos(x, newy)

  92.         local tx, ty = key._rootProp:getLoc()

  93.         key:setPos(x,y)

  94.         --calculate a travel time relevant to the distance being traveled

  95.         local travelTime = distance(x, y, x, newy) / speed

  96.         MOAIThread.blockOnAction(key._rootProp:seekLoc(tx, ty, travelTime, MOAIEaseType.LINEAR))

  97.         --the seekLoc only moves the prop, the prop container is not aware of the move, so tell it.

  98.         key:setPos(x, newy)

  99. end

  100.  

  101. --moves all keys to the desired location

  102. k.showKeyboard = function (self, gui, show)

  103.         if kboard == nil then return end

  104.         --only need to pass in show when you want to hide the keyboard

  105.         if show == nil then show = true end

  106.         for k, v in pairs(kboard) do

  107.                 --move keys in separate threads

  108.                 MOAIThread.new():run(moveKey, v, show)

  109.         end

  110. end

  111.  

  112. k.hideKeyboard = function (self, gui)

  113.         self:showKeyboard(gui, false)

  114. end

  115.  

  116. k.setTextbox = function(self, tbox)

  117.         textbox = tbox

  118. end

  119.  

  120. return k

  121.  



Here is some example code showing how to use the keyboard class:

Code: Select all
  1.  

  2. local kb = require "keyboard"

  3.  

  4. kb:createKeyboard(gui, 11)

  5. keys = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "<",

  6.         "q", "w", "e", "r", "t", "y", "u", "i", "o", "p", "",

  7.         "", "a", "s", "d", "f", "g", "h", "j", "k", "l",  "",

  8.         "", "", "z", "x", "c", "v", "b", "n", "m"}

  9. for k, v in pairs(keys) do

  10.         kb:addKey(gui, v)

  11. end

  12. kb:showKeyboard(gui)

  13.  

  14. local editBox = nil

  15. local function handleEditBoxGainFocus(self, event)

  16.         self._cursorPos = #self._internalText + 1

  17.         self:_addCursor()

  18.         kb:setTextbox(editBox)

  19.         return self:_baseHandleGainFocus(event)

  20. end

  21.  

  22. editBox = gui:createEditBox()

  23. editBox :setPos(40, 30)

  24. editBox :setDim(20, 5)

  25. editBox :setText("")

  26. editBox ._onHandleGainFocus = handleEditBoxGainFocus

  27.  



Hope this is useful, enjoy!
Last edited by lancew on Fri Oct 12, 2012 10:33 am, edited 1 time in total.
Check out my first game released with Moai: https://play.google.com/store/apps/details?id=com.fazed.bugs. Feedback is very welcome =P
lancew
 
Posts: 80
Joined: Wed Aug 22, 2012 12:23 pm

Re: Android keyboard solution

Postby ibisum » Thu Oct 11, 2012 11:34 am

Looks great! Mind if I paste it up on moaisnippets?
;
--
ibisum@gmail.com
Got a MOAI snippet? Please consider adding it to http://moaisnippets.info
User avatar
ibisum
 
Posts: 1005
Joined: Mon Oct 17, 2011 1:11 am
Location: Vienna, Austria

Re: Android keyboard solution

Postby lancew » Thu Oct 11, 2012 11:57 am

Sure, go ahead =P
Check out my first game released with Moai: https://play.google.com/store/apps/details?id=com.fazed.bugs. Feedback is very welcome =P
lancew
 
Posts: 80
Joined: Wed Aug 22, 2012 12:23 pm

Re: Android keyboard solution

Postby ibisum » Thu Oct 11, 2012 2:20 pm

;
--
ibisum@gmail.com
Got a MOAI snippet? Please consider adding it to http://moaisnippets.info
User avatar
ibisum
 
Posts: 1005
Joined: Mon Oct 17, 2011 1:11 am
Location: Vienna, Austria

Re: Android keyboard solution

Postby lancew » Fri Oct 12, 2012 4:52 am

Whats with all the extra spacing at that link? Makes the code much harder to read xd
Check out my first game released with Moai: https://play.google.com/store/apps/details?id=com.fazed.bugs. Feedback is very welcome =P
lancew
 
Posts: 80
Joined: Wed Aug 22, 2012 12:23 pm

Re: Android keyboard solution

Postby Serapth » Fri Oct 12, 2012 9:32 am

Great work Lance, if you don't mind I also mentioned it here.

The spacing was a legacy of the code markup done by this forum, when you select copy all, it comes out a bloody mess. I had to bring it in to an editor and clean it up by hand.
Serapth
 
Posts: 50
Joined: Wed Aug 22, 2012 5:24 pm

Re: Android keyboard solution

Postby lancew » Fri Oct 12, 2012 10:03 am

Happy to contribute =P The neat thing about the design of this keyboard is that it is very flexible. You can make a partial keyboard, a simple keypad/numberpad, or w/e else fits your needs. Just make sure that you pass in the correct number of keys wide to ensure the board looks the way you intend.
Check out my first game released with Moai: https://play.google.com/store/apps/details?id=com.fazed.bugs. Feedback is very welcome =P
lancew
 
Posts: 80
Joined: Wed Aug 22, 2012 12:23 pm

Re: Android keyboard solution

Postby lancew » Fri Oct 12, 2012 10:19 am

I probably won't do it soon, but the next step for improvement would be adding a way to do upper case letters. Unless there are any objections, I will probably just follow the Android model and make an upper case button. Pressing the button once makes the next key selected an upper case letter, but then returns to lower case. Pressing the button twice enters CAPS lock mode, and press again to return to lower case mode.
Check out my first game released with Moai: https://play.google.com/store/apps/details?id=com.fazed.bugs. Feedback is very welcome =P
lancew
 
Posts: 80
Joined: Wed Aug 22, 2012 12:23 pm


Return to New Users

Who is online

Users browsing this forum: No registered users and 0 guests

x