diff options
author | Hatem ElKharashy <hatem.elkharashy@qt.io> | 2024-02-09 16:30:38 +0200 |
---|---|---|
committer | Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io> | 2024-02-22 22:45:13 +0100 |
commit | 406e6054184f87edfbca06cd9ce2a6a7daed9aca (patch) | |
tree | f6ecc054bcf6fe654be382ba1df1e9156dcfa816 | |
parent | dd72694b6046d98a64bd99361ed9cb4613af78f8 (diff) |
QQuickVectorImage: Add VectorImage item
The VectorImage item will take a vector graphics file like an SVG, and
generates a QtQuick representation out of it at runtime. Initially,
it will act as the counterpart of svgtoqml tool, and later on it might
include other formats than SVG.
Task-number: QTBUG-120987
Change-Id: Ie85c5a6309004202b449f7adc6a71d2a772df228
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
-rw-r--r-- | src/quick/doc/qtquick.qdocconf | 3 | ||||
-rw-r--r-- | src/quick/doc/src/qmltypereference.qdoc | 2 | ||||
-rw-r--r-- | src/quick/doc/src/qtquick.qdoc | 2 | ||||
-rw-r--r-- | src/quickvectorimage/CMakeLists.txt | 16 | ||||
-rw-r--r-- | src/quickvectorimage/qquickvectorimage.cpp | 132 | ||||
-rw-r--r-- | src/quickvectorimage/qquickvectorimage_p.h | 49 | ||||
-rw-r--r-- | src/quickvectorimage/qquickvectorimage_p_p.h | 47 | ||||
-rw-r--r-- | tests/manual/CMakeLists.txt | 3 | ||||
-rw-r--r-- | tests/manual/quickvectorimage/CMakeLists.txt | 1 | ||||
-rw-r--r-- | tests/manual/quickvectorimage/vectorimage/CMakeLists.txt | 30 | ||||
-rw-r--r-- | tests/manual/quickvectorimage/vectorimage/Main.qml | 37 | ||||
-rw-r--r-- | tests/manual/quickvectorimage/vectorimage/res/spheres.svg | 72 | ||||
-rw-r--r-- | tests/manual/quickvectorimage/vectorimage/vectorimage.cpp | 22 |
13 files changed, 415 insertions, 1 deletions
diff --git a/src/quick/doc/qtquick.qdocconf b/src/quick/doc/qtquick.qdocconf index 27efe4d087..6b98a6f71a 100644 --- a/src/quick/doc/qtquick.qdocconf +++ b/src/quick/doc/qtquick.qdocconf @@ -83,7 +83,8 @@ imagedirs += images {headerdirs,sourcedirs} += \ ../../particles \ ../../quickshapes \ - ../../effects + ../../effects \ + ../../quickvectorimage # Add imports and plugins directories because of dependencies {headerdirs,sourcedirs} += \ diff --git a/src/quick/doc/src/qmltypereference.qdoc b/src/quick/doc/src/qmltypereference.qdoc index ce4bd264d0..ea87eed087 100644 --- a/src/quick/doc/src/qmltypereference.qdoc +++ b/src/quick/doc/src/qmltypereference.qdoc @@ -37,6 +37,8 @@ information about the concepts that are central to \c QtQuick. one or more simple graphical effects to Qt Quick items. \li \l{Qt Quick Shapes QML Types}{Shapes} - provides types for rendering vector shapes in a Qt Quick scene. + \li \l{Qt Quick Vector Image QML Types}{Vector Image} - provides types for displaying vector + image files. \endlist \target value-types diff --git a/src/quick/doc/src/qtquick.qdoc b/src/quick/doc/src/qtquick.qdoc index e04751ca4c..277ad4f8bb 100644 --- a/src/quick/doc/src/qtquick.qdoc +++ b/src/quick/doc/src/qtquick.qdoc @@ -136,6 +136,8 @@ To find out more about using the QML language, see the \l{Qt Qml} module documen - contains types for writing unit test for a QML application \li \l{Qt Quick Shapes QML Types}{Shapes} - provides types for rendering vector shapes in a Qt Quick scene. + \li \l{Qt Quick Vector Image QML Types}{Vector Image} - provides types for displaying + vector image files. \endlist \endlist diff --git a/src/quickvectorimage/CMakeLists.txt b/src/quickvectorimage/CMakeLists.txt index 2580061e48..ecca0432e5 100644 --- a/src/quickvectorimage/CMakeLists.txt +++ b/src/quickvectorimage/CMakeLists.txt @@ -22,3 +22,19 @@ qt_internal_add_module(QuickVectorImageGeneratorPrivate Qt::SvgPrivate GENERATE_CPP_EXPORTS ) + +qt_internal_add_qml_module(QuickVectorImage + URI "QtQuick.VectorImage" + VERSION "${PROJECT_VERSION}" + PLUGIN_TARGET qquickvectorimageplugin + NO_PLUGIN_OPTIONAL + CLASS_NAME QtQuickVectorImagePlugin + SOURCES + qquickvectorimage_p.h qquickvectorimage.cpp + qquickvectorimage_p_p.h + LIBRARIES + Qt::QuickPrivate + Qt::QuickVectorImageGeneratorPrivate + Qt::SvgPrivate + GENERATE_CPP_EXPORTS +) diff --git a/src/quickvectorimage/qquickvectorimage.cpp b/src/quickvectorimage/qquickvectorimage.cpp new file mode 100644 index 0000000000..d2039c5d38 --- /dev/null +++ b/src/quickvectorimage/qquickvectorimage.cpp @@ -0,0 +1,132 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#include "qquickvectorimage_p.h" +#include "qquickvectorimage_p_p.h" +#include <QtQuickVectorImageGenerator/private/qquickitemgenerator_p.h> +#include <QtQuickVectorImageGenerator/private/qquickvectorimageglobal_p.h> +#include <QtCore/qloggingcategory.h> + +QT_BEGIN_NAMESPACE + +/*! + \qmlmodule QtQuick.VectorImage + \title Qt Quick Vector Image QML Types + \ingroup qmlmodules + \brief Provides QML types for displaying vector image files. + + To use the types in this module, import the module with the following line: + + \qml + import QtQuick.VectorImage + \endqml + + Qt Quick Vector Image provides support for displaying vector image files in a Qt Quick + scene. + + It currently supports the \c SVG file format. + + \section1 QML Types +*/ + +Q_LOGGING_CATEGORY(lcQuickVectorImage, "qt.quick.vectorimage", QtWarningMsg) + +void QQuickVectorImagePrivate::setSource(const QUrl &source) +{ + Q_Q(QQuickVectorImage); + if (sourceFile == source) + return; + + sourceFile = source; + loadSvg(); + emit q->sourceChanged(); +} + +void QQuickVectorImagePrivate::loadSvg() +{ + Q_Q(QQuickVectorImage); + + QUrl resolvedUrl = qmlContext(q)->resolvedUrl(sourceFile); + QString localFile = QQmlFile::urlToLocalFileOrQrc(resolvedUrl); + + if (localFile.isEmpty()) + return; + + QQuickVectorImagePrivate::Format fileFormat = formatFromFilePath(localFile); + + if (fileFormat != QQuickVectorImagePrivate::Format::Svg) { + qCWarning(lcQuickVectorImage) << "Unsupported file format"; + return; + } + + if (svgItem) + svgItem->deleteLater(); + + svgItem = new QQuickItem(q); + + QQuickVectorImageGenerator::GeneratorFlags flags; + flags.setFlag(QQuickVectorImageGenerator::CurveRenderer); + QQuickItemGenerator generator(localFile, flags, svgItem); + generator.generate(); + + svgItem->setParentItem(q); + q->setImplicitWidth(svgItem->width()); + q->setImplicitHeight(svgItem->height()); + q->update(); +} + +QQuickVectorImagePrivate::Format QQuickVectorImagePrivate::formatFromFilePath(const QString &filePath) +{ + Q_UNUSED(filePath) + + QQuickVectorImagePrivate::Format res = QQuickVectorImagePrivate::Format::Unknown; + + if (filePath.endsWith(QLatin1String(".svg")) || filePath.endsWith(QLatin1String(".svgz")) + || filePath.endsWith(QLatin1String(".svg.gz"))) { + res = QQuickVectorImagePrivate::Format::Svg; + } + + return res; +} + +/*! + \qmltype VectorImage + \inqmlmodule QtQuick.VectorImage + \brief Loads a vector image file and displays it in a Qt Quick scene. + \since 6.8 + + The VectorImage can be used to load a vector image file and display this as an item in a Qt + Quick scene. It currently supports the \c SVG file format. + + \note This complements the approach of loading the vector image file through an \l Image + element: \l Image creates a raster version of the image at the requested size. VectorImage + builds a Qt Quick scene that represents the image. This means the resulting item can be scaled + and rotated without losing quality, and it will typically consume less memory than the + rasterized version. +*/ +QQuickVectorImage::QQuickVectorImage(QQuickItem *parent) + : QQuickItem(*(new QQuickVectorImagePrivate), parent) +{ + setFlag(QQuickItem::ItemHasContents, true); +} + +/*! + \qmlproperty url QtQuick.VectorImage::VectorImage::source + + This property holds the URL of the vector image file to load. + + VectorImage currently only supports the \c SVG file format. +*/ +QUrl QQuickVectorImage::source() const +{ + Q_D(const QQuickVectorImage); + return d->sourceFile; +} + +void QQuickVectorImage::setSource(const QUrl &source) +{ + Q_D(QQuickVectorImage); + d->setSource(source); +} + +QT_END_NAMESPACE diff --git a/src/quickvectorimage/qquickvectorimage_p.h b/src/quickvectorimage/qquickvectorimage_p.h new file mode 100644 index 0000000000..d2aa3c51cc --- /dev/null +++ b/src/quickvectorimage/qquickvectorimage_p.h @@ -0,0 +1,49 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#ifndef QQUICKVECTORIMAGE_P_H +#define QQUICKVECTORIMAGE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QQuickItem> +#include <QtQuickVectorImage/qtquickvectorimageexports.h> + +QT_BEGIN_NAMESPACE + +class QQuickVectorImagePrivate; + +class Q_QUICKVECTORIMAGE_EXPORT QQuickVectorImage : public QQuickItem +{ + Q_OBJECT + + Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged) + QML_NAMED_ELEMENT(VectorImage) + +public: + QQuickVectorImage(QQuickItem *parent = nullptr); + + QUrl source() const; + void setSource(const QUrl &source); + +signals: + void sourceChanged(); + +private: + Q_DISABLE_COPY(QQuickVectorImage) + Q_DECLARE_PRIVATE(QQuickVectorImage) +}; + +QT_END_NAMESPACE + +#endif // QQUICKVECTORIMAGE_P_H + diff --git a/src/quickvectorimage/qquickvectorimage_p_p.h b/src/quickvectorimage/qquickvectorimage_p_p.h new file mode 100644 index 0000000000..b0cd4b83d3 --- /dev/null +++ b/src/quickvectorimage/qquickvectorimage_p_p.h @@ -0,0 +1,47 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#ifndef QQUICKVECTORIMAGE_P_P_H +#define QQUICKVECTORIMAGE_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QQuickPaintedItem> +#include <QSvgRenderer> +#include <private/qquickitem_p.h> +#include "qquickvectorimage_p.h" + +QT_BEGIN_NAMESPACE + +class QQuickVectorImagePrivate : public QQuickItemPrivate +{ + Q_DECLARE_PUBLIC(QQuickVectorImage) +public: + QQuickVectorImagePrivate() = default; + virtual ~QQuickVectorImagePrivate() = default; + + void setSource(const QUrl &source); + void loadSvg(); + + enum Format { + Unknown, + Svg + }; + QQuickVectorImagePrivate::Format formatFromFilePath(const QString &filePath); + + QUrl sourceFile; + QQuickItem *svgItem = nullptr; +}; + +QT_END_NAMESPACE + +#endif // QQUICKVECTORIMAGE_P_P_H diff --git a/tests/manual/CMakeLists.txt b/tests/manual/CMakeLists.txt index a4367463c6..c1a5d4f820 100644 --- a/tests/manual/CMakeLists.txt +++ b/tests/manual/CMakeLists.txt @@ -31,3 +31,6 @@ add_subdirectory(itemparticle) add_subdirectory(delegatechooser) add_subdirectory(maskedmousearea) add_subdirectory(windowembedding) +if(TARGET Qt::QuickVectorImage) + add_subdirectory(quickvectorimage) +endif() diff --git a/tests/manual/quickvectorimage/CMakeLists.txt b/tests/manual/quickvectorimage/CMakeLists.txt new file mode 100644 index 0000000000..10b17bb143 --- /dev/null +++ b/tests/manual/quickvectorimage/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(vectorimage) diff --git a/tests/manual/quickvectorimage/vectorimage/CMakeLists.txt b/tests/manual/quickvectorimage/vectorimage/CMakeLists.txt new file mode 100644 index 0000000000..631009594f --- /dev/null +++ b/tests/manual/quickvectorimage/vectorimage/CMakeLists.txt @@ -0,0 +1,30 @@ +# Copyright (C) 2024 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +if (NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(svgitem LANGUAGES C CXX ASM) + find_package(Qt6BuildInternals COMPONENTS STANDALONE_TEST) +endif() + +qt_internal_add_manual_test(tst_manual_vectorimage + GUI + SOURCES + vectorimage.cpp + LIBRARIES + Qt::Quick + Qt::QuickVectorImage +) + +# Resources: +set(res + "res/spheres.svg" + "Main.qml" +) + +qt_internal_add_resource(tst_manual_vectorimage "vectorimage_res" + PREFIX + "/" + FILES + ${res} +) diff --git a/tests/manual/quickvectorimage/vectorimage/Main.qml b/tests/manual/quickvectorimage/vectorimage/Main.qml new file mode 100644 index 0000000000..4ce5f33262 --- /dev/null +++ b/tests/manual/quickvectorimage/vectorimage/Main.qml @@ -0,0 +1,37 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +import QtCore +import QtQuick +import QtQuick.VectorImage +import QtQuick.Controls +import QtQuick.Dialogs + +Window { + width: 1920 + height: 1080 + title: qsTr("Vector Image") + visible: true + + Column { + spacing: 20 + + Button { + width: 100 + height: 50 + text: qsTr("Select Svg file") + onClicked: fileDialog.open() + } + + VectorImage { + id: vectorImage + source: "qrc:/res/spheres.svg" + } + } + + FileDialog { + id: fileDialog + currentFolder: StandardPaths.standardLocations(StandardPaths.HomeLocation)[0] + onAccepted: vectorImage.source = selectedFile + } +} diff --git a/tests/manual/quickvectorimage/vectorimage/res/spheres.svg b/tests/manual/quickvectorimage/vectorimage/res/spheres.svg new file mode 100644 index 0000000000..b23164bce3 --- /dev/null +++ b/tests/manual/quickvectorimage/vectorimage/res/spheres.svg @@ -0,0 +1,72 @@ +<?xml version="1.0" standalone="no"?> +<svg width="8cm" height="8cm" viewBox="0 0 400 400" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink/" + baseProfile="tiny" version="1.2"> + <title>Spheres</title> + <desc>Gradient filled spheres with different colors.</desc> + <defs> + <!-- Create radial gradients for each circle to make them look like + spheres. --> + <radialGradient id="blueSphere" gradientUnits="userSpaceOnUse" + cx="0" cy="0" r="100" fx="-50" fy="-50"> + <stop offset="0%" stop-color="white" /> + <stop offset="75%" stop-color="blue" /> + <stop offset="100%" stop-color="#222244" /> + </radialGradient> + <radialGradient id="redSphere" gradientUnits="userSpaceOnUse" + cx="0" cy="0" r="100" fx="-50" fy="-50"> + <stop offset="0%" stop-color="white" /> + <stop offset="75%" stop-color="red" /> + <stop offset="100%" stop-color="#442222" /> + </radialGradient> + <radialGradient id="greenSphere" gradientUnits="userSpaceOnUse" + cx="0" cy="0" r="100" fx="-50" fy="-50"> + <stop offset="0%" stop-color="white" /> + <stop offset="75%" stop-color="green" /> + <stop offset="100%" stop-color="#113311" /> + </radialGradient> + <radialGradient id="yellowSphere" gradientUnits="userSpaceOnUse" + cx="0" cy="0" r="100" fx="-50" fy="-50"> + <stop offset="0%" stop-color="white" /> + <stop offset="75%" stop-color="yellow" /> + <stop offset="100%" stop-color="#444422" /> + </radialGradient> + <radialGradient id="shadowGrad" gradientUnits="userSpaceOnUse" + cx="0" cy="0" r="100" fx="-50" fy="50"> + <stop offset="0%" stop-color="black" stop-opacity="1.0" /> + <stop offset="100%" stop-color="white" stop-opacity="0.0" /> + </radialGradient> + + <!-- Define a shadow for each sphere. --> + <circle id="shadow" fill="url(#shadowGrad)" cx="0" cy="0" r="100" /> + </defs> + <g fill="#ffee99" stroke="none" > + <rect x="0" y="0" width="400" height="400" /> + </g> + <g fill="white" stroke="none" > + <rect x="0" y="175" width="400" height="225" /> + </g> + <g transform="translate(200,175)"> + <use xlink:href="#shadow" transform="translate(25,55) scale(1.0,0.5)" /> + <circle fill="url(#blueSphere)" cx="0" cy="0" r="100" /> + </g> + <g transform="translate(315,240)"> + <g transform="scale(0.5,0.5)"> + <use xlink:href="#shadow" transform="translate(25,55) scale(1.0,0.5)" /> + <circle fill="url(#redSphere)" cx="0" cy="0" r="100" /> + </g> + </g> + <g transform="translate(80,275)"> + <g transform="scale(0.65,0.65)"> + <use xlink:href="#shadow" transform="translate(25,55) scale(1.0,0.5)" /> + <circle fill="url(#greenSphere)" cx="0" cy="0" r="100" /> + </g> + </g> + <g transform="translate(255,325)"> + <g transform="scale(0.3,0.3)"> + <use xlink:href="#shadow" transform="translate(25,55) scale(1.0,0.5)" /> + <circle fill="url(#yellowSphere)" cx="0" cy="0" r="100" /> + </g> + </g> +</svg> diff --git a/tests/manual/quickvectorimage/vectorimage/vectorimage.cpp b/tests/manual/quickvectorimage/vectorimage/vectorimage.cpp new file mode 100644 index 0000000000..d6795d7c64 --- /dev/null +++ b/tests/manual/quickvectorimage/vectorimage/vectorimage.cpp @@ -0,0 +1,22 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#include <QGuiApplication> +#include <QQmlApplicationEngine> + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + const QString filePath(QLatin1String(":/Main.qml")); + QObject::connect( + &engine, + &QQmlApplicationEngine::objectCreationFailed, + &app, + []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.load(filePath); + + return app.exec(); +} |