diff options
author | Piotr Mikolajczyk <piotr.mikolajczyk@qt.io> | 2022-02-24 14:53:58 +0100 |
---|---|---|
committer | Piotr Mikolajczyk <piotr.mikolajczyk@qt.io> | 2022-03-17 10:37:25 +0100 |
commit | cd9026d12a9669657b4db2502fef352d3a879c49 (patch) | |
tree | 1501b22268c0e73908efd848d0eb436b8783200b | |
parent | b6d541ebcb57c22606ea95c370a44660c66e7b07 (diff) |
QtAndroidAutomotive: Add ActivityView component
Task-number: QAA-1013
Change-Id: I9b87eab17e70f81eaf9140aba6fd63b68da0547c
Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
13 files changed, 456 insertions, 1 deletions
diff --git a/src/imports/compatibility/QtAndroidAutomotive/ActivityView/ActivityView.qml b/src/imports/compatibility/QtAndroidAutomotive/ActivityView/ActivityView.qml new file mode 100644 index 0000000..e63c3a1 --- /dev/null +++ b/src/imports/compatibility/QtAndroidAutomotive/ActivityView/ActivityView.qml @@ -0,0 +1,254 @@ +/**************************************************************************** +** +** Copyright (C) 2022 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Quick Ultralite compatibility. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls + +Item { + id: root + + width: 480 + height: 640 + + property alias radius: rect.radius + property string packageName: "some.package.name" + property string className + readonly property alias status: internal.status + property alias placeholder: placeholderItem.children + property bool usePlaceholder: false + + onUsePlaceholderChanged: { + if (placeholder) { + placeholder.visible = usePlaceholder + avMock.visible = !usePlaceholder + } else { + avMock.visible = true + } + } + + onPlaceholderChanged: { + if (!placeholder) + avMock.visible = true + } + + enum Status { + NotInitialized, + Ready, + Starting, + Started + } + + function getScreenshot() { + return "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAeAAAAKACAIAAADLqjwFAAAACXBIWXMAA + AsTAAALEwEAmpwYAAAAB3RJTUUH5gIWDSYrZMHgKwAACHpJREFUeNrt3cFxwjAQQNGQcSuugyrcAyW5B + rsK10EzuYYDGrAsayW/d81AQGb+7GVHt2VZfgCI59cRAAg0AAININAACDSAQAMg0AAINIBAAyDQAAINg + EADINAAAg2AQAMINAACDSDQAAg0AGlDzounaXKCAAnrupqgAXoj0AACDYBAAwg0AAININAACDQAAg0g0 + AAINIBAAyDQAAg0gEADINAAAg2AQAMINAACDYBAAwg0AAININAACDQAAg0g0AAINIBAA3CGwRHwzryNi + b8+7k9H5JwxQQMINAACDYBAAwg0AAININAACDQAAg0Qn01C3krvsNl/+5yzwgQNINAACDSAQAMg0AAIN + IBAAyDQAAINQEU2CQknvXdXi30/TNAACDSAQAMg0AACDYBAAwg0AAINgEADNMomITvl3FjYopxvZAsRE + zSAQAMg0AACDYBAAyDQAAINgEADCDQAFdkkZKf+dgVrnZU9Q0zQAAINgEADCDQAAg2AQAMINAACDSDQA + BRlk5C37ApGOGd7hiZoAAQaAIEGEGgABBpAoAEQaAAEGkCgAchkk/DSau0KprfjYm4w1vrM9gxN0AAIN + AACDSDQAAg0gEADINAACDSAQAOQySYhFbR426EbGjFBAyDQAAINgEADCDQAAg0g0AAINAACDdAom4Sds + /925efrxkITNAACDSDQAAg0AAININAACDSAQAMg0AAINIBAAyDQAAINgEADCDQAAg2AQAMINAACDdA5d + xJ2zq10YIIGQKABBBoAgQZAoAEEGgCBBhBoAAQa4OJsEp5k3sbdr83ZBsz5v7Su1i/H/qoJGkCgARBoA + AQaQKABEGgAgQZAoAEEGoBQbBIeptzOXvqdbW3hF2uCBkCgARBoAIEGQKABBBoAgQYQaAAEGgCBBhBoA + AQaQKABEGgABBpAoAEQaACBBkCgAQQaAIEGQKABBBoAgQYQaAAEGgCBBhBoAAQaQKABEGgAgQZAoAEQa + ACBBkCgAQQaAIEGQKABBBoAgQYQaAAEGgCBBhBoAAQaQKABEGgAgQZAoAEQaACBBkCgAQQaAIEGQKABB + BoAgQYQaAAEGkCgARBoAAQaQKABEGgAgQZAoAEQaACBBkCgAQQaAIEGEGgABBoAgQYQaAAEGkCgARBoA + AQaQKABEGgAgQZAoAEQaACBBkCgAQQaAIEGEGgABBoAgQYQaAAEGkCgARBoAAQaQKABEGiAbgyO4CiP+ + zPx13kbC70z+MWaoAEQaAAEGkCgARBoAIEGQKABBBoAgQYgwSbhSexW4ReLCRpAoAEQaACBBkCgARBoA + IEGQKABBBoAgQZAoAEEGgCBBhBoAAQaQKABEGgABBpAoAEQaACBBkCgARBoAIEGQKABBBoAgQYQaAAEG + oCPDY6gb4/7s9A7z9voGwX/RpigARBoAIEGQKABEGgAgQZAoAEEGgCBBkCgAQQaAIEGEGgABBpAoAEQa + AAEGkCgARBoAIEGQKABEGgAgQZAoAEEGgCBBhBoAAQaAIEGEGgABBpAoAEQaAAEGkCgARBoAIEGQKABB + BoAgQZAoAEEGgCBBhBoAAQaAIEGEGgABBpAoAE41eAI2Odxfyb+Om9joXf2jTBBAyDQAAg0gEADINAAA + g2AQAMg0AACDcBXbBJSRH+7c7YBMUEDINAAAg2AQAMINAACDSDQAAg0AAININAACDSAQAMg0AAINIBAA + yDQAAINgEADCDQAAg2AQAMINAACDSDQAAg0AAININAACDSAQAMg0AAINIBAAyDQAAINgEADCDQAAg2AQ + AMINAACDSDQAAg0AAININAACDSAQAMg0AACDYBAAyDQAAINgEADCDQAAg2AQAMINAACDSDQAAg0gEADI + NAACDSAQAMg0AACDYBAAyDQAAINgEADdGlwBP+t61rl/07T5FN9+H89wXM+VbmnkPPOJmgABBoAgQYQa + AAEGkCgARBoAAQaQKAB2MEm4RdibkD196nK7aF5ghGeAiZoAIEGQKABBBoAgQZAoAEEGgCBBhBoAE5mk + /ALMW/h46gnWOsp2NnDBA0g0AAINIBAAyDQAAg0gEADINAAAg1AUTYJX5Tb2iq3hRhTzvct9xTcSXjUp + 7ra79kEDYBAAwg0AAININAACDSAQAMg0AAINEDTbBK+aHE/KuZNiTmvLXdHX8yzavGuS3uGJmgAgQZAo + AEQaACBBkCgAQQaAIEGQKABGnJblmX3i2PepQYQR85epQkaICiBBhBoAAQaQKABEGgAgQZAoAEQaACBB + kCgAQQaAIEGQKABBBoAgQYQaAAEGkCgAYhjcAQR5NxaliPnVsn0Z27xnWudVS3uFDVBAyDQAAINgEADC + DQAAg2AQAMINAACDXARNgkbYOPrczH3G2PuVWKCBkCgAQQaAIEGEGgABBoAgQYQaAAEGuAibBI2oNyNd + uX20GLewgcmaAAEGkCgARBoAAQaQKABEGgAgQZAoAEuyCZhCP1t9JW7hQ9M0AAINAACDSDQAAg0gEADI + NAACDSAQAPwFZuEIdidO0p6gzHnnMtte4IJGkCgARBoAIEGQKABEGgAgQZAoAEEGoCibsuy7H6x3SqAt + Jz9VRM0QFACDSDQAAg0gEADINAAAg2AQAMg0AACDYBAAwg0AAINgEADCDQAAg0g0AAINIBAAyDQAAg0g + EADINAAAg2AQAMg0AACDYBAAwg0AAININAACDQAAg0g0AAINIBAAyDQAAg0gEADINAAAg2AQAMItCMAE + GgABBpAoAEQaACBBkCgARBoAIEGQKABBBoAgQZAoAEEGgCBBhBoAAQa4IqGnBev6+oEAUzQAAINgEADI + NAAAg2AQAMINAACDYBAAwg0AAININAACDSAQAMg0AAINIBAAyDQAAINQB1/r8/rsfODy+gAAAAASUVOR + K5CYII=" + } + + QtObject { + id: internal + + property var status: ActivityView.NotInitialized + property real fontPointSize: 20 + + function enumToString(val) { + switch (val) { + case ActivityView.NotInitialized: return "NotInitialized" + case ActivityView.Ready: return "Ready" + case ActivityView.Starting: return "Starting" + case ActivityView.Started: return "Started" + } + return "Unknown" + } + } + + component StatusButton: Rectangle { + id: button + + color: highlighted ? "lightGray" : "gray" + radius: 5 + clip: true + width: btnText.width + height: btnText.height + + property int statusId: 0 + property bool highlighted: false + signal clicked(int value) + + Label { + id: btnText + + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + font.pointSize: internal.fontPointSize + + text: " " + internal.enumToString(statusId) + " " + } + + MouseArea { + anchors.fill: parent + onClicked: button.clicked(statusId) + } + } + + Item { + id: placeholderItem + anchors.fill: parent + } + + Item { + id: avMock + + anchors.fill: parent + + Rectangle { + id: rect + + anchors.fill: parent + color: "#AAAAAA" + radius: 0 + border.color: "#888888" + border.width: 2 + clip: true + + Image { + id: icon + + anchors.centerIn: parent + anchors.verticalCenterOffset: - statusArea.height / 2 + + source: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACAAQMAAAD58POIAAAABlBMV + EUAAAA+Pj4LNneDAAAAAXRSTlMAQObYZgAAAAlwSFlzAAALEwAACxMBAJqcGAAAASNJREFUSMft1 + TFuwzAMBVApAqIlgNZu6hF6A/UovYm99VjV1mu46AUyelDNilJgftkx0gbtZg4C/BCFNETRSnE88 + 3JQEi+8HAEel/DEywngYV624DTv24KjMrHmvsRBEfUIxhGdI4B+I/rqESgHgmHALZbhDOAZRoDAM + AF0DARQniGNrhDbrERDmxXBpZwmBSnEj7mQ0Y9LSFLXBkipXf3TaVE51E5b0Lev8hOI7cveBcP9s + Aw4U1c2JNkSYjkDO0PHv3b0OkPpAC/wcYF3gXQNgsDnDjv8AdxuuqZP07VOdtDrZdrZCZqfr5BOA + j7ikJIr9i9w+2avJsxqBq3nWKjPE871wTZzfYffQ2zBUTTNx3MFlnrdjGiTz6j5AOvcsF09yG/q3 + /z/4fD/YgAAAABJRU5ErkJggg==" + } + + Label { + id: packageLabel + + anchors.top: icon.bottom + anchors.left: parent.left + anchors.right: parent.right + anchors.margins: 5 + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + font.pointSize: internal.fontPointSize + text: root.packageName + } + } + + Rectangle { + id: statusArea + + anchors.left: parent.left + anchors.right: parent.right + anchors.top: statusFlow.top + anchors.bottom: statusFlow.bottom + anchors.topMargin: -5 + anchors.bottomMargin: -5 + color:"black" + opacity: 0.5 + radius: rect.radius + } + + Label { + id: statusLabel + + anchors.top: statusFlow.top + anchors.left: parent.left + + text: " " + "status:" + " " + color: "lightGray" + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + font.pointSize: internal.fontPointSize + } + + Flow { + id: statusFlow + + anchors.bottom: parent.bottom + anchors.left: parent.left + anchors.right: parent.right + anchors.margins: 5 + anchors.leftMargin: statusLabel.width + spacing: 5 + + Repeater { + model: [ActivityView.NotInitialized, ActivityView.Ready, ActivityView.Starting, + ActivityView.Started] + + delegate: StatusButton { + statusId: modelData + onClicked: (value) => internal.status = value + highlighted: modelData === internal.status + } + } + } + } +} diff --git a/src/imports/compatibility/QtAndroidAutomotive/ActivityView/activityview.pri b/src/imports/compatibility/QtAndroidAutomotive/ActivityView/activityview.pri new file mode 100644 index 0000000..183f2f0 --- /dev/null +++ b/src/imports/compatibility/QtAndroidAutomotive/ActivityView/activityview.pri @@ -0,0 +1,2 @@ +QML_FILES += \ + $$PWD/ActivityView.qml diff --git a/src/imports/compatibility/QtAndroidAutomotive/ActivityView/activityview.pro b/src/imports/compatibility/QtAndroidAutomotive/ActivityView/activityview.pro new file mode 100644 index 0000000..6b8b63d --- /dev/null +++ b/src/imports/compatibility/QtAndroidAutomotive/ActivityView/activityview.pro @@ -0,0 +1,23 @@ +TARGET = studioqtandroidautomotiveactivityview +TARGETPATH = QtAndroidAutomotive/ActivityView +IMPORT_VERSION = 1.0 + +QT += qml quick +QT_PRIVATE += core-private gui-private qml-private quick-private quicktemplates2-private quickcontrols2-private + +DEFINES += QT_NO_CAST_TO_ASCII QT_NO_CAST_FROM_ASCII + +include(activityview.pri) + +OTHER_FILES += \ + qmldir \ + $$QML_FILES + +SOURCES += \ + $$PWD/studiocompatibilityqaaactivityview.cpp + +!static: qtConfig(quick-designer): include(designer/designer.pri) +## include(doc/doc.pri) + +CONFIG += no_cxx_module install_qml_files qtquickcompiler +load(qml_plugin) diff --git a/src/imports/compatibility/QtAndroidAutomotive/ActivityView/designer/ActivityViewSpecifics.qml b/src/imports/compatibility/QtAndroidAutomotive/ActivityView/designer/ActivityViewSpecifics.qml new file mode 100644 index 0000000..48fcd81 --- /dev/null +++ b/src/imports/compatibility/QtAndroidAutomotive/ActivityView/designer/ActivityViewSpecifics.qml @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** Copyright (C) 2022 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Quick Ultralite compatibility. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Layouts +import HelperWidgets +import StudioTheme 1.0 as StudioTheme + +//! [ActivityView compatibility] +Section { + anchors.left: parent.left + anchors.right: parent.right + caption: qsTr("Activity View") + + SectionLayout { + PropertyLabel { text: qsTr("Package name") } + + LineEdit { + backendValue: backendValues.packageName + Layout.fillWidth: true + + } + + PropertyLabel { text: qsTr("Class name") } + + LineEdit { + backendValue: backendValues.className + Layout.fillWidth: true + } + + PropertyLabel { text: qsTr("Corner radius") } + + SecondColumnLayout { + SpinBox { + minimumValue: 0 + maximumValue: 128 + decimals: 0 + backendValue: backendValues.radius + Layout.fillWidth: true + } + } + } +} +//! [ActivityView compatibility] diff --git a/src/imports/compatibility/QtAndroidAutomotive/ActivityView/designer/designer.pri b/src/imports/compatibility/QtAndroidAutomotive/ActivityView/designer/designer.pri new file mode 100644 index 0000000..58861bc --- /dev/null +++ b/src/imports/compatibility/QtAndroidAutomotive/ActivityView/designer/designer.pri @@ -0,0 +1,9 @@ +AUX_QML_FILES += \ + $$PWD/qtandroidautomotiveactivityview.metainfo + +AUX_QML_FILES += \ + $$PWD/ActivityViewSpecifics.qml + +AUX_QML_FILES += \ + $$PWD/images/qtaa-av-icon.png \ + $$PWD/images/qtaa-av-icon@2x.png diff --git a/src/imports/compatibility/QtAndroidAutomotive/ActivityView/designer/images/qtaa-av-icon.png b/src/imports/compatibility/QtAndroidAutomotive/ActivityView/designer/images/qtaa-av-icon.png Binary files differnew file mode 100644 index 0000000..fc14ca4 --- /dev/null +++ b/src/imports/compatibility/QtAndroidAutomotive/ActivityView/designer/images/qtaa-av-icon.png diff --git a/src/imports/compatibility/QtAndroidAutomotive/ActivityView/designer/images/qtaa-av-icon@2x.png b/src/imports/compatibility/QtAndroidAutomotive/ActivityView/designer/images/qtaa-av-icon@2x.png Binary files differnew file mode 100644 index 0000000..a195f66 --- /dev/null +++ b/src/imports/compatibility/QtAndroidAutomotive/ActivityView/designer/images/qtaa-av-icon@2x.png diff --git a/src/imports/compatibility/QtAndroidAutomotive/ActivityView/designer/qtandroidautomotiveactivityview.metainfo b/src/imports/compatibility/QtAndroidAutomotive/ActivityView/designer/qtandroidautomotiveactivityview.metainfo new file mode 100644 index 0000000..babf3e1 --- /dev/null +++ b/src/imports/compatibility/QtAndroidAutomotive/ActivityView/designer/qtandroidautomotiveactivityview.metainfo @@ -0,0 +1,23 @@ + +MetaInfo { + + Type { + name: "QtAndroidAutomotive.ActivityView.ActivityView" + icon: "images/qtaa-av-icon.png" + + Hints { + visibleInNavigator: true + canBeDroppedInNavigator: true + canBeDroppedInFormEditor: true + } + + ItemLibraryEntry { + name: "ActivityView" + category: "ActivityView" + version: "1.0" + requiredImport: "QtAndroidAutomotive.ActivityView" + libraryIcon: "images/qtaa-av-icon@2x.png" + } + } + +} diff --git a/src/imports/compatibility/QtAndroidAutomotive/ActivityView/plugins.qmltypes b/src/imports/compatibility/QtAndroidAutomotive/ActivityView/plugins.qmltypes new file mode 100644 index 0000000..6a6c815 --- /dev/null +++ b/src/imports/compatibility/QtAndroidAutomotive/ActivityView/plugins.qmltypes @@ -0,0 +1,13 @@ +import QtQuick.tooling 1.2 + +// This file describes the plugin-supplied types contained in the library. +// It is used for QML tooling purposes only. +// +// This file was auto-generated by: +// 'qmlplugindump -nonrelocatable -dependencies dependencies.json QtQuick.Controls 2.15' + +Module { + dependencies: [ + "QtQuick 2.12" + ] +} diff --git a/src/imports/compatibility/QtAndroidAutomotive/ActivityView/qmldir b/src/imports/compatibility/QtAndroidAutomotive/ActivityView/qmldir new file mode 100644 index 0000000..9e8508c --- /dev/null +++ b/src/imports/compatibility/QtAndroidAutomotive/ActivityView/qmldir @@ -0,0 +1,2 @@ +module QtAndroidAutomotive.ActivityView +ActivityView 1.0 ActivityView.qml diff --git a/src/imports/compatibility/QtAndroidAutomotive/ActivityView/studiocompatibilityqaaactivityview.cpp b/src/imports/compatibility/QtAndroidAutomotive/ActivityView/studiocompatibilityqaaactivityview.cpp new file mode 100644 index 0000000..ff51895 --- /dev/null +++ b/src/imports/compatibility/QtAndroidAutomotive/ActivityView/studiocompatibilityqaaactivityview.cpp @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** Copyright (C) 2022 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Quick Ultralite compatibility. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtQml/qqmlextensionplugin.h> + +QT_BEGIN_NAMESPACE + +class StudioCompatibilityQtAaActivityView: public QQmlExtensionPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid) + +public: + StudioCompatibilityQtAaActivityView(QObject *parent = nullptr); + void registerTypes(const char *uri) override; +}; + +StudioCompatibilityQtAaActivityView::StudioCompatibilityQtAaActivityView(QObject *parent) + : QQmlExtensionPlugin(parent) +{ +} + +void StudioCompatibilityQtAaActivityView::registerTypes(const char *) +{ +} + +QT_END_NAMESPACE + +#include "studiocompatibilityqaaactivityview.moc" diff --git a/src/imports/compatibility/QtAndroidAutomotive/QtAndroidAutomotive.pro b/src/imports/compatibility/QtAndroidAutomotive/QtAndroidAutomotive.pro new file mode 100644 index 0000000..9381f4c --- /dev/null +++ b/src/imports/compatibility/QtAndroidAutomotive/QtAndroidAutomotive.pro @@ -0,0 +1,3 @@ +TEMPLATE = subdirs +SUBDIRS += \ + ActivityView/activityview.pro diff --git a/src/imports/compatibility/compatibility.pro b/src/imports/compatibility/compatibility.pro index 24b614f..7156aa6 100644 --- a/src/imports/compatibility/compatibility.pro +++ b/src/imports/compatibility/compatibility.pro @@ -1,4 +1,5 @@ TEMPLATE = subdirs SUBDIRS += \ - QtQuickUltralite + QtQuickUltralite \ + QtAndroidAutomotive |