Moai Tutorial Part 4: Dealing with the keyboard… or not

5. September 2012

 

In this section we are going to do something we probably shouldn’t… work with the keyboard.  As you will soon see, when dealing with mobiles, this isn’t a particularly smooth journey! Mobile and keyboards go together like peanut butter and hand grenades.

 

As is always the way, let’s jump right in with code:

 

screenWidth = MOAIEnvironment.screenWidth
screenHeight = MOAIEnvironment.screenHeight
print("Starting up on:" .. MOAIEnvironment.osBrand);

if screenWidth == nil then screenWidth =640 end
if screenHeight == nil then screenHeight = 480 end

MOAISim.openWindow("Window",screenWidth,screenHeight)

viewport = MOAIViewport.new()
viewport:setSize(screenWidth,screenHeight)
viewport:setScale(screenWidth,screenHeight)


layer = MOAILayer2D.new()
layer:setViewport(viewport)

MOAIRenderMgr.pushRenderPass(layer)


chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'

font = MOAIFont.new()
font:loadFromTTF('comic.ttf',chars,60,72)


text = MOAITextBox.new()
text:setString('Press a key')
text:setFont(font)
text:setTextSize(60,72)
text:setYFlip(true)
text:setRect(-320,-240,320,240)
text:setAlignment(MOAITextBox.CENTER_JUSTIFY,MOAITextBox.CENTER_JUSTIFY)


if(MOAIInputMgr.device.keyboard) then
    print("Keyboard")
    MOAIInputMgr.device.keyboard:setCallback(
        function(key,down)
            if down==true then
                text:setString(string.char(tostring(key)))

            end
        end
    )
else
    print("No Keyboard")

    if(MOAIEnvironment.osBrand == "iOS")   then
        MOAIKeyboardIOS.showKeyboard()
        MOAIKeyboardIOS.setListener(MOAIKeyboardIOS.EVENT_INPUT,function(start,length,textVal)
            text:setString(textVal);
        end
        )
    else
        print("The keyboard is a lie");
        -- Android, no keyboard support :(
    end
end

layer:insertProp(text)

 

Here is the program in action:

 

image

 

Exciting eh?  Again, we are going to skip over the familiar bits and jump right in to the new stuff.

 

One thing you might notice compared to prior tutorials, the line:

 

print("Starting up on:" .. MOAIEnvironment.osBrand  .. " version:" .. MOAIEnvironment.osVersion)

 

Has changed to

 

print("Starting up on:" .. MOAIEnvironment.osBrand);

 

Why is this?  Well remember when I said it was up to the host to implement the various values in MOAIEnvironment.  Well, I finally got around to testing on iOS and apparently MOAIEnvironment.osVersion isn’t implemented, at least, it isn’t on the Simulator.  As I recommended earlier, never trust these values to exist on all platforms! In production code, be sure to check for Nil.

 

Now the new code, let’s start with:

chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'

font = MOAIFont.new()
font:loadFromTTF('comic.ttf',chars,60,72)

 

The first line is a string of characters representing the individual characters we are going to be using.  If you need additional characters ( such as punctuation ) be sure to add them to this string.  We then create a new MOAIFont object, then load the font from a ttf file, comic.ttf ( I copied from the Windows font directory, you cannot legally redistribute fonts you don’t license! ).  Regardless to where you got it from, be sure to place a ttf file in the same directory as main.lua.  I moai to create the font created at a font height of 60 pixels and at a resolution of 72dpi.

 

Next up:

text = MOAITextBox.new()
text:setString('Press a key')
text:setFont(font)
text:setTextSize(60,72)
text:setYFlip(true)
text:setRect(-320,-240,320,240)
text:setAlignment(MOAITextBox.CENTER_JUSTIFY,MOAITextBox.CENTER_JUSTIFY)

 

Now we are creating a MOAITextBox, which is a bit misleading in name, especially if you have done some prior WinForm or ASP.NET programming.  A MOAITextBox is simply a text area on screen, often referred to as a label or text area in other libraries.  We then set text’s string value to “Press a Key” using the setString() method, set the font to the font we created earlier with a call to setFont(), and set the text size and dpi to match the values we used to create the font.  Next we call setYFlip to invert the font.  For reasons I don’t completely understand, MOAI renders text upside down by default… so this inverts it to the proper position.  Next we position and size the MOAITextBox with a call to setRect, telling it to position centered and use our full 640x480 screen ( again, remembering that coordinates are relative to 0,0 being the middle of the screen ).  Finally we center the text horizontally and vertically within the text area with a call to setAlignment().

 

Now we actually deal with handling keyboard entry:

 

if(MOAIInputMgr.device.keyboard) then
    print("Keyboard")
    MOAIInputMgr.device.keyboard:setCallback(
        function(key,down)
            if down==true then
                text:setString(string.char(tostring(key)))

            end
        end
    )
else

 

Here we are testing to see if a MOAIInputMgr.device.keyboard has been defined.  If this value is assigned, it means we have a keyboard ( currently this means we are running on a PC or Mac host, but don’t expect that to stay true forever ).  If a keyboard is in fact available, we set a callback function to handle key input.  This callback takes the key code ( as a number ) and a boolean, indicating if it was pressed or released and will be called every time a key is pressed.  We check to see if the key was pressed ( as opposed to released ), and if so, we simply convert the key code to an actual character and display it in our text box.

 

However, if there isn’t a keyboard…

 

else
    print("No Keyboard")

    if(MOAIEnvironment.osBrand == "iOS")   then
        MOAIKeyboardIOS.showKeyboard()
        MOAIKeyboardIOS.setListener(MOAIKeyboardIOS.EVENT_INPUT,function(start,length,textVal)
            text:setString(textVal);
        end
        )
    else
        print("The keyboard is a lie");
        -- Android, no keyboard support :(
    end
end

 

First we check to see if we are running on an iOS device.  If we are, we display the on screen keyboard, then set an event listener using MOAIKeyboardIOS listening for EVENT_INPUT events.  We then set the typed value textVal to our text box, which will be the currently typed character.  Otherwise we assume we are running on Android in which case we are…

 

 

Screwed.  Basically.  As of exactly this moment, there is no MOAIKeyboardAndroid available, although one has been developed so it should be available soon.  Until then, you can’t really handle keyboard entry on Android, unless you extend the host yourself.  I will update this guide when Android support is officially added.  You may be thinking to yourself “what about my hardware keyboard, it surely works, right???”.  Actually no.  Alternatives do exist ( there is a GUI package with an onscreen keyboard included ) that we will cover later, but for now at least until Android keyboard support is made publically available, you are kinda screwed.

 

 

Finally, we add our MOAITextBox to the layer with a call to

layer:insertProp(text)

 

Now you are happily traveling along with full keyboard support in your application!  Well, unless of course you have an Android device, in which case you are probably sulking in a corner.

 

 

Programming , , ,







blog comments powered by Disqus