Using Bacon2D with Sailfish OS

Sailfish OS development for Jolla is quite versatile and you can use QML plugins to enhance your application. But if you’ve used a QML module which isn’t approved in Harbour and want to distribute your application via Jolla Store, you’ve to do some extra steps with it. Lately I ported Ubuntu Phone’s Falldown game for Sailfish OS and it uses Bacon2D framework to ease 2D game development. Bacon2D isn’t allowed in Harbour so I had to patch it to accept custom namespace and either package the dynamically linked library with my app’s RPM or use statically linked Bacon2D with my app. Here are my notes about it.

The examples will be with my Falldown game project and the code can be found on GitHub. The steps shown below are not the optimal way of doing things as you could streamline the process by including Bacon2D build to your project build and in RPM spec patch the needed files. Will see if I get around doing that and automate things.

Building Bacon2D for Sailfish OS

Bacon2D is a framework to ease 2D game development, providing ready-to-use QML elements representing basic game entities needed by most of games. Bacon2D uses Box2D, a 2D rigid body simulation engine for games. Box2D lets you make objects move in realistic ways and make the game world more interactive.

You can use Bacon2D in your Sailfish OS project by using it as dynamically or statically linked library. The easiest way is to just use the statically linked version so it’s statically compiled into your project. But it’s almost as easy to build the dynamically linked library.

The other issue is getting the Bacon2D built such way that you can use it in your project and submit your application to Jolla Store. As Bacon2D plugin isn’t allowed in Harbour you’ve to patch it to your own namespace, e.g harbour.falldown.bacon2d.

The next chapters cover the three different ways to build and use Bacon2D with Sailfish OS.

Get Bacon2D framework

Start with adding the Bacon2D repository to your project’s Git repository as submodule.

$ git submodule add https://github.com/Bacon2D/Bacon2D.git

Now the Bacon2D project files are in e.g. falldown/Bacon2D and falldown directory will be our base.

Now you’re ready to build and use Bacon2D with three optional ways:

After I got the needed things to work, I used the Option 3 way to get Bacon2D included in my application and hopefully it gets approved to Jolla Store.

Option 1: Using statically linked Bacon2D

In your project’s project file e.g. harbour-falldown.pro add to the top of the file include clause for including Bacon2D statically

include(./Bacon2D/src/Bacon2D-static.pri)

In your project’s main.cpp include plugins.h and register types before loading QML resources.

#include <plugins.h>
 
Plugins plugins;
plugins.registerTypes("Bacon2D");

Build your project in Qt Creator by selecting Build->Release, Deploy->Deploy as RPM Package and then running Build -> Clean, Build, Deploy.

Your Bacon2D powered app should now launch in your phone.

Option 2: Using dynamically linked Bacon2D

Open Bacon2D/Bacon2D.pro with Qt Creator and disable the test and examples subdirectories.

SUBDIRS += src

Build Bacon2D for Armv7: Select Kit – MerSDK-SailfishOS-armv7hl – Release – Deploy by copying binaries. The build will fail with “Error 127” but the libbacon2dplugin.so is built so you can use it now.

Copy the “build-Bacon2D-MerSDK_SailfishOS_armv7hl-Release/src/imports” directory which contains QML files and libbacon2dplugin.so to your project’s lib directory, e.g. falldown/lib.

$ cp -r build-Bacon2D-MerSDK_SailfishOS_armv7hl-Release/src/imports/Bacon2D lib

In e.g. harbour-falldown.pro add the lib directory to be added inside RPM.

DEPLOYMENT_PATH = /usr/share/$${TARGET}
lib.files += lib
lib.path = $${DEPLOYMENT_PATH}
INSTALLS += lib

In your main.cpp add import path to Bacon2D files.

view->engine()->addImportPath(SailfishApp::pathTo("qml/imports/").toLocalFile());

In Qt Creator select Build->Release, Deploy->Deploy as RPM Package. Run Build -> Clean, Build, Deploy.

Your Bacon2D powered app for Sailfish OS should now launch in Jolla.

Option 3: Using statically linked Bacon2D the Harbour way

Including statically linked Bacon2D to be built with you Sailfish OS application can be done different ways and I chose not to write my own plugins.cpp to register QML types and just patched the plugins.cpp which Bacon2D provides.

In harbour-falldown.pro add to the top of the file include clause for including Bacon2D statically

include(./Bacon2D/src/Bacon2D-static.pri)

Patch Bacon2D Bacon2D/src/plugins.cpp to accept e.g. harbour.falldown.bacon2d namespace. Change every qmlRegisterType line from “Bacon2D” to your namespace.

qmlRegisterType<Layer>("harbour.falldown.bacon2d", 1, 0, "Layer");

In your project’s src/main.cpp include plugins.h and register types before loading QMLresources.

#include <plugins.h>
 
Plugins plugins;
plugins.registerTypes("harbour.falldown.bacon2d");

Put Bacon2D QML files under e.g. qml/components and change them to import e.g. harbour.falldown.bacon2d 1.0. Somehow I didn’t get the Bacon2D type to work which defines enums.

Build your project in Qt Creator by selecting Build->Release, Deploy->Deploy as RPM Package and then running Build -> Clean, Build, Deploy.

Your Bacon2D powered app should now launch in your phone.

Option 4: Using dynamically linked Bacon2D the Harbour way

You can link against shared libraries which ships with your Sailfish OS app in the RPM but because of Harbour rules you have to install the library under e.g. /usr/share/harbour-falldown/lib.

But before you can use the dynamically linked Bacon2D for Sailfish OS app intended to be distributed via Jolla Harbour you have to patch Bacon2D to accept e.g. harbour.falldown.bacon2d namespace and build the library.

In Bacon2D project change the following files.

Bacon2D/Bacon2D.pro

PROJECT_NAME = harbour.falldown.bacon2d

Bacon2D/src/src.pro

TARGETPATH = harbour/falldown/bacon2d
DESTDIR = $$OUT_PWD/imports/harbour/falldown/bacon2d/

Bacon2D/src/plugins.cpp

qmlRegisterType<Layer>("harbour.falldown.bacon2d", 1, 0, "Layer");

Bacon2D/src/qmldir

module harbour.falldown.bacon2d

In Bacon2D/src directory change every QML file to import e.g. harbour.falldown.bacon2d 1.0

Build Bacon2D with Qt Creator for Armv7: Kit – MerSDK-SailfishOS-armv7hl – Release – Deploy by copying binaries

Copy Bacon2D QML files and libbacon2dplugin.so under lib directory and to the structure which match you import namespace, e.g.: lib/harbour/falldown/bacon2d/.

$ cp -r build-Bacon2D-MerSDK_SailfishOS_armv7hl-Release/src/imports/harbour lib

In your project’s project file, e.g. harbour-falldown.pro add the lib directory to be added inside RPM

DEPLOYMENT_PATH = /usr/share/$${TARGET}
lib.files += lib
lib.path = $${DEPLOYMENT_PATH}
INSTALLS += lib

In your spec file, e.g. rpm/harbour-falldown.spec add following exclude as Harbour RPM packages should not provide anything.

# >> macros
%define __provides_exclude_from ^%{_datadir}/.*$
# << macros

Also to use QML modules which ships together with the application but you have to prefix the name of the imports with e.g. “harbour.falldown.bacon2d”. And you have to install them under /usr/share/harbour-falldown (loadable QML plugins or the QML files).

In src/main.cpp add import path to Bacon2D QML files and plugin before loading qml resources.

view->engine()->addImportPath(SailfishApp::pathTo("lib/").toLocalFile());

Build your project in Qt Creator by selecting Kit – MerSDK-SailfishOS-armv7hl – Release – Deploy – Deploy as RPM Package and then running Clean, Build, Deploy.

Your Bacon2D powered app should now launch in your phone.

Sailfish OS User Interface design practices

The operating system running on Jolla has different and refreshing approach to user experience than the mainstream mobile operating systems. Sailfish OS is quite new project which also shows in applications’ user interfaces as common practices are not quite established. There are some guidelines and component usage examples how the applications should be built but they don’t cover every aspect especially with complex applications. Here are some examples how different apps solve common design issues in Sailfish OS.

Sailfish OS user interface design practices

Sailfish OS UI design practices

Sailfish OS guides you to make your app to work in certain ways and component gallery in development environment shows some practices but at the end how the app’s flow and user experience really works is up to the developer. There really isn’t comprehensive guide how elements and menu structures should work like there’s for Windows Phone and iOS. And thus Sailfish OS applications’ look and feel are sometimes quite different.

Here are some examples how different user interface aspects are designed in couple of Jolla’s own and third party developers’ apps. The presented examples and comments are just to point out different ways to build the user interface in Sailfish OS applications and doesn’t take a stance on which way is better or how it should be done.

Menu for different sections

There are couple of practices to present a menu for app’s different pages. The default is to use the pull down and push up menus but with more complex apps it’s not enough as the recommendation is to have only couple of items in that menu.

Tweetian (Twitter) uses bottom tab panel and you can flick left or right or press to change the page. In HalfTrail (map + GPS app) different sections are also as icons in bottom tab panel but activate only when pressed. In Haikala (high.fi news) settings page’s can be flicked or pressed with textual buttons.

Tab panel for pages
Action buttons on bottom panel
Bottom tab panel

Haikala uses side panel for actions to switch category. IRC uses the side panel for actions to select different IRC channels. Previously also Sailimgur (imgur) used left side panel for navigating to different pages.

Side panel for pages
Side panel for info & actions
Side panel for info & actions

Cargo Dock (file manager) is based on having two different sides and you can copy files between them. Both sides are identical but separate pages. Jolla Store shows links to apps in grid view and also arrows for selecting certain category of apps.

Two sides to work with
Arrows for sections
Grid view for selecting items

Settings menu

Settings are usually shown in separate page like in Jolla’s Settings and Hunger Meter (battery usage). Terminal app on the other hand uses hamburger menu which opens side panel.

Settings page
Settings in own page
Hamburger-menu settings

Showing controls and actions

Jolla’s Media app uses docked panel to show controls. The panel is shown only when a song is playing. You can also have docked panel with pull up menu for showing more controls icons. Tweetian has different actions in pull up and pull down menus.

Controls in docked panel
Docked panel with pull up menu
Actions in Pull up menu

Other common way is to show controls in bottom or top panel with tool icons. This can be seen in HalfTrail with action buttons in bottom toolbar. In Paint there’s a top toolbar with icons. Neither provide legend for icons although Paint has help in About page. MitaKuuluu (WhatsApp) also uses bottom toolbar for chat related actions. In Sailimgur you can choose to have to toolbar at the bottom or at the top. The bottom toolbar has better reachability if used with one hand.

Action buttons on bottom panel
Tools in top panel
Actions in bottom toolbar
Toolbar at the bottom
Top toolbar

Jolla Settings app uses switches to toggle different features. Terminal app on the contrary takes quite different approach to showing actions and settings. Terminal uses so called Hamburger menu which works quite nicely although isn’t “Sailfish OS” style.

Actions as switches
Hamburger-menu
Hamburger-menu settings

Sailimgur shows actions for the photo when long pressed in a context menu. Actions related to a comment are shown as bottom context menu or icon buttons. Quickddit (Reddit) shows actions as icon buttons.

Actions in context menu
Actions in context menu
Actions as icon buttons

Back navigation

For the back navigation there isn’t a physical button and you either flick left, click page stack icon or use some button and action in pull down menu.

In Jolla’s Gallery app you scroll through photos in slideshow view and you get actions for back navigation only when pressing the photo and opening the Docked panel where you can flick back to the gallery overview. Alternative way for back navigation from photo slideshow is just press the photo as seen in e.g. Jolla Store.

Jolla Opas (Reittiopas) uses simple icon button in toolbar for navigating the route on the map and navigating back. And of course you can have the back navigation in pull down menu like in Sailimgur when navigating back from Web view.

Back navigation in docked panel
Back navigation with button
Closing view in pull down menu

Navigating between items

Navigating between items in a list is normally done by flicking left or right. But sometimes that’s not usable or it’s better to provide also alternative way.

Sailimgur has previous and next buttons at the bottom, Tidings (RSS feeds) provides them in pull down and pull up menus and Browser has them in bottom tool bar as icons.

Next & Previous as buttons
Next in pull down menu
Prev/next in toolbar

Search

Providing search is usually done as a separate page but it can be put on pull down menu or as normal element in page.

Warehouse (OpenRepos) application has search link in pull down menu which navigates you to separate search page which also shows the results. Sailimgur has the search element in pull down menu and it closes after user presses enter to show the results in main view. Jolla Opas is a route planning app so the search elements are in main page. The search results are shown (if found more than one destination) as blue circle with results number and can be selected in separate dialog page.

Search in own page
Search in menu
Search as main function
Inline search in main view

Showing gallery of images

Showing list of images is pretty simple but there are differences how applications do it. Gallery application uses one big grid of cropped thumbnails, Warehouse shows full thumbnail and selection list in side and Jolla Store shows limited list of cropped thumbnails which opens in own view.

Only thumbnails, press to open own view
Grid view of images
Large image, side preview list

Notifications about new features

Mobile applications update quite often but users don’t usually check the changelog what’s changed or if there’s new features. So it’s nice to provide a simple changelog in first start like Flashlight, Paketti (post packages) and Haikala.

New features notification
Showing changelog
Changelog dialog