From: wang_zhiqiang Date: Tue, 18 Dec 2018 09:50:44 +0000 (+0800) Subject: change onscreenapp X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?p=apps%2Fonscreenapp.git;a=commitdiff_plain;h=fe42b81570d9730042a52d02ba8715bf75686ca0 change onscreenapp --- diff --git a/app/Onscreen.qml b/app/Onscreen.qml new file mode 100644 index 0000000..76538cf --- /dev/null +++ b/app/Onscreen.qml @@ -0,0 +1,138 @@ +import QtQuick 2.0 +import QtQuick.Layouts 1.1 +import QtQuick.Controls 2.0 + +Rectangle { + id: mainform + height: 300 + width: 1000 + radius:2 + + gradient: Gradient { + GradientStop { position: 0.0; color: "#12262E" } + GradientStop { position: 1.0; color: "#18899B" } + } + + ColumnLayout { + anchors { + topMargin: 10; bottomMargin:10 + leftMargin: 20; rightMargin: 20 + fill: parent + } + spacing: 2 + + ColumnLayout { + id: title_part + anchors { + top: parent.top + left: parent.left + topMargin: 10 + } + + Label { + id: title + text: dsp_title + color: "white" + font.pixelSize: 32 + font.bold: true + maximumLineCount: 1 + wrapMode: Text.Wrap + elide: Text.ElideRight + horizontalAlignment: Label.AlignHCenter + verticalAlignment: Label.AlignVCenter + Layout.preferredWidth: 960 + Layout.preferredHeight: 40 + } + + Image { + source: '../images/DividingLine.svg' + anchors.left: title.left + anchors.top: title.bottom + } + } + + RowLayout { + id: contents_part + anchors { + left: parent.left; leftMargin: 20 + right: parent.right; rightMargin: 20 + } + Layout.preferredWidth: 920 + Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter + spacing: 10 + Image { + id: dsp_mark + source: dsp_icon + Layout.maximumHeight: 120 + Layout.maximumWidth: 120 + } + Label { + text: dsp_contents + color: "white" + font.pixelSize: 24 + wrapMode: Text.Wrap + maximumLineCount: btn_area.visible ? 4 : 5 + elide: Text.ElideRight + horizontalAlignment: Label.AlignLeft + verticalAlignment: Label.AlignVCenter + Layout.preferredWidth: 780 + Layout.preferredHeight: 160 + } + } + + RowLayout { + id: btn_area + spacing: 60 + visible: btnNum > 0 ? true : false + anchors { + horizontalCenter: parent.horizontalCenter + } + Layout.preferredWidth: parent.width*0.75 + Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter + + Button { + id: btn1 + visible: btn1Name == "" ? false : true + text: btn1Name + highlighted: true + onClicked: { + eventHandler.onScreenReply(btn1.text) + } + Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter + } + + Button { + id: btn2 + visible: btn2Name == "" ? false : true + text: btn2Name + highlighted: true + onClicked: { + eventHandler.onScreenReply(btn2.text) + } + Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter + } + + Button { + id: btn3 + visible: btn3Name == "" ? false : true + text: btn3Name + highlighted: true + onClicked: { + eventHandler.onScreenReply(btn3.text) + } + Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter + } + } + + Rectangle { + id: footer + opacity: 0 + width: parent.width + height: 5 + anchors { + bottom: parent.bottom + } + } + } + +} diff --git a/app/app.pro b/app/app.pro index f234ea6..cf8a020 100644 --- a/app/app.pro +++ b/app/app.pro @@ -6,13 +6,16 @@ DESTDIR = $${OUT_PWD}/../package/root/bin PKGCONFIG += qlibwindowmanager libhomescreen HEADERS += \ - eventhandler.h + eventhandler.h \ + onscreenmodel.h SOURCES += \ eventhandler.cpp \ - main.cpp + main.cpp \ + onscreenmodel.cpp RESOURCES += \ - qml.qrc + qml.qrc \ + images/images.qrc LIBS += -ljson-c diff --git a/app/eventhandler.cpp b/app/eventhandler.cpp index d76fcbe..802b11b 100644 --- a/app/eventhandler.cpp +++ b/app/eventhandler.cpp @@ -26,28 +26,22 @@ #include "eventhandler.h" +const char _myrole[] = "on_screen"; const char _parameter[] = "parameter"; const char _replyto[] = "replyto"; -const char _data[] = "data"; -const char _file[] = "file"; -const char _area[] = "area"; -const char _suffix[] = ".qml"; const char _button_name[] = "buttonName"; -const char _button_press_mode[] = "buttonPressMode"; -const char _button_press_state[] = "buttonPressState"; const char _drawing_name[] = "drawing_name"; const char _application_id[] = "application_id"; -const char _onscreen_directory[] = "/usr/lib/qt5/qml/AGL/OnScreen/"; + void* EventHandler::myThis = 0; EventHandler::EventHandler(QObject *parent) : QObject(parent), mp_hs(nullptr), - mp_wm(nullptr) + mp_wm(nullptr), + m_dsp_sts(false) { - m_dspreq = QString(""); - m_req.clear(); } EventHandler::~EventHandler() @@ -68,35 +62,29 @@ void EventHandler::init(int port, const char *token) mp_hs = new LibHomeScreen(); mp_hs->init(port, token); - + mp_hs->registerCallback(nullptr, EventHandler::onRep_static); mp_hs->set_event_handler(LibHomeScreen::Event_ShowWindow, [this](json_object *object){ - // {"id": "onscreenXXX", "parameter": {"file": "onsreen file path", "data": {"key": "value", ...}}, "replyto": "app's id"} + /* + { + "application_id": "onscreenapp", + "parameter": { + "title": "onscreen title", + "type": "critical,exclamation,question,information", + "contents": "message contents", + "buttons": ["button_name1", "button_name2", "button_name3"], + "replyto":"caller application id" + } + } */ HMI_DEBUG(APP_ID, "recived json message is[%s]", json_object_get_string(object)); struct json_object *param; - json_object_object_get_ex(object, _parameter, ¶m); - if(json_object_get_type(param) != json_type_object ) { + if(!json_object_object_get_ex(object, _parameter, ¶m) + || json_object_get_type(param) != json_type_object) { HMI_DEBUG(APP_ID, "parameter error!"); return; } - struct json_object *qml_path; - const char *file = nullptr; - if(json_object_object_get_ex(param, _file, &qml_path)) - file = json_object_get_string(qml_path); - if(file == nullptr) { - HMI_DEBUG(APP_ID, "received qml file is null!"); - return; - } - - QString qml_file = QString(_onscreen_directory) + file; - QFileInfo file_info(qml_file); - if(!file_info.isFile() || !qml_file.contains(QString(_suffix), Qt::CaseSensitive)) { - HMI_DEBUG(APP_ID, "received qml file error! file=%s.", file); - return; - } - struct json_object *replyid; const char *replyto = nullptr; if(json_object_object_get_ex(param, _replyto, &replyid)) @@ -105,61 +93,46 @@ void EventHandler::init(int port, const char *token) HMI_DEBUG(APP_ID, "received replyto is null!"); return; } + m_req = qMakePair(QString(replyto), QString(json_object_to_json_string(param))); - struct json_object *display_area; - const char *area = nullptr; - if(json_object_object_get_ex(param, _area, &display_area)) - area = json_object_get_string(display_area); - - struct json_object *param_data; - const char* data = nullptr; - if(json_object_object_get_ex(param, _data, ¶m_data)) - data = json_object_to_json_string(param_data); - - m_dspreq = QString(replyto); - if(m_req.contains(m_dspreq)) { - m_req[m_dspreq] = qMakePair(qml_file, QString(data)); + if (this->getDisplayStatus() == HIDING) { + this->activateWindow(_myrole, "on_screen"); + } + else if(this->getDisplayStatus() == SHOWING) { + this->setDisplayStatus(SWAPPING); + emit this->hideOnScreen(); + } + else { + HMI_DEBUG(APP_ID, "onscreen swapping!"); } - else - m_req.insert(QString(m_dspreq), qMakePair(qml_file, QString(data))); - - if(area == nullptr) - this->activateWindow(ROLE_NAME); - else - this->activateWindow(ROLE_NAME, area); - HMI_DEBUG(APP_ID, "received showWindow event, end!, line=%d", __LINE__); }); mp_hs->set_event_handler(LibHomeScreen::Event_HideWindow, [this](json_object *object){ - struct json_object *value; - json_object_object_get_ex(object, _application_id, &value); - const char *appid = json_object_get_string(value); - HMI_DEBUG(APP_ID, "request release onScreen application is %s!", appid); - - // onscreenapp only can release by application which request show - if (appid == m_dspreq) - this->deactivateWindow(); - else - HMI_DEBUG(APP_ID, "request hideWindow application isn't request displaying application, m_dspreq=%s", m_dspreq.toStdString().c_str()); + emit this->hideOnScreen(); + HMI_DEBUG(APP_ID, "hideWindow json_object=%s", json_object_get_string(object)); }); - if (mp_wm->requestSurface(ROLE_NAME) != 0) { + if (mp_wm->requestSurface(_myrole) != 0) { HMI_DEBUG(APP_ID, "!!!!LayoutHandler requestSurface Failed!!!!!"); exit(EXIT_FAILURE); } mp_wm->set_event_handler(QLibWindowmanager::Event_SyncDraw, [this](json_object *object) { - HMI_DEBUG(APP_ID, "Surface %s got syncDraw!", ROLE_NAME); - emit this->signalLoader(QVariant("file://" + m_req[m_dspreq].first)); - emit this->signalOnScreenParameter(QVariant(m_req[m_dspreq].second)); - this->mp_wm->endDraw(QString(ROLE_NAME)); + HMI_DEBUG(APP_ID, "Surface %s got syncDraw!", _myrole); + this->mp_wm->endDraw(QString(_myrole)); }); mp_wm->set_event_handler(QLibWindowmanager::Event_Visible, [this](json_object *object) { struct json_object *value; json_object_object_get_ex(object, _drawing_name, &value); const char *name = json_object_get_string(value); + if(!strcasecmp(_myrole, name)){ + this->setDisplayStatus(SHOWING); + this->m_dsp = this->m_req; + this->updateModel(QVariant(this->m_dsp.second)); + emit this->showOnScreen(); + } HMI_DEBUG(APP_ID, "Event_Visible kKeyDrawingName = %s", name); }); @@ -195,24 +168,24 @@ void EventHandler::activateWindow(const char *role, const char *area) void EventHandler::deactivateWindow() { HMI_DEBUG(APP_ID, "EventHandler::deactivateWindow()"); - - emit this->signalLoader(QVariant("")); - mp_wm->deactivateWindow(ROLE_NAME); + if(getDisplayStatus() == SWAPPING) { + setDisplayStatus(SHOWING); + m_dsp = m_req; + updateModel(QVariant(this->m_dsp.second)); + emit showOnScreen(); + } + else { + this->setDisplayStatus(HIDING); + mp_wm->deactivateWindow(_myrole); + } } -void EventHandler::onScreenReply(const QString &btn_name, const QString &press_mode, const QString &press_state) +void EventHandler::onScreenReply(const QString &btn_name) { - HMI_DEBUG(APP_ID, "EventHandler::onScreenReply()"); -// deactivateWindow(); - - struct json_object* j_obj = json_object_new_object(); - json_object_object_add(j_obj, _application_id, json_object_new_string(m_dspreq.toLatin1())); + HMI_DEBUG(APP_ID, "EventHandler::onScreenReply(),btn_name=%s", btn_name.toStdString().c_str()); + emit this->hideOnScreen(); struct json_object* j_param = json_object_new_object(); json_object_object_add(j_param, _button_name, json_object_new_string(btn_name.toStdString().c_str())); - json_object_object_add(j_param, _button_press_mode, json_object_new_string(press_mode.toStdString().c_str())); - json_object_object_add(j_param, _button_press_state, json_object_new_string(press_state.toStdString().c_str())); - json_object_object_add(j_obj, _parameter, j_param); - - mp_hs->replyShowWindow(m_dspreq.toLatin1(), j_obj); + mp_hs->replyShowWindow(m_dsp.first.toStdString().c_str(), j_param); } diff --git a/app/eventhandler.h b/app/eventhandler.h index 612e3de..40e3672 100644 --- a/app/eventhandler.h +++ b/app/eventhandler.h @@ -21,12 +21,11 @@ #include #include #include -#include +//#include #include #include #include "hmi-debug.h" -#define ROLE_NAME "on_screen" #define APP_ID "onscreenapp" class QQmlApplicationEngine; @@ -46,20 +45,28 @@ public: static void* myThis; static void onRep_static(struct json_object* reply_contents); - void activateWindow(const char *role, const char *area = "normal"); Q_INVOKABLE void deactivateWindow(); - Q_INVOKABLE void onScreenReply(const QString &btn_name, - const QString &press_mode = QString("shortPress"), - const QString &press_state = QString("release")); + Q_INVOKABLE void onScreenReply(const QString &btn_name); signals: - void signalLoader(QVariant url); - void signalOnScreenParameter(QVariant text); + void updateModel(QVariant data); + void showOnScreen(); + void hideOnScreen(); private: + enum { + HIDING = 0, + SHOWING, + SWAPPING + }; + + int getDisplayStatus() {return m_dsp_sts;} + void setDisplayStatus(int sts) {m_dsp_sts = sts;} + void activateWindow(const char *role, const char *area = "normal.full"); + LibHomeScreen *mp_hs; QLibWindowmanager* mp_wm; - QMap> m_req; - QString m_dspreq; + QPair m_req, m_dsp; + int m_dsp_sts = HIDING; }; #endif // HOMESCREENHANDLER_H diff --git a/app/images/DividingLine.svg b/app/images/DividingLine.svg new file mode 100644 index 0000000..788256c --- /dev/null +++ b/app/images/DividingLine.svg @@ -0,0 +1,62 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/app/images/critical.svg b/app/images/critical.svg new file mode 100644 index 0000000..e2df6fc --- /dev/null +++ b/app/images/critical.svg @@ -0,0 +1,146 @@ + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/app/images/exclamation.svg b/app/images/exclamation.svg new file mode 100644 index 0000000..c43ebdd --- /dev/null +++ b/app/images/exclamation.svg @@ -0,0 +1,130 @@ + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + ! + + diff --git a/app/images/images.qrc b/app/images/images.qrc new file mode 100644 index 0000000..842a9fb --- /dev/null +++ b/app/images/images.qrc @@ -0,0 +1,10 @@ + + + DividingLine.svg + critical.svg + exclamation.svg + information.svg + question.svg + + + diff --git a/app/images/information.svg b/app/images/information.svg new file mode 100644 index 0000000..44b0ef8 --- /dev/null +++ b/app/images/information.svg @@ -0,0 +1,130 @@ + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + i + + diff --git a/app/images/question.svg b/app/images/question.svg new file mode 100644 index 0000000..7d55a46 --- /dev/null +++ b/app/images/question.svg @@ -0,0 +1,130 @@ + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + ? + + diff --git a/app/main.cpp b/app/main.cpp index 67a6e9e..7dbd13c 100644 --- a/app/main.cpp +++ b/app/main.cpp @@ -19,10 +19,12 @@ #include #include #include +#include #include #include #include "eventhandler.h" +#include "onscreenmodel.h" int main(int argc, char *argv[]) @@ -58,6 +60,7 @@ int main(int argc, char *argv[]) EventHandler *eventHandler = new EventHandler(); eventHandler->init(port, token.toStdString().c_str()); engine.rootContext()->setContextProperty("eventHandler", eventHandler); + qmlRegisterType("OnScreenModel", 1, 0, "OnScreenModel"); engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); if (engine.rootObjects().isEmpty()) { HMI_DEBUG(APP_ID, "Fatal Error, rootObject is empty!"); @@ -66,10 +69,11 @@ int main(int argc, char *argv[]) QObject *root = engine.rootObjects().first(); QQuickWindow *window = qobject_cast(root); - QObject::connect(eventHandler, SIGNAL(signalLoader(QVariant)), window, SLOT(qmlLoader(QVariant))); - QObject::connect(eventHandler, SIGNAL(signalOnScreenParameter(QVariant)), window, SLOT(qmlOnScreenParameter(QVariant))); + QObject::connect(eventHandler, SIGNAL(updateModel(QVariant)), window, SLOT(setOnScreenModel(QVariant))); + QObject::connect(eventHandler, SIGNAL(showOnScreen()), window, SLOT(showOnScreen())); + QObject::connect(eventHandler, SIGNAL(hideOnScreen()), window, SLOT(hideOnScreen())); - HMI_DEBUG(APP_ID, "Launched!"); + HMI_DEBUG(APP_ID, "onscreenapp started!"); return app.exec(); } diff --git a/app/main.qml b/app/main.qml index 758115b..99d50f8 100644 --- a/app/main.qml +++ b/app/main.qml @@ -19,6 +19,7 @@ import QtQuick.Window 2.2 import QtQuick.Layouts 1.1 import QtQuick.Controls 2.0 import AGL.Demo.Controls 1.0 +import OnScreenModel 1.0 Window { id: root @@ -30,29 +31,95 @@ Window { height: 1488 color: '#00000000' - function qmlLoader(url) { - console.log(qsTr('onscreenapp >>> qmlLoader load ' + url)); - osLoader.source = url; - } + Onscreen { + id: ons + anchors.centerIn: parent + visible: true + scale: 0 + + property string dsp_sts: "hide" + property string dsp_title: "" + property string dsp_icon: "" + property string dsp_contents: "" + property int btnNum: 0 + property string btn1Name: "" + property string btn2Name: "" + property string btn3Name: "" - function qmlOnScreenParameter(text) { - console.log(qsTr('onscreenapp >>> qmlOnScreenParameter.' + text)); - if (osLoader.status == Loader.Ready) { - // call qmlOnScreenParameter in qml to post parameter which from application - if (osLoader.item && osLoader.item.qmlOnScreenParameter) { - osLoader.item.qmlOnScreenParameter(text); + states: [ + State { + name: 'active' + when: ons.dsp_sts == "show" + PropertyChanges { + target: ons + scale: 1 + z: 1 + } + }, + State { + name: 'inactive' + when: ons.dsp_sts == "hide" + PropertyChanges { + target: ons + scale: 0 + z: -1 + } + } + ] + transitions: Transition { + NumberAnimation { + properties: 'scale'; + duration: 300; + easing.type: Easing.Linear + alwaysRunToEnd: true } } - else { - console.log("osLoader.status is not ready") + } + + OnScreenModel { + id: onscreenModel + } + + Timer { + id: ons_timer + interval: 3000 + onTriggered: { + hideOnScreen(); + clearOnScreenModel(); } } - Loader { - objectName: "loaderObject" - id: osLoader - anchors.centerIn: parent - width: childrenRect.width - height: childrenRect.height + Connections { + target: ons + onScaleChanged : { + if(ons.scale == 0) { + console.log(qsTr('hide animation finished')); + eventHandler.deactivateWindow(); + } + } + } + + function showOnScreen() { + console.log(qsTr('show onscreenapp')); + ons.dsp_title = onscreenModel.getTitle() + ons.dsp_icon = "../images/" + onscreenModel.getType() + ".svg" + ons.dsp_contents = onscreenModel.getContents() + ons.btnNum = onscreenModel.buttonNum() + ons.btn1Name = onscreenModel.buttonName(0) + ons.btn2Name = onscreenModel.buttonName(1) + ons.btn3Name = onscreenModel.buttonName(2) + ons_timer.running = ons.btnNum > 0 ? false : true + ons.dsp_sts = "show" + } + + function hideOnScreen() { + console.log(qsTr('hide onscreenapp')); + ons.dsp_sts = "hide" + ons_timer.running = false + } + + function setOnScreenModel(data) { + console.log(qsTr('onscreenapp >>> setModel status: ' + data)); + onscreenModel.setModel(data) } } diff --git a/app/onscreenmodel.cpp b/app/onscreenmodel.cpp new file mode 100644 index 0000000..429c711 --- /dev/null +++ b/app/onscreenmodel.cpp @@ -0,0 +1,74 @@ +#include "onscreenmodel.h" +#include "hmi-debug.h" +#include + +const char _modelName[] = "OnScreenModel"; +const char _title[] = "title"; +const char _type[] = "type"; +const char _contents[] = "contents"; +const char _buttons[] = "buttons"; + + +void OnScreenModel::setModel(QVariant data) +{ + HMI_DEBUG(_modelName, "setModel start!"); + clearModel(); + struct json_object *j_title = nullptr, *j_type = nullptr, *j_contents = nullptr, *j_buttons = nullptr; + struct json_object *j_param = json_tokener_parse(data.toString().toStdString().c_str()); + if(json_object_object_get_ex(j_param, _title, &j_title)) { + m_title = json_object_get_string(j_title); + } + else { + HMI_DEBUG(_modelName, "title input is null"); + } + + if(json_object_object_get_ex(j_param, _type, &j_type)) { + m_type = json_object_get_string(j_type); + } + else { + HMI_DEBUG(_modelName, "type input is null"); + } + + if(json_object_object_get_ex(j_param, _contents, &j_contents)) { + m_contents = json_object_get_string(j_contents); + } + else { + HMI_DEBUG(_modelName, "contents input is null"); + } + + if(json_object_object_get_ex(j_param, _buttons, &j_buttons)) { + if(json_object_get_type(j_buttons) != json_type_array) { + HMI_DEBUG(_modelName, "buttons josn type isn't array!"); + } + else { + m_buttons.clear(); + int len = json_object_array_length(j_buttons); + struct json_object *json_tmp = nullptr; + for (int i = 0; i < len; i++) { + json_tmp = json_object_array_get_idx(j_buttons, i); + m_buttons << QString(json_object_get_string(json_tmp)); + } + } + } + else { + HMI_DEBUG("OnScreenModel", "buttons input is null"); + } + HMI_DEBUG(_modelName, "setModel end!titile=%s,type=%s,contents=%s,btnNum=%d", + m_title.toStdString().c_str(), m_type.toStdString().c_str(), m_contents.toStdString().c_str(), m_buttons.size()); +} + +QString OnScreenModel::buttonName(int index) const +{ + if(index >= m_buttons.size()) + return QString(""); + else + return m_buttons[index]; +} + +void OnScreenModel::clearModel(void) +{ + m_title = ""; + m_type = ""; + m_contents = ""; + m_buttons.clear(); +} diff --git a/app/onscreenmodel.h b/app/onscreenmodel.h new file mode 100644 index 0000000..4524904 --- /dev/null +++ b/app/onscreenmodel.h @@ -0,0 +1,32 @@ +#ifndef ONSCREENMODEL_H +#define ONSCREENMODEL_H + +#include +#include +#include + + +class OnScreenModel : public QObject +{ + Q_OBJECT +public: + explicit OnScreenModel(QObject *parent = nullptr){} + ~OnScreenModel() = default; + + Q_INVOKABLE QString getTitle(void) const {return m_title;} + Q_INVOKABLE QString getType(void) const {return m_type;} + Q_INVOKABLE QString getContents(void) const {return m_contents;} + Q_INVOKABLE int buttonNum(void) const {return m_buttons.size();} + Q_INVOKABLE QString buttonName(int index) const; + Q_INVOKABLE void setModel(QVariant data); + +private: + void clearModel(void); + + QString m_title; + QString m_type; + QString m_contents; + QStringList m_buttons; +}; + +#endif // ONSCREENMODEL_H diff --git a/app/qml.qrc b/app/qml.qrc index 5f6483a..bad4ade 100644 --- a/app/qml.qrc +++ b/app/qml.qrc @@ -1,5 +1,6 @@ main.qml + Onscreen.qml diff --git a/onscreenapp.pro b/onscreenapp.pro index 8d60f8b..90b63a8 100644 --- a/onscreenapp.pro +++ b/onscreenapp.pro @@ -18,7 +18,6 @@ load(configure) SUBDIRS += \ package \ - app \ - sample + app package.depends += app