Of course, a translation engine isn't much use unless you can enter text that you want translated. To collect this, we'll use a native display object, a text box. The user can enter a large string of text into this box, and the program will be notified when the user closes it.
Native display objects aren't quite the same as widgets, although they often look similar. A widget is actually a Corona display group containing other rectangles, text, and other Corona display objects, created and managed with internal Lua code. This means that you can put widgets into other display groups and control their front-to-back ordering. Native objects, on the other hand, are created by the device's operating system at Corona's request. Although they have many of the same properties as display objects, such as x and y position and visibility, they don't move with their parent group or inherit any characteristics like alpha, and they always appear in front of any standard Corona display objects you create, regardless of group; that means they aren't affected by things like storyboard transitions.
We'll give the scene a blank white background to help the elements stay visually separate:
function scene:createScene( event )
display.newRect(self.view, 0, 0, display.contentWidth, display.contentHeight)
end
Because text boxes and other native interface elements aren't really part of the Corona canvas, they won't move or hide when you change scenes with the storyboard. You can deal with this in a few ways, but we're going to settle it by deleting the text box when the scene is closed, and recreating it when the scene is re-opened:
function scene:enterScene( event ) local group = self.view local width, height = display.contentWidth, display.contentHeight self.Entry = native.newTextField(width * 0.075, height * 0.1, width * 0.85, height * 0.66) end -- Called when scene is about to move offscreen: function scene:exitScene( event ) self.Entry:removeSelf() self.Entry = nil end
Native text objects work more closely with the event model, dispatching events onto the text object. These events have the name userInput
and update their listeners about several sorts of events, such as when the editor or keyboard appears, when the text has changed, when the user has hit Enter, or when the keyboard has been closed, which is usually interpreted as a cue to process whatever the box contains. Listeners can use these triggers to perform complex tasks like auto-fill, but in our case, we're only interested in submission.
self.Entry = native.newTextField(width * 0.075, height * 0.1, width * 0.85, height * 0.66)
self.Entry:addEventListener('userInput', self)
end
submitted
, which indicates that the user has hit a button like done or Enter, and ended
, which indicates that the text box is no longer receiving input; either the keyboard has been hidden or a different text field is now in charge of input:local scene = storyboard.newScene() function scene:userInput(event) if event.phase == 'submitted' then native.setKeyboardFocus(nil) elseif event.phase == 'ended' then end end -- Called when the scene's view does not exist: function scene:createScene( event )
function scene:userInput(event) if event.phase == 'submitted' then native.setKeyboardFocus(nil) elseif event.phase == 'ended' then local originalText = event.target.text -- process translation end end
local scene = storyboard.newScene() local credentials = require "credentials" local translation = require "translation" function scene:userInput(event)
local credentials = require "credentials"
local translation = require "translation"
local translator = translation.microsoft(credentials.id, credentials.secret)
function scene:userInput(event)
scene:userInput
function. Remember that the translator returns true
to indicate that it's started processing your request, or false
to show that it was busy and couldn't take your request at this time. We'll use this to provide user feedback:elseif event.phase == 'ended' then local originalText = event.target.text if translator(originalText, 'en', 'ja', output) then native.setActivityIndicator(true) end end
output
. This needs to be the callback function that will process the translated text when the translation is finished. Frame it in before the scene:userInput
function:local translator = translation.microsoft(credentials.id, credentials.secret) local function output(event) end function scene:userInput(event)
local function output(event)
native.setActivityIndicator(false)
end
local function output(event) native.setActivityIndicator(false) local texts = {event.source, event.result} displayResults(texts) end
local translator = translation.microsoft(credentials.id, credentials.secret) local function displayResults(texts) storyboard.gotoScene( "result", {effect = 'slideLeft'; params = texts }) end local function output(event)
Save entry.lua
and open main.lua
. It should still contain the template text that gets added when Corona creates a new project for you. Let's start by setting the status bar to the light appearance typical of productivity apps:
display.setStatusBar(display.DefaultStatusBar)
local storyboard = require "storyboard"
storyboard.gotoScene( "scenetemplate" )
Now, make sure that the app starts by displaying the input screen:
local storyboard = require "storyboard"
storyboard.gotoScene( "entry" )
At this point, you should be able to test the app in the simulator or on your device. We have only one part left to make sure that the app is fully functional and efficient.
We created a view that uses built-in operating facilities to easily collect a string of text from the user. We created a translation engine that authenticates with our app's unique passcodes and used it to obtain translated text. We used a familiar, well-understood interface element to tell the user to wait until we received the translation back and forwarded it to our display view.
18.119.131.178