skin: add xml parser for Qt UI 55/34555/3
authorGiWoong Kim <giwoong.kim@samsung.com>
Thu, 29 Jan 2015 03:11:34 +0000 (12:11 +0900)
committerSeokYeon Hwang <syeon.hwang@samsung.com>
Fri, 30 Jan 2015 02:34:38 +0000 (18:34 -0800)
Change-Id: Id5752b47b9ea7563e5f548496a4076f89a66140d
Signed-off-by: GiWoong Kim <giwoong.kim@samsung.com>
tizen/src/display/Makefile.objs
tizen/src/display/qt5_supplement.cpp
tizen/src/display/xmllayoutparser.cpp [new file with mode: 0644]
tizen/src/display/xmllayoutparser.h [new file with mode: 0644]
tizen/src/ui/mainform.h
tizen/src/ui/resource/mobile-720x1280-3btn/layout.xml [new file with mode: 0644]

index b8e49dc..97e49f1 100644 (file)
@@ -6,6 +6,7 @@ obj-$(CONFIG_SDL) += maru_sdl.o maru_sdl_processing.o maru_finger.o
 
 obj-$(CONFIG_QT) += qt5.o
 obj-$(CONFIG_QT) += qt5_supplement.o
+obj-$(CONFIG_QT) += xmllayoutparser.o
 
 $(obj)/maru_display.o $(obj)/maru_sdl.o $(obj)/maru_sdl_processing.o $(obj)/maru_finger.o: QEMU_CFLAGS += $(SDL_CFLAGS)
 
index 34906e1..8be7e66 100644 (file)
@@ -38,6 +38,7 @@
 #include "uiinformation.h"
 #include "hardwarekey.h"
 #include "floatingcontroller.h"
+#include "xmllayoutparser.h"
 #include "ui/xml/emulatoruitype.h"
 #include "uiutil.h"
 
@@ -47,6 +48,8 @@ extern "C" {
 
 //using namespace std;
 void qMessageOutput(QtMsgType, const QMessageLogContext &, const QString &);
+void loadMainFormFromQML(QFile *, UIInformation *);
+void loadConFormFromQML(QFile *, UIInformation *);
 void loadMainFormFromXML(QFile *, UIInformation *);
 void loadConFormFromXML(QFile *, UIInformation *);
 
@@ -70,7 +73,7 @@ static UIInformation *uiInfo;
 #define SKIN_PROPERTY_CONTROLLER_DOCK "controller.dock"
 
 #define SKIN_INFO_FILE_NAME "info.ini"
-#define FORM_FILE_NAME "layout.qml"
+#define FORM_FILE_NAME "layout.xml"
 #define CON_FORM_SUBPATH "controller"
 
 class ConFile {
@@ -372,7 +375,7 @@ void qMessageOutput(QtMsgType type, const QMessageLogContext &context, const QSt
     }
 }
 
-void loadMainFormFromXML(QFile *file, UIInformation *uiInfo/* out */)
+void loadMainFormFromQML(QFile *file, UIInformation *uiInfo/* out */)
 {
     if (file->exists() == false) {
         qFatal("%s is not found", qPrintable(file->fileName()));
@@ -436,7 +439,7 @@ void loadMainFormFromXML(QFile *file, UIInformation *uiInfo/* out */)
     delete engine;
 }
 
-void loadConFormFromXML(QFile *file, UIInformation *uiInfo/* out */)
+void loadConFormFromQML(QFile *file, UIInformation *uiInfo/* out */)
 {
     if (file->exists() == false) {
         qWarning("%s is not found", qPrintable(file->fileName()));
@@ -492,6 +495,118 @@ void loadConFormFromXML(QFile *file, UIInformation *uiInfo/* out */)
     delete engine;
 }
 
+void loadMainFormFromXML(QFile *file, UIInformation *uiInfo/* out */)
+{
+    if (file->exists() == false) {
+        qFatal("%s is not found", qPrintable(file->fileName()));
+        return;
+    }
+
+    if (!file->open(QIODevice::ReadOnly | QIODevice::Text)) {
+        qFatal("Couldn't open %s file", qPrintable(file->fileName()));
+        return;
+    }
+
+    qDebug("main form is loaded from %s", qPrintable(file->fileName()));
+
+    /* read xml */
+    QFileInfo fileInfo(*file);
+    QXmlStreamReader xml(file);
+
+    XmlLayoutParser parser;
+
+    MainForm *form = NULL;
+    QXmlStreamReader::TokenType token;
+    while (xml.atEnd() == false && xml.hasError() == false) {
+        token = xml.readNext();
+        /* If token is just StartDocument, go to next.*/
+        if(token == QXmlStreamReader::StartDocument) {
+            continue;
+        }
+
+        if (token == QXmlStreamReader::StartElement) {
+            if (xml.name() == "EmulatorUI") {
+                continue;
+            }
+
+            if (xml.name() == "version") {
+                qDebug() << "xml version :" << xml.readElementText();
+                continue;
+            } else if (xml.name() == "form") { // TODO: formList
+                form = parser.parseMainForm(xml, fileInfo.absolutePath());
+                if (form != NULL) {
+                    uiInfo->mainFormList.append(form);
+                }
+            }
+        }
+    }
+
+    const bool hasError = xml.hasError();
+    xml.clear();
+    file->close();
+
+    if (hasError == true) {
+        qFatal("Invalid xml format");
+        return;
+    }
+}
+
+void loadConFormFromXML(QFile *file, UIInformation *uiInfo/* out */)
+{
+    if (file->exists() == false) {
+        qWarning("%s is not found", qPrintable(file->fileName()));
+        return;
+    }
+
+    if (!file->open(QIODevice::ReadOnly | QIODevice::Text)) {
+        qFatal("Couldn't open %s file", qPrintable(file->fileName()));
+        return;
+    }
+
+    qDebug("controller form is loaded from %s", qPrintable(file->fileName()));
+
+    /* read xml */
+    QFileInfo fileInfo(*file);
+    QXmlStreamReader xml(file);
+
+    XmlLayoutParser parser;
+
+    ControllerForm *form = NULL;
+    QXmlStreamReader::TokenType token;
+    while (xml.atEnd() == false && xml.hasError() == false) {
+        token = xml.readNext();
+        /* If token is just StartDocument, go to next.*/
+        if(token == QXmlStreamReader::StartDocument) {
+            continue;
+        }
+
+        if (token == QXmlStreamReader::StartElement) {
+            if (xml.name() == "ControllerUI") {
+                continue;
+            }
+
+            if (xml.name() == "version") {
+                qDebug() << "xml version :" << xml.readElementText();
+                continue;
+            } else if (xml.name() == "form") {
+                form = parser.parseControllerForm(xml, fileInfo.absolutePath());
+                if (form != NULL) {
+                    uiInfo->conFormList.append(form);
+                }
+            }
+        }
+    }
+
+    const bool hasError = xml.hasError();
+    xml.clear();
+    file->close();
+
+    if (hasError == true) {
+        qFatal("Invalid xml format");
+        return;
+    }
+}
+
 #if 0
 #define CONTROL_PRIORITY_MAX 10
 
diff --git a/tizen/src/display/xmllayoutparser.cpp b/tizen/src/display/xmllayoutparser.cpp
new file mode 100644 (file)
index 0000000..f2f2be8
--- /dev/null
@@ -0,0 +1,222 @@
+/*
+ * Qt UI
+ *
+ * Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * GiWoong Kim <giwoong.kim@samsung.com>
+ * Sangho Park <sangho1206.park@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ *
+ */
+
+#include "xmllayoutparser.h"
+
+XmlLayoutParser::XmlLayoutParser()
+{
+    /* do nothing */
+}
+
+QRect XmlLayoutParser::parseRegion(QXmlStreamReader &xml)
+{
+    int left = 0, top = 0;
+    unsigned int width = 0, height = 0;
+
+    if (xml.name() == "region" &&
+        xml.tokenType() == QXmlStreamReader::StartElement) {
+        QXmlStreamAttributes attributes = xml.attributes();
+        if (attributes.hasAttribute("left")) {
+            left = attributes.value("left").toString().toInt();
+        }
+        if (attributes.hasAttribute("top")) {
+            top = attributes.value("top").toString().toInt();
+        }
+        if (attributes.hasAttribute("width")) {
+            width = attributes.value("width").toString().toUInt();
+        }
+        if (attributes.hasAttribute("height")) {
+            height = attributes.value("height").toString().toUInt();
+        }
+    }
+
+    return QRect(left, top, width, height);
+}
+
+HardwareKey *XmlLayoutParser::parseKey(QXmlStreamReader &xml)
+{
+    QString keyName;
+    QRect keyRegion;
+    int keycode = 0;
+    QString keyTooptip;
+
+    /* attribute */
+    QXmlStreamAttributes attributes = xml.attributes();
+    if (attributes.hasAttribute("name")) {
+        keyName = attributes.value("name").toString();
+    }
+
+    QXmlStreamReader::TokenType token = xml.readNext();
+
+    while (xml.atEnd() == false && (xml.name() == "key" &&
+        token == QXmlStreamReader::EndElement) == false) /* ~ </key> */
+    {
+        if (token == QXmlStreamReader::StartElement) {
+            if (xml.name() == "region") {
+                keyRegion = parseRegion(xml);
+            } else if (xml.name() == "keycode") {
+                /* keycode */
+                keycode = xml.readElementText().toInt();
+            } else if (xml.name() == "tooltip") {
+                /* tooltip */
+                keyTooptip = xml.readElementText();
+            }
+        }
+
+        token = xml.readNext();
+    }
+
+    return new HardwareKey(keyName, keycode, keyRegion, keyTooptip);
+}
+
+int XmlLayoutParser::parseKeyList(
+    QXmlStreamReader &xml, QList<HardwareKey *> &list)
+{
+    HardwareKey *hwKey = NULL;
+    QXmlStreamReader::TokenType token = xml.readNext();
+
+    while (xml.atEnd() == false && (xml.name() == "keyList" &&
+        token == QXmlStreamReader::EndElement) == false) /* ~ </keyList> */
+    {
+        if (token == QXmlStreamReader::StartElement) {
+            if (xml.name() == "key") {
+                hwKey = parseKey(xml);
+                if (hwKey != NULL) {
+                    list.append(hwKey);
+                }
+            }
+        }
+
+        token = xml.readNext();
+    }
+
+    return list.count();
+}
+
+MainForm *XmlLayoutParser::parseMainForm(
+    QXmlStreamReader &xml, QString skinPath)
+{
+    MainForm *form = new MainForm();
+
+    /* attribute */
+    QXmlStreamAttributes attributes = xml.attributes();
+    if (attributes.hasAttribute("name")) {
+        form->name = attributes.value("name").toString();
+    }
+
+    QXmlStreamReader::TokenType token = xml.readNext();
+
+    while (xml.atEnd() == false && (xml.name() == "form" &&
+        token == QXmlStreamReader::EndElement) == false) /* ~ </form> */
+    {
+        if (token == QXmlStreamReader::StartElement) {
+            if (xml.name() == "display") {
+                xml.readNextStartElement();
+
+                /* region */
+                form->displayRegion = parseRegion(xml);
+                qDebug("- display : (%d,%d %dx%d)",
+                    form->displayRegion.x(), form->displayRegion.y(),
+                    form->displayRegion.width(), form->displayRegion.height());
+            } else if (xml.name() == "normalImage") {
+                /* normal image */
+                QString normalImageFileName = xml.readElementText();
+                qDebug() << "- normalImage :" << normalImageFileName;
+
+                form->skinImg[MainForm::normal].load(
+                    skinPath + QDir::separator() + normalImageFileName);
+            } else if (xml.name() == "pressedImage") {
+                /* key pressed image */
+                QString pressedImageFileName = xml.readElementText();
+                qDebug() << "- pressedImage :" << pressedImageFileName;
+
+                form->skinImg[MainForm::pressed].load(
+                    skinPath + QDir::separator() + pressedImageFileName);
+            } else if (xml.name() == "keyList") {
+                /* HW keys */
+                int cnt = parseKeyList(xml, form->keyList);
+                qDebug("- keyList : %d", cnt);
+            } else {
+                qWarning() << "undefined element :" << xml.name();
+            }
+        }
+
+        token = xml.readNext();
+    }
+
+    return form;
+}
+
+ControllerForm *XmlLayoutParser::parseControllerForm(
+    QXmlStreamReader &xml, QString skinPath)
+{
+    QString formName = "";
+
+    QXmlStreamAttributes attributes = xml.attributes();
+    if (attributes.hasAttribute("name")) {
+        formName = attributes.value("name").toString();
+    }
+
+    ControllerForm *form = new ControllerForm(
+        formName.isEmpty() ? skinPath.section(QDir::separator(), -1) : formName);
+
+    QXmlStreamReader::TokenType token = xml.readNext();
+
+    while (xml.atEnd() == false && (xml.name() == "form" &&
+        token == QXmlStreamReader::EndElement) == false) /* ~ </form> */
+    {
+        if (token == QXmlStreamReader::StartElement) {
+            if (xml.name() == "normalImage") {
+                /* normal image */
+                QString normalImageFileName = xml.readElementText();
+                qDebug() << "- normalImage :" << normalImageFileName;
+
+                form->conImg[ControllerForm::normal].load(
+                    skinPath + QDir::separator() + normalImageFileName);
+            } else if (xml.name() == "pressedImage") {
+                /* key pressed image */
+                QString pressedImageFileName = xml.readElementText();
+                qDebug() << "- pressedImage :" << pressedImageFileName;
+
+                form->conImg[ControllerForm::pressed].load(
+                    skinPath + QDir::separator() + pressedImageFileName);
+            } else if (xml.name() == "keyList") {
+                /* HW keys */
+                int cnt = parseKeyList(xml, form->keyList);
+                qDebug("- keyList : %d", cnt);
+            } else {
+                qWarning() << "undefined element :" << xml.name();
+            }
+        }
+
+        token = xml.readNext();
+    }
+
+    return form;
+}
diff --git a/tizen/src/display/xmllayoutparser.h b/tizen/src/display/xmllayoutparser.h
new file mode 100644 (file)
index 0000000..223b6dd
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Qt UI
+ *
+ * Copyright (C) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * GiWoong Kim <giwoong.kim@samsung.com>
+ * Sangho Park <sangho1206.park@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ *
+ */
+
+#ifndef XMLLAYOUTPARSER_H
+#define XMLLAYOUTPARSER_H
+
+ #include <QXmlStreamReader>
+
+#include "mainform.h"
+#include "controllerform.h"
+
+class XmlLayoutParser
+{
+public:
+    XmlLayoutParser();
+
+    QRect parseRegion(QXmlStreamReader &xml);
+    HardwareKey *parseKey(QXmlStreamReader &xml);
+    int parseKeyList(QXmlStreamReader &xml, QList<HardwareKey *> &list);
+    MainForm *parseMainForm(QXmlStreamReader &xml, QString skinPath);
+    ControllerForm *parseControllerForm(QXmlStreamReader &xml, QString skinPath);
+
+private:
+
+};
+
+#endif // XMLLAYOUTPARSER_H
index 28bcede..c53ce68 100644 (file)
@@ -42,6 +42,7 @@ public:
     MainForm();
     ~MainForm();
 
+    QString name;
     QImage skinImg[2];
     QRect displayRegion;
     QList<HardwareKey *> keyList;
diff --git a/tizen/src/ui/resource/mobile-720x1280-3btn/layout.xml b/tizen/src/ui/resource/mobile-720x1280-3btn/layout.xml
new file mode 100644 (file)
index 0000000..1dc0a1c
--- /dev/null
@@ -0,0 +1,162 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<EmulatorUI xmlns="http://www.tizen.org/emulator/ui/layout">
+    <dbi_version>2.4</dbi_version>
+    <formList>
+        <form name="Portrait">
+            <display id="0">
+                <region left="67" top="116" width="720" height="1280"/>
+            </display>
+            <normalImage>default_0.png</normalImage>
+            <pressedImage>default_0_p.png</pressedImage>
+            <keyList>
+                <key name="Menu">
+                    <region left="210" top="1401" width="84" height="84"/>
+                    <keycode>169</keycode>
+                    <tooltip>Menu</tooltip>
+                </key>
+                <key name="Home">
+                    <region left="390" top="1401" width="84" height="84"/>
+                    <keycode>139</keycode>
+                    <tooltip>Home</tooltip>
+                </key>
+                <key name="Back">
+                    <region left="570" top="1401" width="84" height="84"/>
+                    <keycode>158</keycode>
+                    <tooltip>Back</tooltip>
+                </key>
+                <key name="Power">
+                    <region left="841" top="1309" width="24" height="96"/>
+                    <keycode>116</keycode>
+                    <tooltip>Power</tooltip>
+                </key>
+                <key name="Volume +">
+                    <region left="841" top="108" width="24" height="96"/>
+                    <keycode>115</keycode>
+                    <tooltip>Volume +</tooltip>
+                </key>
+                <key name="Volume -">
+                    <region left="841" top="219" width="24" height="96"/>
+                    <keycode>114</keycode>
+                    <tooltip>Volume -</tooltip>
+                </key>
+            </keyList>
+        </form>
+        <form name="Landscape">
+            <display id="0">
+                <region left="116" top="78" width="1280" height="720"/>
+            </display>
+            <normalImage>default_L90.png</normalImage>
+            <pressedImage>default_L90_p.png</pressedImage>
+            <keyList>
+                <key name="Menu">
+                    <region left="1400" top="570" width="84" height="84"/>
+                    <keycode>169</keycode>
+                    <tooltip>Menu</tooltip>
+                </key>
+                <key name="Home">
+                    <region left="1400" top="392" width="84" height="84"/>
+                    <keycode>139</keycode>
+                    <tooltip>Home</tooltip>
+                </key>
+                <key name="Back">
+                    <region left="1400" top="210" width="84" height="84"/>
+                    <keycode>158</keycode>
+                    <tooltip>Back</tooltip>
+                </key>
+                <key name="Power">
+                    <region left="1308" top="2" width="96" height="24"/>
+                    <keycode>116</keycode>
+                    <tooltip>Power</tooltip>
+                </key>
+                <key name="Volume +">
+                    <region left="108" top="2" width="96" height="24"/>
+                    <keycode>115</keycode>
+                    <tooltip>Volume +</tooltip>
+                </key>
+                <key name="Volume -">
+                    <region left="217" top="2" width="96" height="24"/>
+                    <keycode>114</keycode>
+                    <tooltip>Volume -</tooltip>
+                </key>
+            </keyList>
+        </form>
+        <form name="Reverse Portrait">
+            <display id="0">
+                <region left="78" top="117" width="720" height="1280"/>
+            </display>
+            <normalImage>default_180.png</normalImage>
+            <pressedImage>default_180_p.png</pressedImage>
+            <keyList>
+                <key name="Menu">
+                    <region left="570" top="30" width="84" height="84"/>
+                    <keycode>169</keycode>
+                    <tooltip>Menu</tooltip>
+                </key>
+                <key name="Home">
+                    <region left="390" top="30" width="84" height="84"/>
+                    <keycode>139</keycode>
+                    <tooltip>Home</tooltip>
+                </key>
+                <key name="Back">
+                    <region left="210" top="30" width="84" height="84"/>
+                    <keycode>158</keycode>
+                    <tooltip>Back</tooltip>
+                </key>
+                <key name="Power">
+                    <region left="2" top="110" width="24" height="96"/>
+                    <keycode>116</keycode>
+                    <tooltip>Power</tooltip>
+                </key>
+                <key name="Volume +">
+                    <region left="2" top="1310" width="24" height="96"/>
+                    <keycode>115</keycode>
+                    <tooltip>Volume +</tooltip>
+                </key>
+                <key name="Volume -">
+                    <region left="2" top="1200" width="24" height="96"/>
+                    <keycode>114</keycode>
+                    <tooltip>Volume -</tooltip>
+                </key>
+            </keyList>
+        </form>
+        <form name="Reverse Landscape">
+            <display id="0">
+                <region left="117" top="67" width="1280" height="720"/>
+            </display>
+            <normalImage>default_R90.png</normalImage>
+            <pressedImage>default_R90_p.png</pressedImage>
+            <keyList>
+                <key name="Menu">
+                    <region left="28" top="209" width="84" height="84"/>
+                    <keycode>169</keycode>
+                    <tooltip>Menu</tooltip>
+                </key>
+                <key name="Home">
+                    <region left="28" top="391" width="84" height="84"/>
+                    <keycode>139</keycode>
+                    <tooltip>Home</tooltip>
+                </key>
+                <key name="Back">
+                    <region left="28" top="568" width="84" height="84"/>
+                    <keycode>158</keycode>
+                    <tooltip>Back</tooltip>
+                </key>
+                <key name="Power">
+                    <region left="109" top="841" width="96" height="24"/>
+                    <keycode>116</keycode>
+                    <tooltip>Power</tooltip>
+                </key>
+                <key name="Volume +">
+                    <region left="1309" top="841" width="96" height="24"/>
+                    <keycode>115</keycode>
+                    <tooltip>Volume +</tooltip>
+                </key>
+                <key name="Volume -">
+                    <region left="1199" top="841" width="96" height="24"/>
+                    <keycode>114</keycode>
+                    <tooltip>Volume -</tooltip>
+                </key>
+            </keyList>
+        </form>
+    </formList>
+</EmulatorUI>