Interface Design for MoSync applications

Contributor - 01 October 2014 - 12min
Contributor - 01 October 2014 - 12min
Introduction
“Interface Design for MoSync applications” … doesn’t sound very interesting! As a matter of fact, it isn’t. There is not much new to what I am going to discuss here. The same age old problem, the same old solution, what’s new is implementing the solution for MoSync. This blog post is based more on personal experience of working with MoSync. What’s MoSync? I’ll talk about MoSync more in the next section, for now you can think of a powerful-yet-not-much-popular cross platform mobile application development framework.
MoSync provides a number of ways for creating user interfaces, based on what your application requires and what you are most comfortable with, you can choose your pick. This blog post discusses some of these methods to create interfaces for your applications, their pros and cons and concludes with a class that I wrote to simplify my requirement for designing user interfaces for MoSync applications.
MoSync is an open-source cross-platform mobile application development environment that makes it easy to develop apps for all major mobile platforms from a single code base. There are a number of such frameworks out there in the market, you can see a comparison of most of the available options on this wikipedia page.
I’ll just give a quick highlight of MoSync features:
You can explore more about MoSync here. I am sure you’ll find more interesting and useful stuff about MoSync on their website.
This post is about designing interfaces, so, I’ll skip everything else and directly jump to interface design with MoSync. MoSync provides multiple solutions for cross-platform user interface development. You can develop your MoSync applications with plain HTML/HTML5 UI or Native UI or Java based UI for older devices. Along with supporting multiple UI, MoSync also provides multiple libraries for implementing these UI. Following table gives a little more detailed view:
Library/API | Pros & Cons | |
Vanilla HTML/HTML5 |
|
|
Wormhole NativeUI JavaScript API |
|
|
MAUI C++ Library |
|
|
NativeUI C++ Library |
|
|
Widget C API |
|
That’s a lot of options for a single framework! You can check this page for more detailed description and example applications.
When I started working with MoSync, I was working on a TMDB API based movie application. The target platforms were Android, iOS and Windows with native look and feel. You guessed it right! I had an option of using Native C++ library or Wormhole NativeUI JavaScript API or Widget C API.
The Native C++ library suffers the same problem as most of the UI libraries. It provides a number of useful classes, but you need to write C++ code create your interfaces. There is nothing wrong with writing code to create interfaces, except:
The MoSync Wormhole library provides a bridge between the HTML5/JavaScript and C++ layers of your application. Using the wormhole library it is possible to use HTML5 markup to create NativeUI interfaces. The HTML5 in this case is used more as XML markup, you create div tags for everything with some special data attributes to specify widget properties. What MoSync does here is create a hidden WebView which parses the HTML5 markup and use JavaScript to navigate the DOM and create NativeUI widgets for each HTML5 element. I still couldn’t use this approach because:
In my case, rest of the whole application was written in C++, all I wanted was to somehow use some code-free markup to create interfaces dynamically at run time. What we required was:
Similar methods are used by many frameworks and UI libraries e.g. MFC uses .rc resource files to define user interfaces, Qt uses .ui xml files. MoSync supports both XML and JSON parsing. Personally I am not a very big fan of XML (no offence, but those tags make me feel uneasy!), so I went with JSON to define UI.
Following is a sample UI JSON file:
{ "Properties": { "fillHorizontally": { "width": -1 }, "fillVertically": { "height": -1 }, "fillParent": { "inheritProperty": ["fillVertically", "fillHorizontally"] }, "redEditBox": { "fontColor": "0xee2233", "placeholderFontColor": "0x33eeff" } }, "MainLayout" : { "class": "VerticalLayout", "properties": { "childVerticalAlignment": "top", "backgroundColor": "0xeeeeee", "inheritProperty": ["fillParent"] }, "AnotherTextBox": { "class": "EditBox", "properties": { "placeholder": "Hey!!!", "inheritProperty": ["fillHorizontally", "redEditBox"] } } }, "MainScreen": { "class": "Screen", "MainScreenLayout": { "class": "R:MainLayout", "ATextBox": { "class": "R:MainLayout.AnotherTextBox", "properties": { "placeholder": "Hello World!!!" } } } } }
The above JSON file shows some of the main functionality that I wanted to be able to achieve by defining UI using a markup:
I wrote a class to dynamically create UI at run time from JSON files. The class handles above scenarios and supports loading multiple JSON files, so that it is possible to define global properties in a separate file and keeping UI for different screens in different files or any other way we want to organize the UI definition.
As for accessing the widgets easily, the class provides a getWidget() function, which takes the complete widget name as argument e.g. “MainScreen.MainScreenLayout” and returns the widget. Internally it maintains a map of name-widget pairs. If the widget already exists, it is returned otherwise the widget is created and returned. In case there are any child widgets, they are created as well and added to the widget map. As a developer, I need not worry about creating or styling my widgets I can just magically get a reference to them wherever I need.
You might be bothered with what if you try to get a widget without creating its parent. Well, the widget will be created without a parent, but as soon as the parent widget gets requested, it will be created and any already created child widgets will be added as children to it.
Regarding destroying any widget, the class provides a destroyWidget() function, which again takes complete name of a widget and destroys it. This function is used by another higher level class – ScreenManager. This class handles creating/displaying/hiding/destroying screens. When a screen gets lowered, it automatically gets destroyed to release any acquired resources.
For maintaining multiple UI for various devices, I can define multiple JSON files for same screen. The ScreenManager can take care of picking the right one based on screen resolution or orientation. All I need to take care of is using the same widget names and the rest of the code will keep working without any change!
MoSync is a very powerful framework to develop cross platform applications. Although it supports multiple UI solutions and libraries to implement them, there is still scope for making life easier for developers. The class I wrote works quite well for my requirements, but it can still be improved in both efficiency and functionality e.g. support for some sort of event binding in the JSON file itself would be great !!!
Leave a Reply