diff options
-rw-r--r-- | .gitlab/issue_templates/mytemplate.md | 3 | ||||
-rw-r--r-- | .gitlab/merge_request_templates/mytemplate.md | 3 | ||||
-rw-r--r-- | launcher/launcher.pro | 12 | ||||
-rw-r--r-- | launcher/qml/IconItem.qml | 120 | ||||
-rw-r--r-- | launcher/qml/Launcher.qml | 159 | ||||
-rw-r--r-- | launcher/qml/qml.qrc | 1 | ||||
-rw-r--r-- | launcher/src/appinfo.h | 13 | ||||
-rw-r--r-- | launcher/src/applicationmodel.cpp | 27 | ||||
-rw-r--r-- | launcher/src/applicationmodel.h | 19 | ||||
-rw-r--r-- | launcher/src/homescreenhandler.cpp | 90 | ||||
-rw-r--r-- | launcher/src/homescreenhandler.h | 52 | ||||
-rw-r--r-- | launcher/src/main.cpp | 49 |
12 files changed, 142 insertions, 406 deletions
diff --git a/.gitlab/issue_templates/mytemplate.md b/.gitlab/issue_templates/mytemplate.md new file mode 100644 index 0000000..25d91d8 --- /dev/null +++ b/.gitlab/issue_templates/mytemplate.md @@ -0,0 +1,3 @@ +**Please use https://gerrit.automotivelinux.org for code contributions.** +See also: https://docs.automotivelinux.org/ chapter "How to contribute". + diff --git a/.gitlab/merge_request_templates/mytemplate.md b/.gitlab/merge_request_templates/mytemplate.md new file mode 100644 index 0000000..25d91d8 --- /dev/null +++ b/.gitlab/merge_request_templates/mytemplate.md @@ -0,0 +1,3 @@ +**Please use https://gerrit.automotivelinux.org for code contributions.** +See also: https://docs.automotivelinux.org/ chapter "How to contribute". + diff --git a/launcher/launcher.pro b/launcher/launcher.pro index 929960f..674a0d9 100644 --- a/launcher/launcher.pro +++ b/launcher/launcher.pro @@ -15,27 +15,23 @@ TEMPLATE = app TARGET = launcher -QT = qml quick gui-private dbus +QT = qml quick gui-private CONFIG += c++11 link_pkgconfig DESTDIR = $${OUT_PWD} -PKGCONFIG += json-c +PKGCONFIG += qtappfw-applauncher CONFIG(release, debug|release) { QMAKE_POST_LINK = $(STRIP) --strip-unneeded $(TARGET) } -DBUS_INTERFACES = $$[QT_SYSROOT]/usr/share/dbus-1/interfaces/org.automotivelinux.AppLaunch.xml - SOURCES += \ src/main.cpp \ src/applicationmodel.cpp \ - src/appinfo.cpp \ - src/homescreenhandler.cpp + src/appinfo.cpp HEADERS += \ src/applicationmodel.h \ - src/appinfo.h \ - src/homescreenhandler.h + src/appinfo.h OTHER_FILES += \ README.md diff --git a/launcher/qml/IconItem.qml b/launcher/qml/IconItem.qml deleted file mode 100644 index 5207196..0000000 --- a/launcher/qml/IconItem.qml +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (C) 2016 The Qt Company Ltd. - * Copyright (c) 2018 TOYOTA MOTOR CORPORATION - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import QtQuick 2.0 -import QtQuick.Controls 2.0 -import QtGraphicalEffects 1.0 - -Item { - id: main - width: 320 - height: 320 - property string icon: model.icon - - Item { - id: container - parent: loc - x: main.x - y: main.y - width: main.width - height: main.height - - Image { - id: item - anchors.top: parent.top - anchors.topMargin: 20 - anchors.horizontalCenter: parent.horizontalCenter - width: 220 - height: width - source: main.icon - antialiasing: item.state !== '' - - property string initial: model.name.substring(0,1).toUpperCase() - - Item { - id: title - width: 125 - height: 125 - anchors.centerIn: parent - Repeater { - delegate: Label { - style: Text.Outline - styleColor: 'red' - color: 'transparent' - font.pixelSize: 125 - anchors.centerIn: parent - anchors.horizontalCenterOffset: model.index / 3 - 1 - anchors.verticalCenterOffset: model.index % 3 - 1 - text: item.initial - } - model: main.icon === 'blank' ? 9 : 0 - } - layer.enabled: true - layer.effect: LinearGradient { - gradient: Gradient { - GradientStop { position: -0.5; color: "#6BFBFF" } - GradientStop { position: +1.5; color: "#00ADDC" } - } - } - } - } - Label { - id: name - anchors.top: item.bottom - anchors.left: parent.left - anchors.right: parent.right - anchors.margins: 20 - font.pixelSize: 25 - font.letterSpacing: 5 - wrapMode: Text.WordWrap - horizontalAlignment: Text.AlignHCenter - color: "white" - text: qsTr(model.name.toUpperCase()) - } - - Behavior on x { enabled: item.state !== 'active'; NumberAnimation { duration: 400; easing.type: Easing.OutCubic } } - Behavior on y { enabled: item.state !== 'active'; NumberAnimation { duration: 400; easing.type: Easing.OutCubic } } - SequentialAnimation on rotation { - NumberAnimation { to: 5; duration: 100 } - NumberAnimation { to: -5; duration: 200 } - NumberAnimation { to: 0; duration: 100 } - running: loc.currentId !== '' && item.state !== 'active' - loops: Animation.Infinite; alwaysRunToEnd: true - } - states: [ - State { - name: 'active' - when: loc.currentId === model.id - PropertyChanges { - target: container - x: loc.mouseX - width/2 - y: loc.mouseY - height/2 - scale: 1.15 - z: 10 - } - }, - State { - when: loc.currentId !== '' - PropertyChanges { - target: container - scale: 0.85 - opacity: 0.75 - } - } - ] - transitions: Transition { NumberAnimation { properties: 'scale, opacity, x, y'; duration: 150; easing.type: Easing.OutCubic} } - } -} diff --git a/launcher/qml/Launcher.qml b/launcher/qml/Launcher.qml index 3c948dd..3aef4e6 100644 --- a/launcher/qml/Launcher.qml +++ b/launcher/qml/Launcher.qml @@ -15,15 +15,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import QtQuick 2.6 +import QtQuick 2.13 import QtQuick.Layouts 1.1 import QtQuick.Controls 2.0 import QtQuick.Window 2.13 +import QtGraphicalEffects 1.0 import AppModel 1.0 ApplicationWindow { - id: root + id: root //width: container.width //height: container.height flags: Qt.FramelessWindowHint @@ -36,77 +37,107 @@ ApplicationWindow { height: Window.height Image { - anchors.centerIn: parent - source: './images/AGL_HMI_Blue_Background_Car-01.png' + anchors.centerIn: parent + source: './images/AGL_HMI_Blue_Background_Car-01.png' } - GridView { - id: grid - anchors { - topMargin: 60; bottomMargin: 0 - leftMargin: 60; rightMargin: 60 - fill: parent - } - contentHeight: 320 - flickableDirection: Flickable.AutoFlickDirection - snapMode: GridView.SnapOneRow - visible: true - cellWidth: 320 - cellHeight: 320 - interactive: false + GridView { + id: grid + anchors { + topMargin: 60; bottomMargin: 60 + leftMargin: 60; rightMargin: 60 + fill: parent + } + contentHeight: 320 + // change this HorizontalFlick or see Flickable documentation + // for other possible combinations + flickableDirection: Flickable.VerticalFlick + snapMode: GridView.SnapOneRow + visible: true + cellWidth: 320 + cellHeight: 320 + interactive: apps_len > 12 ? true : false - model: ApplicationModel { id: applicationModel } - delegate: IconItem { - width: grid.cellWidth - height: grid.cellHeight - } + // the follow makes it display from left to right to allow + // horizontal scrolling to work + //verticalLayoutDirection: Grid.TopToBottom + //layoutDirection: Qt.LeftToRight + //flow: Grid.TopToBottom - Connections { - target: homescreenHandler - onAppListUpdate: { - console.warn("applist update in Launcher.qml") - applicationModel.updateApplist(info); - } - } - Connections { - target: homescreenHandler - onInitAppList: { - console.warn("applist init in Launcher.qml") - applicationModel.initAppList(data); - } - } + // uncomment this out if you want to highlight the currently selected item + //highlight: Rectangle { width: 80; height: 80; color: "steelblue"; opacity: 0.3 } - MouseArea { - id: loc - anchors.fill: parent - property string currentId: '' - property int newIndex: -1 - property int index: grid.indexAt(loc.mouseX, loc.mouseY) - x: 62 - y: 264 - onPressAndHold: currentId = applicationModel.id(newIndex = index) - onReleased: { - if(loc.index < 0) { - return + model: ApplicationModel + delegate: Item { + width: grid.cellWidth + height: grid.cellHeight + + Text { + color: "white" + anchors.top: myIcon.bottom + anchors.left: parent.left + anchors.right: parent.right + anchors.margins: 20 + font.pixelSize: 25 + font.letterSpacing: 5 + wrapMode: Text.WordWrap + horizontalAlignment: Text.AlignHCenter + text: qsTr(model.name.toUpperCase()) } - //if (applicationModel.appid(loc.index) === 'tbtnavi' || - // applicationModel.appid(loc.index) === 'hvac') { - // output_screen = 'Virtual-1' - //} - if (currentId === '') { - homescreenHandler.tapShortcut(applicationModel.appid(loc.index)) - } else { - currentId = '' + Image { + id: myIcon + anchors.top: parent.top + anchors.topMargin: 20 + anchors.horizontalCenter: parent.horizontalCenter + // make the image/icons smaller than the grid cell size as + // the text below/above current cell not be on top of the + // current icon + width: 220 + height: 220 + source: model.icon + antialiasing: true + property string initial: model.name.substring(0,1).toUpperCase() + + Item { + id: title + width: 125 + height: 125 + anchors.centerIn: parent + Label { + style: Text.Outline + styleColor: '#00ADDC' + color: 'transparent' + font.pixelSize: 125 + anchors.centerIn: parent + anchors.horizontalCenterOffset: model.index / 3 - 1 + anchors.verticalCenterOffset: model.index % 3 - 1 + text: model.icon === 'blank' ? myIcon.initial : '' + } + + layer.enabled: true + layer.effect: LinearGradient { + gradient: Gradient { + GradientStop { position: -0.5; color: "#6BFBFF" } + GradientStop { position: +1.5; color: "#00ADDC" } + } + } + } + } + + MouseArea { + id: loc + anchors.fill: parent + property string currentApp: '' + onClicked: { + parent.GridView.view.currentIndex = index + currentApp = ApplicationModel.appid(parent.GridView.view.currentIndex) + console.debug("Launcher: Starting app " + currentApp) + applauncher.startApplication(currentApp) + console.debug("Launcher: Started app " + currentApp) + } } - } - onPositionChanged: { - if (loc.currentId === '') return - if (index < 0) return - if (index === newIndex) return - applicationModel.move(newIndex, newIndex = index) } } } } -} diff --git a/launcher/qml/qml.qrc b/launcher/qml/qml.qrc index d132fed..3094f71 100644 --- a/launcher/qml/qml.qrc +++ b/launcher/qml/qml.qrc @@ -1,6 +1,5 @@ <RCC> <qresource prefix="/"> <file>Launcher.qml</file> - <file>IconItem.qml</file> </qresource> </RCC> diff --git a/launcher/src/appinfo.h b/launcher/src/appinfo.h index 1d1953d..ecbb6dc 100644 --- a/launcher/src/appinfo.h +++ b/launcher/src/appinfo.h @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: Apache-2.0 /* * Copyright (C) 2016, 2017 Mentor Graphics Development (Deutschland) GmbH * Copyright (C) 2016 The Qt Company Ltd. * Copyright (c) 2018 TOYOTA MOTOR CORPORATION - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. */ #ifndef APPINFO_H diff --git a/launcher/src/applicationmodel.cpp b/launcher/src/applicationmodel.cpp index 1af4366..d54d171 100644 --- a/launcher/src/applicationmodel.cpp +++ b/launcher/src/applicationmodel.cpp @@ -1,19 +1,9 @@ +// SPDX-License-Identifier: Apache-2.0 /* * Copyright (C) 2016 The Qt Company Ltd. * Copyright (C) 2016, 2017 Mentor Graphics Development (Deutschland) GmbH * Copyright (c) 2018,2019 TOYOTA MOTOR CORPORATION - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright (C) 2022 Konsulko Group */ #include "applicationmodel.h" @@ -197,18 +187,13 @@ void ApplicationModel::updateApplist(QStringList info) endResetModel(); } -void ApplicationModel::initAppList(QString data) +void ApplicationModel::initAppList(QList<QMap<QString, QString>> &apps) { HMI_DEBUG("launcher","init application list."); beginResetModel(); - QJsonDocument japps = QJsonDocument::fromJson(data.toUtf8()); - for (auto const &app : japps.array()) { - QJsonObject const &jso = app.toObject(); - auto const name = jso["name"].toString(); - auto const id = jso["id"].toString(); - auto const icon = get_icon_name(jso); - - d->addApp(icon, name, id); + qDebug() << "ApplicationModel::initAppList: got " << apps.size() << " apps"; + for (int i = 0; i < apps.size(); i++) { + d->addApp(apps[i]["icon_path"], apps[i]["name"], apps[i]["id"]); } endResetModel(); } diff --git a/launcher/src/applicationmodel.h b/launcher/src/applicationmodel.h index 780e575..c2693b2 100644 --- a/launcher/src/applicationmodel.h +++ b/launcher/src/applicationmodel.h @@ -1,28 +1,19 @@ +// SPDX-License-Identifier: Apache-2.0 /* * Copyright (C) 2016 The Qt Company Ltd. * Copyright (c) 2018,2019 TOYOTA MOTOR CORPORATION - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright (C) 2022 Konsulko Group */ #ifndef APPLICATIONMODEL_H #define APPLICATIONMODEL_H -#include <QtCore/QAbstractListModel> +#include <QAbstractListModel> class ApplicationModel : public QAbstractListModel { Q_OBJECT + public: explicit ApplicationModel(QObject *parent = nullptr); ~ApplicationModel(); @@ -35,7 +26,7 @@ public: Q_INVOKABLE QString id(int index) const; Q_INVOKABLE QString name(int index) const; Q_INVOKABLE void move(int from, int to); - Q_INVOKABLE void initAppList(QString data); + Q_INVOKABLE void initAppList(QList<QMap<QString, QString>> &apps); Q_INVOKABLE void updateApplist(QStringList info); private: diff --git a/launcher/src/homescreenhandler.cpp b/launcher/src/homescreenhandler.cpp deleted file mode 100644 index 9cf7e61..0000000 --- a/launcher/src/homescreenhandler.cpp +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2017 TOYOTA MOTOR CORPORATION - * Copyright (c) 2018,2019 TOYOTA MOTOR CORPORATION - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <QDBusMessage> -#include <QDBusConnection> -#include "homescreenhandler.h" -#include "hmi-debug.h" - -#include <json.h> - -#define APPLAUNCH_DBUS_IFACE "org.automotivelinux.AppLaunch" -#define APPLAUNCH_DBUS_OBJECT "/org/automotivelinux/AppLaunch" - -HomescreenHandler::HomescreenHandler(QObject *parent) : QObject(parent) -{ - applaunch_iface = new org::automotivelinux::AppLaunch(APPLAUNCH_DBUS_IFACE, APPLAUNCH_DBUS_OBJECT, QDBusConnection::sessionBus(), this); -} - -HomescreenHandler::~HomescreenHandler() -{ -} - -void HomescreenHandler::tapShortcut(QString application_id) -{ - HMI_DEBUG("Launcher","tapShortcut %s", application_id.toStdString().c_str()); - - QDBusPendingReply<> reply = applaunch_iface->start(application_id); - reply.waitForFinished(); - if (reply.isError()) { - HMI_ERROR("Launcher","Unable to start application '%s': %s", - application_id.toStdString().c_str(), - reply.error().message().toStdString().c_str()); - } -} - -void HomescreenHandler::getRunnables(void) -{ - struct json_object *json_applist; - QString applist; - QStringList apps; - - QDBusPendingReply<QVariantList> reply = applaunch_iface->listApplications(true); - reply.waitForFinished(); - if (reply.isError()) { - HMI_ERROR("Launcher","Unable to retrieve application list: %s", - reply.error().message().toStdString().c_str()); - return; - } else { - QVariantList applist_variant = reply.value(); - for (auto &v: applist_variant) { - QString app_id; - QString name; - QString icon_path; - const QDBusArgument &dbus_arg = v.value<QDBusArgument>(); - - dbus_arg.beginStructure(); - dbus_arg >> app_id >> name >> icon_path; - - apps << QString("{ \"name\":\"%1\", \"id\":\"%2\", \"icon\":\"%3\" }") - .arg(name) - .arg(app_id) - .arg(icon_path); - dbus_arg.endStructure(); - } - } - - applist = QString("[ %1 ]").arg(apps.join(", ")); - json_applist = json_tokener_parse(applist.toLocal8Bit().data()); - if (json_applist) { - QString data = json_object_to_json_string(json_applist); - HMI_DEBUG("Launcher", "doing an emit initAppList()"); - emit initAppList(data); - } else { - HMI_DEBUG("Launcher", "app list is invalid!"); - } -} diff --git a/launcher/src/homescreenhandler.h b/launcher/src/homescreenhandler.h deleted file mode 100644 index 616f816..0000000 --- a/launcher/src/homescreenhandler.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2017 TOYOTA MOTOR CORPORATION - * Copyright (c) 2018,2019 TOYOTA MOTOR CORPORATION - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef HOMESCREENHANDLER_H -#define HOMESCREENHANDLER_H - -#include <QObject> -#include <QString> -#include <QStringList> -#include <string> - -#include <json.h> - -#include "applaunch_interface.h" - -using namespace std; - -class HomescreenHandler : public QObject -{ - Q_OBJECT -public: - explicit HomescreenHandler(QObject *parent = 0); - ~HomescreenHandler(); - - Q_INVOKABLE void tapShortcut(QString application_id); - Q_INVOKABLE void getRunnables(void); - - void onRep(struct json_object* reply_contents); - -signals: - void initAppList(QString data); - void appListUpdate(QStringList info); - -private: - org::automotivelinux::AppLaunch *applaunch_iface; -}; - -#endif // HOMESCREENHANDLER_H diff --git a/launcher/src/main.cpp b/launcher/src/main.cpp index 563e883..40110ef 100644 --- a/launcher/src/main.cpp +++ b/launcher/src/main.cpp @@ -1,18 +1,8 @@ +// SPDX-License-Identifier: Apache-2.0 /* * Copyright (C) 2016, 2017 Mentor Graphics Development (Deutschland) GmbH * Copyright (c) 2018 TOYOTA MOTOR CORPORATION - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright (C) 2022 Konsulko Group */ #include <QGuiApplication> @@ -27,26 +17,37 @@ #include "applicationmodel.h" #include "appinfo.h" -#include "homescreenhandler.h" +#include "AppLauncherClient.h" int main(int argc, char *argv[]) { QString myname = QString("launcher"); - QGuiApplication a(argc, argv); + QGuiApplication app(argc, argv); // necessary to identify correctly by app_id - a.setDesktopFileName(myname); + app.setDesktopFileName(myname); - // import C++ class to QML - qmlRegisterType<ApplicationModel>("AppModel", 1, 0, "ApplicationModel"); - - HomescreenHandler* homescreenHandler = new HomescreenHandler(); - - // mail.qml loading QQmlApplicationEngine engine; - engine.rootContext()->setContextProperty(QStringLiteral("homescreenHandler"), homescreenHandler); + + AppLauncherClient* applauncher = new AppLauncherClient(); + QList<QMap<QString, QString>> apps; + if (applauncher) { + applauncher->listApplications(apps); + engine.rootContext()->setContextProperty(QStringLiteral("applauncher"), applauncher); + engine.rootContext()->setContextProperty(QStringLiteral("apps_len"), apps.size()); + } else { + qFatal("Could not create AppLauncherClient"); + } + + ApplicationModel *appmodel = new ApplicationModel(); + if (appmodel) { + appmodel->initAppList(apps); + qmlRegisterSingletonType<ApplicationModel>("AppModel", 1, 0, "ApplicationModel", + [appmodel](QQmlEngine *, QJSEngine *) -> QObject * { return appmodel; }); + } else { + qFatal("Could not create ApplicationModel"); + } engine.load(QUrl(QStringLiteral("qrc:/Launcher.qml"))); - homescreenHandler->getRunnables(); - return a.exec(); + return app.exec(); } |