App-Entwicklung für bada – ein Beispiel

Know-how  –  0 Kommentare

Ein früherer Artikel führte in die Grundlagen der Entwicklung und den Vertrieb von Anwendungen für Samsungs Betriebssystem bada ein. Nun heißt es, tiefer in die Materie einzutauchen.

Gegen Ende des letzten Jahres hat das koreanische Unternehmen Samsung weitere Informationen zum neuen Linux-System TiZen herausgegeben. Böse Zungen bezeichnen TiZen als Meego aus Korea – das ist nicht ganz falsch. Der wesentliche Unterschied besteht darin, dass die erste Version von TiZen keine eigene native API für Entwickler mitbringt. Stattdessen programmiert man à la WebOS in JavaScript, was nicht sonderlich befriedigend ist.

Der Exkurs des letzten Artikels verdeutlichte, dass die sogenannte Open Service Platform (also bada) nicht allein als Betriebssystem anzusehen ist. Vielmehr sieht Samsung bada als API für C++, die ganz nach der Art von Qt vom zugrunde liegenden Kernel unabhängig ist. Das lässt diese Programmierumgebung geradezu prädestiniert erscheinen, als Basis für die native API von TiZen zu dienen. Samsung-Manager bestätigten diese (an sich logische) Überlegung auf mehreren Events. Die zum Zeitpunkt der Drucklegung aktuellste Meldung stammt aus dem Oktober 2012 und bestätigt die Intention der "Zusammenführung".

Steuerelemente? Steuerelemente!

Im ersten Artikel hat sich der Autor darauf beschränkt, das Projektskelett zu besprechen. Das GUI-Framework der Open Service Platform enthält einige Module, deren Verwendung für Uneingeweihte alles andere als logisch ist. Listen sind besonders haarig, wie im Beispiel HeiseBada1 zu sehen ist.

Quellcode

Den Beispielcode zum Artikel finden Leser hier.

Der Inhalt des folgenden Lehrbeispiels ist das Verwalten einer Liste von Items, die der Benutzer je nach Wunsch ergänzen oder reduzieren kann. HeiseBada1 ist eine normale Anwendung vom Typ "bada Form Based Application", die aus zwei Formularen besteht. Im ersten Schritt öffnet der Entwickler IDF_FORM1.xml und entfernt den dort von Haus aus befindlichen Button. Stattdessen zieht er eine List View aus dem rechts eingeblendeten Tool-Dialog und legt sie in die Mitte des Formulars.

Obwohl man theoretisch auch auf "klassische" Buttons zurückgreifen könnte, sei hier aus Gründen der Eleganz eine Footer-Toolbar verwendet. Diese Information benötigt der Ressourceneditor – die Eigenschaft "Show Footer" findet sich in den Properties des Formulars (weder die Liste noch den Header markieren). Nachdem diese auf "True" gesetzt wurde, blendet der Editor sofort eine graue Fußzeile ein. Wenn der Entwickler die Eigenschaft wider Erwarten nicht findet, sollte er das selektierte Element in der Outline prüfen. Wenn IDF_FORM1 nicht markiert ist, ist das falsche Steuerelement aktiv.

Im nächsten Schritt ist der Footer zu parametrisieren, sodass er statt Tabs Knöpfe enthält. Dazu markiert man ihn und passt danach die Eigenschaft Footer Style an, sodass FOOTER_STYLE_BUTTON_TEXT selektiert ist. Die IDE zeigt daraufhin eine Warnmeldung an: Sie erscheint bei jeder Änderung des Footer Style, ist meist ohne Konsequenzen und wird durch Klick auf Yes quittiert. Damit ist der Footer zur Aufnahme von Elementen bereit. Danach zieht man drei Footer Items aus der Toolbar in den Footer. Das erste der drei wird als blauer, die zwei weiteren als graue Knopfsilhouetten dargestellt.

Die Footer Items sind im Prinzip nichts anderes als Buttons. Deshalb sind sie nun zu parametrisieren. Dafür sind die Text-Eigenschaften so anzupassen, dass drei Buttons mit den Texten "Add", "Edit" und "Remove" entstehen. Die IDs dienen der Korrelation der Klicks in den Event-Handlern. Es ist deshalb sinnvoll, jedem Element eine in diesem Formular einzigartige ID zuzuweisen. Außerdem ist darauf zu achten, dass die eigenen IDs nicht kleiner sind als 1001. Eine denkbare Zuordnung wäre "Add = 1001", "Edit = 1002", "Remove = 1003".

Im nächsten Schritt ist mit der Verdrahtung der Steuerelemente zu beginnen. Dazu öffnet man Form1.h und ergänzt die Klassendeklaration um drei Konstanten mit den zu verwendenden IDs:

protected:
static const int ID_FOOTER_ADD = 1001;
static const int ID_FOOTER_EDIT = 1002;
static const int ID_FOOTER_REMOVE = 1003;

Damit ist man in der Lage, die Events zuzuordnen. Leider hilft einem das nicht, da sie nirgendwo ankommen – der Footer hat noch keinen Event-Handler erhalten. Das holt man in der Methode OnInitializing nach, die während des Formularaufbaus aufgerufen wird:

result
Form1::OnInitializing(void)
{
result r = E_SUCCESS;

GetFooter()->AddActionEventListener(*this);

return r;
}

An der Stelle sieht der Leser ein fundamentales Pattern in bada: Von Haus aus hat kein Widget einen verdrahteten Event-Handler. Es ist immer die Aufgabe des Entwicklers, das Routing der Ereignisse vorzunehmen. Damit bleibt nur noch das Abfangen der Events. Da das Formular das Interface IActionEventListener schon implementiert hat, ist noch OnActionPerformed anzupassen:

void
Form1::OnActionPerformed(const Osp::Ui::Control& source, int actionId)
{
switch(actionId)
{
case ID_FOOTER_ADD:
{
AppLog("Add clicked \n");
}
break;
case ID_FOOTER_EDIT:
{
AppLog("Edit clicked \n");
}
break;
case ID_FOOTER_REMOVE:
{
AppLog("Remove clicked \n");
}
break;
default:
break;
}
}

In der Codepassage identifiziert der Leser den aktivierten Button und gibt seinen Namen in der Debugger-Konsole aus.