Soliciting input

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.

Getting ready

Copy scenetemplate.lua into a new file called entry.lua and open it.

Getting on with 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.

Creating a backdrop

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

Creating the text box

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

Processing the user input

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.

  1. We'll start by registering the scene object as a listener on the text box:
      self.Entry = native.newTextField(width * 0.075, height * 0.1, width * 0.85, height * 0.66)
      self.Entry:addEventListener('userInput', self)
    end
  2. We'll add a function to the scene object to process the events sent to its listeners. We're interested in two specific event actions, 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 )
  3. When the box is submitted, we'll just remove focus from it, hiding the keyboard and triggering the other event, where we'll do the actual work:
    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
  4. When the input is complete, we'll want to process it. To do that, we need a translator engine that we can make the request of. To create one of those, we need authorization info to contact the translation service. Move up to the top of the file, after the storyboard calls, and add two new required calls:
    local scene = storyboard.newScene()
    
    local credentials = require "credentials"
    local translation = require "translation"
    
    function scene:userInput(event)
  5. Pass the credentials to the factory to create a translator:
    local credentials = require "credentials"
    local translation = require "translation"
    
    local translator = translation.microsoft(credentials.id, credentials.secret)
    
    function scene:userInput(event)
  6. Now, step back to the 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
  7. The activity indicator is a system-dependent signal that tells the user that the system is busy and their actions can't be processed at the moment. While it's visible, Corona ignores user events like touches. On iOS, it looks like a spinning spokes pattern that fades its way around the circle. Also notice that we call the translator with an argument called 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)
  8. The first thing it needs to do is dismiss the activity indicator, to tell the user that the translation is done and to tell the system that user input can be accepted again:
    local function output(event)
      native.setActivityIndicator(false)
    end
  9. The result display screen expects an array of strings, so it creates one:
    local function output(event)
      native.setActivityIndicator(false)
      local texts = {event.source, event.result}
      displayResults(texts)
    end
  10. Finally, it calls a function to pass this array to the result screen. This function is pretty simple and we probably wouldn't make a separate function for it except that we'll need it again in the next section:
    local translator = translation.microsoft(credentials.id, credentials.secret)
    
    local function displayResults(texts) 
      storyboard.gotoScene( "result", {effect = 'slideLeft'; params = texts })
    end
    
    local function output(event)

Tying the pieces together

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" )

Note

Interestingly, display.DefaultStatusBar is frequently not the status bar that apps display by default. Many devices default to showing display.TranslucentStatusBar.

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.

What did we do?

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.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.119.131.178