From da726aa2bdb0aa4bad33c2cfbdefa46f90fb6c17 Mon Sep 17 00:00:00 2001 From: Tasuku Suzuki Date: Fri, 26 May 2017 11:09:59 +0900 Subject: PoC: Qt Compositor-ized homescreen Change-Id: Icec91030f8f4a8bf001b30ba9b7547751abfafed Signed-off-by: Tasuku Suzuki --- homescreen/qml/Home.qml | 12 +- homescreen/qml/ShortcutArea.qml | 20 +-- homescreen/qml/SystemUI.qml | 258 ++++++++++++++++++++++++++++++++++++ homescreen/qml/main.qml | 73 +++------- homescreen/qml/qml.qrc | 1 + homescreen/src/applicationmodel.cpp | 9 ++ homescreen/src/main.cpp | 11 +- 7 files changed, 296 insertions(+), 88 deletions(-) create mode 100644 homescreen/qml/SystemUI.qml diff --git a/homescreen/qml/Home.qml b/homescreen/qml/Home.qml index a312670..7effe19 100644 --- a/homescreen/qml/Home.qml +++ b/homescreen/qml/Home.qml @@ -54,17 +54,7 @@ Item { onPressAndHold: currentId = applicationModel.id(newIndex = index) onReleased: { if (currentId === '') { - pid = launcher.launch(applicationModel.id(loc.index)) - if (1 < pid) { - layoutHandler.makeMeVisible(pid) - - applicationArea.visible = true - appLauncherAreaLauncher.visible = false - layoutHandler.showAppLayer(pid) - } - else { - console.warn("app cannot be launched!") - } + launcher.show(applicationModel.id(loc.index)) } else { currentId = '' } diff --git a/homescreen/qml/ShortcutArea.qml b/homescreen/qml/ShortcutArea.qml index 14c7b6b..bdbd59a 100644 --- a/homescreen/qml/ShortcutArea.qml +++ b/homescreen/qml/ShortcutArea.qml @@ -57,24 +57,8 @@ Item { name: model.name active: model.application === launcher.current onClicked: { - if (0 === model.index) { - appLauncherAreaLauncher.visible = true - applicationArea.visible = false - layoutHandler.hideAppLayer() - launcher.current = '' - } - else { - pid = launcher.launch(model.application) - if (1 < pid) { - applicationArea.visible = true - appLauncherAreaLauncher.visible = false - layoutHandler.makeMeVisible(pid) - layoutHandler.showAppLayer(pid) - } - else { - console.warn("app cannot be launched!") - } - } + if (model.index < 3) // disable navi to launch + launcher.show(model.index === 0 ? '' : model.application) } } } diff --git a/homescreen/qml/SystemUI.qml b/homescreen/qml/SystemUI.qml new file mode 100644 index 0000000..1e1c6be --- /dev/null +++ b/homescreen/qml/SystemUI.qml @@ -0,0 +1,258 @@ +/* + * Copyright (C) 2016 The Qt Company Ltd. + * Copyright (C) 2016, 2017 Mentor Graphics Development (Deutschland) GmbH + * + * 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.2 +import QtQuick.Window 2.1 +import QtQuick.Layouts 1.1 +import QtQuick.Controls 2.1 +import QtWayland.Compositor 1.0 +import HomeScreen 1.0 +import QtGraphicalEffects 1.0 + +Window { + id: root + visible: true + flags: Qt.FramelessWindowHint + width: container.width * container.scale + height: container.height * container.scale + title: 'HomeScreen' + property alias applicationStack: applicationStack + + property var app2item: new Object + property string appLaunching + + Component { + id: chrome + ShellSurfaceItem { + onSurfaceDestroyed: destroy() + } + } + + function show(shellSurface) { + var a2i = root.app2item + var item = chrome.createObject(root, {"shellSurface": shellSurface}) + a2i[appLaunching] = item + root.app2item = a2i + shellSurface.sendConfigure(Qt.size(applicationStack.width, applicationStack.height), WlShellSurface.NoneEdge) + if (applicationStack.depth == 1) { + applicationStack.push(item) + } else { + applicationStack.replace(item) + } + appLaunching = '' + } + + ApplicationLauncher { + id: launcher + + function show(app) { + if (current === app) return + if (app.length > 0) { + if (root.appLaunching.length > 0) + return + if (app2item[app]) { + if (applicationStack.depth == 1) { + applicationStack.push(app2item[app]) + } else { + applicationStack.replace(app2item[app]) + } + current = app + } else { + root.appLaunching = app + if (launch(app) < 0) { + root.appLaunching = '' + } + } + } else if (applicationStack.depth > 1) { + applicationStack.pop() + current = '' + } + } + } + + Component { + id: home + Home { + width: parent.width + height: parent.height + } + } + + Transition { + id: inTransition + NumberAnimation { + properties: "opacity, scale" + from: 0 + to:1 + duration: 250 + } + } + Transition { + id: outTransition + NumberAnimation { + properties: "opacity" + from: 1 + to:0 + duration: 250 + } + NumberAnimation { + properties: "scale" + from: 1 + to:5 + duration: 250 + } + } + + Image { + id: container + anchors.centerIn: parent + width: 1080 + height: 1920 + rotation: 270 + source: './images/AGL_HMI_Background_NoCar-01.png' + + ColumnLayout { + anchors.fill: parent + spacing: 0 + TopArea { + id: topArea + Layout.fillWidth: true + Layout.preferredHeight: 218 + } + + Item { + id: applicationArea + Layout.fillWidth: true + Layout.fillHeight: true + Layout.preferredHeight: 1920 - 218 - 215 + clip: true + StackView { + id: applicationStack + anchors.fill: parent + initialItem: home + + pushEnter: inTransition + pushExit: outTransition + replaceEnter: inTransition + replaceExit: outTransition + popEnter: inTransition + popExit: outTransition + } + } + + MediaArea { + id: mediaArea + Layout.fillWidth: true + Layout.fillHeight: true + Layout.preferredHeight: 215 + MouseArea { + z: 100 + anchors.fill: parent + onClicked: { + notificationLayer.shown = true + } + } + } + } + } + + MouseArea { + id: notificationLayer + property bool shown: false + anchors.fill: container + scale: container.scale + visible: opacity > 0 + opacity: 0 + rotation: 270 + z: 100 + + onClicked: shown = false + + Rectangle { + anchors.fill: parent + color: 'black' + opacity: 0.75 + } + + states: [ + State { + name: "notify" + when: notificationLayer.shown + PropertyChanges { + target: notificationLayer + opacity: 1.0 + } + PropertyChanges { + target: timer + running: true + } + } + ] + + transitions: [ + Transition { + NumberAnimation { + properties: 'opacity' + duration: 250 + easing.type: Easing.OutExpo + } + } + ] + + Column { + anchors.centerIn: parent + spacing: 20 + Rectangle { + width: 600 + height: 250 + radius: 20 + color: 'white' + + Label { + anchors.centerIn: parent + text: "Message 1" + font.pixelSize: 96 + color: 'blue' + antialiasing: true + } + } + Rectangle { + width: 600 + height: 250 + radius: 20 + color: 'white' + + Label { + anchors.centerIn: parent + text: "Restart" + font.pixelSize: 96 + color: 'red' + antialiasing: true + MouseArea { + anchors.fill: parent + onClicked: Qt.quit() + } + } + } + Timer { + id: timer + interval: 3000 + onTriggered: notificationLayer.shown = false + } + } + } +} diff --git a/homescreen/qml/main.qml b/homescreen/qml/main.qml index 11bd9d5..86b3ee9 100644 --- a/homescreen/qml/main.qml +++ b/homescreen/qml/main.qml @@ -1,6 +1,5 @@ /* - * Copyright (C) 2016 The Qt Company Ltd. - * Copyright (C) 2016, 2017 Mentor Graphics Development (Deutschland) GmbH + * Copyright (C) 2017 The Qt Company Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,62 +14,24 @@ * limitations under the License. */ -import QtQuick 2.2 +import QtQuick 2.6 import QtQuick.Window 2.1 -import QtQuick.Layouts 1.1 -import HomeScreen 1.0 - -Window { - visible: true - flags: Qt.FramelessWindowHint - width: container.width * container.scale - height: container.height * container.scale - title: 'HomeScreen' - - ApplicationLauncher { - id: launcher +import QtWayland.Compositor 1.0 + +WaylandCompositor { + id: compositor + + WaylandOutput { + id: screen + compositor: compositor + sizeFollowsWindow: true + transform: WaylandOutput.Transform90 + window: SystemUI { + id: systemUI + } } - Image { - id: container - anchors.centerIn: parent - width: 1080 - height: 1920 - scale: 1.0 - source: './images/AGL_HMI_Background_NoCar-01.png' - - ColumnLayout { - anchors.fill: parent - spacing: 0 - TopArea { - id: topArea - Layout.fillWidth: true - Layout.preferredHeight: 218 - } - - Item { - id: applicationArea - Layout.fillWidth: true - Layout.fillHeight: true - Layout.preferredHeight: 1920 - 218 - 215 - - visible: false - } - - Home { - id: appLauncherAreaLauncher - Layout.fillWidth: true - Layout.fillHeight: true - Layout.preferredHeight: 1920 - 218 - 215 - visible: true - } - - MediaArea { - id: mediaArea - Layout.fillWidth: true - Layout.fillHeight: true - Layout.preferredHeight: 215 - } - } + WlShell { + onWlShellSurfaceCreated: systemUI.show(shellSurface) } } diff --git a/homescreen/qml/qml.qrc b/homescreen/qml/qml.qrc index c25e266..1f69726 100644 --- a/homescreen/qml/qml.qrc +++ b/homescreen/qml/qml.qrc @@ -11,5 +11,6 @@ StatusArea.qml TopArea.qml IconItem.qml + SystemUI.qml diff --git a/homescreen/src/applicationmodel.cpp b/homescreen/src/applicationmodel.cpp index 417bc4c..c940149 100644 --- a/homescreen/src/applicationmodel.cpp +++ b/homescreen/src/applicationmodel.cpp @@ -54,10 +54,19 @@ ApplicationModel::Private::Private() { QString apps = afm_user_daemon_proxy->runnables(QStringLiteral("")); QJsonDocument japps = QJsonDocument::fromJson(apps.toUtf8()); + // disable apps which don't work with the compositor right now + QStringList notShow = { + "navigation@0.1" + , "phone@0.1" + , "controls@0.1" + , "poi@0.1" + , "mixer@0.1" + }; for (auto const &app : japps.array()) { QJsonObject const &jso = app.toObject(); auto const name = jso["name"].toString(); auto const id = jso["id"].toString(); + if (notShow.contains(id)) continue; auto const icon = get_icon_name(jso); this->data.append(AppInfo(icon, name, id)); qDebug() << "name:" << name << "icon:" << icon << "id:" << id; diff --git a/homescreen/src/main.cpp b/homescreen/src/main.cpp index 215e7c6..7eba5bb 100644 --- a/homescreen/src/main.cpp +++ b/homescreen/src/main.cpp @@ -52,7 +52,11 @@ void noOutput(QtMsgType, const QMessageLogContext &, const QString &) int main(int argc, char *argv[]) { - QGuiApplication a(argc, argv); + qputenv("QT_QPA_PLATFORM", "eglfs"); + qputenv("QT_QPA_EGLFS_INTEGRATION","eglfs_kms"); + qputenv("QT_QPA_EGLFS_KMS_CONFIG","/home/root/kmsconfig"); + + QGuiApplication app(argc, argv); QScopedPointer afm_user_daemon_proxy(new org::AGL::afm::user("org.AGL.afm.user", "/org/AGL/afm/user", @@ -72,7 +76,7 @@ int main(int argc, char *argv[]) QCommandLineOption quietOption(QStringList() << "q" << "quiet", QCoreApplication::translate("main", "Be quiet. No outputs.")); parser.addOption(quietOption); - parser.process(a); + parser.process(app); if (parser.isSet(quietOption)) { @@ -118,5 +122,6 @@ int main(int argc, char *argv[]) // Initalize PA client client->init(); - return a.exec(); + QObject::connect(&engine, &QQmlApplicationEngine::quit, &app, &QGuiApplication::quit); + return app.exec(); } -- cgit 1.2.3-korg