aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarius Vlad <marius.vlad@collabora.com>2022-02-11 17:05:40 +0200
committerMarius Vlad <marius.vlad@collabora.com>2022-02-18 12:58:06 +0200
commitfd578508fe8f59a0bf11916ea99561125dcfc4ba (patch)
tree09c9adcf3e45a6828ec56b93a8889a0c1233a431
parentcd7744af494a3399eca3e19fe6d0e134f36c21e7 (diff)
launcher: Enable scrolling for the GridView to display more appsHEADneedlefish_13.93.0needlefish/13.93.013.93.0master
This enables the GridView to allow scrolling and implicitly be able to display more than a dozen of applications. The interactive mode controls whether this is enabled or not, if the items is higher than what the grid can contain (which is 4x3 in our current item cell dimension). If interactive is enabled we use vertical scrolling, with some commented out examples on how to enable horizontal scrolling. In tests, horizontal scrolling caused some animation artefacts while vertical seemed to behave much more reliable. With it, we simplify the QML considerably by removing IconItem. Most of the functionality has been retained, being copy-pasted from IconItem like displaying icons, or using the first letter of the application name in case there's no icon. Note that this change removes The icon movement entirely, which seemed to cause quite a bit of issues while draging/dropping scrolling in the the grid itself. This seems to remove one feature for another, but by just enabling interactive resulted in a jerky inconsistent animation. Bug-AGL: SPEC-3028 Signed-off-by: Marius Vlad <marius.vlad@collabora.com> Change-Id: I64810dbd7ef014ed0473fd92df67807d10cc36ba
-rw-r--r--launcher/qml/IconItem.qml120
-rw-r--r--launcher/qml/Launcher.qml170
-rw-r--r--launcher/qml/qml.qrc1
-rw-r--r--launcher/src/homescreenhandler.cpp24
-rw-r--r--launcher/src/homescreenhandler.h1
-rw-r--r--launcher/src/main.cpp2
6 files changed, 132 insertions, 186 deletions
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..894ff98 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,120 @@ 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 { id: 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)
+ homescreenHandler.tapShortcut(currentApp)
+ }
+ }
+ }
+
+ Connections {
+ target: homescreenHandler
+ onAppListUpdate: {
+ console.warn("applist update in Launcher.qml")
+ applicationModel.updateApplist(info);
}
}
- onPositionChanged: {
- if (loc.currentId === '') return
- if (index < 0) return
- if (index === newIndex) return
- applicationModel.move(newIndex, newIndex = index)
+ Connections {
+ target: homescreenHandler
+ onInitAppList: {
+ console.warn("applist init in Launcher.qml")
+ applicationModel.initAppList(data);
+ }
}
}
}
}
-}
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/homescreenhandler.cpp b/launcher/src/homescreenhandler.cpp
index 9cf7e61..33987dd 100644
--- a/launcher/src/homescreenhandler.cpp
+++ b/launcher/src/homescreenhandler.cpp
@@ -47,10 +47,30 @@ void HomescreenHandler::tapShortcut(QString application_id)
}
}
+int HomescreenHandler::getRunnablesCount(void)
+{
+ int apps = 0;
+
+ 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 apps;
+ } else {
+ QVariantList applist_variant = reply.value();
+ for (auto &v: applist_variant)
+ apps++;
+ }
+
+ return apps;
+}
+
void HomescreenHandler::getRunnables(void)
{
- struct json_object *json_applist;
- QString applist;
+ struct json_object *json_applist;
+ QString applist;
QStringList apps;
QDBusPendingReply<QVariantList> reply = applaunch_iface->listApplications(true);
diff --git a/launcher/src/homescreenhandler.h b/launcher/src/homescreenhandler.h
index 616f816..7392992 100644
--- a/launcher/src/homescreenhandler.h
+++ b/launcher/src/homescreenhandler.h
@@ -38,6 +38,7 @@ public:
Q_INVOKABLE void tapShortcut(QString application_id);
Q_INVOKABLE void getRunnables(void);
+ int getRunnablesCount(void);
void onRep(struct json_object* reply_contents);
diff --git a/launcher/src/main.cpp b/launcher/src/main.cpp
index 563e883..77dee27 100644
--- a/launcher/src/main.cpp
+++ b/launcher/src/main.cpp
@@ -44,7 +44,9 @@ int main(int argc, char *argv[])
// mail.qml loading
QQmlApplicationEngine engine;
+ int apps = homescreenHandler->getRunnablesCount();
engine.rootContext()->setContextProperty(QStringLiteral("homescreenHandler"), homescreenHandler);
+ engine.rootContext()->setContextProperty(QStringLiteral("apps_len"), apps);
engine.load(QUrl(QStringLiteral("qrc:/Launcher.qml")));
homescreenHandler->getRunnables();