Categories
Lua Tutorials

Lua code for OneSignal notification

OneSignal notification example code that are provided here include languages such as Node.js, C#, Python, PHP, Java, Ruby, Perl…, but there’s no Lua.

So here it is, the Lua version for Corona SDK (including a listener):

local json = require "json"

local function listener(e) 
	if e.isError then 
		print("Network Error: ", e.response) 
	else 
		print("Response: ", e.response) 
	end 
end 

local headers = { ["Content-Type"] = "application/json;charset=utf-8", ["Authorization"] = "Basic NGEwMGZmMjItY2NkNy0xMWUzLTk5ZDUtMDAwYzI5NDBlNjJj" } 
local body = { ["app_id"] = "5eb5a37e-b458-11e3-ac11-000c2940e62c", ["included_segments"] = "All", ["data"] = {["foo"] = "bar"}, ["contents"] = {["en"] = "English Message"} } 

network.request("https://onesignal.com/api/v1/notifications", "POST", listener, { headers=headers, body=json.encode(body) })
Categories
Corona SDK Lua Tutorials

UI data binding for Corona SDK

Here is a simple demo of data-binding to user-interface elements in Corona SDK. The purpose is to update variables so that UI elements (textfields in this demo) are updated automatically.

-- UI data binding demo for Corona SDK
--
-- Update variables and UI elements (textfields in this demo) are updated automatically
--
-- Created by:  Dave Yang / Quantumwave Interactive Inc.
-- Version:     1.00

-- place variables inside UIdata
local UIdata = {
    sum = 0,
    rand = -1,
}

-- create the UI elements
local sumTxt = display.newText( UIdata.sum, 150, 125, native.systemFont, 24 )
local randTxt = display.newText( UIdata.rand, 150, 250, native.systemFont, 24 )

-- bind the data to the UI elements
local UIdataBinding = {
    sum = sumTxt,
    rand = randTxt,
}

---------------------------------------------------------------------------

-- reference to the original UIdata table
local _uidata = UIdata

-- empty UIdata to make it work with the metatable below
UIdata = {}

-- the metatable defines what to do with access and change to data in UIdata
local UIdataMT = {
    __index = function(t,k)
        return _uidata[k]
    end,

    __newindex = function(t,k,v)
        -- changes to the data is updated in the textfield; other UI elements can be applied according to type
        UIdataBinding[tostring(k)].text = v
        -- update the original data
        _uidata[k] = v
    end
}

setmetatable(UIdata, UIdataMT)

-- single line if you prefer to replace the lines above starting from 'local UIdataMT = {'
--setmetatable(UIdata, {__index=function(t,k) return _uidata[k] end, __newindex=function(t,k,v) UIdataBinding[tostring(k)].text=v;_uidata[k]=v end})

---------------------------------------------------------------------------

-- change and access data

UIdata.sum = 42
print(UIdata.sum)

UIdata.rand = math.random(99)
print(UIdata.rand)

The latest updates can be found at github.

Categories
Corona SDK Lua OOP Tutorials

Simple demo of implementing Undo and Redo in Corona / Lua

Just posted a simple demo of HistoryStack, to show how Undo and Redo can be implemented in Corona SDK / Lua. It also demonstrates using EventDispatcher to dispatch events to update button states.

https://github.com/daveyang/HistoryStack

 

Categories
Corona SDK Mobile & Devices Tutorials

Screen scaling for different devices

In multi-device development, one of the issues to deal with is displaying the same content in different screen resolutions. Corona SDK offers a simple solution by specifying the scaling mode in the config.lua file. The scaling modes include: none, letterbox, zoomEven, zoomStretch. Sometimes it’s easier to understand by seeing the visual difference than reading the docs.

Below are the 4 modes displayed in four different devices (starting top-left clockwise: Galaxy Tab, iPad, iPhone & iPhone 4). The background photo is loaded at the Galaxy Tab screen resolution (1024×600).

To view the original full-size images, click on the images to view at Flickr (then choose Actions -> View all sizes), or use the links at the bottom of this post.

 

None

Screen Scaling None

 

 

Letterbox

Screen Scaling Letterbox

 

ZoomEven

Screen Scaling ZoomEven

 

ZoomStretch

Screen Scaling ZoomStretch

 

The source files used to create the display can be downloaded here. The four full size images are here: None, Letterbox, ZoomEven, ZoomStretch.

Hope this is useful.

 

Categories
Tutorials Web Services

Tutorial: BabelFish with WebServiceConnector

The new WebServiceConnector component in Flash MX 2004 Professional makes talking to standard (SOAP) web services extremely easy. Here’s how to make a simple call to the BabelFish web service using Flash MX 2004 Professional’s new features:

  1. Drag the WebServiceConnector component to the stage (just outside of it), and give it an instance name “babelfish”
  2. Select it and open the Component Inspector
  3. Under the Parameters tab, enter the WSDLURL:
    http://www.xmethods.net/sd/2001/BabelFishService.wsdl
  4. Click the next field “operation” and select BabelFish
  5. Click the Schema tab and check out the schema for this web service
  6. Note that it requires two parameters (translationmode and sourcedata), and it returns a string
  7. Now let’s create the interface of the application:

  8. Drag a TextInput component to the stage, adjust its size as needed, and give it an instance name “sourcedata”
  9. Drag a ComboBox to the stage and name it “translationmode”
  10. Drag a TextArea component to the stage (this is for displaying the result from the web service), adjust its size as needed, and name it “results”
  11. Drag a button to the stage, change its label to “Translate”
  12. With the button selected, add a new behavior from the Behaviors panel: Click the + button, select Data – Trigger Data Source. In the popup window, select babelfish.
  13. Let’s bind the babelfish component to the interface:

  14. Select the babelfish component, open the Component Inspector panel and click the Bindings tab
  15. Click the + button, select “translationmode:string”, and click OK. Double-click on the “bound to” field underneath. In the Bound To dialog box, select “Combobox, ” on the left, and “value:String” on the right. Click OK.
  16. Add another binding, this time select “sourcedata:String” and click OK. In the Bound To dialog box, choose “TextInput, ” and click OK.
  17. Add another binding, select “results:String” and click OK. In the Bound To dialog box, choose “TextArea, ” and click OK.

Now is a good time to save the FLA.

Before we can make this work, we need to populate the ComboBox. First, let’s take a look at how the web interface of BabelFish looks like: http://babelfish.altavista.com/. From the dropdown menus, you can tell the languages and translation directions.

View Source from the browser, inspect the data that is sent to the server when an item is selected from the dropdown menu:

English to Chinese
English to French
English to German
English to Italian
English to Japanese
English to Korean
English to Portuguese
English to Spanish
Chinese to English
French to English
French to German
German to English
German to French
Italian to English
Japanese to English
Korean to English
Portuguese to English
Russian to English
Spanish to English

Let’s populate these data into our ComboBox: Deselect all items from the stage, and add a new script:

translationmode.addItem(({label:"English to Chinese", data:"en_zh"}));
translationmode.addItem(({label:"English to German", data:"en_de"}));
translationmode.addItem(({label:"English to Italian", data:"en_it"}));
translationmode.addItem(({label:"English to Japanese", data:"en_ja"}));
translationmode.addItem(({label:"English to Korean", data:"en_ko"}));
translationmode.addItem(({label:"English to Portuguese", data:"en_pt"}));
translationmode.addItem(({label:"English to Spanish", data:"en_es"}));
translationmode.addItem(({label:"Chinese to English", data:"zh_en"}));
translationmode.addItem(({label:"French to English", data:"fr_en"}));
translationmode.addItem(({label:"French to German", data:"fr_de"}));
translationmode.addItem(({label:"German to English", data:"de_en"}));
translationmode.addItem(({label:"German to French", data:"de_fr"}));
translationmode.addItem(({label:"Italian to English", data:"it_en"}));
translationmode.addItem(({label:"Japanese to English", data:"ja_en"}));
translationmode.addItem(({label:"Korean to English", data:"ko_en"}));
translationmode.addItem(({label:"Portuguese to English", data:"pt_en"}));
translationmode.addItem(({label:"Russian to English", data:"ru_en"}));
translationmode.addItem(({label:"Spanish to English", data:"es_en"}));

That’s it! Test movie and enter some text, select a translation mode, and click the Translate button to see the translated text! Not too bad is it? Try it out:

Okay, this is what it looks like. Why doesn’t it work? It’s because when the new Flash Player 7 is running inside a browser through HTTP, the new cross-domain security prevents this SWF from loading data from another domain.

What is needed is a policy file – an XML document specifying who is allowed, and this file has to reside at the web service domain. One way to get around this is to use a redirection proxy (server-side script) at this domain, to pass the data between servers and back to this translator. This will be the subject for another day.

UPDATE:

Instead of hardcoding the translation modes into the movie, Mark Shepherd of Macromedia suggested using the XMLConnector component to load an external XML file with the translation modes, and bind the data to the ComboBox. I’ve gone one step further by adding the web service URL in this XML document (BabelFish.xml). This is what I usually do for application configurations, it makes updating quick and easy without going into the source movie and recompiling another SWF.

Also, a redirection proxy file is being used. However, for some reason, this proxy only works when the movie is running inside Flash’s IDE or from the desktop standalone projector, but still not from this domain, even though both the SWF and the proxy are located in the same folder. This is the proxy similar to the one posted at Macromedia, except I’m using JScript instead of VBScript (that does not work either):

Why does this proxy work outside of the browser and not from the same domain? I’d really like to get an answer to this one.

You can download the source files, check them out and let me know if you find anything. Thanks!