Developing mobile applications with MoSync

What is a Moblet Project?
The MoSync platform can be used in two very broad ways. Firstly, if <you’re porting an existing C game to mobile, or writing a new one in C or C++, then MoSync provides a very lightweight compatibility API to get your game running on as many phones as possible, and as quickly as possible. This provides low-level APIs to sound and screen which you can use.

If you are doing something which doesn’t require direct access to graphics, then there is a higher-level set of APIs and an event-based environment ready for you to work with: Moblets. Moblets are a quick way to create rich and attractive mobile applications.

Creating a New Project in Eclipse
The MoSync SDK includes a complete IDE (integrated development environment) that you can write your programs in. The MoSync IDE is based on a popular open-source IDE called Eclipse. Java developers will be familiar with the IDE concept already, and anyone with experience of Visual Studio or other similar system will find MoSync very easy to work with.

To get started with this tutorial, Launch MoSync then close the Welcome page. When you’ve done that, you’ll have a screen which looks like this:

01

Here you can see all the main views of the IDE (in Eclipse terminology, each panel is called a “view”). On the left is the Project Explorer view which will soon show your project’s folders and files, in the centre is the Edit view where you will write code, and on the right are the Device Profiles view and (hidden behind it) the Finalizer view.

Now select New > Project from the IDE’s File menu. You will get a dialog box like this:

02
Select MoSync Project and then press then Next button.

Now you need to give your application a name. For this tutorial, call it MoSyncDemoApp:

xxxxx
Note: do not use spaces or any character which isn’t a letter or a number into the application name. It can cause problems with the compiler later if the file path has a space in, or a character that can be interpreted differently.

On the next screen, you’ve got a series of options for the type of application we want to use. Although there is an option to create a Moblet project, we want to select the MAUI Project.

 

StartingANewMobletProject4

MAUI is the moblet user interface (UI) library from MoSync. It contains common UI controls you can use in your application. We will be creating some MAUI controls in this tutorial, and later tutorials will delve much deeper into the inner workings of MAUI.

There, you should now have a screen which looks like this, and is waiting for you to enter some code.

 

tt
Creating a New Screen

To create our Moblet application, we have to use some controls from the MAUI library. The first one we want to use is the Screen control. This is a canvas which we can put other controls on, and can be shown to the user.

The code that the project wizard creates looks something like this:

#include <MAUtil/Moblet.h>
#include <MAUI/Screen.h>
#include <MAUI/Label.h>

using namespace MAUtil;
using namespace MAUI;

/**
 * MAUI is short for MoSync API User Interface.
 *
 * A Screen is a MAUI object that holds widgets.
 */
class MAUIScreen : public Screen
{
public:
    /**
     * Create widgets in the constructor.
     */
    MAUIScreen()
    {
        mBackgroundArea = new Label(
            0, // Left
            0, // Top
            0, // Width
            0, // Height
            NULL // Parent widget
            );
        mBackgroundArea->setBackgroundColor(0xFFFFFF);

        mTouchArea = new Label(
            100, // Left
            100, // Top
            50,  // Width
            50,  // Height
            mBackgroundArea // Parent widget
            );
        mTouchArea->setBackgroundColor(0x000000);

        // Set the main widget of the screen. This will
        // resize the widget to fit the screen.
        setMain(mBackgroundArea);
    }

    /**
     * Deallocate objects in the destructor.
     */
    virtual ~MAUIScreen()
    {
        delete mBackgroundArea;
        delete mTouchArea;
    }

    /**
     * Called when a key is pressed.
     */
    virtual void keyPressEvent(int keyCode, int nativeCode)
    {
        // Default color is white.
        int color = 0xFFFFFF;

        switch (keyCode)
        {
            case MAK_1:
                color = 0xFF5555;
                break;
            case MAK_2:
                color = 0x55FF55;
                break;
            case MAK_3:
                color = 0x5555FF;
                break;
        }

        // Set the new background color.
        mBackgroundArea->setBackgroundColor(color);
    }

    /**
     * Called when the screen is touched.
     */
    virtual void pointerPressEvent(MAPoint2d point)
    {
        // Center the touch area at the pointer position.
        mTouchArea->setPosition(point.x - 25, point.y - 25);

        // We need to repaint the parent when a child
        // widget is changed.
        mBackgroundArea->requestRepaint();
    }

private:
    Label* mBackgroundArea;
    Label* mTouchArea;
};

/**
 * A Moblet is a high-level class that defines the
 * behaviour of a MoSync program.
 *
 * To use MAUI you need a Moblet, but a  Moblet can
 * be used with or without the MAUI library.
 */
class MAUIMoblet : public Moblet
{
public:
    /**
     * Initialize the application in the constructor.
     */
    MAUIMoblet()
    {
        mScreen = new MAUIScreen();
        mScreen->show();
    }

    /**
     * Deallocate objects in the destructor.
     */
    virtual ~MAUIMoblet()
    {
        delete mScreen;
    }

    /**
     * Called when a key is pressed.
     */
    void keyPressEvent(int keyCode, int nativeCode)
    {
        if (MAK_BACK == keyCode || MAK_0 == keyCode)
        {
            // Call close to exit the application.
            close();
        }
    }

private:
    MAUIScreen* mScreen;
};

/**
 * Entry point of the program. The MAMain function
 * needs to be declared as extern "C".
 */
extern "C" int MAMain()
{
    Moblet::run(new MAUIMoblet());
    return 0;
}

This isn’t a tutorial on the C language, there are plenty of those already, but we can break this down into three recognisable sections.

Firstly, at the top of the code is the declaration of a new class MAUIScreen, which is inheriting from the MAUI Screen class. This is where we are going to do our work today.

Beneath that is the class MAUIMoblet. This is some standard code which creates a new instance of MAUIScreen and calls the show() method, which displays the screen on the mobile.

Finally, at the end is the main function (called MAMain) which creates our new Moblet code.

The Moblet code exists to give the developer access to some basic phone functions. It manages the environment, and it can tell you when a key has been pressed, when the screen has been touched, what the screen size is, and so on. By basing our application on the Moblet code, we automatically have access to all of these things, regardless of the device it is going to run on. We are not going to have to change any code between an Android device, Symbian device, a Windows Mobile device, or a phone running J2ME.

To create our screen, we need to look at the code for MAUIScreen:

class MAUIScreen : public Screen
{
public:
    /**
     * Create widgets in the constructor.
     */
    MAUIScreen()
    {
        mBackgroundArea = new Label(
            0, // Left
            0, // Top
            0, // Width
            0, // Height
            NULL // Parent widget
            );
        mBackgroundArea->setBackgroundColor(0xFFFFFF);

        mTouchArea = new Label(
            100, // Left
            100, // Top
            50,  // Width
            50,  // Height
            mBackgroundArea // Parent widget
            );
        mTouchArea->setBackgroundColor(0x000000);

        // Set the main widget of the screen. This will
        // resize the widget to fit the screen.
        setMain(mBackgroundArea);
    }

    /**
     * Deallocate objects in the destructor.
     */
    virtual ~MAUIScreen()
    {
        delete mBackgroundArea;
        delete mTouchArea;
    }

    /**
     * Called when a key is pressed.
     */
    virtual void keyPressEvent(int keyCode, int nativeCode)
    {
        // Default color is white.
        int color = 0xFFFFFF;

        switch (keyCode)
        {
            case MAK_1:
                color = 0xFF5555;
                break;
            case MAK_2:
                color = 0x55FF55;
                break;
            case MAK_3:
                color = 0x5555FF;
                break;
        }

        // Set the new background color.
        mBackgroundArea->setBackgroundColor(color);
    }

    /**
     * Called when the screen is touched.
     */
    virtual void pointerPressEvent(MAPoint2d point)
    {
        // Center the touch area at the pointer position.
        mTouchArea->setPosition(point.x - 25, point.y - 25);

        // We need to repaint the parent when a child
        // widget is changed.
        mBackgroundArea->requestRepaint();
    }

private:
    Label* mBackgroundArea;
    Label* mTouchArea;
};

There is some handy code here already, which creates two labels BackgroundArea and TouchArea. We will craete another MAUI control, a Label. Just like all the other environments, this label control will let you put text on the screen.

Lets’ add some more code in the MAUIScreen constructor and put another label control in it. To do this, we first need to provide our program with a font. There is a separate more detailed tutorial available for creating new fonts in your project “Creating New Fonts”.

Adding Font Resources
In MAUI, fonts are bitmap fonts, and the tools to create new fonts have been provided in the download. Creating new fonts will be the subject of another tutorial though, so here we will simplify things by using a font which has already been created.

To include the font in our application, we need to create a resource file. A resource file is a file which contains the paths to all of the external resources that an application requires, including fonts, images, and sounds, which are then packaged up with your application.

To create a resource file, right-click on the name of your application on the left hand side of the Eclipse window, and select New > Other. From the dialog box that appears, select MoSync Resource File.

 

06

 

Click Next. Type the file name res.lst, then click Finish. You will see the new file appear in the MoSyncDemoApp project.

Open up res.lst and add the following entry.

.res MYFONT
.bin
.include "../../examples/MAUI/MAUIex/pretty.mof"

MoSync font files have the .mof extension. This one, pretty.mof, is supplied with one of the examples.

Obviously, you’ll need to change the path here if you’ve installed MoSync anywhere other than C:\MoSync. Note that the path to the font file cannot be absolute. Furthermore you must use either forward slashes in the path or escaped backslashes like this:

.include "..\..\examples\MAUI\MAUIex\pretty.mof"

Now that you’ve included the font file in the project, you can reference it your program. To do this, you need to add an additional #include directive. You’ll also need to reference the Font class. Add these lines to the existing list of includes:

#include <MAUI/Font.h>
#include

MAHeaders.h is a special file which is created when you build the application. It provides a reference (known as an MAHandle) to your program.

With these included, we can create a font in the application:

Font* f = new Font(MYFONT);

And we can use it to create a label:

Label* l = new Label(0, 0, 50, 50, NULL);
l->setFont(f);
l->setCaption("Welcome to my mobile application");

There is another way where we can create all of this on one line, but that is for another tutorial, or for you to explore yourself.

If you now click the Run button on the toolbar, you’ll see your first mobile application!

 

07+

 

Tracing Your Application
You can trace the execution of your application with a command lprintfln(). This sends a formatted line to debug console in Eclipse. You need to add an include directive as:

#include

If you add the line:

lprintfln("Starting");

as the first line in the constructor code, then you will see this in the console window in Eclipse. Use lprintfln as you write your program so you can see what it being executed.

Interacting with the User
You can now use the Moblet interfaces to interact with the user. We can capture key presses and cause different things to happen. In our application, we want it to exit.

There are five basic events for user interaction. Key press, key release, screen touch, screen drag and screen release. Each of these events has already been set up for you, you just need to write some code to react to these events in the screen. In fact, in the Moblet class, you can even see example stubs for these. However, I want to capture key presses in the MyScreen class

void keyPressEvent(int keyCode)
{
    lprintfln("Caught a key press");
    if(keyCode == MAK_5)
    maExit(0);
}

The function ‘keyPressEvent’ has already been set up for you by the Moblet, you just need to implement it. By adding this code to the screen, we can capture key presses. Every time a key is pressed, then it will write a line to the console, so you can see it working. The MoSync APIs also contain constants representing all of the keys. You can find the full list in the maapi.h File Reference in the MoSYnc API Reference Guide.

If the key pressed is 5 on the keypad, then we’re going to do a brute force exit of the program. There is a Moblet::close() method which is probably preferred, but this will do for our demonstration.

There we have it, a mobile application. You now got a basis for creating your own applications. If you want to check what you’ve got against my program, here is my listing:

#include <MAUtil/Moblet.h>
#include <MAUI/Screen.h>
#include <MAUI/Label.h>
#include <MAUI/Font.h>
#include 
#include 
using namespace MAUtil;
using namespace MAUI;
class MyScreen : public Screen {
public:
    MyScreen() {
        lprintfln("Starting");
        Font* f = new Font(MYFONT);
        Label* l = new Label(0, 0, 50, 50, NULL);
        l->setFont(f);
        l->setCaption("Welcome to my mobile application");
        setMain(l);
    }
    ~MyScreen() {
        // todo: delete main widget of this screen
    }
    void keyPressEvent(int keyCode)
    {
        lprintfln("Caught a key press");
        if(keyCode == MAK_5)
        maExit(0);
    }
private:
};
class MAUIMoblet : public Moblet {
public:
    MAUIMoblet() {
        // initialize
        screen = new MyScreen();
        screen->show();
    }
    void keyPressEvent(int keyCode) {
        // todo: handle key presses
    }
    void keyReleaseEvent(int keyCode) {
        // todo: handle key releases
    }
    MyScreen* screen;
    ~MAUIMoblet() {
        delete screen;
    }
};
extern "C" int MAMain() {
    Moblet::run(new MAUIMoblet());
    return 0;
};